@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
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Types for the TOOL self-improvement path (sibling to the lesson path). A tool
|
|
3
|
+
* "covers" a scenario only BEHAVIORALLY: it must run on fixed inputs and produce
|
|
4
|
+
* asserted outputs (a presence predicate would be trivially gamed).
|
|
5
|
+
*
|
|
6
|
+
* @module agent/self-improvement/tool-types
|
|
7
|
+
*/
|
|
8
|
+
import type { AuthoredToolSpec } from './authored-tool-runtime.js';
|
|
9
|
+
/** One behavioural assertion: run the tool on `input`, output must contain ALL of `expectIncludes`. */
|
|
10
|
+
export interface ToolCase {
|
|
11
|
+
input: Record<string, unknown>;
|
|
12
|
+
expectIncludes: string[];
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* A behavioural benchmark for an authored tool. `visibleCases` describe the
|
|
16
|
+
* capability (and may be shown to the proposer); `heldOutCases` use fresh inputs
|
|
17
|
+
* and are NEVER shown to the proposer — a tool that hardcodes the visible
|
|
18
|
+
* outputs passes visible but fails held-out (the anti-reward-hacking defence).
|
|
19
|
+
*/
|
|
20
|
+
export interface ToolBenchmarkScenario {
|
|
21
|
+
id: string;
|
|
22
|
+
/** Human capability description (safe to show the proposer). */
|
|
23
|
+
capability: string;
|
|
24
|
+
description: string;
|
|
25
|
+
visibleCases: ToolCase[];
|
|
26
|
+
heldOutCases: ToolCase[];
|
|
27
|
+
}
|
|
28
|
+
/** A candidate authored tool, motivated by a scenario. The spec must be produced WITHOUT seeing heldOutCases. */
|
|
29
|
+
export interface ToolProposal {
|
|
30
|
+
id: string;
|
|
31
|
+
targetScenarioId: string;
|
|
32
|
+
experienceId?: string;
|
|
33
|
+
spec: AuthoredToolSpec;
|
|
34
|
+
}
|
|
35
|
+
export type ToolGateRejection = 'static-scan' | 'visible-fail' | 'heldout-fail';
|
|
36
|
+
export interface ToolGateOutcome {
|
|
37
|
+
accepted: boolean;
|
|
38
|
+
proposalId: string;
|
|
39
|
+
scenarioId: string;
|
|
40
|
+
visiblePassed: number;
|
|
41
|
+
visibleTotal: number;
|
|
42
|
+
heldOutPassed: number;
|
|
43
|
+
heldOutTotal: number;
|
|
44
|
+
rejectionReason?: ToolGateRejection;
|
|
45
|
+
reasons: string[];
|
|
46
|
+
/** Name of the tool left registered (only when accepted AND kept). */
|
|
47
|
+
appliedRef?: string;
|
|
48
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Types for the TOOL self-improvement path (sibling to the lesson path). A tool
|
|
3
|
+
* "covers" a scenario only BEHAVIORALLY: it must run on fixed inputs and produce
|
|
4
|
+
* asserted outputs (a presence predicate would be trivially gamed).
|
|
5
|
+
*
|
|
6
|
+
* @module agent/self-improvement/tool-types
|
|
7
|
+
*/
|
|
8
|
+
export {};
|
|
9
|
+
//# sourceMappingURL=tool-types.js.map
|
|
@@ -97,13 +97,15 @@ export interface GateOutcome {
|
|
|
97
97
|
/** One accepted improvement, kept as an evolutionary stepping stone (DGM). */
|
|
98
98
|
export interface ArchiveEntry {
|
|
99
99
|
proposalId: string;
|
|
100
|
-
kind: ImprovementProposal['kind'];
|
|
100
|
+
kind: ImprovementProposal['kind'] | 'tool' | 'skill';
|
|
101
101
|
targetScenarioId: string;
|
|
102
102
|
experienceId?: string;
|
|
103
103
|
delta: number;
|
|
104
104
|
scoreAfter: number;
|
|
105
105
|
/** Id of the applied lesson (so it can be traced/rolled back later). */
|
|
106
106
|
appliedRef?: string;
|
|
107
|
+
/** For consolidation: the umbrella skill an archived sibling was absorbed into. */
|
|
108
|
+
absorbedInto?: string;
|
|
107
109
|
createdAt: string;
|
|
108
110
|
/** Sentinel for auditability, mirrors the learning-loop convention. */
|
|
109
111
|
reviewedBy: string;
|
|
@@ -9,7 +9,10 @@
|
|
|
9
9
|
* 2. reusable lesson candidates via the existing review-gated
|
|
10
10
|
* auto-proposer (PENDING only — a human approves them into lessons.md,
|
|
11
11
|
* which the per-turn `<lessons_context>` injection then re-injects on
|
|
12
|
-
* future runs)
|
|
12
|
+
* future runs);
|
|
13
|
+
* 3. declarative long-term memory candidates via the review-gated memory
|
|
14
|
+
* queue. These do not enter prompt-injected persistent memory until a
|
|
15
|
+
* human accepts them.
|
|
13
16
|
*
|
|
14
17
|
* Guard-rails: trivial sessions are skipped (no LLM call, no file), and
|
|
15
18
|
* everything written here passes the privacy lint first (PII/secret spans
|
|
@@ -32,6 +35,8 @@ export interface SessionEndFlushInput {
|
|
|
32
35
|
export interface SessionEndFlushResult {
|
|
33
36
|
/** Lesson candidates enqueued for review (`buddy lessons` to approve). */
|
|
34
37
|
proposedLessons: number;
|
|
38
|
+
/** Declarative memory candidates enqueued for review (`/memory candidates`). */
|
|
39
|
+
proposedMemories: number;
|
|
35
40
|
/** Absolute path of the handoff file, when one was (re)written. */
|
|
36
41
|
handoffPath?: string;
|
|
37
42
|
openRisks: string[];
|
|
@@ -9,7 +9,10 @@
|
|
|
9
9
|
* 2. reusable lesson candidates via the existing review-gated
|
|
10
10
|
* auto-proposer (PENDING only — a human approves them into lessons.md,
|
|
11
11
|
* which the per-turn `<lessons_context>` injection then re-injects on
|
|
12
|
-
* future runs)
|
|
12
|
+
* future runs);
|
|
13
|
+
* 3. declarative long-term memory candidates via the review-gated memory
|
|
14
|
+
* queue. These do not enter prompt-injected persistent memory until a
|
|
15
|
+
* human accepts them.
|
|
13
16
|
*
|
|
14
17
|
* Guard-rails: trivial sessions are skipped (no LLM call, no file), and
|
|
15
18
|
* everything written here passes the privacy lint first (PII/secret spans
|
|
@@ -145,7 +148,7 @@ export function writeHandoffSync(history, workDir = process.cwd(), options = {})
|
|
|
145
148
|
}
|
|
146
149
|
lines.push('', '## Reprise', '', risks.length > 0
|
|
147
150
|
? '- Commencer par lever les risques ouverts ci-dessus.'
|
|
148
|
-
: '- Continuer le dernier objectif, ou `buddy --continue` pour recharger la session.', '- Leçons en attente de revue : `buddy lessons` (candidats proposés en fin de session).', '');
|
|
151
|
+
: '- Continuer le dernier objectif, ou `buddy --continue` pour recharger la session.', '- Leçons en attente de revue : `buddy lessons` (candidats proposés en fin de session).', '- Mémoires en attente de revue : `/memory candidates` puis `/memory accept <id> <reviewer>`.', '');
|
|
149
152
|
const content = redactSecrets(lines.join('\n'));
|
|
150
153
|
const dir = path.join(workDir, '.codebuddy');
|
|
151
154
|
const target = path.join(dir, 'HANDOFF.md');
|
|
@@ -168,7 +171,7 @@ export function writeHandoffSync(history, workDir = process.cwd(), options = {})
|
|
|
168
171
|
* no-ops on trivial sessions, never throws.
|
|
169
172
|
*/
|
|
170
173
|
export async function runSessionEndFlush(input) {
|
|
171
|
-
const empty = { proposedLessons: 0, openRisks: [] };
|
|
174
|
+
const empty = { proposedLessons: 0, proposedMemories: 0, openRisks: [] };
|
|
172
175
|
try {
|
|
173
176
|
if (!isFeatureEnabled('SESSION_END_FLUSH')) {
|
|
174
177
|
return { ...empty, skipped: 'disabled' };
|
|
@@ -195,12 +198,25 @@ export async function runSessionEndFlush(input) {
|
|
|
195
198
|
catch (err) {
|
|
196
199
|
logger.debug('[session-end-flush] lesson proposal failed', { err: String(err) });
|
|
197
200
|
}
|
|
198
|
-
|
|
201
|
+
let proposedMemories = 0;
|
|
202
|
+
if (process.env.CODEBUDDY_MEMORY_AUTO_PROPOSE !== 'false') {
|
|
203
|
+
try {
|
|
204
|
+
const { proposeMemoryCandidatesFromSession } = await import('../memory/memory-auto-proposer.js');
|
|
205
|
+
const proposed = await proposeMemoryCandidatesFromSession(history, workDir, input.client, input.sessionId);
|
|
206
|
+
proposedMemories = proposed.length;
|
|
207
|
+
}
|
|
208
|
+
catch (err) {
|
|
209
|
+
logger.debug('[session-end-flush] memory proposal failed', { err: String(err) });
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
if (proposedLessons > 0 || proposedMemories > 0 || handoffPath) {
|
|
199
213
|
logger.info(`[session-end-flush] ${proposedLessons} lesson candidate(s) proposed` +
|
|
214
|
+
`, ${proposedMemories} memory candidate(s) proposed` +
|
|
200
215
|
(handoffPath ? `, handoff written to ${path.relative(workDir, handoffPath)}` : ''));
|
|
201
216
|
}
|
|
202
217
|
return {
|
|
203
218
|
proposedLessons,
|
|
219
|
+
proposedMemories,
|
|
204
220
|
...(handoffPath ? { handoffPath } : {}),
|
|
205
221
|
openRisks,
|
|
206
222
|
};
|
|
@@ -118,6 +118,12 @@ export interface AccumulatedMessage {
|
|
|
118
118
|
content?: string;
|
|
119
119
|
/** Accumulated tool calls */
|
|
120
120
|
tool_calls?: CodeBuddyToolCall[];
|
|
121
|
+
/**
|
|
122
|
+
* The terminal `finish_reason`/`stop_reason` reported by the provider on the
|
|
123
|
+
* final chunk (`'stop'` | `'length'` | `'tool_calls'` | …). Used by the
|
|
124
|
+
* executor's in-loop recovery to detect a length-truncated turn.
|
|
125
|
+
*/
|
|
126
|
+
finishReason?: string | null;
|
|
121
127
|
/** Any additional fields from the API */
|
|
122
128
|
[key: string]: unknown;
|
|
123
129
|
}
|
|
@@ -153,6 +159,7 @@ export declare class StreamingHandler {
|
|
|
153
159
|
private accumulatedMessage;
|
|
154
160
|
private accumulatedRawContent;
|
|
155
161
|
private accumulatedReasoningContent;
|
|
162
|
+
private accumulatedFinishReason;
|
|
156
163
|
private tokenCounter;
|
|
157
164
|
private lastTokenUpdate;
|
|
158
165
|
private toolCallsYielded;
|
|
@@ -42,6 +42,7 @@ export class StreamingHandler {
|
|
|
42
42
|
accumulatedMessage = {};
|
|
43
43
|
accumulatedRawContent = '';
|
|
44
44
|
accumulatedReasoningContent = '';
|
|
45
|
+
accumulatedFinishReason = null;
|
|
45
46
|
tokenCounter = null;
|
|
46
47
|
lastTokenUpdate = 0;
|
|
47
48
|
toolCallsYielded = false;
|
|
@@ -86,6 +87,11 @@ export class StreamingHandler {
|
|
|
86
87
|
}
|
|
87
88
|
// Accumulate the message using reducer
|
|
88
89
|
this.accumulatedMessage = reduceStreamChunk(this.accumulatedMessage, chunk);
|
|
90
|
+
// Capture the terminal finish_reason (present on the final chunk). The last
|
|
91
|
+
// non-null value wins so a trailing usage-only chunk can't clear it.
|
|
92
|
+
if (chunk.choices[0].finish_reason) {
|
|
93
|
+
this.accumulatedFinishReason = chunk.choices[0].finish_reason;
|
|
94
|
+
}
|
|
89
95
|
// Extract content delta
|
|
90
96
|
const rawContentDelta = chunk.choices[0].delta?.content || '';
|
|
91
97
|
this.accumulatedRawContent += rawContentDelta;
|
|
@@ -208,7 +214,7 @@ export class StreamingHandler {
|
|
|
208
214
|
* @returns The accumulated message with all processed content and tool calls
|
|
209
215
|
*/
|
|
210
216
|
getAccumulatedMessage() {
|
|
211
|
-
return { ...this.accumulatedMessage };
|
|
217
|
+
return { ...this.accumulatedMessage, finishReason: this.accumulatedFinishReason };
|
|
212
218
|
}
|
|
213
219
|
/**
|
|
214
220
|
* Gets the raw accumulated content before sanitization.
|
|
@@ -261,6 +267,7 @@ export class StreamingHandler {
|
|
|
261
267
|
this.accumulatedMessage = {};
|
|
262
268
|
this.accumulatedRawContent = '';
|
|
263
269
|
this.accumulatedReasoningContent = '';
|
|
270
|
+
this.accumulatedFinishReason = null;
|
|
264
271
|
this.lastTokenUpdate = 0;
|
|
265
272
|
this.toolCallsYielded = false;
|
|
266
273
|
}
|
|
@@ -37,6 +37,11 @@ export interface ToolHandlerDependencies {
|
|
|
37
37
|
/** Coordinates auto-repair attempts for failed commands */
|
|
38
38
|
repairCoordinator: RepairCoordinator;
|
|
39
39
|
}
|
|
40
|
+
export interface NormalizedHallucinatedToolCall {
|
|
41
|
+
toolName: string;
|
|
42
|
+
args: Record<string, unknown>;
|
|
43
|
+
}
|
|
44
|
+
export declare function normalizeHallucinatedLocalToolCall(toolName: string, args: Record<string, unknown>): NormalizedHallucinatedToolCall | null;
|
|
40
45
|
/**
|
|
41
46
|
* ToolHandler manages tool instantiation and execution
|
|
42
47
|
*
|
|
@@ -16,7 +16,8 @@
|
|
|
16
16
|
* Tool instances are lazy-loaded on first access for optimal startup time.
|
|
17
17
|
*/
|
|
18
18
|
import { TextEditorTool, MorphEditorTool, ImageTool, BashTool, } from "../tools/index.js";
|
|
19
|
-
import { getFormalToolRegistry, createTextEditorTools, createBashTools, createLsTools, createSearchTools, createWebTools, createTodoTools, createCronjobTools, createDockerTools, createKubernetesTools, createGitTools, createMiscTools, createBrowserTools, createProcessTools, createVisionTools, createScriptTools, createPlanTools, createKnowledgeTools, createRelationshipIntelligenceTools, createInternetScoutTools, createLeadScoutTools, createBrowserOperatorTools, createMemoryTools, createParallelTools, createAttentionTools, createSkillsInspectionTools, createLessonsTools, createUserModelTools, createAliasTools, createMultimodalTools, createAdvancedTools, createCanvasTools, createLspTools, createMergeConflictTools, createVulnScannerTools, createCodebaseReplaceTools, createAdvisorTools, createFleetTools, createAskUserQuestionTools, createExitPlanModeTools, createGuiTools, createSessionTools, createGitNexusTools, createScreenpipeTools, } from "../tools/registry/index.js";
|
|
19
|
+
import { getFormalToolRegistry, createTextEditorTools, createBashTools, createLsTools, createSearchTools, createWebTools, createTodoTools, createCronjobTools, createDockerTools, createKubernetesTools, createGitTools, createMiscTools, createBrowserTools, createProcessTools, createVisionTools, createScriptTools, createPlanTools, createKnowledgeTools, createRelationshipIntelligenceTools, createInternetScoutTools, createLeadScoutTools, createBrowserOperatorTools, createWindowsTools, createMemoryTools, createParallelTools, createAttentionTools, createSkillsInspectionTools, createLessonsTools, createUserModelTools, createAliasTools, createMultimodalTools, createAdvancedTools, createCanvasTools, createLspTools, createMergeConflictTools, createVulnScannerTools, createCodebaseReplaceTools, createAdvisorTools, createFleetTools, createAskUserQuestionTools, createExitPlanModeTools, createGuiTools, createSessionTools, createGitNexusTools, createScreenpipeTools, } from "../tools/registry/index.js";
|
|
20
|
+
import { createRegisterToolTool } from "../tools/register-tool-handler.js";
|
|
20
21
|
import { getMCPManager } from "../codebuddy/tools.js";
|
|
21
22
|
import { getErrorMessage } from "../errors/index.js";
|
|
22
23
|
import { logger } from "../utils/logger.js";
|
|
@@ -44,6 +45,67 @@ const READ_ONLY_FILE_TOOLS = new Set([
|
|
|
44
45
|
'find_definition',
|
|
45
46
|
'search_multi',
|
|
46
47
|
]);
|
|
48
|
+
export function normalizeHallucinatedLocalToolCall(toolName, args) {
|
|
49
|
+
const normalizedName = toolName.toLowerCase().replace(/\s+/g, '');
|
|
50
|
+
const thoughtToolCallSuffix = normalizedName.match(/^thought_tool_call_\d+(?:_\d+)*\.(bash|create_file|write_file|view_file|read_file)$/)?.[1];
|
|
51
|
+
if (thoughtToolCallSuffix === 'bash') {
|
|
52
|
+
const command = firstStringValue(args.command, args.cmd, args.shell_command, args.command_to_execute, args.code);
|
|
53
|
+
return {
|
|
54
|
+
toolName: 'bash',
|
|
55
|
+
args: command ? { ...args, command } : args,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
if (thoughtToolCallSuffix === 'create_file' || thoughtToolCallSuffix === 'write_file') {
|
|
59
|
+
const path = firstStringValue(args.path, args.file_path, args.target_file, args.filename, args.file);
|
|
60
|
+
const content = firstStringValue(args.content, args.file_content, args.contents, args.text);
|
|
61
|
+
return {
|
|
62
|
+
toolName: 'create_file',
|
|
63
|
+
args: {
|
|
64
|
+
...args,
|
|
65
|
+
...(path ? { path } : {}),
|
|
66
|
+
...(content !== undefined ? { content } : {}),
|
|
67
|
+
},
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
if (thoughtToolCallSuffix === 'view_file' || thoughtToolCallSuffix === 'read_file') {
|
|
71
|
+
const path = firstStringValue(args.path, args.file_path, args.target_file, args.filename, args.file);
|
|
72
|
+
return {
|
|
73
|
+
toolName: 'view_file',
|
|
74
|
+
args: path ? { ...args, path } : args,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
if (normalizedName.includes('bash_tool:execute') ||
|
|
78
|
+
normalizedName.includes('thought-tool:execute_command') ||
|
|
79
|
+
normalizedName === 'execute_command') {
|
|
80
|
+
const command = firstStringValue(args.command, args.cmd, args.shell_command, args.command_to_execute, args.code);
|
|
81
|
+
return {
|
|
82
|
+
toolName: 'bash',
|
|
83
|
+
args: command ? { ...args, command } : args,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
if (normalizedName.includes('bash_tool:write_file') ||
|
|
87
|
+
normalizedName.includes('thought-tool:write_file') ||
|
|
88
|
+
normalizedName.includes('call:bash_tool:write_file')) {
|
|
89
|
+
const path = firstStringValue(args.path, args.file_path, args.target_file, args.filename, args.file);
|
|
90
|
+
const content = firstStringValue(args.content, args.file_content, args.contents, args.text);
|
|
91
|
+
return {
|
|
92
|
+
toolName: 'create_file',
|
|
93
|
+
args: {
|
|
94
|
+
...args,
|
|
95
|
+
...(path ? { path } : {}),
|
|
96
|
+
...(content !== undefined ? { content } : {}),
|
|
97
|
+
},
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
function firstStringValue(...values) {
|
|
103
|
+
for (const value of values) {
|
|
104
|
+
if (typeof value === 'string' && value.trim())
|
|
105
|
+
return value;
|
|
106
|
+
}
|
|
107
|
+
return undefined;
|
|
108
|
+
}
|
|
47
109
|
/**
|
|
48
110
|
* ToolHandler manages tool instantiation and execution
|
|
49
111
|
*
|
|
@@ -156,6 +218,7 @@ export class ToolHandler {
|
|
|
156
218
|
...createInternetScoutTools(),
|
|
157
219
|
...createLeadScoutTools(),
|
|
158
220
|
...createBrowserOperatorTools(),
|
|
221
|
+
...(process.platform === 'win32' ? createWindowsTools() : []),
|
|
159
222
|
...createMemoryTools(),
|
|
160
223
|
...createParallelTools(),
|
|
161
224
|
...createAttentionTools(),
|
|
@@ -177,6 +240,8 @@ export class ToolHandler {
|
|
|
177
240
|
...createSessionTools(),
|
|
178
241
|
...createGitNexusTools(),
|
|
179
242
|
...createScreenpipeTools(),
|
|
243
|
+
// Self-improvement: the agent can author its own tools (opt-in only).
|
|
244
|
+
...(process.env.CODEBUDDY_SELF_IMPROVE === 'true' ? [createRegisterToolTool()] : []),
|
|
180
245
|
];
|
|
181
246
|
// Register canonical-prefix alias tools (shell_exec→bash, file_read→view_file, etc.)
|
|
182
247
|
const aliasTools = createAliasTools(allTools);
|
|
@@ -244,8 +309,25 @@ export class ToolHandler {
|
|
|
244
309
|
const startTime = Date.now();
|
|
245
310
|
const hooksManager = getToolHooksManager();
|
|
246
311
|
try {
|
|
247
|
-
|
|
248
|
-
|
|
312
|
+
let args = JSON.parse(toolCall.function.arguments);
|
|
313
|
+
let toolName = toolCall.function.name;
|
|
314
|
+
const normalized = normalizeHallucinatedLocalToolCall(toolName, args);
|
|
315
|
+
if (normalized) {
|
|
316
|
+
logger.debug('Normalized hallucinated local tool name', {
|
|
317
|
+
from: toolName,
|
|
318
|
+
to: normalized.toolName,
|
|
319
|
+
});
|
|
320
|
+
toolName = normalized.toolName;
|
|
321
|
+
args = normalized.args;
|
|
322
|
+
toolCall = {
|
|
323
|
+
...toolCall,
|
|
324
|
+
function: {
|
|
325
|
+
...toolCall.function,
|
|
326
|
+
name: toolName,
|
|
327
|
+
arguments: JSON.stringify(args),
|
|
328
|
+
},
|
|
329
|
+
};
|
|
330
|
+
}
|
|
249
331
|
// Create hook context
|
|
250
332
|
let hookContext = {
|
|
251
333
|
toolName,
|
|
@@ -693,6 +775,12 @@ export class ToolHandler {
|
|
|
693
775
|
*/
|
|
694
776
|
async executeBashWithHooks(args, context) {
|
|
695
777
|
const command = args.command;
|
|
778
|
+
if (typeof command !== 'string' || command.trim() === '') {
|
|
779
|
+
return {
|
|
780
|
+
success: false,
|
|
781
|
+
error: 'bash: missing a non-empty "command" string argument. Put the shell command to run in the "command" field.',
|
|
782
|
+
};
|
|
783
|
+
}
|
|
696
784
|
// Execute pre-bash hooks
|
|
697
785
|
try {
|
|
698
786
|
await this.deps.hooksManager.executeHooks("pre-bash", { command });
|
|
@@ -754,6 +842,15 @@ export class ToolHandler {
|
|
|
754
842
|
const args = JSON.parse(toolCall.function.arguments);
|
|
755
843
|
const command = args.command;
|
|
756
844
|
const timeout = args.timeout || 30000;
|
|
845
|
+
// A weaker model can emit a `bash` call without a `command` (or a
|
|
846
|
+
// non-string one). Fail with a clear, recoverable message instead of
|
|
847
|
+
// crashing downstream on `command.trim()` (auto-repair can then re-prompt).
|
|
848
|
+
if (typeof command !== 'string' || command.trim() === '') {
|
|
849
|
+
return {
|
|
850
|
+
success: false,
|
|
851
|
+
error: 'bash: missing a non-empty "command" string argument. Put the shell command to run in the "command" field.',
|
|
852
|
+
};
|
|
853
|
+
}
|
|
757
854
|
const gen = this.bash.executeStreaming(command, timeout);
|
|
758
855
|
let result = await gen.next();
|
|
759
856
|
while (!result.done) {
|
|
@@ -778,8 +875,15 @@ export class ToolHandler {
|
|
|
778
875
|
mode: mode,
|
|
779
876
|
});
|
|
780
877
|
reasoner.setMode(mode);
|
|
878
|
+
const problem = args.problem;
|
|
879
|
+
if (typeof problem !== 'string' || problem.trim() === '') {
|
|
880
|
+
return {
|
|
881
|
+
success: false,
|
|
882
|
+
error: 'reason: missing a non-empty "problem" string argument. Put the problem to reason about in the "problem" field.',
|
|
883
|
+
};
|
|
884
|
+
}
|
|
781
885
|
const gen = reasoner.solveStreaming({
|
|
782
|
-
description:
|
|
886
|
+
description: problem,
|
|
783
887
|
context: args.context,
|
|
784
888
|
constraints: args.constraints,
|
|
785
889
|
});
|
|
@@ -796,6 +900,31 @@ export class ToolHandler {
|
|
|
796
900
|
return { success: false, error: `Reasoning error: ${getErrorMessage(error)}` };
|
|
797
901
|
}
|
|
798
902
|
}
|
|
903
|
+
// generate_document: stream the build phases (prepare → parse → build →
|
|
904
|
+
// write → verify → done) so the UI shows the steps unfold one by one
|
|
905
|
+
// instead of a single opaque "Created X" at the end.
|
|
906
|
+
if (toolName === 'generate_document') {
|
|
907
|
+
try {
|
|
908
|
+
const args = JSON.parse(toolCall.function.arguments);
|
|
909
|
+
const { executeGenerateDocumentStreaming } = await import('../tools/document-generator.js');
|
|
910
|
+
const gen = executeGenerateDocumentStreaming({
|
|
911
|
+
type: args.type,
|
|
912
|
+
title: args.title,
|
|
913
|
+
content: args.content,
|
|
914
|
+
outputPath: args.outputPath ?? args.output_path,
|
|
915
|
+
theme: args.theme,
|
|
916
|
+
});
|
|
917
|
+
let r = await gen.next();
|
|
918
|
+
while (!r.done) {
|
|
919
|
+
yield r.value;
|
|
920
|
+
r = await gen.next();
|
|
921
|
+
}
|
|
922
|
+
return r.value ?? { success: false, error: 'Document tool returned no result' };
|
|
923
|
+
}
|
|
924
|
+
catch (error) {
|
|
925
|
+
return { success: false, error: `Document streaming error: ${getErrorMessage(error)}` };
|
|
926
|
+
}
|
|
927
|
+
}
|
|
799
928
|
// Fallback: non-streaming execution
|
|
800
929
|
return await this.executeTool(toolCall);
|
|
801
930
|
}
|
|
@@ -189,12 +189,27 @@ export class BrowserOperatorExecutor {
|
|
|
189
189
|
'access denied',
|
|
190
190
|
'security checkpoint',
|
|
191
191
|
];
|
|
192
|
+
const sensitivePlatforms = [
|
|
193
|
+
'yandex.com',
|
|
194
|
+
'yandex.ru',
|
|
195
|
+
'login.microsoftonline.com',
|
|
196
|
+
'zoom.us',
|
|
197
|
+
];
|
|
192
198
|
for (const indicator of antiBotIndicators) {
|
|
193
199
|
if (lower.includes(indicator)) {
|
|
194
200
|
raiseCheckpoint(`Security checkpoint detected: "${indicator}"`);
|
|
195
201
|
break;
|
|
196
202
|
}
|
|
197
203
|
}
|
|
204
|
+
if (!checkpointDetected) {
|
|
205
|
+
const currentUrl = String(this.page.url?.() ?? '').toLowerCase();
|
|
206
|
+
for (const platform of sensitivePlatforms) {
|
|
207
|
+
if (currentUrl.includes(platform)) {
|
|
208
|
+
raiseCheckpoint(`OSINT Policy Violation: Target-specific exploit scripts are strictly declined for "${platform}"`);
|
|
209
|
+
break;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
198
213
|
}
|
|
199
214
|
catch {
|
|
200
215
|
// Ignore polling errors while pages are navigating or closing.
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Browser Use Runner
|
|
3
|
+
*
|
|
4
|
+
* browser-use is an open-source agentic browser-automation library. This runner
|
|
5
|
+
* routes a task through one of three paths, in precedence order:
|
|
6
|
+
*
|
|
7
|
+
* 1. The Browser Use **managed API** (via `BROWSER_USE_API_KEY`), or
|
|
8
|
+
* 2. The **Nous Tool Gateway** (`CODEBUDDY_NOUS_TOOL_GATEWAY_URL`), or
|
|
9
|
+
* 3. A **local** browser-use install driven against a local Ollama model
|
|
10
|
+
* (no paid account required). Enabled with `CODEBUDDY_BROWSER_USE_LOCAL=1`
|
|
11
|
+
* or auto-detected when the `browser_use` Python package is importable and
|
|
12
|
+
* neither managed path is configured.
|
|
13
|
+
*
|
|
14
|
+
* The managed paths (1 and 2) speak HTTP via `fetch`. The local path (3) spawns
|
|
15
|
+
* a Python subprocess that runs `Agent(task=..., llm=ChatOllama(...)).run()` and
|
|
16
|
+
* prints a sentinel-delimited JSON result line, which we parse and normalise
|
|
17
|
+
* back into the same `BrowserUseActionResult` shape.
|
|
18
|
+
*
|
|
19
|
+
* Returns structured results with optional screenshot data. Falls back
|
|
20
|
+
* gracefully (typed error result, never throws) when nothing is configured.
|
|
21
|
+
*/
|
|
22
|
+
export interface BrowserUseRunnerOptions {
|
|
23
|
+
/** Browser Use API key (falls back to `BROWSER_USE_API_KEY` env). */
|
|
24
|
+
apiKey?: string;
|
|
25
|
+
/** Nous Tool Gateway URL (falls back to `CODEBUDDY_NOUS_TOOL_GATEWAY_URL` env). */
|
|
26
|
+
gatewayUrl?: string;
|
|
27
|
+
/** Request/run timeout in milliseconds (default: 60 000 managed, 180 000 local). */
|
|
28
|
+
timeout?: number;
|
|
29
|
+
/**
|
|
30
|
+
* Force/disable the local browser-use path explicitly. When undefined it is
|
|
31
|
+
* read from `CODEBUDDY_BROWSER_USE_LOCAL` and otherwise auto-detected.
|
|
32
|
+
*/
|
|
33
|
+
local?: boolean;
|
|
34
|
+
/**
|
|
35
|
+
* Python interpreter that has the `browser_use` package installed.
|
|
36
|
+
* Defaults to `$CODEBUDDY_BROWSER_USE_PYTHON`, then `python3`.
|
|
37
|
+
*/
|
|
38
|
+
pythonPath?: string;
|
|
39
|
+
/**
|
|
40
|
+
* Ollama model the local browser-use agent should drive. Defaults to
|
|
41
|
+
* `$CODEBUDDY_BROWSER_USE_MODEL`, then `qwen2.5:7b-instruct` (a tool-calling
|
|
42
|
+
* capable model — browser-use relies on structured tool calls).
|
|
43
|
+
*/
|
|
44
|
+
model?: string;
|
|
45
|
+
/**
|
|
46
|
+
* Ollama host the local agent should connect to. Defaults to `$OLLAMA_HOST`,
|
|
47
|
+
* then `http://localhost:11434`.
|
|
48
|
+
*/
|
|
49
|
+
ollamaHost?: string;
|
|
50
|
+
/**
|
|
51
|
+
* Path to a Chrome/Chromium binary for browser-use to launch
|
|
52
|
+
* (`BrowserProfile.executable_path`). Defaults to `$CODEBUDDY_BROWSER_USE_CHROME`.
|
|
53
|
+
* On sandboxed Linux/CI hosts the snap-confined chromium often fails the
|
|
54
|
+
* 30 s browser-start watchdog; pointing at a plain Chromium binary (e.g. the
|
|
55
|
+
* Playwright cache) plus `chromiumSandbox: false` is what makes launch work.
|
|
56
|
+
*/
|
|
57
|
+
chromePath?: string;
|
|
58
|
+
/**
|
|
59
|
+
* Disable Chromium's sandbox and add `--no-sandbox` (needed inside most
|
|
60
|
+
* containers / sandboxed CI). Defaults from `$CODEBUDDY_BROWSER_USE_NO_SANDBOX`
|
|
61
|
+
* (truthy), else true on Linux where the sandbox commonly blocks launch.
|
|
62
|
+
*/
|
|
63
|
+
noSandbox?: boolean;
|
|
64
|
+
/**
|
|
65
|
+
* Whether browser-use should send screenshots to the model. browser-use sends
|
|
66
|
+
* them by default, which 400s on text-only Ollama models
|
|
67
|
+
* (`Multimodal data provided, but model does not support multimodal requests`).
|
|
68
|
+
* Defaults to `false` so the default text model works; set true with a vision
|
|
69
|
+
* model. Read from `$CODEBUDDY_BROWSER_USE_VISION` when undefined.
|
|
70
|
+
*/
|
|
71
|
+
useVision?: boolean;
|
|
72
|
+
/** Max agent steps for the local run (default: 6). */
|
|
73
|
+
maxSteps?: number;
|
|
74
|
+
}
|
|
75
|
+
export interface BrowserUseActionResult {
|
|
76
|
+
ok: boolean;
|
|
77
|
+
/** Extracted page content or action result text. */
|
|
78
|
+
content?: string;
|
|
79
|
+
/** Base64-encoded screenshot, when the service provides one. */
|
|
80
|
+
screenshot?: string;
|
|
81
|
+
error?: string;
|
|
82
|
+
}
|
|
83
|
+
/** Pull the last sentinel-prefixed JSON object out of accumulated stdout. */
|
|
84
|
+
export declare function parseLocalResult(stdout: string): BrowserUseActionResult | null;
|
|
85
|
+
/**
|
|
86
|
+
* Execute a browser action through the Browser Use service.
|
|
87
|
+
*
|
|
88
|
+
* ```ts
|
|
89
|
+
* const result = await executeBrowserUseAction(
|
|
90
|
+
* 'Extract the main heading',
|
|
91
|
+
* 'https://example.com',
|
|
92
|
+
* );
|
|
93
|
+
* if (result.ok) console.log(result.content);
|
|
94
|
+
* ```
|
|
95
|
+
*/
|
|
96
|
+
export declare function executeBrowserUseAction(action: string, url: string, options?: BrowserUseRunnerOptions): Promise<BrowserUseActionResult>;
|