@phuetz/code-buddy 1.1.0 → 1.3.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.md +211 -163
- package/dist/agent/autonomous/agentic-coding-contract.d.ts +12 -12
- package/dist/agent/base-agent.d.ts +4 -0
- package/dist/agent/base-agent.js +6 -0
- package/dist/agent/codebuddy-agent.d.ts +1 -1
- package/dist/agent/codebuddy-agent.js +69 -14
- package/dist/agent/execution/agent-executor.js +122 -12
- package/dist/agent/execution/tool-dependency-graph.js +7 -0
- package/dist/agent/execution/tool-hooks.d.ts +6 -0
- package/dist/agent/execution/tool-hooks.js +13 -5
- package/dist/agent/execution/tool-selection-strategy.d.ts +11 -2
- package/dist/agent/execution/tool-selection-strategy.js +67 -10
- package/dist/agent/extended-thinking.d.ts +8 -0
- package/dist/agent/extended-thinking.js +27 -0
- package/dist/agent/facades/infrastructure-facade.d.ts +9 -2
- package/dist/agent/facades/infrastructure-facade.js +15 -6
- package/dist/agent/hermes-browser-backends.js +151 -11
- package/dist/agent/hermes-claw-migrate.d.ts +59 -0
- package/dist/agent/hermes-claw-migrate.js +427 -26
- package/dist/agent/hermes-parity-manifest.js +78 -71
- package/dist/agent/hermes-runtime-lifecycle.d.ts +67 -0
- package/dist/agent/hermes-runtime-lifecycle.js +468 -0
- package/dist/agent/middleware/index.d.ts +1 -0
- package/dist/agent/middleware/index.js +1 -0
- package/dist/agent/middleware/visual-validation-middleware.d.ts +17 -0
- package/dist/agent/middleware/visual-validation-middleware.js +67 -0
- package/dist/agent/model-benchmark.d.ts +77 -0
- package/dist/agent/model-benchmark.js +309 -0
- package/dist/agent/model-tier.d.ts +14 -0
- package/dist/agent/model-tier.js +71 -0
- package/dist/agent/multi-agent/agents/orchestrator-agent.js +17 -6
- package/dist/agent/multi-agent/multi-agent-system.js +3 -1
- package/dist/agent/multi-agent/session-fleet-bridge.d.ts +2 -0
- package/dist/agent/multi-agent/session-fleet-bridge.js +9 -1
- package/dist/agent/multi-agent/session-tools.js +22 -5
- package/dist/agent/reasoning/mcts.js +20 -6
- package/dist/agent/self-improvement/authored-artifact-gate.d.ts +18 -0
- package/dist/agent/self-improvement/authored-artifact-gate.js +42 -0
- package/dist/agent/self-improvement/authored-tool-runtime.d.ts +27 -0
- package/dist/agent/self-improvement/authored-tool-runtime.js +57 -0
- package/dist/agent/self-improvement/authored-tool-store.d.ts +24 -0
- package/dist/agent/self-improvement/authored-tool-store.js +57 -0
- package/dist/agent/self-improvement/llm-tool-proposer.d.ts +41 -0
- package/dist/agent/self-improvement/llm-tool-proposer.js +136 -0
- package/dist/agent/self-improvement/sandbox-scorer.d.ts +17 -0
- package/dist/agent/self-improvement/sandbox-scorer.js +43 -0
- package/dist/agent/self-improvement/self-knowledge.d.ts +8 -0
- package/dist/agent/self-improvement/self-knowledge.js +24 -0
- package/dist/agent/self-improvement/skill-benchmark.d.ts +9 -0
- package/dist/agent/self-improvement/skill-benchmark.js +22 -0
- package/dist/agent/self-improvement/skill-consolidator.d.ts +71 -0
- package/dist/agent/self-improvement/skill-consolidator.js +137 -0
- package/dist/agent/self-improvement/skill-engine.d.ts +42 -0
- package/dist/agent/self-improvement/skill-engine.js +87 -0
- package/dist/agent/self-improvement/skill-gate.d.ts +19 -0
- package/dist/agent/self-improvement/skill-gate.js +62 -0
- package/dist/agent/self-improvement/skill-mutator.d.ts +74 -0
- package/dist/agent/self-improvement/skill-mutator.js +223 -0
- package/dist/agent/self-improvement/skill-proposer.d.ts +40 -0
- package/dist/agent/self-improvement/skill-proposer.js +82 -0
- package/dist/agent/self-improvement/skill-types.d.ts +41 -0
- package/dist/agent/self-improvement/skill-types.js +13 -0
- package/dist/agent/self-improvement/tool-benchmark.d.ts +10 -0
- package/dist/agent/self-improvement/tool-benchmark.js +37 -0
- package/dist/agent/self-improvement/tool-engine.d.ts +54 -0
- package/dist/agent/self-improvement/tool-engine.js +101 -0
- package/dist/agent/self-improvement/tool-gate.d.ts +20 -0
- package/dist/agent/self-improvement/tool-gate.js +78 -0
- package/dist/agent/self-improvement/tool-proposer.d.ts +31 -0
- package/dist/agent/self-improvement/tool-proposer.js +34 -0
- package/dist/agent/self-improvement/tool-skill-mutator.d.ts +40 -0
- package/dist/agent/self-improvement/tool-skill-mutator.js +79 -0
- package/dist/agent/self-improvement/tool-types.d.ts +48 -0
- package/dist/agent/self-improvement/tool-types.js +9 -0
- package/dist/agent/self-improvement/types.d.ts +3 -1
- package/dist/agent/session-end-flush.d.ts +6 -1
- package/dist/agent/session-end-flush.js +20 -4
- package/dist/agent/streaming/streaming-handler.d.ts +7 -0
- package/dist/agent/streaming/streaming-handler.js +8 -1
- package/dist/agent/tool-executor.js +1 -0
- package/dist/agent/tool-handler.d.ts +5 -0
- package/dist/agent/tool-handler.js +133 -4
- package/dist/browser-automation/browser-operator-executor.js +15 -0
- package/dist/browser-automation/browser-use-runner.d.ts +96 -0
- package/dist/browser-automation/browser-use-runner.js +492 -0
- package/dist/browser-automation/camofox-runner.d.ts +107 -0
- package/dist/browser-automation/camofox-runner.js +287 -0
- package/dist/channels/dingtalk/index.js +3 -0
- package/dist/channels/discord/client.d.ts +9 -0
- package/dist/channels/discord/client.js +12 -0
- package/dist/channels/feishu/index.d.ts +167 -1
- package/dist/channels/feishu/index.js +432 -7
- package/dist/channels/gateway-lifecycle.d.ts +132 -0
- package/dist/channels/gateway-lifecycle.js +219 -0
- package/dist/channels/google-chat/index.d.ts +5 -1
- package/dist/channels/google-chat/index.js +5 -1
- package/dist/channels/imessage/index.d.ts +14 -0
- package/dist/channels/imessage/index.js +64 -17
- package/dist/channels/index.d.ts +4 -0
- package/dist/channels/index.js +4 -0
- package/dist/channels/irc/index.d.ts +73 -3
- package/dist/channels/irc/index.js +446 -11
- package/dist/channels/line/index.js +3 -0
- package/dist/channels/mattermost/index.d.ts +51 -4
- package/dist/channels/mattermost/index.js +303 -20
- package/dist/channels/nextcloud-talk/index.d.ts +89 -8
- package/dist/channels/nextcloud-talk/index.js +367 -16
- package/dist/channels/nostr/index.d.ts +121 -1
- package/dist/channels/nostr/index.js +396 -8
- package/dist/channels/ntfy/index.js +3 -0
- package/dist/channels/qq/index.js +3 -0
- package/dist/channels/slash-parity.d.ts +117 -0
- package/dist/channels/slash-parity.js +185 -0
- package/dist/channels/synology-chat/index.js +3 -0
- package/dist/channels/teams/index.d.ts +3 -0
- package/dist/channels/teams/index.js +3 -0
- package/dist/channels/telegram/client.d.ts +9 -0
- package/dist/channels/telegram/client.js +12 -0
- package/dist/channels/twilio-voice/index.js +3 -0
- package/dist/channels/webchat/index.d.ts +7 -1
- package/dist/channels/webchat/index.js +7 -1
- package/dist/channels/wecom/index.js +3 -0
- package/dist/channels/weixin/index.js +3 -0
- package/dist/channels/zalo/index.js +3 -0
- package/dist/cli/config-loader.js +1 -1
- package/dist/codebuddy/client.d.ts +30 -1
- package/dist/codebuddy/client.js +167 -20
- package/dist/codebuddy/providers/provider-chatgpt-responses.d.ts +5 -0
- package/dist/codebuddy/providers/provider-chatgpt-responses.js +7 -1
- package/dist/codebuddy/providers/provider-gemini-native.js +1 -1
- package/dist/codebuddy/providers/provider-openai-compat.d.ts +5 -0
- package/dist/codebuddy/providers/provider-openai-compat.js +82 -2
- package/dist/codebuddy/tool-definitions/computer-control-tools.js +32 -2
- package/dist/codebuddy/tool-definitions/core-tools.js +3 -3
- package/dist/codebuddy/tool-definitions/index.d.ts +2 -1
- package/dist/codebuddy/tool-definitions/index.js +2 -1
- package/dist/codebuddy/tool-definitions/multimodal-tools.d.ts +1 -0
- package/dist/codebuddy/tool-definitions/multimodal-tools.js +44 -1
- package/dist/codebuddy/tool-definitions/windows-tools.d.ts +2 -0
- package/dist/codebuddy/tool-definitions/windows-tools.js +34 -0
- package/dist/codebuddy/tools.d.ts +8 -1
- package/dist/codebuddy/tools.js +67 -24
- package/dist/commands/cli/hermes-commands.js +108 -0
- package/dist/commands/cli/improve-command.js +123 -0
- package/dist/commands/cli/native-engine-commands.js +102 -3
- package/dist/commands/cli/utility-commands.js +45 -0
- package/dist/commands/enhanced-command-handler.js +2 -2
- package/dist/commands/goal-cli.d.ts +30 -0
- package/dist/commands/goal-cli.js +210 -27
- package/dist/commands/handlers/goal-handler.d.ts +9 -2
- package/dist/commands/handlers/goal-handler.js +36 -9
- package/dist/commands/handlers/infra-handlers.js +36 -0
- package/dist/commands/handlers/memory-handlers.js +96 -1
- package/dist/commands/handlers/missing-handlers.d.ts +1 -1
- package/dist/commands/handlers/missing-handlers.js +26 -3
- package/dist/commands/headless-slash.d.ts +2 -0
- package/dist/commands/headless-slash.js +12 -0
- package/dist/commands/llm-provider-resolution.d.ts +5 -3
- package/dist/commands/llm-provider-resolution.js +87 -33
- package/dist/commands/ollama.d.ts +25 -0
- package/dist/commands/ollama.js +100 -0
- package/dist/commands/provider.d.ts +5 -0
- package/dist/commands/provider.js +106 -55
- package/dist/commands/skills-cli/index.js +123 -0
- package/dist/commands/slash/builtin-commands.js +1 -1
- package/dist/commands/spec-next.js +2 -1
- package/dist/commands/spec-plan.js +5 -16
- package/dist/commands/tunnel.d.ts +2 -0
- package/dist/commands/tunnel.js +48 -0
- package/dist/companion/percepts.js +11 -1
- package/dist/config/config-resolver.d.ts +2 -1
- package/dist/config/config-resolver.js +54 -41
- package/dist/config/constants.d.ts +28 -0
- package/dist/config/constants.js +7 -0
- package/dist/config/env-schema.js +756 -0
- package/dist/config/model-tools.js +4 -4
- package/dist/config/toml-config.d.ts +16 -0
- package/dist/config/toml-config.js +3 -0
- package/dist/context/bootstrap-loader.js +6 -23
- package/dist/context/context-manager-v2.js +1 -0
- package/dist/context/import-directive-parser.d.ts +4 -0
- package/dist/context/import-directive-parser.js +51 -6
- package/dist/context/instruction-excludes.d.ts +30 -1
- package/dist/context/instruction-excludes.js +71 -1
- package/dist/context/jit-context.d.ts +8 -10
- package/dist/context/jit-context.js +28 -106
- package/dist/context/project-context.d.ts +90 -0
- package/dist/context/project-context.js +295 -0
- package/dist/daemon/autonomous-daemon.d.ts +1 -1
- package/dist/daemon/autonomous-daemon.js +3 -3
- package/dist/daemon/autonomous-loop.d.ts +31 -1
- package/dist/daemon/autonomous-loop.js +91 -4
- package/dist/daemon/colab-goal.js +9 -1
- package/dist/daemon/cron-agent-bridge.d.ts +12 -3
- package/dist/daemon/cron-agent-bridge.js +25 -9
- package/dist/desktop/codebuddy-engine-adapter.d.ts +32 -0
- package/dist/desktop/codebuddy-engine-adapter.js +257 -80
- package/dist/desktop/engine-adapter.d.ts +14 -0
- package/dist/desktop-automation/automation-manager.js +16 -0
- package/dist/desktop-automation/omniparser-runner.d.ts +63 -0
- package/dist/desktop-automation/omniparser-runner.js +115 -0
- package/dist/desktop-automation/smart-snapshot.d.ts +11 -0
- package/dist/desktop-automation/smart-snapshot.js +72 -5
- package/dist/doctor/index.js +40 -23
- package/dist/events/types.d.ts +11 -0
- package/dist/fleet/colab-store.js +14 -2
- package/dist/fleet/peer-session-bridge.js +50 -12
- package/dist/fleet/peer-tool-bridge.js +14 -0
- package/dist/goals/goal-decomposer.d.ts +27 -0
- package/dist/goals/goal-decomposer.js +293 -0
- package/dist/goals/goal-judge-client.d.ts +15 -0
- package/dist/goals/goal-judge-client.js +45 -0
- package/dist/goals/goal-judge.d.ts +2 -0
- package/dist/goals/goal-judge.js +35 -6
- package/dist/goals/goal-loop.d.ts +14 -0
- package/dist/goals/goal-loop.js +47 -2
- package/dist/goals/goal-manager.d.ts +6 -0
- package/dist/goals/goal-manager.js +67 -14
- package/dist/goals/goal-state.d.ts +13 -0
- package/dist/goals/goal-state.js +83 -13
- package/dist/goals/goal-store.d.ts +3 -0
- package/dist/goals/goal-store.js +31 -15
- package/dist/harness/contract.d.ts +28 -28
- package/dist/hooks/user-hooks.js +17 -3
- package/dist/identity/identity-manager.js +3 -2
- package/dist/index.js +481 -26
- package/dist/input/text-to-speech.d.ts +2 -6
- package/dist/input/text-to-speech.js +2 -27
- package/dist/integrations/screenpipe/screenpipe-client.d.ts +10 -0
- package/dist/integrations/screenpipe/screenpipe-client.js +12 -2
- package/dist/integrations/tailscale.d.ts +13 -0
- package/dist/integrations/tailscale.js +87 -34
- package/dist/knowledge/workspace-indexer.js +53 -9
- package/dist/mcp/client.js +1 -0
- package/dist/mcp/mcp-desktop-tools.d.ts +23 -0
- package/dist/mcp/mcp-desktop-tools.js +158 -0
- package/dist/mcp/mcp-resources.js +2 -3
- package/dist/mcp/mcp-server.js +2 -0
- package/dist/memory/enhanced-memory.d.ts +10 -0
- package/dist/memory/enhanced-memory.js +33 -2
- package/dist/memory/index.d.ts +3 -1
- package/dist/memory/index.js +4 -1
- package/dist/memory/memory-auto-proposer.d.ts +23 -0
- package/dist/memory/memory-auto-proposer.js +308 -0
- package/dist/memory/memory-candidate-queue.d.ts +92 -0
- package/dist/memory/memory-candidate-queue.js +261 -0
- package/dist/memory/persistent-memory.d.ts +45 -2
- package/dist/memory/persistent-memory.js +236 -40
- package/dist/ml/bayesian-qualifier.d.ts +1 -1
- package/dist/ml/bayesian-qualifier.js +35 -2
- package/dist/openclaw/gateway-bridge.js +5 -0
- package/dist/plugins/marketplace.d.ts +1 -0
- package/dist/plugins/marketplace.js +7 -0
- package/dist/prompts/execution-discipline.d.ts +14 -0
- package/dist/prompts/execution-discipline.js +29 -0
- package/dist/prompts/variation-injector.js +9 -2
- package/dist/protocols/acp/acp-agentic-runner.d.ts +7 -6
- package/dist/protocols/acp/acp-agentic-runner.js +115 -18
- package/dist/protocols/acp/acp-session-store.d.ts +23 -0
- package/dist/protocols/acp/acp-session-store.js +77 -0
- package/dist/protocols/acp/acp-stdio-server.d.ts +7 -0
- package/dist/protocols/acp/acp-stdio-server.js +71 -16
- package/dist/providers/active-llm-registry.d.ts +37 -0
- package/dist/providers/active-llm-registry.js +186 -0
- package/dist/providers/auxiliary-provider.d.ts +25 -0
- package/dist/providers/auxiliary-provider.js +192 -0
- package/dist/providers/codex-oauth.d.ts +1 -1
- package/dist/providers/codex-oauth.js +27 -4
- package/dist/providers/index.d.ts +3 -0
- package/dist/providers/index.js +4 -0
- package/dist/providers/provider-catalog.d.ts +70 -0
- package/dist/providers/provider-catalog.js +738 -0
- package/dist/providers/provider-fallback.d.ts +35 -0
- package/dist/providers/provider-fallback.js +171 -0
- package/dist/providers/xai-oauth.d.ts +128 -0
- package/dist/providers/xai-oauth.js +735 -0
- package/dist/scheduler/cron-scheduler.d.ts +15 -3
- package/dist/scheduler/cron-scheduler.js +53 -7
- package/dist/scheduler/script-runner.d.ts +2 -0
- package/dist/scheduler/script-runner.js +19 -4
- package/dist/scheduler/watchdog-handlers.js +7 -20
- package/dist/search/usearch-index.js +7 -2
- package/dist/security/tool-policy/tool-groups.js +2 -0
- package/dist/sensory/dreaming.d.ts +45 -0
- package/dist/sensory/dreaming.js +114 -0
- package/dist/sensory/heartbeat-scheduler.d.ts +38 -0
- package/dist/sensory/heartbeat-scheduler.js +72 -0
- package/dist/sensory/reactions.d.ts +24 -0
- package/dist/sensory/reactions.js +31 -0
- package/dist/sensory/screen-reaction.d.ts +23 -0
- package/dist/sensory/screen-reaction.js +59 -0
- package/dist/sensory/sensory-bridge.d.ts +23 -0
- package/dist/sensory/sensory-bridge.js +85 -0
- package/dist/sensory/sensory-memory.d.ts +20 -0
- package/dist/sensory/sensory-memory.js +39 -0
- package/dist/sensory/speech-reaction.d.ts +21 -0
- package/dist/sensory/speech-reaction.js +83 -0
- package/dist/sensory/vision-reaction.d.ts +31 -0
- package/dist/sensory/vision-reaction.js +74 -0
- package/dist/server/index.js +106 -2
- package/dist/server/routes/mobile.d.ts +12 -4
- package/dist/server/routes/mobile.js +116 -1
- package/dist/server/tls-config.d.ts +35 -0
- package/dist/server/tls-config.js +142 -0
- package/dist/server/tunnel-manager.d.ts +20 -0
- package/dist/server/tunnel-manager.js +58 -0
- package/dist/server/websocket/fleet-bridge.js +5 -0
- package/dist/services/prompt-builder.d.ts +11 -0
- package/dist/services/prompt-builder.js +124 -17
- package/dist/shared/engine-types.d.ts +15 -1
- package/dist/sidecar/sidecar-bridge.d.ts +1 -0
- package/dist/sidecar/sidecar-bridge.js +21 -10
- package/dist/skills/parser.js +3 -0
- package/dist/skills/skill-importer.d.ts +58 -0
- package/dist/skills/skill-importer.js +261 -0
- package/dist/skills/skill-sources.d.ts +20 -0
- package/dist/skills/skill-sources.js +102 -0
- package/dist/skills/types.d.ts +6 -0
- package/dist/spec/spec-store.js +8 -1
- package/dist/talk-mode/providers/audioreader-tts.d.ts +1 -1
- package/dist/talk-mode/providers/audioreader-tts.js +8 -8
- package/dist/templates/project-scaffolding.js +3 -2
- package/dist/themes/theme-schema.d.ts +10 -10
- package/dist/tools/application-profiles.js +38 -0
- package/dist/tools/bash/bash-tool.d.ts +1 -0
- package/dist/tools/bash/bash-tool.js +16 -2
- package/dist/tools/bash/command-validator.js +3 -0
- package/dist/tools/bash/rtk-rewrite.d.ts +16 -0
- package/dist/tools/bash/rtk-rewrite.js +100 -0
- package/dist/tools/bash/streaming-executor.js +14 -1
- package/dist/tools/computer-control-tool.d.ts +16 -1
- package/dist/tools/computer-control-tool.js +317 -5
- package/dist/tools/document-generator.d.ts +14 -0
- package/dist/tools/document-generator.js +79 -0
- package/dist/tools/execute-code-rpc-invoker.d.ts +26 -2
- package/dist/tools/execute-code-rpc-invoker.js +46 -5
- package/dist/tools/metadata.js +28 -0
- package/dist/tools/office-macro-tool.d.ts +10 -0
- package/dist/tools/office-macro-tool.js +93 -0
- package/dist/tools/register-tool-handler.d.ts +25 -0
- package/dist/tools/register-tool-handler.js +100 -0
- package/dist/tools/registry/index.d.ts +2 -1
- package/dist/tools/registry/index.js +2 -1
- package/dist/tools/registry/memory-tools.d.ts +20 -0
- package/dist/tools/registry/memory-tools.js +225 -3
- package/dist/tools/registry/multimodal-tools.js +2 -2
- package/dist/tools/registry/vision-tools.d.ts +33 -0
- package/dist/tools/registry/vision-tools.js +308 -6
- package/dist/tools/registry/windows-tools.d.ts +2 -0
- package/dist/tools/registry/windows-tools.js +47 -0
- package/dist/tools/registry.d.ts +6 -0
- package/dist/tools/registry.js +8 -0
- package/dist/tools/route-peer-tool.js +14 -0
- package/dist/tools/screenshot-tool.js +14 -2
- package/dist/tools/text-to-speech-tool.d.ts +1 -1
- package/dist/tools/text-to-speech-tool.js +2 -12
- package/dist/tools/tool-selector.js +3 -59
- package/dist/utils/config-validation/schema.d.ts +40 -7
- package/dist/utils/config-validation/schema.js +130 -1
- package/dist/utils/cost-tracker.js +21 -1
- package/dist/utils/disk-guard.d.ts +180 -0
- package/dist/utils/disk-guard.js +404 -0
- package/dist/utils/init-project.d.ts +7 -0
- package/dist/utils/init-project.js +37 -0
- package/dist/utils/interactive-setup.js +35 -2
- package/dist/utils/model-utils.js +11 -2
- package/dist/utils/output-sanitizer.js +11 -0
- package/dist/utils/provider-detector.d.ts +8 -7
- package/dist/utils/provider-detector.js +19 -77
- package/dist/utils/settings-manager.d.ts +19 -0
- package/dist/utils/token-display.d.ts +3 -3
- package/dist/utils/token-display.js +22 -4
- package/dist/wizard/onboarding.d.ts +39 -0
- package/dist/wizard/onboarding.js +433 -21
- package/dist/wizard/provider-onboarding.d.ts +8 -23
- package/dist/wizard/provider-onboarding.js +39 -158
- package/package.json +4 -2
- package/dist/plugins/provider-onboarding.d.ts +0 -23
- package/dist/plugins/provider-onboarding.js +0 -116
- package/dist/utils/kokoro-tts.d.ts +0 -8
- package/dist/utils/kokoro-tts.js +0 -67
|
@@ -58,15 +58,15 @@ export declare const agenticCodingApprovalDecisionSchema: z.ZodObject<{
|
|
|
58
58
|
}, "strict", z.ZodTypeAny, {
|
|
59
59
|
reason: string;
|
|
60
60
|
decision: "rejected" | "approved";
|
|
61
|
-
kind: "agentic-coding-approval-decision";
|
|
62
61
|
schemaVersion: 1;
|
|
62
|
+
kind: "agentic-coding-approval-decision";
|
|
63
63
|
reviewer: string;
|
|
64
64
|
decidedAt?: string | undefined;
|
|
65
65
|
}, {
|
|
66
66
|
reason: string;
|
|
67
67
|
decision: "rejected" | "approved";
|
|
68
|
-
kind: "agentic-coding-approval-decision";
|
|
69
68
|
schemaVersion: 1;
|
|
69
|
+
kind: "agentic-coding-approval-decision";
|
|
70
70
|
reviewer: string;
|
|
71
71
|
decidedAt?: string | undefined;
|
|
72
72
|
}>;
|
|
@@ -83,14 +83,14 @@ export declare const agenticCodingWorkflowBuilderProposalSchema: z.ZodEffects<z.
|
|
|
83
83
|
}, "strict", z.ZodTypeAny, {
|
|
84
84
|
type: "action" | "trigger" | "logic";
|
|
85
85
|
id: string;
|
|
86
|
-
description: string;
|
|
87
86
|
label: string;
|
|
87
|
+
description: string;
|
|
88
88
|
agenticType: "edit" | "analysis" | "handoff" | "approval" | "verification" | "gate";
|
|
89
89
|
}, {
|
|
90
90
|
type: "action" | "trigger" | "logic";
|
|
91
91
|
id: string;
|
|
92
|
-
description: string;
|
|
93
92
|
label: string;
|
|
93
|
+
description: string;
|
|
94
94
|
agenticType: "edit" | "analysis" | "handoff" | "approval" | "verification" | "gate";
|
|
95
95
|
}>, "many">;
|
|
96
96
|
edges: z.ZodArray<z.ZodObject<{
|
|
@@ -108,15 +108,15 @@ export declare const agenticCodingWorkflowBuilderProposalSchema: z.ZodEffects<z.
|
|
|
108
108
|
risks: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
|
|
109
109
|
}, "strict", z.ZodTypeAny, {
|
|
110
110
|
summary: string;
|
|
111
|
+
schemaVersion: 1;
|
|
111
112
|
kind: "agentic-coding-workflow-builder-proposal";
|
|
112
113
|
nodes: {
|
|
113
114
|
type: "action" | "trigger" | "logic";
|
|
114
115
|
id: string;
|
|
115
|
-
description: string;
|
|
116
116
|
label: string;
|
|
117
|
+
description: string;
|
|
117
118
|
agenticType: "edit" | "analysis" | "handoff" | "approval" | "verification" | "gate";
|
|
118
119
|
}[];
|
|
119
|
-
schemaVersion: 1;
|
|
120
120
|
edges: {
|
|
121
121
|
source: string;
|
|
122
122
|
target: string;
|
|
@@ -126,15 +126,15 @@ export declare const agenticCodingWorkflowBuilderProposalSchema: z.ZodEffects<z.
|
|
|
126
126
|
coworkVisualizationNotes: string[];
|
|
127
127
|
}, {
|
|
128
128
|
summary: string;
|
|
129
|
+
schemaVersion: 1;
|
|
129
130
|
kind: "agentic-coding-workflow-builder-proposal";
|
|
130
131
|
nodes: {
|
|
131
132
|
type: "action" | "trigger" | "logic";
|
|
132
133
|
id: string;
|
|
133
|
-
description: string;
|
|
134
134
|
label: string;
|
|
135
|
+
description: string;
|
|
135
136
|
agenticType: "edit" | "analysis" | "handoff" | "approval" | "verification" | "gate";
|
|
136
137
|
}[];
|
|
137
|
-
schemaVersion: 1;
|
|
138
138
|
edges: {
|
|
139
139
|
source: string;
|
|
140
140
|
target: string;
|
|
@@ -144,15 +144,15 @@ export declare const agenticCodingWorkflowBuilderProposalSchema: z.ZodEffects<z.
|
|
|
144
144
|
coworkVisualizationNotes?: string[] | undefined;
|
|
145
145
|
}>, {
|
|
146
146
|
summary: string;
|
|
147
|
+
schemaVersion: 1;
|
|
147
148
|
kind: "agentic-coding-workflow-builder-proposal";
|
|
148
149
|
nodes: {
|
|
149
150
|
type: "action" | "trigger" | "logic";
|
|
150
151
|
id: string;
|
|
151
|
-
description: string;
|
|
152
152
|
label: string;
|
|
153
|
+
description: string;
|
|
153
154
|
agenticType: "edit" | "analysis" | "handoff" | "approval" | "verification" | "gate";
|
|
154
155
|
}[];
|
|
155
|
-
schemaVersion: 1;
|
|
156
156
|
edges: {
|
|
157
157
|
source: string;
|
|
158
158
|
target: string;
|
|
@@ -162,15 +162,15 @@ export declare const agenticCodingWorkflowBuilderProposalSchema: z.ZodEffects<z.
|
|
|
162
162
|
coworkVisualizationNotes: string[];
|
|
163
163
|
}, {
|
|
164
164
|
summary: string;
|
|
165
|
+
schemaVersion: 1;
|
|
165
166
|
kind: "agentic-coding-workflow-builder-proposal";
|
|
166
167
|
nodes: {
|
|
167
168
|
type: "action" | "trigger" | "logic";
|
|
168
169
|
id: string;
|
|
169
|
-
description: string;
|
|
170
170
|
label: string;
|
|
171
|
+
description: string;
|
|
171
172
|
agenticType: "edit" | "analysis" | "handoff" | "approval" | "verification" | "gate";
|
|
172
173
|
}[];
|
|
173
|
-
schemaVersion: 1;
|
|
174
174
|
edges: {
|
|
175
175
|
source: string;
|
|
176
176
|
target: string;
|
|
@@ -191,6 +191,10 @@ export declare abstract class BaseAgent extends EventEmitter implements Agent {
|
|
|
191
191
|
getMCPTools(): Promise<Map<string, unknown[]>>;
|
|
192
192
|
getMCPClient(): MCPClient;
|
|
193
193
|
protected initializeMCP(): void;
|
|
194
|
+
/** Resolves once MCP server initialization has settled (or no-op if MCP was
|
|
195
|
+
* never started). Headless/one-shot callers await this so the gitnexus-style
|
|
196
|
+
* MCP tools are registered before the first turn instead of racing init. */
|
|
197
|
+
getMCPReady(): Promise<void>;
|
|
194
198
|
getContextStats(): import("./facades/agent-context-facade.js").ContextStats;
|
|
195
199
|
formatContextStats(): string;
|
|
196
200
|
/**
|
package/dist/agent/base-agent.js
CHANGED
|
@@ -316,6 +316,12 @@ export class BaseAgent extends EventEmitter {
|
|
|
316
316
|
initializeMCP() {
|
|
317
317
|
this.infrastructureFacade.initializeMCP();
|
|
318
318
|
}
|
|
319
|
+
/** Resolves once MCP server initialization has settled (or no-op if MCP was
|
|
320
|
+
* never started). Headless/one-shot callers await this so the gitnexus-style
|
|
321
|
+
* MCP tools are registered before the first turn instead of racing init. */
|
|
322
|
+
getMCPReady() {
|
|
323
|
+
return this.infrastructureFacade.getMCPReady();
|
|
324
|
+
}
|
|
319
325
|
// ============================================================================
|
|
320
326
|
// Context Management (delegates to contextFacade)
|
|
321
327
|
// ============================================================================
|
|
@@ -58,7 +58,7 @@ export declare class CodeBuddyAgent extends BaseAgent {
|
|
|
58
58
|
* @param useRAGToolSelection - Enable RAG-based tool selection (default: true)
|
|
59
59
|
*/
|
|
60
60
|
constructor(apiKey: string, baseURL?: string, model?: string, maxToolRounds?: number, useRAGToolSelection?: boolean, systemPromptId?: string, // New: external prompt ID (default, minimal, secure, etc.)
|
|
61
|
-
workingDirectory?: string, systemPromptAppend?: string);
|
|
61
|
+
workingDirectory?: string, systemPromptAppend?: string, initialSystemPromptOverride?: string);
|
|
62
62
|
/** Resolves when the system prompt has been loaded (or failed gracefully). */
|
|
63
63
|
systemPromptReady: Promise<void>;
|
|
64
64
|
/**
|
|
@@ -14,7 +14,7 @@ import { ToolHandler } from "./tool-handler.js";
|
|
|
14
14
|
import { BaseAgent } from "./base-agent.js";
|
|
15
15
|
import { createAgentInfrastructureSync } from "./infrastructure/index.js";
|
|
16
16
|
import { getLaneQueue } from "../concurrency/lane-queue.js";
|
|
17
|
-
import { findSkill, findStarterPack } from "../skills/index.js";
|
|
17
|
+
import { findSkill, findStarterPack, resetSkillRegistry } from "../skills/index.js";
|
|
18
18
|
import { skillMdToUnified } from "../skills/adapters/index.js";
|
|
19
19
|
import { getSkillsHub } from "../skills/hub.js";
|
|
20
20
|
import { MessageQueue } from "./message-queue.js";
|
|
@@ -24,6 +24,12 @@ import { initializeMemory, getMemoryManager } from "../memory/persistent-memory.
|
|
|
24
24
|
import { getUserHooksManager } from "../hooks/user-hooks.js";
|
|
25
25
|
import { isFeatureEnabled } from "../config/feature-flags.js";
|
|
26
26
|
import { getActiveRunStore } from "../observability/run-store.js";
|
|
27
|
+
import { resetIdentityManager } from "../identity/identity-manager.js";
|
|
28
|
+
import { resetHotReloadManager } from "../config/hot-reload/index.js";
|
|
29
|
+
import { resetConfigWatcher } from "../config/hot-reload/watcher.js";
|
|
30
|
+
import { resetPersonaManager } from "../personas/persona-manager.js";
|
|
31
|
+
import { resetEnhancedMemory } from "../memory/enhanced-memory.js";
|
|
32
|
+
import { resetPluginMarketplace } from "../plugins/marketplace.js";
|
|
27
33
|
/**
|
|
28
34
|
* Main agent class that orchestrates conversation with CodeBuddy AI and tool execution
|
|
29
35
|
*
|
|
@@ -76,9 +82,10 @@ export class CodeBuddyAgent extends BaseAgent {
|
|
|
76
82
|
* @param useRAGToolSelection - Enable RAG-based tool selection (default: true)
|
|
77
83
|
*/
|
|
78
84
|
constructor(apiKey, baseURL, model, maxToolRounds, useRAGToolSelection = true, systemPromptId, // New: external prompt ID (default, minimal, secure, etc.)
|
|
79
|
-
workingDirectory, systemPromptAppend) {
|
|
85
|
+
workingDirectory, systemPromptAppend, initialSystemPromptOverride) {
|
|
80
86
|
super();
|
|
81
87
|
this.systemPromptAppend = systemPromptAppend;
|
|
88
|
+
this.customSystemPromptOverride = initialSystemPromptOverride?.trim() || null;
|
|
82
89
|
this.visionGroundingModel = process.env.CODEBUDDY_VISION_GROUNDING_MODEL || undefined;
|
|
83
90
|
const initialWorkingDirectory = workingDirectory || process.cwd();
|
|
84
91
|
// Determine model to use
|
|
@@ -334,6 +341,27 @@ export class CodeBuddyAgent extends BaseAgent {
|
|
|
334
341
|
catch (err) {
|
|
335
342
|
logger.debug('Failed to register AutoRepairMiddleware (non-critical)', { error: err instanceof Error ? err.message : String(err) });
|
|
336
343
|
}
|
|
344
|
+
// Verification enforcement (priority 155) — after >= 3 file changes with
|
|
345
|
+
// no task_verify/run_tests, nudges the model to verify before finishing.
|
|
346
|
+
// Closes the "loop completes on no-more-tool-calls without a verify gate"
|
|
347
|
+
// gap surfaced by the Hermes agentic-loop audit (2026-06-16).
|
|
348
|
+
try {
|
|
349
|
+
const { createVerificationEnforcementMiddleware } = await import('./middleware/verification-enforcement.js');
|
|
350
|
+
pipeline.use(createVerificationEnforcementMiddleware());
|
|
351
|
+
logger.debug('VerificationEnforcementMiddleware registered in pipeline (priority 155)');
|
|
352
|
+
}
|
|
353
|
+
catch (err) {
|
|
354
|
+
logger.debug('Failed to register VerificationEnforcementMiddleware (non-critical)', { error: err instanceof Error ? err.message : String(err) });
|
|
355
|
+
}
|
|
356
|
+
// Visual validation middleware (priority 156) — suggests taking screenshots of generated Office documents
|
|
357
|
+
try {
|
|
358
|
+
const { VisualValidationMiddleware } = await import('./middleware/visual-validation-middleware.js');
|
|
359
|
+
pipeline.use(new VisualValidationMiddleware());
|
|
360
|
+
logger.debug('VisualValidationMiddleware registered in pipeline (priority 156)');
|
|
361
|
+
}
|
|
362
|
+
catch (err) {
|
|
363
|
+
logger.debug('Failed to register VisualValidationMiddleware (non-critical)', { error: err instanceof Error ? err.message : String(err) });
|
|
364
|
+
}
|
|
337
365
|
// Quality gate middleware (priority 200) — auto-delegates to specialized agents
|
|
338
366
|
try {
|
|
339
367
|
const { createQualityGateMiddleware } = await import('./middleware/quality-gate-middleware.js');
|
|
@@ -492,18 +520,22 @@ Look at the screenshot and find the element matching the user's intent. Output o
|
|
|
492
520
|
}
|
|
493
521
|
async initializeAgentSystemPrompt(systemPromptId, modelName, customInstructions) {
|
|
494
522
|
try {
|
|
495
|
-
|
|
523
|
+
const hasInitialOverride = !!this.customSystemPromptOverride;
|
|
524
|
+
let systemPrompt = this.customSystemPromptOverride
|
|
525
|
+
?? await this.promptBuilder.buildSystemPrompt(systemPromptId, modelName, customInstructions);
|
|
496
526
|
// Inject repoProfile.contextPack if available
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
527
|
+
if (!hasInitialOverride) {
|
|
528
|
+
try {
|
|
529
|
+
const profiler = getRepoProfiler();
|
|
530
|
+
const profile = await profiler.getProfile();
|
|
531
|
+
if (profile.contextPack) {
|
|
532
|
+
systemPrompt = `${systemPrompt}\n\n[Repo] ${profile.contextPack}`;
|
|
533
|
+
logger.debug('RepoProfiler: injected contextPack into system prompt');
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
catch {
|
|
537
|
+
// Non-fatal — repo profiling is best-effort
|
|
503
538
|
}
|
|
504
|
-
}
|
|
505
|
-
catch {
|
|
506
|
-
// Non-fatal — repo profiling is best-effort
|
|
507
539
|
}
|
|
508
540
|
systemPrompt = this.applyRuntimeSystemPromptAppend(systemPrompt);
|
|
509
541
|
// Knowledge base is already injected by PromptBuilder.buildSystemPrompt() — skip duplicate injection here.
|
|
@@ -1639,7 +1671,9 @@ Look at the screenshot and find the element matching the user's intent. Output o
|
|
|
1639
1671
|
// Fire SessionEnd user hook (non-blocking). Shutdown errors should be
|
|
1640
1672
|
// visible (warn, not debug) — silent debug logs masked prior bugs.
|
|
1641
1673
|
getUserHooksManager(process.cwd()).executeHooks('SessionEnd', {}).catch((err) => logger.warn(`[user-hooks] SessionEnd error: ${err instanceof Error ? err.message : String(err)}`));
|
|
1642
|
-
|
|
1674
|
+
const skipAsyncSessionLearning = process.env.CODEBUDDY_HEADLESS === 'true' ||
|
|
1675
|
+
process.env.CODEBUDDY_HEADLESS === '1';
|
|
1676
|
+
if (!skipAsyncSessionLearning && isFeatureEnabled('USER_MODEL_DIALECTIC_ON_SESSION_END')) {
|
|
1643
1677
|
const chatHistory = this.historyManager.getChatHistory();
|
|
1644
1678
|
if (chatHistory && chatHistory.length > 0) {
|
|
1645
1679
|
import('../memory/user-model.js')
|
|
@@ -1659,7 +1693,7 @@ Look at the screenshot and find the element matching the user's intent. Output o
|
|
|
1659
1693
|
// WS3-T1 — session-end flush: handoff + review-gated lesson candidates.
|
|
1660
1694
|
// Fire-and-forget like the dialectic above; callers that need the flush
|
|
1661
1695
|
// to complete before process exit await runSessionEndFlush directly.
|
|
1662
|
-
{
|
|
1696
|
+
if (!skipAsyncSessionLearning) {
|
|
1663
1697
|
const chatHistory = this.historyManager.getChatHistory();
|
|
1664
1698
|
if (chatHistory && chatHistory.length > 0) {
|
|
1665
1699
|
import('./session-end-flush.js')
|
|
@@ -1696,6 +1730,27 @@ Look at the screenshot and find the element matching the user's intent. Output o
|
|
|
1696
1730
|
this.contextManager.stopPeriodicSnapshot?.();
|
|
1697
1731
|
this.peerRoutingConfig = null;
|
|
1698
1732
|
super.dispose();
|
|
1733
|
+
if (skipAsyncSessionLearning) {
|
|
1734
|
+
cleanupHeadlessSingletonWatchers();
|
|
1735
|
+
}
|
|
1736
|
+
}
|
|
1737
|
+
}
|
|
1738
|
+
function cleanupHeadlessSingletonWatchers() {
|
|
1739
|
+
for (const cleanup of [
|
|
1740
|
+
resetSkillRegistry,
|
|
1741
|
+
resetIdentityManager,
|
|
1742
|
+
resetHotReloadManager,
|
|
1743
|
+
resetConfigWatcher,
|
|
1744
|
+
resetPersonaManager,
|
|
1745
|
+
resetEnhancedMemory,
|
|
1746
|
+
resetPluginMarketplace,
|
|
1747
|
+
]) {
|
|
1748
|
+
try {
|
|
1749
|
+
cleanup();
|
|
1750
|
+
}
|
|
1751
|
+
catch (error) {
|
|
1752
|
+
logger.debug('Headless watcher cleanup skipped', { error: String(error) });
|
|
1753
|
+
}
|
|
1699
1754
|
}
|
|
1700
1755
|
}
|
|
1701
1756
|
//# sourceMappingURL=codebuddy-agent.js.map
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
*
|
|
8
8
|
* @module agent/execution
|
|
9
9
|
*/
|
|
10
|
+
import { normalizeHallucinatedLocalToolCall } from "../tool-handler.js";
|
|
10
11
|
import { logger } from "../../utils/logger.js";
|
|
11
12
|
import { getErrorMessage } from "../../errors/index.js";
|
|
12
13
|
import { sanitizeToolResult } from "../../utils/sanitize.js";
|
|
@@ -32,6 +33,22 @@ function withTimeout(promise, ms, fallback) {
|
|
|
32
33
|
new Promise(resolve => setTimeout(() => resolve(fallback), ms)),
|
|
33
34
|
]);
|
|
34
35
|
}
|
|
36
|
+
function isIgnorableControlToolCall(toolCall) {
|
|
37
|
+
const name = toolCall.function?.name?.trim();
|
|
38
|
+
if (!name)
|
|
39
|
+
return true;
|
|
40
|
+
// Some local models leak thinking/channel markers as tool names. Keep
|
|
41
|
+
// malformed-but-actionable aliases such as `thought-tool:execute_command`
|
|
42
|
+
// because ToolHandler normalizes those to real tools.
|
|
43
|
+
if (normalizeHallucinatedLocalToolCall(name, {}))
|
|
44
|
+
return false;
|
|
45
|
+
const lower = name.toLowerCase();
|
|
46
|
+
return (lower === 'thought' ||
|
|
47
|
+
lower === 'thought|' ||
|
|
48
|
+
lower.startsWith('thought|') ||
|
|
49
|
+
lower.includes('<|channel>') ||
|
|
50
|
+
lower.includes('<|tool_call>'));
|
|
51
|
+
}
|
|
35
52
|
// Lazy-loaded workspace context to avoid blocking tests.
|
|
36
53
|
// Includes a 3s hard timeout so git commands never stall the agent loop.
|
|
37
54
|
let _getWorkspaceContext = null;
|
|
@@ -418,6 +435,21 @@ export class AgentExecutor {
|
|
|
418
435
|
const maxToolRounds = this.config.maxToolRounds;
|
|
419
436
|
let toolRounds = 0;
|
|
420
437
|
let totalOutputTokens = 0;
|
|
438
|
+
// In-loop recovery budgets (Hermes parity): bound re-prompts WITHIN a turn
|
|
439
|
+
// so a length-truncated or post-tool-empty response is recovered instead of
|
|
440
|
+
// returned half-written. 0 disables. Per-turn counters.
|
|
441
|
+
const parseRecoveryBudget = (raw, dflt) => {
|
|
442
|
+
const n = Number.parseInt(raw ?? '', 10);
|
|
443
|
+
return Number.isFinite(n) && n >= 0 ? n : dflt;
|
|
444
|
+
};
|
|
445
|
+
const maxLengthContinuations = parseRecoveryBudget(process.env.CODEBUDDY_MAX_LENGTH_CONTINUATIONS, 3);
|
|
446
|
+
// Length-continuation ships ON (default 3, real-tested). The post-tool
|
|
447
|
+
// empty-response re-prompt is harder to trigger deterministically with a
|
|
448
|
+
// real model, so it ships OFF by default (no untested-by-default behaviour
|
|
449
|
+
// in the hot loop) — opt in with CODEBUDDY_MAX_EMPTY_RETRIES=N.
|
|
450
|
+
const maxEmptyRetries = parseRecoveryBudget(process.env.CODEBUDDY_MAX_EMPTY_RETRIES, 0);
|
|
451
|
+
let lengthContinuations = 0;
|
|
452
|
+
let emptyRetries = 0;
|
|
421
453
|
// Phase (d).21 ship 4 — start a progress session for this turn.
|
|
422
454
|
// The default sink (boot-wired) logs at 25/50/75/100. Lazy-import to
|
|
423
455
|
// avoid circular load at module init time.
|
|
@@ -485,12 +517,14 @@ export class AgentExecutor {
|
|
|
485
517
|
// shrink the tool set to ~5 with a minimal alwaysInclude — we
|
|
486
518
|
// don't want to dangle `remember`/`lessons_*` in front of a model
|
|
487
519
|
// that can't actually call tools and would inline-hallucinate them.
|
|
488
|
-
|
|
520
|
+
const activeModelName = this.deps.client.getCurrentModel() ?? '';
|
|
521
|
+
let selectionOpts = activeModelName ? { modelName: activeModelName } : {};
|
|
489
522
|
try {
|
|
490
523
|
const { getModelToolConfig } = await import('../../config/model-tools.js');
|
|
491
|
-
const cfg = getModelToolConfig(
|
|
524
|
+
const cfg = getModelToolConfig(activeModelName);
|
|
492
525
|
if (cfg.promptProfile === 'lite') {
|
|
493
526
|
selectionOpts = {
|
|
527
|
+
...selectionOpts,
|
|
494
528
|
maxTools: 5,
|
|
495
529
|
alwaysInclude: ['view_file', 'bash', 'search'],
|
|
496
530
|
};
|
|
@@ -499,8 +533,9 @@ export class AgentExecutor {
|
|
|
499
533
|
catch { /* model-tools optional, never block */ }
|
|
500
534
|
const selectionResult = await this.deps.toolSelectionStrategy.selectToolsForQuery(message, selectionOpts);
|
|
501
535
|
let tools = selectionResult.tools;
|
|
536
|
+
let forcedChatOnlyToolRunModel = null;
|
|
502
537
|
if (toolRounds === 0)
|
|
503
|
-
this.deps.toolSelectionStrategy.cacheTools(tools);
|
|
538
|
+
this.deps.toolSelectionStrategy.cacheTools(tools, activeModelName);
|
|
504
539
|
// If the active model is flagged `supportsToolCalls: false` in
|
|
505
540
|
// model-tools.ts (typical of small Ollama / LM Studio models that
|
|
506
541
|
// can't reliably emit OpenAI-style tool_call frames), drop the
|
|
@@ -515,12 +550,17 @@ export class AgentExecutor {
|
|
|
515
550
|
// `(client as { defaultModel? }).defaultModel` access always
|
|
516
551
|
// resolved to undefined because that field doesn't exist on
|
|
517
552
|
// the dispatcher class — left the guard latent for ages.
|
|
518
|
-
const modelName =
|
|
553
|
+
const modelName = activeModelName;
|
|
519
554
|
if (modelName) {
|
|
520
555
|
const cfg = getModelToolConfig(modelName);
|
|
521
556
|
if (cfg.supportsToolCalls === false && tools.length > 0) {
|
|
522
|
-
|
|
523
|
-
|
|
557
|
+
if (process.env.GROK_FORCE_TOOLS === 'true') {
|
|
558
|
+
forcedChatOnlyToolRunModel = modelName;
|
|
559
|
+
}
|
|
560
|
+
else {
|
|
561
|
+
logger.debug(`[agent-executor] supportsToolCalls=false for ${modelName} — dropping ${tools.length} tools from chat call`);
|
|
562
|
+
tools = [];
|
|
563
|
+
}
|
|
524
564
|
}
|
|
525
565
|
}
|
|
526
566
|
}
|
|
@@ -597,7 +637,7 @@ export class AgentExecutor {
|
|
|
597
637
|
yield { type: "token_count", tokenCount: inputTokens + result.tokenCount };
|
|
598
638
|
}
|
|
599
639
|
}
|
|
600
|
-
if (!this.deps.streamingHandler.hasYieldedToolCalls()) {
|
|
640
|
+
if (tools.length > 0 && !this.deps.streamingHandler.hasYieldedToolCalls()) {
|
|
601
641
|
const extracted = this.deps.streamingHandler.extractToolCalls();
|
|
602
642
|
if (extracted.toolCalls.length > 0) {
|
|
603
643
|
yield { type: "tool_calls", toolCalls: extracted.toolCalls };
|
|
@@ -605,9 +645,33 @@ export class AgentExecutor {
|
|
|
605
645
|
}
|
|
606
646
|
const accumulatedMessage = this.deps.streamingHandler.getAccumulatedMessage();
|
|
607
647
|
// Sanitize streamed assistant content: strip model control tokens and invisible chars
|
|
608
|
-
|
|
648
|
+
let toolCalls = accumulatedMessage.tool_calls;
|
|
649
|
+
if (Array.isArray(toolCalls) && toolCalls.length > 0) {
|
|
650
|
+
const filteredToolCalls = toolCalls.filter((toolCall) => !isIgnorableControlToolCall(toolCall));
|
|
651
|
+
if (filteredToolCalls.length !== toolCalls.length) {
|
|
652
|
+
logger.debug('[agent-executor] dropped hallucinated control tool calls', {
|
|
653
|
+
dropped: toolCalls.length - filteredToolCalls.length,
|
|
654
|
+
kept: filteredToolCalls.length,
|
|
655
|
+
});
|
|
656
|
+
}
|
|
657
|
+
toolCalls = filteredToolCalls.length > 0 ? filteredToolCalls : undefined;
|
|
658
|
+
}
|
|
659
|
+
const hasToolCalls = Array.isArray(toolCalls) && toolCalls.length > 0;
|
|
660
|
+
// Pre-fallback raw content — used by in-loop recovery to tell a real
|
|
661
|
+
// partial answer (retry-able) from a truly empty turn (give up).
|
|
662
|
+
const streamedContentRaw = (accumulatedMessage.content || "").trim();
|
|
663
|
+
const streamFinishReason = accumulatedMessage.finishReason;
|
|
664
|
+
let rawStreamedContent = accumulatedMessage.content || "";
|
|
665
|
+
if (forcedChatOnlyToolRunModel && !hasToolCalls && !rawStreamedContent.trim()) {
|
|
666
|
+
rawStreamedContent =
|
|
667
|
+
`Blocked: ${forcedChatOnlyToolRunModel} is configured as a chat-only local model and ` +
|
|
668
|
+
'returned no structured tool call even with GROK_FORCE_TOOLS=true. ' +
|
|
669
|
+
'Use a tool-capable model such as qwen3.5-ctx32k or gpt-5.5 for goals that need shell/tools.';
|
|
670
|
+
yield { type: "content", content: `${rawStreamedContent}\n` };
|
|
671
|
+
}
|
|
672
|
+
if (!rawStreamedContent)
|
|
673
|
+
rawStreamedContent = "Using tools to help you...";
|
|
609
674
|
const content = sanitizeAssistantOutput(rawStreamedContent);
|
|
610
|
-
const toolCalls = accumulatedMessage.tool_calls;
|
|
611
675
|
const assistantEntry = {
|
|
612
676
|
type: "assistant",
|
|
613
677
|
content: content,
|
|
@@ -616,6 +680,9 @@ export class AgentExecutor {
|
|
|
616
680
|
};
|
|
617
681
|
history.push(assistantEntry);
|
|
618
682
|
messages.push({ role: "assistant", content: content, tool_calls: toolCalls });
|
|
683
|
+
const currentOutputTokens = this.deps.streamingHandler.getTokenCount() || 0;
|
|
684
|
+
totalOutputTokens += currentOutputTokens;
|
|
685
|
+
yield { type: "token_count", tokenCount: inputTokens + totalOutputTokens };
|
|
619
686
|
if (toolCalls && toolCalls.length > 0) {
|
|
620
687
|
toolRounds++;
|
|
621
688
|
// Pre-check cost limit before executing tools (estimate only — no side effects)
|
|
@@ -703,7 +770,7 @@ export class AgentExecutor {
|
|
|
703
770
|
// Use streaming execution for tools that support it (bash, reason, + adapter-based)
|
|
704
771
|
let result;
|
|
705
772
|
const _streamToolStartMs = Date.now();
|
|
706
|
-
const STREAMING_TOOLS = ['bash', 'reason'];
|
|
773
|
+
const STREAMING_TOOLS = ['bash', 'reason', 'generate_document'];
|
|
707
774
|
if (STREAMING_TOOLS.includes(toolCall.function.name)) {
|
|
708
775
|
const gen = this.deps.toolHandler.executeToolStreaming(toolCall);
|
|
709
776
|
let genResult = await gen.next();
|
|
@@ -914,8 +981,6 @@ export class AgentExecutor {
|
|
|
914
981
|
if (terminateDetectedStreaming)
|
|
915
982
|
break;
|
|
916
983
|
inputTokens = this.deps.tokenCounter.countMessageTokens(messages);
|
|
917
|
-
const currentOutputTokens = this.deps.streamingHandler.getTokenCount() || 0;
|
|
918
|
-
totalOutputTokens += currentOutputTokens;
|
|
919
984
|
yield { type: "token_count", tokenCount: inputTokens + totalOutputTokens };
|
|
920
985
|
// Run after_turn middleware (handles cost recording + limit)
|
|
921
986
|
if (pipeline) {
|
|
@@ -942,6 +1007,51 @@ export class AgentExecutor {
|
|
|
942
1007
|
catch { /* masking is optional */ }
|
|
943
1008
|
}
|
|
944
1009
|
else {
|
|
1010
|
+
// ── In-loop recovery (Hermes parity) ─────────────────────────────
|
|
1011
|
+
// Re-prompt WITHIN the turn before accepting this as the final answer.
|
|
1012
|
+
// Only reachable in the no-tool-calls branch, so we never split a
|
|
1013
|
+
// tool_call/tool_result pair (keeps transcript-repair invariants intact).
|
|
1014
|
+
if (!abortController?.signal.aborted) {
|
|
1015
|
+
// (1) Length truncation: the model hit the output-token cap mid-prose.
|
|
1016
|
+
// Ask it to continue from where it stopped, bounded. A continuation
|
|
1017
|
+
// that produced ZERO new tokens (e.g. a too-small num_ctx) leaves
|
|
1018
|
+
// `streamedContentRaw` empty — we do NOT retry that (the fix is config,
|
|
1019
|
+
// not looping); we fall through and stop.
|
|
1020
|
+
if (streamFinishReason === 'length' &&
|
|
1021
|
+
streamedContentRaw.length > 0 &&
|
|
1022
|
+
lengthContinuations < maxLengthContinuations) {
|
|
1023
|
+
lengthContinuations++;
|
|
1024
|
+
logger.debug('[agent-executor] length-truncation continuation', {
|
|
1025
|
+
attempt: lengthContinuations,
|
|
1026
|
+
max: maxLengthContinuations,
|
|
1027
|
+
});
|
|
1028
|
+
messages.push({
|
|
1029
|
+
role: 'user',
|
|
1030
|
+
content: 'Your previous message was cut off because it reached the output length limit. ' +
|
|
1031
|
+
'Continue it from exactly where it stopped — do not repeat earlier text and do not ' +
|
|
1032
|
+
'restart. When the full response is complete, finish normally.',
|
|
1033
|
+
});
|
|
1034
|
+
continue;
|
|
1035
|
+
}
|
|
1036
|
+
// (2) Post-tool empty response: the model went silent after running
|
|
1037
|
+
// tools. Nudge it to use the results and continue, bounded.
|
|
1038
|
+
if (streamedContentRaw.length === 0 &&
|
|
1039
|
+
streamFinishReason !== 'length' &&
|
|
1040
|
+
toolRounds > 0 &&
|
|
1041
|
+
emptyRetries < maxEmptyRetries) {
|
|
1042
|
+
emptyRetries++;
|
|
1043
|
+
logger.debug('[agent-executor] empty-response re-prompt', {
|
|
1044
|
+
attempt: emptyRetries,
|
|
1045
|
+
max: maxEmptyRetries,
|
|
1046
|
+
});
|
|
1047
|
+
messages.push({
|
|
1048
|
+
role: 'user',
|
|
1049
|
+
content: 'Your last response was empty. Use the results of the tool calls you just made ' +
|
|
1050
|
+
'to continue the task and produce your answer.',
|
|
1051
|
+
});
|
|
1052
|
+
continue;
|
|
1053
|
+
}
|
|
1054
|
+
}
|
|
945
1055
|
// Fire-and-forget auto-capture on final assistant response (streaming)
|
|
946
1056
|
try {
|
|
947
1057
|
const { getAutoCaptureManager } = await import('../../memory/auto-capture.js');
|
|
@@ -183,6 +183,13 @@ export const TOOL_METADATA = {
|
|
|
183
183
|
parallelSafe: false, // Single local camera device + explicit privacy boundary
|
|
184
184
|
priority: 6,
|
|
185
185
|
},
|
|
186
|
+
camera_analyze: {
|
|
187
|
+
reads: [],
|
|
188
|
+
writes: ["file"],
|
|
189
|
+
hasSideEffects: true,
|
|
190
|
+
parallelSafe: false, // Single local camera device + network vision call
|
|
191
|
+
priority: 6,
|
|
192
|
+
},
|
|
186
193
|
diagram: {
|
|
187
194
|
reads: [],
|
|
188
195
|
writes: ["file"],
|
|
@@ -11,6 +11,12 @@
|
|
|
11
11
|
* @module agent/execution/tool-hooks
|
|
12
12
|
*/
|
|
13
13
|
import type { CodeBuddyMessage } from '../../codebuddy/client.js';
|
|
14
|
+
export type FleetEventBroadcaster = (type: any, payload: any, agentId?: string) => void;
|
|
15
|
+
/**
|
|
16
|
+
* Register the fleet event broadcaster. Called by the server at boot
|
|
17
|
+
* to wire up fleet events without introducing a circular dependency.
|
|
18
|
+
*/
|
|
19
|
+
export declare function registerFleetBroadcaster(broadcaster: FleetEventBroadcaster): void;
|
|
14
20
|
/**
|
|
15
21
|
* Emit a fleet event for tool execution. Best-effort: never throws,
|
|
16
22
|
* silently no-ops when fleet streaming is disabled or the WS server
|
|
@@ -11,11 +11,19 @@
|
|
|
11
11
|
* @module agent/execution/tool-hooks
|
|
12
12
|
*/
|
|
13
13
|
import { getUserHooksManager } from '../../hooks/user-hooks.js';
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
14
|
+
let _fleetBroadcaster = null;
|
|
15
|
+
/**
|
|
16
|
+
* Register the fleet event broadcaster. Called by the server at boot
|
|
17
|
+
* to wire up fleet events without introducing a circular dependency.
|
|
18
|
+
*/
|
|
19
|
+
export function registerFleetBroadcaster(broadcaster) {
|
|
20
|
+
_fleetBroadcaster = broadcaster;
|
|
21
|
+
}
|
|
22
|
+
function _broadcastFleetEvent(type, payload, agentId) {
|
|
23
|
+
if (_fleetBroadcaster) {
|
|
24
|
+
_fleetBroadcaster(type, payload, agentId);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
19
27
|
/**
|
|
20
28
|
* Phase (d).2 V0.4.1 — fleet stream opt-in. When CODEBUDDY_FLEET_STREAM=1
|
|
21
29
|
* (or =true), every tool execution emits a fleet:agent:tool_started /
|
|
@@ -37,6 +37,12 @@ export interface ToolSelectionConfig {
|
|
|
37
37
|
enableCaching: boolean;
|
|
38
38
|
/** Cache TTL in milliseconds (default: 5 minutes) */
|
|
39
39
|
cacheTTLMs: number;
|
|
40
|
+
/**
|
|
41
|
+
* Active model name. When present, model capability rules from
|
|
42
|
+
* model-tools.ts are applied to the model-facing schemas before they are
|
|
43
|
+
* cached or sent to the provider.
|
|
44
|
+
*/
|
|
45
|
+
modelName?: string;
|
|
40
46
|
}
|
|
41
47
|
/**
|
|
42
48
|
* Result of a tool selection operation
|
|
@@ -80,6 +86,7 @@ export declare class ToolSelectionStrategy {
|
|
|
80
86
|
private config;
|
|
81
87
|
private cachedTools;
|
|
82
88
|
private cachedToolNames;
|
|
89
|
+
private cacheModelName;
|
|
83
90
|
private lastQuery;
|
|
84
91
|
private lastSelection;
|
|
85
92
|
private cacheTimestamp;
|
|
@@ -109,13 +116,13 @@ export declare class ToolSelectionStrategy {
|
|
|
109
116
|
*
|
|
110
117
|
* @param tools - Tools to cache
|
|
111
118
|
*/
|
|
112
|
-
cacheTools(tools: CodeBuddyTool[]): void;
|
|
119
|
+
cacheTools(tools: CodeBuddyTool[], modelName?: string): void;
|
|
113
120
|
/**
|
|
114
121
|
* Get cached tools if available and valid
|
|
115
122
|
*
|
|
116
123
|
* @returns Cached tools or null if cache is invalid/empty
|
|
117
124
|
*/
|
|
118
|
-
getCachedTools(): CodeBuddyTool[] | null;
|
|
125
|
+
getCachedTools(modelName?: string): CodeBuddyTool[] | null;
|
|
119
126
|
/**
|
|
120
127
|
* Set the active skill for tool augmentation.
|
|
121
128
|
*
|
|
@@ -140,6 +147,8 @@ export declare class ToolSelectionStrategy {
|
|
|
140
147
|
* Check if the cache is still valid
|
|
141
148
|
*/
|
|
142
149
|
private isCacheValid;
|
|
150
|
+
private static normalizeModelName;
|
|
151
|
+
private applyModelFacingSchemaFilter;
|
|
143
152
|
/**
|
|
144
153
|
* Record a tool request for metrics tracking
|
|
145
154
|
*
|