Commit Graph

34 Commits

Author SHA1 Message Date
rcourtman 2774744b11 Preserve canonical resource IDs in Patrol queries 2026-07-15 09:16:39 +01:00
rcourtman e008343b7a Align Docker host query schema and executor 2026-07-14 19:13:11 +01:00
rcourtman 8c8affc041 Split tool registration authority and make the registry append-only
Review of 3073a5061 found the remaining registration hole: Register
rejected canonical descriptor overrides but still accepted a canonical
NAME with a nil override, inheriting the canonical descriptor while
replacing the governed handler in the map - an extension could re-register
pulse_read and bypass its execution-intent enforcement.

Registration authority is now split. registerBuiltin is the unexported
construction-time path for canonical Pulse tools: shared descriptor
mandatory, overrides rejected. RegisterExtension - the only path exposed
through PulseToolExecutor.RegisterTool - rejects every canonical tool
name outright and requires the extension to declare its own descriptor.
Both paths are append-only: a name registers exactly once, so no later
registration can swap out an already-governed handler.

Proofs cover the exact bypass (canonical name, nil override), extension
and builtin duplicate rejection, builtin override rejection, and
descriptor-less extension rejection. Tests that previously swapped
handlers by re-registering now use fresh executors per scenario.
Contract prose and source pins updated.
2026-07-10 15:16:06 +01:00
rcourtman ee8a24e14a backend and governance: MCP contract, agent capabilities, API, and release-control
Manifest-backed MCP tools, prompts, and resources with surface affordance contracts; agent capability manifest and governance projection; API contract tests and capability route projection; operations-loop and intelligence-funnel telemetry; release-control subsystem documentation, registry, and tooling; licensing and configuration.
2026-06-23 17:26:15 +01:00
rcourtman 8439ce6e6b Dedupe AI runtime guest-family, tool-pipeline, and provider clones
Clears the ten dupl pairs across internal/ai:

- patrol_intelligence.go, tools_query.go, tools_storage.go: VM and LXC
  system-container paths collapse into generics over read-state view
  method subsets (gatherGuestIntelligenceFromViews, canonicalGuestGetResult
  + guestViewGetResult, addCanonicalGuestSearchMatches +
  addGuestViewSearchMatches, appendGuestDiskSummaries).
- tools_file.go: append/write share executeFileMutation driven by
  fileMutationSpec (approval-command text, shell redirect, verification
  strategy stay per-action and verbatim).
- tools_kubernetes.go: deployment restart / pod delete share
  executeKubernetesResourceAction driven by kubernetesResourceAction.
