@phuetz/code-buddy 2.0.0 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.fr.md +56 -0
- package/README.md +73 -16
- package/codebuddy-runtime.json +5 -5
- package/dist/agent/codebuddy-agent.d.ts +18 -0
- package/dist/agent/codebuddy-agent.js +45 -8
- package/dist/agent/execution/agent-executor.d.ts +0 -9
- package/dist/agent/execution/agent-executor.js +165 -12
- package/dist/agent/execution/context-pipeline.d.ts +9 -0
- package/dist/agent/execution/context-pipeline.js +64 -2
- package/dist/agent/execution/tool-loop-guard.d.ts +76 -0
- package/dist/agent/execution/tool-loop-guard.js +165 -0
- package/dist/agent/execution/tool-selection-strategy.js +19 -2
- package/dist/agent/facades/session-facade.d.ts +0 -6
- package/dist/agent/facades/session-facade.js +0 -45
- package/dist/agent/hermes-claw-migrate.d.ts +0 -21
- package/dist/agent/hermes-claw-migrate.js +9 -4
- package/dist/agent/hermes-protocol-gateways.js +8 -1
- package/dist/agent/repo-profiler.js +17 -4
- package/dist/agent/self-improvement/authored-tool-runtime.js +10 -2
- package/dist/agent/self-improvement/evolution/ast-novelty.d.ts +5 -0
- package/dist/agent/self-improvement/evolution/ast-novelty.js +58 -23
- package/dist/agent/self-improvement/evolution/code-variant-store.d.ts +3 -0
- package/dist/agent/self-improvement/evolution/evolution-engine.js +2 -0
- package/dist/agent/self-improvement/evolution/protected-paths.js +6 -0
- package/dist/agent/self-improvement/evolution/variant-fitness.d.ts +13 -2
- package/dist/agent/self-improvement/evolution/variant-fitness.js +184 -58
- package/dist/agent/self-improvement/evolution/worktree-scorer.d.ts +2 -0
- package/dist/agent/self-improvement/evolution/worktree-scorer.js +15 -0
- package/dist/agent/self-improvement/evolutionary-archive.d.ts +2 -1
- package/dist/agent/self-improvement/evolutionary-archive.js +34 -5
- package/dist/agent/self-improvement/proposal-store.d.ts +1 -0
- package/dist/agent/self-improvement/proposal-store.js +79 -17
- package/dist/agent/self-improvement/skill-apply-journal.d.ts +44 -0
- package/dist/agent/self-improvement/skill-apply-journal.js +178 -0
- package/dist/agent/self-improvement/skill-behavior-benchmark.d.ts +3 -0
- package/dist/agent/self-improvement/skill-behavior-benchmark.js +19 -0
- package/dist/agent/self-improvement/skill-behavior-gate.d.ts +34 -0
- package/dist/agent/self-improvement/skill-behavior-gate.js +96 -0
- package/dist/agent/self-improvement/skill-engine.d.ts +22 -0
- package/dist/agent/self-improvement/skill-engine.js +385 -13
- package/dist/agent/self-improvement/skill-gate.d.ts +2 -0
- package/dist/agent/self-improvement/skill-gate.js +17 -2
- package/dist/agent/self-improvement/skill-mutator.d.ts +6 -1
- package/dist/agent/self-improvement/skill-mutator.js +51 -15
- package/dist/agent/self-improvement/skill-types.d.ts +2 -1
- package/dist/agent/self-improvement/types.d.ts +11 -0
- package/dist/agent/tool-handler.d.ts +1 -1
- package/dist/agent/tool-handler.js +28 -9
- package/dist/auth/profile-manager.js +1 -1
- package/dist/channels/companion-channel-turn.d.ts +53 -4
- package/dist/channels/companion-channel-turn.js +218 -16
- package/dist/channels/slash-parity.d.ts +4 -6
- package/dist/channels/slash-parity.js +9 -44
- package/dist/cli/session-commands.d.ts +9 -0
- package/dist/cli/session-commands.js +45 -5
- package/dist/cli/session-picker.d.ts +43 -0
- package/dist/cli/session-picker.js +128 -0
- package/dist/codebuddy/a2a-call-tool-defs.d.ts +26 -0
- package/dist/codebuddy/a2a-call-tool-defs.js +12 -0
- package/dist/codebuddy/fleet-tool-defs.d.ts +1 -0
- package/dist/codebuddy/fleet-tool-defs.js +24 -0
- package/dist/codebuddy/providers/chatgpt-headers.d.ts +18 -0
- package/dist/codebuddy/providers/chatgpt-headers.js +37 -0
- package/dist/codebuddy/providers/provider-chatgpt-responses.d.ts +2 -1
- package/dist/codebuddy/providers/provider-chatgpt-responses.js +10 -23
- package/dist/codebuddy/providers/provider-openai-compat.js +1 -1
- package/dist/codebuddy/ragchat-tool-defs.d.ts +31 -0
- package/dist/codebuddy/ragchat-tool-defs.js +19 -0
- package/dist/codebuddy/resource-catalog-tool-defs.d.ts +28 -0
- package/dist/codebuddy/resource-catalog-tool-defs.js +18 -0
- package/dist/codebuddy/tool-definitions/agent-tools.js +2 -2
- package/dist/codebuddy/tool-definitions/code-exec-tools.js +5 -1
- package/dist/codebuddy/tool-definitions/cron-tools.js +6 -0
- package/dist/codebuddy/tool-definitions/self-describe-tools.js +6 -1
- package/dist/codebuddy/tools.d.ts +0 -6
- package/dist/codebuddy/tools.js +25 -3
- package/dist/commands/cli/daemon-commands.js +3 -1
- package/dist/commands/cli/evolve-command.js +21 -5
- package/dist/commands/cli/fleet-collaboration-commands.d.ts +2 -0
- package/dist/commands/cli/fleet-collaboration-commands.js +57 -0
- package/dist/commands/cli/fleet-commands.js +29 -0
- package/dist/commands/cli/fleet-mission-commands.d.ts +3 -0
- package/dist/commands/cli/fleet-mission-commands.js +72 -0
- package/dist/commands/cli/fleet-rooms-commands.d.ts +10 -0
- package/dist/commands/cli/fleet-rooms-commands.js +289 -0
- package/dist/commands/cli/tools-commands.js +2 -1
- package/dist/commands/cli/triage-command.d.ts +8 -0
- package/dist/commands/cli/triage-command.js +72 -0
- package/dist/commands/cli/utility-commands.js +25 -1
- package/dist/commands/client-dispatcher.d.ts +7 -0
- package/dist/commands/client-dispatcher.js +73 -21
- package/dist/commands/cron-cli/index.d.ts +3 -1
- package/dist/commands/cron-cli/index.js +25 -0
- package/dist/commands/device-auth.d.ts +10 -0
- package/dist/commands/device-auth.js +91 -0
- package/dist/commands/enhanced-command-handler.d.ts +9 -0
- package/dist/commands/enhanced-command-handler.js +28 -6
- package/dist/commands/handlers/agent-handlers.d.ts +1 -1
- package/dist/commands/handlers/agent-handlers.js +4 -4
- package/dist/commands/handlers/channel-handlers.js +53 -2
- package/dist/commands/handlers/export-handlers.d.ts +3 -2
- package/dist/commands/handlers/export-handlers.js +55 -28
- package/dist/commands/handlers/extra-handlers.js +5 -1
- package/dist/commands/handlers/grill-me-handler.js +26 -18
- package/dist/commands/handlers/memory-handlers.d.ts +6 -2
- package/dist/commands/handlers/memory-handlers.js +35 -15
- package/dist/commands/handlers/missing-handlers.d.ts +2 -2
- package/dist/commands/handlers/missing-handlers.js +4 -4
- package/dist/commands/handlers/resources-handler.d.ts +12 -0
- package/dist/commands/handlers/resources-handler.js +52 -0
- package/dist/commands/handlers/starter-handlers.d.ts +1 -1
- package/dist/commands/handlers/starter-handlers.js +32 -2
- package/dist/commands/handlers/switch-handler.d.ts +1 -1
- package/dist/commands/handlers/switch-handler.js +15 -0
- package/dist/commands/handlers/test-handlers.js +4 -86
- package/dist/commands/handlers/ui-handlers.js +11 -5
- package/dist/commands/login-chatgpt.d.ts +8 -0
- package/dist/commands/login-chatgpt.js +17 -0
- package/dist/commands/mcp-import.d.ts +11 -0
- package/dist/commands/mcp-import.js +67 -0
- package/dist/commands/mcp-invoke.d.ts +2 -0
- package/dist/commands/mcp-invoke.js +68 -0
- package/dist/commands/mcp.js +4 -0
- package/dist/commands/pipeline.d.ts +7 -1
- package/dist/commands/pipeline.js +104 -7
- package/dist/commands/resources.d.ts +2 -0
- package/dist/commands/resources.js +64 -0
- package/dist/commands/skills-cli/index.js +35 -12
- package/dist/commands/slash/builtin-commands.js +16 -3
- package/dist/commands/slash/index.d.ts +3 -1
- package/dist/commands/slash/index.js +2 -0
- package/dist/commands/slash/surfaces.d.ts +53 -0
- package/dist/commands/slash/surfaces.js +177 -0
- package/dist/commands/slash/types.d.ts +17 -0
- package/dist/commands/try.d.ts +1 -1
- package/dist/commands/try.js +1 -1
- package/dist/companion/companion-identity.d.ts +43 -0
- package/dist/companion/companion-identity.js +136 -0
- package/dist/companion/companion-toolset.d.ts +66 -0
- package/dist/companion/companion-toolset.js +368 -0
- package/dist/companion/companion-turn.d.ts +10 -2
- package/dist/companion/companion-turn.js +38 -1
- package/dist/config/code-exec-policy.d.ts +25 -0
- package/dist/config/code-exec-policy.js +39 -0
- package/dist/config/model-tools.d.ts +9 -0
- package/dist/config/model-tools.js +4 -0
- package/dist/context/context-manager-v2.js +2 -2
- package/dist/context/lm-resizer-compressor.js +3 -2
- package/dist/context/lm-resizer-diagnostics.d.ts +9 -0
- package/dist/context/lm-resizer-diagnostics.js +30 -0
- package/dist/context/tool-output-masking.js +3 -4
- package/dist/curator/curator.d.ts +6 -0
- package/dist/curator/curator.js +53 -3
- package/dist/daemon/cron-agent-bridge.d.ts +6 -0
- package/dist/daemon/cron-agent-bridge.js +31 -4
- package/dist/doctor/index.d.ts +11 -2
- package/dist/doctor/index.js +84 -21
- package/dist/doctor/integrations.d.ts +179 -0
- package/dist/doctor/integrations.js +227 -0
- package/dist/doctor/triage.d.ts +108 -0
- package/dist/doctor/triage.js +304 -0
- package/dist/fleet/collaboration.d.ts +44 -0
- package/dist/fleet/collaboration.js +170 -0
- package/dist/fleet/fleet-listener.d.ts +1 -0
- package/dist/fleet/fleet-listener.js +87 -46
- package/dist/fleet/fleet-registry.d.ts +2 -0
- package/dist/fleet/resource-catalog.d.ts +245 -0
- package/dist/fleet/resource-catalog.js +211 -0
- package/dist/fleet/rooms/room-access.d.ts +138 -0
- package/dist/fleet/rooms/room-access.js +196 -0
- package/dist/fleet/rooms/room-client.d.ts +158 -0
- package/dist/fleet/rooms/room-client.js +685 -0
- package/dist/fleet/rooms/room-event.d.ts +139 -0
- package/dist/fleet/rooms/room-event.js +330 -0
- package/dist/fleet/rooms/room-filter.d.ts +48 -0
- package/dist/fleet/rooms/room-filter.js +152 -0
- package/dist/fleet/rooms/room-hub.d.ts +154 -0
- package/dist/fleet/rooms/room-hub.js +363 -0
- package/dist/fleet/rooms/room-identity.d.ts +26 -0
- package/dist/fleet/rooms/room-identity.js +82 -0
- package/dist/fleet/rooms/room-lock.d.ts +34 -0
- package/dist/fleet/rooms/room-lock.js +180 -0
- package/dist/fleet/rooms/room-observations.d.ts +7 -0
- package/dist/fleet/rooms/room-observations.js +61 -0
- package/dist/fleet/rooms/room-server.d.ts +28 -0
- package/dist/fleet/rooms/room-server.js +75 -0
- package/dist/fleet/rooms/room-store.d.ts +119 -0
- package/dist/fleet/rooms/room-store.js +448 -0
- package/dist/fleet/rooms/room-ws-bridge.d.ts +27 -0
- package/dist/fleet/rooms/room-ws-bridge.js +137 -0
- package/dist/fleet/sensory-mission-bridge.d.ts +42 -0
- package/dist/fleet/sensory-mission-bridge.js +136 -0
- package/dist/git/worktree-sessions.js +1 -0
- package/dist/harness/contract.d.ts +4 -4
- package/dist/harness/fleet-supervisor.d.ts +16 -0
- package/dist/harness/fleet-supervisor.js +64 -0
- package/dist/harness/index.d.ts +4 -0
- package/dist/harness/index.js +4 -0
- package/dist/harness/mission-runner.d.ts +3 -0
- package/dist/harness/mission-runner.js +53 -0
- package/dist/harness/mission-store.d.ts +93 -0
- package/dist/harness/mission-store.js +297 -0
- package/dist/harness/tool-harness.d.ts +56 -0
- package/dist/harness/tool-harness.js +153 -0
- package/dist/hooks/use-enhanced-input.js +48 -4
- package/dist/hooks/use-input-handler.d.ts +1 -0
- package/dist/hooks/use-input-handler.js +82 -22
- package/dist/hooks/use-input-history.js +1 -0
- package/dist/identity/lisa-introspection.js +5 -2
- package/dist/identity/operational-self-model.d.ts +2 -0
- package/dist/identity/operational-self-model.js +4 -0
- package/dist/index.js +52 -6
- package/dist/mcp/client.js +6 -0
- package/dist/mcp/config.d.ts +20 -0
- package/dist/mcp/config.js +121 -8
- package/dist/mcp/import-normalize.d.ts +12 -0
- package/dist/mcp/import-normalize.js +114 -0
- package/dist/mcp/transports.d.ts +10 -5
- package/dist/mcp/transports.js +61 -99
- package/dist/mcp/types.d.ts +5 -0
- package/dist/media/comfyui-recipe-contract.d.ts +7 -7
- package/dist/memory/facts-memory.d.ts +11 -1
- package/dist/memory/facts-memory.js +47 -8
- package/dist/memory/memory-candidate-queue.d.ts +2 -2
- package/dist/memory/memory-candidate-queue.js +6 -6
- package/dist/memory/persistent-memory.d.ts +13 -8
- package/dist/memory/persistent-memory.js +77 -30
- package/dist/nodes/device-node.js +5 -9
- package/dist/observability/mobile-supervision-gateway-contract.js +20 -7
- package/dist/observability/run-event-writer.d.ts +21 -0
- package/dist/observability/run-event-writer.js +81 -0
- package/dist/observability/run-store.d.ts +5 -0
- package/dist/observability/run-store.js +18 -13
- package/dist/observability/run-trajectory.js +1 -1
- package/dist/optimization/prompt-cache.d.ts +19 -2
- package/dist/optimization/prompt-cache.js +41 -6
- package/dist/orchestration/orchestrator.d.ts +21 -0
- package/dist/orchestration/orchestrator.js +122 -15
- package/dist/persistence/session-content.d.ts +8 -0
- package/dist/persistence/session-content.js +76 -0
- package/dist/persistence/session-handoff.d.ts +64 -0
- package/dist/persistence/session-handoff.js +80 -0
- package/dist/persistence/session-history.d.ts +4 -0
- package/dist/persistence/session-history.js +38 -0
- package/dist/persistence/session-store.d.ts +9 -0
- package/dist/persistence/session-store.js +48 -20
- package/dist/personas/persona-manager.js +17 -1
- package/dist/plugins/code-explorer/CodeExplorerManager.d.ts +10 -4
- package/dist/plugins/code-explorer/CodeExplorerManager.js +69 -16
- package/dist/plugins/plugin-manager.js +10 -1
- package/dist/prompts/prompt-manager.js +11 -4
- package/dist/prompts/system-base.js +6 -2
- package/dist/protocols/a2a/codebuddy-executor.d.ts +11 -2
- package/dist/protocols/a2a/codebuddy-executor.js +9 -8
- package/dist/protocols/a2a/index.d.ts +1 -1
- package/dist/protocols/a2a/jsonrpc-v1.d.ts +41 -0
- package/dist/protocols/a2a/jsonrpc-v1.js +145 -0
- package/dist/protocols/a2a/peer-config.d.ts +20 -0
- package/dist/protocols/a2a/peer-config.js +55 -0
- package/dist/providers/codex-oauth.js +30 -6
- package/dist/providers/model-provider-compat.js +2 -1
- package/dist/sandbox/os-sandbox.d.ts +1 -1
- package/dist/scheduler/cron-scheduler.d.ts +15 -2
- package/dist/scheduler/cron-scheduler.js +35 -4
- package/dist/scheduler/job-notepad.d.ts +69 -0
- package/dist/scheduler/job-notepad.js +339 -0
- package/dist/security/audit-logger.d.ts +1 -1
- package/dist/security/compute-confinement.d.ts +4 -0
- package/dist/security/compute-confinement.js +89 -0
- package/dist/security/session-encryption.d.ts +4 -0
- package/dist/security/session-encryption.js +31 -0
- package/dist/sensory/voice-loop.d.ts +17 -0
- package/dist/sensory/voice-loop.js +72 -15
- package/dist/server/auth/device-session-context.d.ts +9 -0
- package/dist/server/auth/device-session-context.js +13 -0
- package/dist/server/auth/device-store.d.ts +89 -0
- package/dist/server/auth/device-store.js +261 -0
- package/dist/server/auth/device-token.d.ts +3 -0
- package/dist/server/auth/device-token.js +6 -0
- package/dist/server/auth/jwt.js +4 -0
- package/dist/server/index.d.ts +0 -10
- package/dist/server/index.js +28 -0
- package/dist/server/middleware/auth.js +3 -2
- package/dist/server/routes/a2a-jsonrpc.d.ts +9 -0
- package/dist/server/routes/a2a-jsonrpc.js +66 -0
- package/dist/server/routes/a2a-protocol.d.ts +12 -0
- package/dist/server/routes/a2a-protocol.js +1 -1
- package/dist/server/routes/device-auth.d.ts +4 -0
- package/dist/server/routes/device-auth.js +40 -0
- package/dist/server/types.d.ts +4 -0
- package/dist/server/websocket/handler.d.ts +13 -0
- package/dist/server/websocket/handler.js +102 -17
- package/dist/services/prompt-builder.d.ts +2 -0
- package/dist/services/prompt-builder.js +13 -5
- package/dist/services/runtime-settings-context.d.ts +73 -0
- package/dist/services/runtime-settings-context.js +69 -0
- package/dist/skills/executor.js +2 -0
- package/dist/skills/hub.js +16 -14
- package/dist/skills/local-inventory.d.ts +21 -0
- package/dist/skills/local-inventory.js +72 -0
- package/dist/skills/skill-loader.js +2 -2
- package/dist/skills/skill-usage-store.d.ts +49 -0
- package/dist/skills/skill-usage-store.js +121 -0
- package/dist/testing/ai-integration-tests.js +8 -5
- package/dist/themes/theme-manager.d.ts +12 -0
- package/dist/themes/theme-manager.js +29 -0
- package/dist/themes/theme-schema.d.ts +24 -24
- package/dist/tools/a2a-call-tool.d.ts +34 -0
- package/dist/tools/a2a-call-tool.js +75 -0
- package/dist/tools/bash/streaming-executor.d.ts +1 -0
- package/dist/tools/bash/streaming-executor.js +78 -90
- package/dist/tools/code-exec-preflight-runner.d.ts +41 -0
- package/dist/tools/code-exec-preflight-runner.js +254 -0
- package/dist/tools/code-exec-preflight.d.ts +44 -0
- package/dist/tools/code-exec-preflight.js +501 -0
- package/dist/tools/code-exec-tool.d.ts +48 -1
- package/dist/tools/code-exec-tool.js +191 -47
- package/dist/tools/comment-watcher.js +29 -12
- package/dist/tools/core-code-inspection.d.ts +56 -0
- package/dist/tools/core-code-inspection.js +86 -0
- package/dist/tools/create-skill-tool.d.ts +2 -3
- package/dist/tools/create-skill-tool.js +16 -75
- package/dist/tools/cronjob-tool.d.ts +1 -0
- package/dist/tools/cronjob-tool.js +1 -0
- package/dist/tools/env-doctor-tool.d.ts +2 -0
- package/dist/tools/env-doctor-tool.js +4 -3
- package/dist/tools/execute-code-rpc-invoker.d.ts +1 -1
- package/dist/tools/execute-code-rpc-invoker.js +35 -19
- package/dist/tools/execute-code-runner.d.ts +2 -0
- package/dist/tools/execute-code-runner.js +52 -17
- package/dist/tools/fleet-room-tool.d.ts +104 -0
- package/dist/tools/fleet-room-tool.js +124 -0
- package/dist/tools/integration-tool-hints.d.ts +4 -0
- package/dist/tools/integration-tool-hints.js +19 -0
- package/dist/tools/list-peers-tool.d.ts +3 -0
- package/dist/tools/list-peers-tool.js +11 -4
- package/dist/tools/media-generation-tool.d.ts +16 -1
- package/dist/tools/media-generation-tool.js +341 -9
- package/dist/tools/merge-conflict-tool.js +53 -25
- package/dist/tools/metadata.d.ts +1 -5
- package/dist/tools/metadata.js +21 -28
- package/dist/tools/ragchat-tool.d.ts +39 -0
- package/dist/tools/ragchat-tool.js +105 -0
- package/dist/tools/registry/fleet-tools.d.ts +9 -0
- package/dist/tools/registry/fleet-tools.js +22 -1
- package/dist/tools/registry/knowledge-tools.d.ts +2 -2
- package/dist/tools/registry/knowledge-tools.js +2 -2
- package/dist/tools/registry/lessons-tools.d.ts +7 -0
- package/dist/tools/registry/lessons-tools.js +43 -3
- package/dist/tools/registry/memory-tools.d.ts +1 -1
- package/dist/tools/registry/memory-tools.js +8 -8
- package/dist/tools/registry/research-tools.d.ts +1 -0
- package/dist/tools/registry/research-tools.js +4 -13
- package/dist/tools/registry/self-describe-tools.d.ts +1 -1
- package/dist/tools/registry/self-describe-tools.js +43 -30
- package/dist/tools/resource-catalog-tool.d.ts +38 -0
- package/dist/tools/resource-catalog-tool.js +46 -0
- package/dist/tools/skills-inspection-tool.js +30 -1
- package/dist/tools/stream-tool-output.d.ts +3 -0
- package/dist/tools/stream-tool-output.js +33 -0
- package/dist/tools/tool-call-scheduler.d.ts +10 -0
- package/dist/tools/tool-call-scheduler.js +58 -0
- package/dist/tools/tool-effect.d.ts +5 -0
- package/dist/tools/tool-effect.js +26 -0
- package/dist/tools/tool-search.d.ts +12 -11
- package/dist/tools/tool-search.js +67 -26
- package/dist/tools/types.d.ts +6 -0
- package/dist/ui/components/ChatHistory.d.ts +1 -1
- package/dist/ui/components/ChatHistory.js +2 -2
- package/dist/ui/components/ChatInput.d.ts +2 -1
- package/dist/ui/components/ChatInput.js +42 -88
- package/dist/ui/components/ChatInterface.d.ts +4 -2
- package/dist/ui/components/ChatInterface.js +27 -63
- package/dist/ui/components/CommandSuggestions.d.ts +0 -1
- package/dist/ui/components/CommandSuggestions.js +4 -6
- package/dist/ui/components/FileAutocomplete.js +1 -1
- package/dist/ui/components/KeyboardHelp.js +8 -6
- package/dist/ui/components/ModelSelection.js +6 -5
- package/dist/ui/components/StatusBar.d.ts +2 -1
- package/dist/ui/components/StatusBar.js +8 -7
- package/dist/ui/context/theme-context.js +3 -2
- package/dist/ui/index.d.ts +1 -1
- package/dist/ui/index.js +1 -1
- package/dist/ui/utils/markdown-renderer.js +4 -13
- package/dist/utils/atomic-write.d.ts +22 -0
- package/dist/utils/atomic-write.js +29 -0
- package/dist/utils/bounded-output.d.ts +16 -0
- package/dist/utils/bounded-output.js +63 -0
- package/dist/utils/device-store-file.d.ts +4 -0
- package/dist/utils/device-store-file.js +40 -0
- package/dist/utils/export-manager.d.ts +9 -0
- package/dist/utils/export-manager.js +19 -0
- package/dist/utils/first-use-hints.d.ts +25 -0
- package/dist/utils/first-use-hints.js +58 -0
- package/dist/utils/history-manager.js +1 -1
- package/dist/utils/update-notifier.js +16 -18
- package/dist/wizard/environment-detection.d.ts +5 -1
- package/dist/wizard/environment-detection.js +49 -7
- package/dist/wizard/onboarding.d.ts +5 -1
- package/dist/wizard/onboarding.js +90 -30
- package/dist/wizard/provider-onboarding.d.ts +2 -0
- package/dist/wizard/provider-onboarding.js +55 -17
- package/package.json +7 -3
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { publicResourceStatus, ResourceCatalog, resourceSchema, selectionWarning } from '../fleet/resource-catalog.js';
|
|
3
|
+
import { RESOURCE_CATALOG_TOOL_DEF } from '../codebuddy/resource-catalog-tool-defs.js';
|
|
4
|
+
const schema = z.discriminatedUnion('operation', [
|
|
5
|
+
z.object({ operation: z.literal('list') }).strict(),
|
|
6
|
+
z.object({ operation: z.literal('select'), capability: z.string().regex(/^[a-zA-Z0-9][a-zA-Z0-9._:-]{0,95}$/),
|
|
7
|
+
kind: resourceSchema.shape.kind.optional() }).strict(),
|
|
8
|
+
]);
|
|
9
|
+
export class ResourceCatalogTool {
|
|
10
|
+
catalog;
|
|
11
|
+
name = 'resource_catalog';
|
|
12
|
+
description = RESOURCE_CATALOG_TOOL_DEF.function.description;
|
|
13
|
+
constructor(catalog = new ResourceCatalog()) {
|
|
14
|
+
this.catalog = catalog;
|
|
15
|
+
}
|
|
16
|
+
getSchema() { return RESOURCE_CATALOG_TOOL_DEF.function; }
|
|
17
|
+
getMetadata() {
|
|
18
|
+
return { name: this.name, description: this.description, category: 'system',
|
|
19
|
+
keywords: ['resource', 'catalog', 'network', 'fleet', 'ragchat', 'available', 'ressources', 'réseau'],
|
|
20
|
+
priority: 7, modifiesFiles: false, makesNetworkRequests: false };
|
|
21
|
+
}
|
|
22
|
+
isAvailable() { return true; }
|
|
23
|
+
validate(input) {
|
|
24
|
+
return schema.safeParse(input).success ? { valid: true } : { valid: false, errors: ['Paramètres du catalogue invalides.'] };
|
|
25
|
+
}
|
|
26
|
+
async execute(input) {
|
|
27
|
+
const parsed = schema.safeParse(input);
|
|
28
|
+
if (!parsed.success)
|
|
29
|
+
return { success: false, error: 'Paramètres du catalogue invalides ; seules list et select sont disponibles.' };
|
|
30
|
+
try {
|
|
31
|
+
const args = parsed.data;
|
|
32
|
+
const result = args.operation === 'list' ? { resources: (await this.catalog.list()).map(publicResourceStatus) }
|
|
33
|
+
: await this.catalog.select(args.capability, args.kind).then(choice => {
|
|
34
|
+
const warning = selectionWarning(choice.selected);
|
|
35
|
+
return { excluded: choice.excluded, reason: choice.reason,
|
|
36
|
+
selected: choice.selected ? publicResourceStatus(choice.selected) : null, ...(warning ? { warning } : {}) };
|
|
37
|
+
});
|
|
38
|
+
return { success: true, output: JSON.stringify({ ...result, dispatched: false, probed: false,
|
|
39
|
+
instruction: 'Déclarations explicites, santé observée sans preuve d’usage et charge inconnue. Aucune sonde ni exécution effectuée. Une sélection ne change pas les endpoints des autres outils ; ragchat_search utilise RAGCHAT_BASE_URL configuré séparément.' }) };
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
return { success: false, error: 'Catalogue indisponible ou invalide ; aucune sonde, écriture ni exécution effectuée.' };
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=resource-catalog-tool.js.map
|
|
@@ -6,6 +6,16 @@ function serializePayload(payload) {
|
|
|
6
6
|
data: payload,
|
|
7
7
|
};
|
|
8
8
|
}
|
|
9
|
+
/** Activity telemetry is best-effort: a failure never changes the tool result. */
|
|
10
|
+
async function recordView(name) {
|
|
11
|
+
try {
|
|
12
|
+
const { recordSkillActivity } = await import('../skills/skill-usage-store.js');
|
|
13
|
+
recordSkillActivity(name, 'view', { source: 'skill_view' });
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
// Telemetry must never make skill inspection fail.
|
|
17
|
+
}
|
|
18
|
+
}
|
|
9
19
|
function stripUsage(skill) {
|
|
10
20
|
const { usage: _usage, ...rest } = skill;
|
|
11
21
|
return rest;
|
|
@@ -19,8 +29,16 @@ export async function executeSkillsListTool(input) {
|
|
|
19
29
|
const includeUsage = input.include_usage !== false;
|
|
20
30
|
const shown = includeDisabled ? all : all.filter((skill) => skill.enabled !== false);
|
|
21
31
|
const skills = includeUsage ? shown : shown.map(stripUsage);
|
|
32
|
+
const { readLocalSkillInventory } = await import('../skills/local-inventory.js');
|
|
33
|
+
const inventory = await readLocalSkillInventory(all);
|
|
34
|
+
const availableSkills = inventory.entries.filter((skill) => skill.available);
|
|
22
35
|
return serializePayload({
|
|
23
36
|
action: 'skills_list',
|
|
37
|
+
availableSkills,
|
|
38
|
+
availableCount: availableSkills.length,
|
|
39
|
+
unavailableSkills: inventory.entries.filter((skill) => !skill.available),
|
|
40
|
+
discoveryErrors: inventory.errors,
|
|
41
|
+
guidance: 'Use availableSkills to answer which skills can be used. Requirements may need tools or external configuration. The skills/count/total fields below describe only hub records, not the complete local catalogue. Missing files are not configuration errors.',
|
|
24
42
|
count: skills.length,
|
|
25
43
|
total: all.length,
|
|
26
44
|
includeDisabled,
|
|
@@ -40,9 +58,20 @@ export async function executeSkillViewTool(input) {
|
|
|
40
58
|
const { getSkillsHub } = await import('../skills/hub.js');
|
|
41
59
|
const result = getSkillsHub().info(name);
|
|
42
60
|
if (!result) {
|
|
43
|
-
|
|
61
|
+
const { readLocalSkillInventory, readLocalSkillContent } = await import('../skills/local-inventory.js');
|
|
62
|
+
const inventory = await readLocalSkillInventory(getSkillsHub().listWithIntegrity());
|
|
63
|
+
const skill = inventory.entries.find((entry) => entry.name === name);
|
|
64
|
+
if (!skill)
|
|
65
|
+
return { success: false, error: `skill_view: skill not found: ${name}` };
|
|
66
|
+
await recordView(name);
|
|
67
|
+
return serializePayload({
|
|
68
|
+
action: 'skill_view',
|
|
69
|
+
skill,
|
|
70
|
+
...(input.include_content !== false ? { content: await readLocalSkillContent(skill) } : {}),
|
|
71
|
+
});
|
|
44
72
|
}
|
|
45
73
|
const includeContent = input.include_content !== false;
|
|
74
|
+
await recordView(name);
|
|
46
75
|
return serializePayload({
|
|
47
76
|
action: 'skill_view',
|
|
48
77
|
installed: result.installed,
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { ToolResult } from '../types/index.js';
|
|
2
|
+
/** Adapt a callback-based guarded tool invocation without bypassing its dispatch pipeline. */
|
|
3
|
+
export declare function streamToolOutput(run: (signal: AbortSignal, emit: (delta: string) => void) => Promise<ToolResult>, signal?: AbortSignal): AsyncGenerator<string, ToolResult, undefined>;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { BoundedOutput } from '../utils/bounded-output.js';
|
|
2
|
+
/** Adapt a callback-based guarded tool invocation without bypassing its dispatch pipeline. */
|
|
3
|
+
export async function* streamToolOutput(run, signal) {
|
|
4
|
+
const controller = new AbortController();
|
|
5
|
+
const abort = () => controller.abort();
|
|
6
|
+
signal?.addEventListener('abort', abort, { once: true });
|
|
7
|
+
if (signal?.aborted)
|
|
8
|
+
abort();
|
|
9
|
+
const pending = new BoundedOutput(64 * 1024);
|
|
10
|
+
let result;
|
|
11
|
+
let wake;
|
|
12
|
+
const notify = () => { wake?.(); wake = undefined; };
|
|
13
|
+
const completion = Promise.resolve().then(() => run(controller.signal, delta => { pending.append(delta); notify(); }))
|
|
14
|
+
.then(value => { result = value; })
|
|
15
|
+
.catch(error => { result = { success: false, error: error instanceof Error ? error.message : String(error) }; })
|
|
16
|
+
.finally(notify);
|
|
17
|
+
try {
|
|
18
|
+
while (!result || pending.retainedBytes) {
|
|
19
|
+
if (pending.retainedBytes)
|
|
20
|
+
yield pending.drain();
|
|
21
|
+
else
|
|
22
|
+
await new Promise(resolve => { wake = resolve; });
|
|
23
|
+
}
|
|
24
|
+
return result;
|
|
25
|
+
}
|
|
26
|
+
finally {
|
|
27
|
+
abort();
|
|
28
|
+
signal?.removeEventListener('abort', abort);
|
|
29
|
+
// Observe completion without blocking a consumer that intentionally stops.
|
|
30
|
+
void completion;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=stream-tool-output.js.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** FIFO barriers for mutations, bounded parallelism for explicitly safe reads. */
|
|
2
|
+
export declare class ToolCallScheduler {
|
|
3
|
+
private readonly concurrency;
|
|
4
|
+
private active;
|
|
5
|
+
private exclusive;
|
|
6
|
+
private queue;
|
|
7
|
+
constructor(concurrency?: number);
|
|
8
|
+
schedule<T>(parallel: boolean, action: () => Promise<T>, signal?: AbortSignal): Promise<T>;
|
|
9
|
+
private pump;
|
|
10
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/** FIFO barriers for mutations, bounded parallelism for explicitly safe reads. */
|
|
2
|
+
export class ToolCallScheduler {
|
|
3
|
+
concurrency;
|
|
4
|
+
active = 0;
|
|
5
|
+
exclusive = false;
|
|
6
|
+
queue = [];
|
|
7
|
+
constructor(concurrency = 4) {
|
|
8
|
+
this.concurrency = concurrency;
|
|
9
|
+
if (!Number.isSafeInteger(concurrency) || concurrency < 1 || concurrency > 64)
|
|
10
|
+
throw new Error('Concurrency must be an integer between 1 and 64');
|
|
11
|
+
}
|
|
12
|
+
schedule(parallel, action, signal) {
|
|
13
|
+
return new Promise((resolve, reject) => {
|
|
14
|
+
if (signal?.aborted) {
|
|
15
|
+
reject(new Error('Tool call cancelled'));
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
const entry = { parallel, run: async () => {
|
|
19
|
+
signal?.removeEventListener('abort', abort);
|
|
20
|
+
try {
|
|
21
|
+
resolve(await action());
|
|
22
|
+
}
|
|
23
|
+
catch (error) {
|
|
24
|
+
reject(error);
|
|
25
|
+
}
|
|
26
|
+
} };
|
|
27
|
+
const abort = () => {
|
|
28
|
+
const index = this.queue.indexOf(entry);
|
|
29
|
+
if (index < 0)
|
|
30
|
+
return;
|
|
31
|
+
this.queue.splice(index, 1);
|
|
32
|
+
signal?.removeEventListener('abort', abort);
|
|
33
|
+
reject(new Error('Tool call cancelled'));
|
|
34
|
+
this.pump();
|
|
35
|
+
};
|
|
36
|
+
signal?.addEventListener('abort', abort, { once: true });
|
|
37
|
+
this.queue.push(entry);
|
|
38
|
+
this.pump();
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
pump() {
|
|
42
|
+
while (!this.exclusive && this.active < this.concurrency && this.queue.length) {
|
|
43
|
+
const next = this.queue[0];
|
|
44
|
+
if (!next.parallel && this.active)
|
|
45
|
+
return;
|
|
46
|
+
this.queue.shift();
|
|
47
|
+
this.active++;
|
|
48
|
+
this.exclusive = !next.parallel;
|
|
49
|
+
void next.run().finally(() => {
|
|
50
|
+
this.active--;
|
|
51
|
+
if (!next.parallel)
|
|
52
|
+
this.exclusive = false;
|
|
53
|
+
this.pump();
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=tool-call-scheduler.js.map
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { type ToolEffectClass, type ToolMetadata } from './types.js';
|
|
2
|
+
/** Resolve a tool's declared effect class. Missing catalog/MCP entries warn once and return `unknown`. */
|
|
3
|
+
export declare function resolveToolEffect(name: string, metadata?: Pick<ToolMetadata, 'effect'> | null): ToolEffectClass | 'unknown';
|
|
4
|
+
/** Test hook: unique-warning latch. */
|
|
5
|
+
export declare function resetToolEffectWarningLatch(): void;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { logger } from '../utils/logger.js';
|
|
2
|
+
import { TOOL_METADATA } from './metadata.js';
|
|
3
|
+
import { TOOL_EFFECT_CLASSES } from './types.js';
|
|
4
|
+
// Runtime warnings live here so the tool catalog can also serve browser previews.
|
|
5
|
+
const missingEffectWarned = new Set();
|
|
6
|
+
function isToolEffectClass(value) {
|
|
7
|
+
return TOOL_EFFECT_CLASSES.includes(value);
|
|
8
|
+
}
|
|
9
|
+
/** Resolve a tool's declared effect class. Missing catalog/MCP entries warn once and return `unknown`. */
|
|
10
|
+
export function resolveToolEffect(name, metadata) {
|
|
11
|
+
if (isToolEffectClass(metadata?.effect))
|
|
12
|
+
return metadata.effect;
|
|
13
|
+
const catalog = TOOL_METADATA.find((entry) => entry.name === name)?.effect;
|
|
14
|
+
if (isToolEffectClass(catalog))
|
|
15
|
+
return catalog;
|
|
16
|
+
if (!missingEffectWarned.has(name)) {
|
|
17
|
+
missingEffectWarned.add(name);
|
|
18
|
+
logger.warn('tool metadata missing effect class; treating as unknown', { tool: name });
|
|
19
|
+
}
|
|
20
|
+
return 'unknown';
|
|
21
|
+
}
|
|
22
|
+
/** Test hook: unique-warning latch. */
|
|
23
|
+
export function resetToolEffectWarningLatch() {
|
|
24
|
+
missingEffectWarned.clear();
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=tool-effect.js.map
|
|
@@ -9,21 +9,26 @@
|
|
|
9
9
|
*/
|
|
10
10
|
import { BaseTool, ParameterDefinition } from './base-tool.js';
|
|
11
11
|
import { ToolResult } from '../types/index.js';
|
|
12
|
+
import type { IToolExecutionContext } from './registry/types.js';
|
|
13
|
+
export interface SearchableTool {
|
|
14
|
+
name: string;
|
|
15
|
+
description: string;
|
|
16
|
+
keywords?: string[];
|
|
17
|
+
parameters?: unknown;
|
|
18
|
+
}
|
|
12
19
|
/**
|
|
13
20
|
* Build a BM25 index from tool definitions.
|
|
14
21
|
*/
|
|
15
22
|
export declare class BM25Index {
|
|
16
23
|
private documents;
|
|
17
24
|
private avgDL;
|
|
25
|
+
private catalog;
|
|
26
|
+
getTool(name: string): SearchableTool | undefined;
|
|
18
27
|
private idf;
|
|
19
28
|
/**
|
|
20
29
|
* Add tool definitions to the index.
|
|
21
30
|
*/
|
|
22
|
-
index(tools:
|
|
23
|
-
name: string;
|
|
24
|
-
description: string;
|
|
25
|
-
keywords?: string[];
|
|
26
|
-
}>): void;
|
|
31
|
+
index(tools: SearchableTool[]): void;
|
|
27
32
|
/**
|
|
28
33
|
* Search for tools matching a query.
|
|
29
34
|
* Returns results sorted by BM25 score (highest first).
|
|
@@ -37,11 +42,7 @@ export declare class BM25Index {
|
|
|
37
42
|
/**
|
|
38
43
|
* Initialize the BM25 index with available tools.
|
|
39
44
|
*/
|
|
40
|
-
export declare function initToolSearchIndex(tools:
|
|
41
|
-
name: string;
|
|
42
|
-
description: string;
|
|
43
|
-
keywords?: string[];
|
|
44
|
-
}>): void;
|
|
45
|
+
export declare function initToolSearchIndex(tools: SearchableTool[]): void;
|
|
45
46
|
/**
|
|
46
47
|
* Get the BM25 index (creates empty if not initialized).
|
|
47
48
|
*/
|
|
@@ -50,5 +51,5 @@ export declare class ToolSearchTool extends BaseTool {
|
|
|
50
51
|
readonly name = "tool_search";
|
|
51
52
|
readonly description = "Search for available tools by keyword. Useful when you need to find a specific tool from a large set (especially MCP tools).";
|
|
52
53
|
protected getParameters(): Record<string, ParameterDefinition>;
|
|
53
|
-
execute(input: Record<string, unknown
|
|
54
|
+
execute(input: Record<string, unknown>, context?: IToolExecutionContext): Promise<ToolResult>;
|
|
54
55
|
}
|
|
@@ -8,10 +8,36 @@
|
|
|
8
8
|
* Inspired by OpenAI Codex CLI's tool_search with BM25.
|
|
9
9
|
*/
|
|
10
10
|
import { BaseTool } from './base-tool.js';
|
|
11
|
-
import { resolveToolEffect } from './
|
|
11
|
+
import { resolveToolEffect } from './tool-effect.js';
|
|
12
12
|
// ============================================================================
|
|
13
13
|
// BM25 Implementation
|
|
14
14
|
// ============================================================================
|
|
15
|
+
const QUERY_EQUIVALENTS = {
|
|
16
|
+
lire: ['read', 'view'],
|
|
17
|
+
voir: ['view', 'read'],
|
|
18
|
+
contenu: ['content', 'contents'],
|
|
19
|
+
contenus: ['content', 'contents'],
|
|
20
|
+
consulter: ['view', 'read'],
|
|
21
|
+
ouvrir: ['open', 'read', 'view'],
|
|
22
|
+
afficher: ['show', 'display', 'view', 'list'],
|
|
23
|
+
fichier: ['file'],
|
|
24
|
+
fichiers: ['file', 'files'],
|
|
25
|
+
dossier: ['directory', 'folder'],
|
|
26
|
+
dossiers: ['directory', 'directories', 'folder', 'folders'],
|
|
27
|
+
repertoire: ['directory', 'folder'],
|
|
28
|
+
repertoires: ['directory', 'directories', 'folder', 'folders'],
|
|
29
|
+
chercher: ['search', 'find'],
|
|
30
|
+
rechercher: ['search', 'find'],
|
|
31
|
+
trouver: ['find', 'search'],
|
|
32
|
+
modifier: ['edit', 'replace'],
|
|
33
|
+
remplacer: ['replace', 'edit'],
|
|
34
|
+
creer: ['create'],
|
|
35
|
+
supprimer: ['delete', 'remove'],
|
|
36
|
+
memoire: ['memory'],
|
|
37
|
+
executer: ['execute', 'run'],
|
|
38
|
+
lancer: ['run', 'execute'],
|
|
39
|
+
commande: ['command'],
|
|
40
|
+
};
|
|
15
41
|
/** BM25 parameters */
|
|
16
42
|
const K1 = 1.2; // Term frequency saturation
|
|
17
43
|
const B = 0.75; // Length normalization
|
|
@@ -20,10 +46,11 @@ const B = 0.75; // Length normalization
|
|
|
20
46
|
*/
|
|
21
47
|
function tokenize(text) {
|
|
22
48
|
return text
|
|
49
|
+
.replace(/([a-z\d])([A-Z])/g, '$1 $2')
|
|
50
|
+
.normalize('NFKD').replace(/\p{M}/gu, '')
|
|
23
51
|
.toLowerCase()
|
|
24
|
-
.
|
|
25
|
-
.
|
|
26
|
-
.filter(t => t.length > 1);
|
|
52
|
+
.split(/[^\p{L}\p{N}]+/u)
|
|
53
|
+
.filter(Boolean);
|
|
27
54
|
}
|
|
28
55
|
/**
|
|
29
56
|
* Build a BM25 index from tool definitions.
|
|
@@ -31,14 +58,18 @@ function tokenize(text) {
|
|
|
31
58
|
export class BM25Index {
|
|
32
59
|
documents = [];
|
|
33
60
|
avgDL = 0;
|
|
61
|
+
catalog = new Map();
|
|
62
|
+
getTool(name) { return this.catalog.get(name); }
|
|
34
63
|
idf = new Map();
|
|
35
64
|
/**
|
|
36
65
|
* Add tool definitions to the index.
|
|
37
66
|
*/
|
|
38
67
|
index(tools) {
|
|
39
|
-
this.
|
|
68
|
+
this.idf.clear();
|
|
69
|
+
this.catalog = new Map(tools.map(tool => [tool.name, tool]));
|
|
70
|
+
this.documents = [...this.catalog.values()].map(t => {
|
|
40
71
|
const tokens = [
|
|
41
|
-
...tokenize(t.name),
|
|
72
|
+
...Array.from({ length: 3 }, () => tokenize(t.name)).flat(),
|
|
42
73
|
...tokenize(t.description),
|
|
43
74
|
...(t.keywords ?? []).flatMap(k => tokenize(k)),
|
|
44
75
|
];
|
|
@@ -59,14 +90,13 @@ export class BM25Index {
|
|
|
59
90
|
this.avgDL = this.documents.reduce((sum, d) => sum + d.length, 0) / Math.max(this.documents.length, 1);
|
|
60
91
|
// Compute IDF for all terms
|
|
61
92
|
const N = this.documents.length;
|
|
62
|
-
const
|
|
93
|
+
const frequencies = new Map();
|
|
63
94
|
for (const doc of this.documents) {
|
|
64
95
|
for (const token of doc.tf.keys()) {
|
|
65
|
-
|
|
96
|
+
frequencies.set(token, (frequencies.get(token) ?? 0) + 1);
|
|
66
97
|
}
|
|
67
98
|
}
|
|
68
|
-
for (const term of
|
|
69
|
-
const df = this.documents.filter(d => d.tf.has(term)).length;
|
|
99
|
+
for (const [term, df] of frequencies) {
|
|
70
100
|
this.idf.set(term, Math.log((N - df + 0.5) / (df + 0.5) + 1));
|
|
71
101
|
}
|
|
72
102
|
}
|
|
@@ -75,11 +105,12 @@ export class BM25Index {
|
|
|
75
105
|
* Returns results sorted by BM25 score (highest first).
|
|
76
106
|
*/
|
|
77
107
|
search(query, maxResults = 10) {
|
|
78
|
-
const queryTokens = tokenize(query);
|
|
108
|
+
const queryTokens = [...new Set(tokenize(query).flatMap(term => [term, ...(QUERY_EQUIVALENTS[term] ?? [])]))];
|
|
109
|
+
const limit = Number.isFinite(maxResults) ? Math.max(1, Math.min(50, Math.floor(maxResults))) : 10;
|
|
79
110
|
if (queryTokens.length === 0)
|
|
80
111
|
return [];
|
|
81
112
|
const scored = this.documents.map(doc => {
|
|
82
|
-
let score = 0;
|
|
113
|
+
let score = doc.name.toLowerCase() === query.trim().toLowerCase() ? 100 : 0;
|
|
83
114
|
for (const qToken of queryTokens) {
|
|
84
115
|
const tf = doc.tf.get(qToken) ?? 0;
|
|
85
116
|
const idf = this.idf.get(qToken) ?? 0;
|
|
@@ -88,12 +119,15 @@ export class BM25Index {
|
|
|
88
119
|
const denominator = tf + K1 * (1 - B + B * (doc.length / this.avgDL));
|
|
89
120
|
score += idf * (numerator / denominator);
|
|
90
121
|
}
|
|
122
|
+
const nameTerms = new Set(tokenize(doc.name));
|
|
123
|
+
if (queryTokens.every(term => nameTerms.has(term)))
|
|
124
|
+
score += 5;
|
|
91
125
|
return { name: doc.name, description: doc.description, score };
|
|
92
126
|
});
|
|
93
127
|
return scored
|
|
94
128
|
.filter(s => s.score > 0)
|
|
95
|
-
.sort((a, b) => b.score - a.score)
|
|
96
|
-
.slice(0,
|
|
129
|
+
.sort((a, b) => b.score - a.score || a.name.localeCompare(b.name))
|
|
130
|
+
.slice(0, limit);
|
|
97
131
|
}
|
|
98
132
|
}
|
|
99
133
|
// ============================================================================
|
|
@@ -133,12 +167,17 @@ export class ToolSearchTool extends BaseTool {
|
|
|
133
167
|
},
|
|
134
168
|
};
|
|
135
169
|
}
|
|
136
|
-
async execute(input) {
|
|
170
|
+
async execute(input, context) {
|
|
137
171
|
const query = input.query;
|
|
138
|
-
if (!query)
|
|
139
|
-
return this.error('query
|
|
172
|
+
if (typeof query !== 'string' || !query.trim() || query.length > 2000)
|
|
173
|
+
return this.error('query must be a nonempty string of at most 2000 characters');
|
|
174
|
+
if (input.max_results !== undefined && (typeof input.max_results !== 'number' || !Number.isInteger(input.max_results) || input.max_results < 1 || input.max_results > 50))
|
|
175
|
+
return this.error('max_results must be an integer between 1 and 50');
|
|
140
176
|
const maxResults = typeof input.max_results === 'number' ? input.max_results : 10;
|
|
141
|
-
const
|
|
177
|
+
const catalog = context?.extra?.toolSearchCatalog;
|
|
178
|
+
const index = Array.isArray(catalog) ? new BM25Index() : getToolSearchIndex();
|
|
179
|
+
if (Array.isArray(catalog))
|
|
180
|
+
index.index(catalog);
|
|
142
181
|
const results = index.search(query, maxResults);
|
|
143
182
|
if (results.length === 0) {
|
|
144
183
|
return this.success(`No tools found matching "${query}".`);
|
|
@@ -154,22 +193,24 @@ export class ToolSearchTool extends BaseTool {
|
|
|
154
193
|
catch {
|
|
155
194
|
// tools.js not available — skip deferred schema resolution
|
|
156
195
|
}
|
|
157
|
-
const
|
|
196
|
+
const tools = results.map(result => ({
|
|
197
|
+
...result,
|
|
198
|
+
effect: resolveToolEffect(result.name),
|
|
199
|
+
parameters: index.getTool(result.name)?.parameters ??
|
|
200
|
+
deferredSchemas?.get(result.name)?.function?.parameters,
|
|
201
|
+
}));
|
|
202
|
+
const lines = tools.map((r, i) => {
|
|
158
203
|
const effect = resolveToolEffect(r.name);
|
|
159
204
|
let line = `${i + 1}. **${r.name}** (score: ${r.score.toFixed(2)})\n effect: ${effect}\n ${r.description}`;
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
const fullTool = deferredSchemas.get(r.name);
|
|
163
|
-
if (fullTool?.function?.parameters) {
|
|
164
|
-
line += `\n Schema: ${JSON.stringify(fullTool.function.parameters)}`;
|
|
165
|
-
}
|
|
166
|
-
}
|
|
205
|
+
if (r.parameters)
|
|
206
|
+
line += `\n Schema: ${JSON.stringify(r.parameters)}`;
|
|
167
207
|
return line;
|
|
168
208
|
});
|
|
169
209
|
// data.names lets the executor EXPAND the current turn's tool selection
|
|
170
210
|
// with what was discovered — finding a tool must make it invocable on the
|
|
171
211
|
// next round (true progressive disclosure), not just describe it.
|
|
172
212
|
return this.success(`Found ${results.length} tools:\n\n${lines.join('\n\n')}`, {
|
|
213
|
+
tools,
|
|
173
214
|
names: results.map((r) => r.name),
|
|
174
215
|
effects: Object.fromEntries(results.map((r) => [r.name, resolveToolEffect(r.name)])),
|
|
175
216
|
});
|
package/dist/tools/types.d.ts
CHANGED
|
@@ -49,6 +49,12 @@ export interface ToolMetadata {
|
|
|
49
49
|
* silently filtered out from peer-visible tool lists.
|
|
50
50
|
*/
|
|
51
51
|
fleetSafe?: boolean;
|
|
52
|
+
/**
|
|
53
|
+
* Polling/status tool that may legitimately be called repeatedly with the
|
|
54
|
+
* same arguments and result (e.g. waiting on a background job). The tool
|
|
55
|
+
* loop guard (`src/agent/execution/tool-loop-guard.ts`) never counts it.
|
|
56
|
+
*/
|
|
57
|
+
repeatSafe?: boolean;
|
|
52
58
|
}
|
|
53
59
|
/**
|
|
54
60
|
* Result of classifying a user query into tool categories.
|
|
@@ -6,5 +6,5 @@ interface ChatHistoryProps {
|
|
|
6
6
|
/** Maximum number of messages to display (default: 50) */
|
|
7
7
|
maxMessages?: number;
|
|
8
8
|
}
|
|
9
|
-
export declare
|
|
9
|
+
export declare const ChatHistory: React.NamedExoticComponent<ChatHistoryProps>;
|
|
10
10
|
export {};
|
|
@@ -265,7 +265,7 @@ const MemoizedChatEntry = React.memo(({ entry, index, colors, avatars }) => {
|
|
|
265
265
|
}
|
|
266
266
|
});
|
|
267
267
|
MemoizedChatEntry.displayName = "MemoizedChatEntry";
|
|
268
|
-
export function ChatHistory({ entries, isConfirmationActive = false, maxMessages = 50, }) {
|
|
268
|
+
export const ChatHistory = React.memo(function ChatHistory({ entries, isConfirmationActive = false, maxMessages = 50, }) {
|
|
269
269
|
const { colors, avatars } = useTheme();
|
|
270
270
|
// Number of entries permanently committed to <Static> (monotonically increasing)
|
|
271
271
|
// Entries start in the dynamic section and move to static AFTER being finalized
|
|
@@ -336,5 +336,5 @@ export function ChatHistory({ entries, isConfirmationActive = false, maxMessages
|
|
|
336
336
|
" in scrollback"))),
|
|
337
337
|
React.createElement(Static, { items: staticItems }, (entry) => (React.createElement(MemoizedChatEntry, { key: entry.uniqueKey, entry: entry, index: 0, colors: colors, avatars: avatars }))),
|
|
338
338
|
dynamicItems.map((entry, index) => (React.createElement(MemoizedChatEntry, { key: entry.uniqueKey, entry: entry, index: index, colors: colors, avatars: avatars })))));
|
|
339
|
-
}
|
|
339
|
+
});
|
|
340
340
|
//# sourceMappingURL=ChatHistory.js.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React from
|
|
1
|
+
import React from 'react';
|
|
2
2
|
interface ChatInputProps {
|
|
3
3
|
input: string;
|
|
4
4
|
cursorPosition: number;
|
|
@@ -6,5 +6,6 @@ interface ChatInputProps {
|
|
|
6
6
|
isStreaming: boolean;
|
|
7
7
|
mode?: string;
|
|
8
8
|
}
|
|
9
|
+
/** A bounded draft viewport. Editing remains available while the agent works. */
|
|
9
10
|
export declare const ChatInput: React.NamedExoticComponent<ChatInputProps>;
|
|
10
11
|
export {};
|