- providers/anthropic.go + anthropic_oauth.go: message conversion shared
  via convertMessagesToAnthropic (the OAuth copy was annotated 'same as
  regular client').
- memory/changes.go + memory/remediation.go: history loading shared via
  the generic loadMemoryHistory in memory/paths.go (10 MiB cap, sort,
  missing-file semantics preserved via a found flag).
- findings.go and unified/alerts.go: Finding/findingJSON and
  UnifiedFinding/unifiedFindingJSON are deliberate marshal-mirror twins
  (AlertIdentifier json:"-" vs alert_identifier round-trip); merging
  would break every public literal. Suppressed with nolint:dupl and
  enforced instead by new reflect-based mirror-sync tests.

Contract Extension Points name the shared helpers and the mirror
invariant. Full ./internal/ai/... test tree passes.
2026-06-10 09:38:52 +01:00
rcourtman accebfb305 Infer resource_type from a canonical handle in pulse_query get
In the trace for 'hows esphome', the model called get with the canonical handle
'system-container-599a2e3...' as resource_id and no resource_type, and it failed
twice with 'resource_type is required' before recovering with 'get 102'. The user
sees those failed tool calls in the chat.

A canonical handle already encodes the type (unifiedresources/ids.go builds ids
as '<type>-<hash>'), so executeGetResource now infers resource_type from the
handle when it's omitted, via resourceTypeFromCanonicalID (the trailing hex hash
segment is unambiguous since no type word is all-hex). A bare numeric VMID still
requires an explicit type. Test TestResourceTypeFromCanonicalID covers it; full
internal/ai/tools green.
2026-06-08 15:49:09 +01:00
rcourtman 7c583c0547 Answer Assistant inventory counts locally 2026-06-06 01:47:05 +01:00
rcourtman 29ac5945bc Fix resource-context Assistant tool targeting 2026-06-04 19:18:08 +01:00
rcourtman 3f8525a7c2 Implement resource-aware Assistant context 2026-06-04 16:36:04 +01:00
rcourtman d3934e19e3 Harden repository advisory boundaries 2026-05-24 08:15:29 +01:00
rcourtman 0561a1b5fa Remove Assistant and Patrol tool-routing heuristics 2026-05-15 14:51:15 +01:00
rcourtman 895b78bd89 Make Assistant tool choice model-owned 2026-05-15 11:27:15 +01:00
rcourtman 7df4588f63 Hydrate Assistant handoff resource policy context 2026-05-06 18:55:23 +01:00
rcourtman aeede4fb2f Hydrate Assistant handoff resource scope 2026-05-06 17:59:55 +01:00
rcourtman f8fd641978 Harden Pulse Assistant action governance 2026-04-23 23:01:51 +01:00
rcourtman a41c956320 fix(ai): fail closed on unknown v6 read commands 2026-04-09 19:21:16 +01:00
rcourtman d9d9dd9585 Normalize pulse_query agent and storage floor 2026-03-31 00:26:04 +01:00
rcourtman dd5f099cda Lock VMware phase-1 exclusion integrity 2026-03-30 23:42:32 +01:00
rcourtman 56c14ca19f feat(ai): add canonical truenas app config reads 2026-03-29 20:36:43 +01:00
rcourtman b0ba88d541 feat(ai): add canonical truenas app control 2026-03-29 19:50:31 +01:00
rcourtman a6c0386069 feat(ai): expose canonical truenas resources to pulse query 2026-03-29 18:25:39 +01:00
rcourtman 2afb96ee13 fix(release): align api and hostagent rc contracts 2026-03-26 17:08:48 +00:00
rcourtman 699a81f7a2 Centralize resource policy cloning 2026-03-19 03:11:38 +00:00
rcourtman 778a2577b6 feat: Pulse v6 release 2026-03-18 16:06:30 +00:00
rcourtman 7efcec3120 fix(agents,ai): host URL field, AI Docker routing, Proxmox registration logging (#1197, #1210, #1267)
#1197: Add Custom URL input to the expanded host row in Settings → Agents.
Loads existing URL via HostMetadataAPI on row expand; saves on button click.
Only shown for host-type agent rows.

#1210: Fix agent_connected always false for Docker hosts on Proxmox VMs.
connectedAgentHostnames now also marks Docker host hostnames reachable when
their matching VM/LXC has a node with a connected Proxmox agent, mirroring
the routing logic already used in the control path.

#1267/#1269: Improve Proxmox auto-registration failure logging. Response body
is now included in the error message, and the warning directs users to delete
the state file to force re-registration rather than claiming the node exists.

(cherry picked from commit 305f6d3c94f0da4fc970450a6304da57d6d7fe80)
2026-02-18 12:57:09 +00:00
rcourtman 81ec5c525a feat(ai): parallelize tool execution and refine knowledge extraction
- Implement parallel execution for read-only tools in agentic loop
- Optimize negative marker summaries to be more informative
- Fix memory percentage scaling in query tools
- Add derived memory stats (avg/max) to extraction logic
- Add explicit fresh data intent detection to bypass knowledge gate
- Update associated tests
2026-02-01 00:12:36 +00:00
rcourtman 95a0d7a6bd feat(backend): implement AI Patrol, Investigation, and system-wide refactors 2026-01-30 19:02:14 +00:00
rcourtman e85ec858fd fix(ai): discovery transient error handling, agentic loop detection, and read-only classification
- Discovery: classify transient errors (429, timeout, connection refused, etc.)
  and return IsError:true so models stop retrying rate-limited calls
- Agentic loop: detect identical tool calls repeated >3 times and block with
  LOOP_DETECTED error, forcing the model to try a different approach
- OpenAI provider: skip tool_choice for DeepSeek Reasoner which doesn't support it
- Read-only classifier: fix curl -I case sensitivity (uppercase flags lowered),
  add iostat/vmstat/mpstat/sar/lxc-ls/lxc-info/nc -z to allowlist,
  fix 2>&1 false positive in input redirect detection
2026-01-29 18:29:54 +00:00
rcourtman a75393d1c5 refactor(ai): consolidate tool implementations into domain-specific files
- Merge tools_infrastructure.go, tools_intelligence.go, tools_patrol.go,
  tools_profiles.go into their respective domain tools
- Expand tools_control.go with command execution logic
- Expand tools_discovery.go with resource discovery handlers
- Expand tools_storage.go with storage-related operations
- Expand tools_metrics.go with metrics functionality
- Update tests to match new structure

This consolidation reduces file count and groups related functionality together.
2026-01-28 21:21:28 +00:00
rcourtman 0013d64c7b Consolidate and extend AI tool suite
Major tools refactoring for better organization and capabilities:

New consolidated tools:
- pulse_query: Unified resource search, get, config, topology operations
- pulse_read: Safe read-only command execution with NonInteractiveOnly
- pulse_control: Guest lifecycle control (start/stop/restart)
- pulse_docker: Docker container operations
- pulse_file: Safe file read/write operations
- pulse_kubernetes: K8s resource management
- pulse_metrics: Performance metrics retrieval
- pulse_alerts: Alert management
- pulse_storage: Storage pool operations
- pulse_knowledge: Note-taking and recall
- pulse_pmg: Proxmox Mail Gateway integration

Executor improvements:
- Cleaner tool registration pattern
- Better error handling and recovery
- Protocol layer for result formatting
- Enhanced adapter interfaces

Includes comprehensive tests for:
- File and Docker operations
- Kubernetes control operations
- Command execution safety
2026-01-28 16:50:25 +00:00
rcourtman f293f41499 refactor: consolidate AI tools tests
- Remove executor_test.go (tests moved to specific tool test files)
- Refactor infrastructure, patrol, profiles, and query tests
- Add query tool enhancements for better resource filtering
2026-01-22 00:43:41 +00:00
rcourtman b57b4a7c3c Tighten AI chat routing and context display 2026-01-20 16:30:55 +00:00
rcourtman 96b7370f7b test: improve coverage for API, AI, Alerts, and Frontend Utils
- Add comprehensive tests for internal/api/config_handlers.go (Phases 1-3)
- Improve test coverage for AI tools, chat service, and session management
- Enhance alert and notification tests (ResolvedAlert, Webhook)
- Add frontend unit tests for utils (searchHistory, tagColors, temperature, url)
- Add proximity client API tests
2026-01-20 15:52:39 +00:00
rcourtman 17ca31a557 refactor(ai): Replace mcp package with tools package for direct tool execution
This refactoring removes the MCP (Model Context Protocol) server layer and
converts AI tools to be called directly by the chat service.

Key changes:
- Rename package from internal/ai/mcp to internal/ai/tools
- Remove server.go - tools no longer exposed via MCP server
- Tools are now called directly by the chat service via ExecuteTool()

New tools added:
- Kubernetes: clusters, nodes, pods, deployments (4 tools)
- PMG: mail gateway status, mail stats, queues, spam stats (4 tools)
- Infrastructure: snapshots, PBS jobs, backup tasks, network stats,
  disk I/O, cluster status, swarm, services, tasks, recent tasks,
  physical disks, RAID status, host Ceph, resource disks (14 tools)
- Patrol: connection health, resolved alerts (2 tools)

Test coverage:
- Added comprehensive test files for adapters, infrastructure,
  patrol, profiles, and query tools

Total tools: 50 (was ~25)
2026-01-19 19:17:24 +00:00