hyacinth-ai 0.9.6
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/LICENSE +21 -0
- package/README.md +205 -0
- package/commands.json +25 -0
- package/dist/agents/builtins.d.ts +8 -0
- package/dist/agents/builtins.js +50 -0
- package/dist/agents/config-loader.d.ts +15 -0
- package/dist/agents/config-loader.js +75 -0
- package/dist/agents/delegate-tool.d.ts +109 -0
- package/dist/agents/delegate-tool.js +407 -0
- package/dist/agents/index.d.ts +5 -0
- package/dist/agents/index.js +5 -0
- package/dist/agents/registry.d.ts +2 -0
- package/dist/agents/registry.js +2 -0
- package/dist/bypass/agents/companion/index.d.ts +57 -0
- package/dist/bypass/agents/companion/index.js +487 -0
- package/dist/bypass/agents/orchestrator/index.d.ts +17 -0
- package/dist/bypass/agents/orchestrator/index.js +414 -0
- package/dist/bypass/agents/orchestrator.d.ts +16 -0
- package/dist/bypass/agents/orchestrator.js +377 -0
- package/dist/bypass/agents/world-engine/agent.d.ts +41 -0
- package/dist/bypass/agents/world-engine/agent.js +385 -0
- package/dist/bypass/agents/world-engine/index.d.ts +52 -0
- package/dist/bypass/agents/world-engine/index.js +198 -0
- package/dist/bypass/agents/world-engine/sim.d.ts +14 -0
- package/dist/bypass/agents/world-engine/sim.js +120 -0
- package/dist/bypass/agents/world-engine/store.d.ts +110 -0
- package/dist/bypass/agents/world-engine/store.js +519 -0
- package/dist/bypass/agents/world-engine/ticker.d.ts +37 -0
- package/dist/bypass/agents/world-engine/ticker.js +214 -0
- package/dist/bypass/agents/world-engine/tools.d.ts +6 -0
- package/dist/bypass/agents/world-engine/tools.js +380 -0
- package/dist/bypass/agents/world-engine/types.d.ts +202 -0
- package/dist/bypass/agents/world-engine/types.js +56 -0
- package/dist/bypass/agents/world-engine.d.ts +20 -0
- package/dist/bypass/agents/world-engine.js +63 -0
- package/dist/bypass/base.d.ts +48 -0
- package/dist/bypass/base.js +126 -0
- package/dist/bypass/index.d.ts +5 -0
- package/dist/bypass/index.js +6 -0
- package/dist/bypass/manager.d.ts +41 -0
- package/dist/bypass/manager.js +179 -0
- package/dist/bypass/types.d.ts +63 -0
- package/dist/bypass/types.js +14 -0
- package/dist/channels/auto-detect.d.ts +25 -0
- package/dist/channels/auto-detect.js +77 -0
- package/dist/channels/builtin/http-webhook.d.ts +25 -0
- package/dist/channels/builtin/http-webhook.js +287 -0
- package/dist/channels/builtin/tui-channel.d.ts +33 -0
- package/dist/channels/builtin/tui-channel.js +61 -0
- package/dist/channels/builtin/tui-ws-session.d.ts +16 -0
- package/dist/channels/builtin/tui-ws-session.js +90 -0
- package/dist/channels/builtin/webui-output-handler.d.ts +30 -0
- package/dist/channels/builtin/webui-output-handler.js +93 -0
- package/dist/channels/index.d.ts +5 -0
- package/dist/channels/index.js +3 -0
- package/dist/channels/interface.d.ts +148 -0
- package/dist/channels/interface.js +15 -0
- package/dist/channels/manager.d.ts +43 -0
- package/dist/channels/manager.js +156 -0
- package/dist/channels/message-queue.d.ts +36 -0
- package/dist/channels/message-queue.js +91 -0
- package/dist/channels/plugins/clawbot/clawbot-auth.d.ts +50 -0
- package/dist/channels/plugins/clawbot/clawbot-auth.js +235 -0
- package/dist/channels/plugins/clawbot/clawbot-channel.d.ts +76 -0
- package/dist/channels/plugins/clawbot/clawbot-channel.js +566 -0
- package/dist/channels/plugins/clawbot/clawbot-client.d.ts +180 -0
- package/dist/channels/plugins/clawbot/clawbot-client.js +312 -0
- package/dist/channels/plugins/clawbot/clawbot-config.d.ts +30 -0
- package/dist/channels/plugins/clawbot/clawbot-config.js +28 -0
- package/dist/channels/plugins/clawbot/clawbot-message-queue.d.ts +27 -0
- package/dist/channels/plugins/clawbot/clawbot-message-queue.js +114 -0
- package/dist/channels/plugins/clawbot/clawbot-session.d.ts +10 -0
- package/dist/channels/plugins/clawbot/clawbot-session.js +26 -0
- package/dist/channels/plugins/clawbot/index.d.ts +17 -0
- package/dist/channels/plugins/clawbot/index.js +58 -0
- package/dist/channels/plugins/feishu/feishu-channel.d.ts +57 -0
- package/dist/channels/plugins/feishu/feishu-channel.js +602 -0
- package/dist/channels/plugins/feishu/feishu-client.d.ts +23 -0
- package/dist/channels/plugins/feishu/feishu-client.js +86 -0
- package/dist/channels/plugins/feishu/feishu-config.d.ts +53 -0
- package/dist/channels/plugins/feishu/feishu-config.js +35 -0
- package/dist/channels/plugins/feishu/feishu-event.d.ts +102 -0
- package/dist/channels/plugins/feishu/feishu-event.js +257 -0
- package/dist/channels/plugins/feishu/feishu-log-suppressor.d.ts +7 -0
- package/dist/channels/plugins/feishu/feishu-log-suppressor.js +34 -0
- package/dist/channels/plugins/feishu/feishu-message-queue.d.ts +27 -0
- package/dist/channels/plugins/feishu/feishu-message-queue.js +112 -0
- package/dist/channels/plugins/feishu/feishu-send.d.ts +44 -0
- package/dist/channels/plugins/feishu/feishu-send.js +232 -0
- package/dist/channels/plugins/feishu/feishu-session.d.ts +44 -0
- package/dist/channels/plugins/feishu/feishu-session.js +84 -0
- package/dist/channels/plugins/feishu/feishu-streaming.d.ts +49 -0
- package/dist/channels/plugins/feishu/feishu-streaming.js +185 -0
- package/dist/channels/plugins/feishu/feishu-transport.d.ts +29 -0
- package/dist/channels/plugins/feishu/feishu-transport.js +99 -0
- package/dist/channels/plugins/feishu/index.d.ts +22 -0
- package/dist/channels/plugins/feishu/index.js +68 -0
- package/dist/cli/doctor.d.ts +20 -0
- package/dist/cli/doctor.js +317 -0
- package/dist/context/cache-strategy.d.ts +76 -0
- package/dist/context/cache-strategy.js +123 -0
- package/dist/context/composer.d.ts +77 -0
- package/dist/context/composer.js +318 -0
- package/dist/context/compressor.d.ts +218 -0
- package/dist/context/compressor.js +909 -0
- package/dist/context/index.d.ts +14 -0
- package/dist/context/index.js +8 -0
- package/dist/context/interface.d.ts +33 -0
- package/dist/context/interface.js +2 -0
- package/dist/context/manifest-defaults.d.ts +51 -0
- package/dist/context/manifest-defaults.js +133 -0
- package/dist/context/manifest-loader.d.ts +16 -0
- package/dist/context/manifest-loader.js +103 -0
- package/dist/context/manifest-types.d.ts +26 -0
- package/dist/context/manifest-types.js +2 -0
- package/dist/context/precision/analyzer.d.ts +31 -0
- package/dist/context/precision/analyzer.js +131 -0
- package/dist/context/precision/companion.d.ts +27 -0
- package/dist/context/precision/companion.js +144 -0
- package/dist/context/precision/default.d.ts +14 -0
- package/dist/context/precision/default.js +17 -0
- package/dist/context/precision/index.d.ts +9 -0
- package/dist/context/precision/index.js +7 -0
- package/dist/context/precision/keyword-pool.d.ts +27 -0
- package/dist/context/precision/keyword-pool.js +66 -0
- package/dist/context/precision/strategy.d.ts +18 -0
- package/dist/context/precision/strategy.js +51 -0
- package/dist/context/precision/summary-store.d.ts +18 -0
- package/dist/context/precision/summary-store.js +67 -0
- package/dist/context/precision/types.d.ts +23 -0
- package/dist/context/precision/types.js +2 -0
- package/dist/context/profiles.d.ts +45 -0
- package/dist/context/profiles.js +92 -0
- package/dist/context/prompt-builder.d.ts +76 -0
- package/dist/context/prompt-builder.js +133 -0
- package/dist/context/retriever.d.ts +44 -0
- package/dist/context/retriever.js +203 -0
- package/dist/context/router.d.ts +122 -0
- package/dist/context/router.js +291 -0
- package/dist/context/section-resolver.d.ts +38 -0
- package/dist/context/section-resolver.js +398 -0
- package/dist/context/tokenizer.d.ts +23 -0
- package/dist/context/tokenizer.js +78 -0
- package/dist/dependency/analyzer.d.ts +33 -0
- package/dist/dependency/analyzer.js +242 -0
- package/dist/dependency/data-flow-tracker.d.ts +12 -0
- package/dist/dependency/data-flow-tracker.js +97 -0
- package/dist/dependency/function-parser.d.ts +34 -0
- package/dist/dependency/function-parser.js +295 -0
- package/dist/dependency/index.d.ts +14 -0
- package/dist/dependency/index.js +20 -0
- package/dist/dependency/parser.d.ts +10 -0
- package/dist/dependency/parser.js +93 -0
- package/dist/dependency/types.d.ts +57 -0
- package/dist/dependency/types.js +2 -0
- package/dist/env/env-collector.d.ts +45 -0
- package/dist/env/env-collector.js +221 -0
- package/dist/env/index.d.ts +3 -0
- package/dist/env/index.js +2 -0
- package/dist/event-store.d.ts +27 -0
- package/dist/event-store.js +71 -0
- package/dist/evolution/git-manager.d.ts +46 -0
- package/dist/evolution/git-manager.js +276 -0
- package/dist/evolution/index.d.ts +3 -0
- package/dist/evolution/index.js +2 -0
- package/dist/flow/bootstrap-flow.d.ts +19 -0
- package/dist/flow/bootstrap-flow.js +72 -0
- package/dist/flow/flow-registry.d.ts +12 -0
- package/dist/flow/flow-registry.js +74 -0
- package/dist/flow/flow-tools.d.ts +8 -0
- package/dist/flow/flow-tools.js +106 -0
- package/dist/flow/index.d.ts +6 -0
- package/dist/flow/index.js +8 -0
- package/dist/flow/todo-flow.d.ts +25 -0
- package/dist/flow/todo-flow.js +107 -0
- package/dist/flow/types.d.ts +78 -0
- package/dist/flow/types.js +12 -0
- package/dist/flows/bootstrap.d.ts +18 -0
- package/dist/flows/bootstrap.js +119 -0
- package/dist/flows/index.d.ts +6 -0
- package/dist/flows/index.js +11 -0
- package/dist/flows/todo.d.ts +26 -0
- package/dist/flows/todo.js +174 -0
- package/dist/flows/tools.d.ts +8 -0
- package/dist/flows/tools.js +119 -0
- package/dist/flows/types.d.ts +27 -0
- package/dist/flows/types.js +10 -0
- package/dist/gateway/cli.d.ts +5 -0
- package/dist/gateway/cli.js +1027 -0
- package/dist/gateway/factory.d.ts +80 -0
- package/dist/gateway/factory.js +832 -0
- package/dist/gateway/guardian.d.ts +8 -0
- package/dist/gateway/guardian.js +30 -0
- package/dist/gateway/index.d.ts +3 -0
- package/dist/gateway/index.js +3 -0
- package/dist/gateway/server.d.ts +17 -0
- package/dist/gateway/server.js +96 -0
- package/dist/gateway/tui.d.ts +16 -0
- package/dist/gateway/tui.js +3273 -0
- package/dist/hot-reload/agent-watcher.d.ts +24 -0
- package/dist/hot-reload/agent-watcher.js +175 -0
- package/dist/hot-reload/bundle-watcher.d.ts +12 -0
- package/dist/hot-reload/bundle-watcher.js +35 -0
- package/dist/hot-reload/channel-watcher.d.ts +19 -0
- package/dist/hot-reload/channel-watcher.js +54 -0
- package/dist/hot-reload/command-watcher.d.ts +14 -0
- package/dist/hot-reload/command-watcher.js +54 -0
- package/dist/hot-reload/config-watcher.d.ts +20 -0
- package/dist/hot-reload/config-watcher.js +58 -0
- package/dist/hot-reload/index.d.ts +12 -0
- package/dist/hot-reload/index.js +12 -0
- package/dist/hot-reload/manager.d.ts +58 -0
- package/dist/hot-reload/manager.js +243 -0
- package/dist/hot-reload/manifest-watcher.d.ts +9 -0
- package/dist/hot-reload/manifest-watcher.js +42 -0
- package/dist/hot-reload/mcp-watcher.d.ts +18 -0
- package/dist/hot-reload/mcp-watcher.js +64 -0
- package/dist/hot-reload/model-catalog-watcher.d.ts +18 -0
- package/dist/hot-reload/model-catalog-watcher.js +62 -0
- package/dist/hot-reload/plugin-watcher.d.ts +20 -0
- package/dist/hot-reload/plugin-watcher.js +56 -0
- package/dist/hot-reload/prompt-watcher.d.ts +6 -0
- package/dist/hot-reload/prompt-watcher.js +38 -0
- package/dist/hot-reload/provider-watcher.d.ts +16 -0
- package/dist/hot-reload/provider-watcher.js +45 -0
- package/dist/hot-reload/skill-watcher.d.ts +19 -0
- package/dist/hot-reload/skill-watcher.js +82 -0
- package/dist/hot-reload/tool-watcher.d.ts +16 -0
- package/dist/hot-reload/tool-watcher.js +168 -0
- package/dist/hot-reload/workflow-watcher.d.ts +19 -0
- package/dist/hot-reload/workflow-watcher.js +84 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +6 -0
- package/dist/knowledge/fts5-retriever.d.ts +30 -0
- package/dist/knowledge/fts5-retriever.js +223 -0
- package/dist/knowledge/index.d.ts +11 -0
- package/dist/knowledge/index.js +14 -0
- package/dist/knowledge/indexer.d.ts +41 -0
- package/dist/knowledge/indexer.js +186 -0
- package/dist/knowledge/query-preprocessor.d.ts +13 -0
- package/dist/knowledge/query-preprocessor.js +63 -0
- package/dist/knowledge/retriever.d.ts +45 -0
- package/dist/knowledge/retriever.js +9 -0
- package/dist/knowledge/store.d.ts +27 -0
- package/dist/knowledge/store.js +61 -0
- package/dist/knowledge/structured-store.d.ts +78 -0
- package/dist/knowledge/structured-store.js +280 -0
- package/dist/knowledge/structured-tools.d.ts +12 -0
- package/dist/knowledge/structured-tools.js +151 -0
- package/dist/knowledge/tools.d.ts +20 -0
- package/dist/knowledge/tools.js +238 -0
- package/dist/knowledge/watcher.d.ts +28 -0
- package/dist/knowledge/watcher.js +113 -0
- package/dist/lifecycle/index.d.ts +12 -0
- package/dist/lifecycle/index.js +14 -0
- package/dist/lifecycle/interface.d.ts +94 -0
- package/dist/lifecycle/interface.js +2 -0
- package/dist/lifecycle/local-model.d.ts +62 -0
- package/dist/lifecycle/local-model.js +331 -0
- package/dist/lifecycle/manager.d.ts +70 -0
- package/dist/lifecycle/manager.js +374 -0
- package/dist/lifecycle/supervisor.d.ts +89 -0
- package/dist/lifecycle/supervisor.js +277 -0
- package/dist/lifecycle-integration-test.d.ts +2 -0
- package/dist/lifecycle-integration-test.js +72 -0
- package/dist/local-model/download-manager.d.ts +59 -0
- package/dist/local-model/download-manager.js +517 -0
- package/dist/local-model/index.d.ts +109 -0
- package/dist/local-model/index.js +233 -0
- package/dist/local-model/llamacpp-provider.d.ts +95 -0
- package/dist/local-model/llamacpp-provider.js +379 -0
- package/dist/local-model/model-bridge.d.ts +48 -0
- package/dist/local-model/model-bridge.js +256 -0
- package/dist/local-model/model-registry.d.ts +47 -0
- package/dist/local-model/model-registry.js +188 -0
- package/dist/local-model/types.d.ts +49 -0
- package/dist/local-model/types.js +2 -0
- package/dist/logging/index.d.ts +3 -0
- package/dist/logging/index.js +3 -0
- package/dist/logging/logger.d.ts +56 -0
- package/dist/logging/logger.js +94 -0
- package/dist/machine/flows/bootstrap.d.ts +18 -0
- package/dist/machine/flows/bootstrap.js +119 -0
- package/dist/machine/flows/index.d.ts +6 -0
- package/dist/machine/flows/index.js +11 -0
- package/dist/machine/flows/spec.d.ts +17 -0
- package/dist/machine/flows/spec.js +176 -0
- package/dist/machine/flows/todo.d.ts +26 -0
- package/dist/machine/flows/todo.js +175 -0
- package/dist/machine/flows/tools.d.ts +8 -0
- package/dist/machine/flows/tools.js +119 -0
- package/dist/machine/flows/types.d.ts +33 -0
- package/dist/machine/flows/types.js +10 -0
- package/dist/machine/index.d.ts +8 -0
- package/dist/machine/index.js +9 -0
- package/dist/machine/registry.d.ts +34 -0
- package/dist/machine/registry.js +98 -0
- package/dist/machine/runner.d.ts +41 -0
- package/dist/machine/runner.js +177 -0
- package/dist/machine/types.d.ts +121 -0
- package/dist/machine/types.js +9 -0
- package/dist/mcp/bridge.d.ts +33 -0
- package/dist/mcp/bridge.js +99 -0
- package/dist/mcp/client.d.ts +37 -0
- package/dist/mcp/client.js +161 -0
- package/dist/mcp/config.d.ts +15 -0
- package/dist/mcp/config.js +85 -0
- package/dist/mcp/index.d.ts +7 -0
- package/dist/mcp/index.js +7 -0
- package/dist/mcp/install-manager.d.ts +31 -0
- package/dist/mcp/install-manager.js +158 -0
- package/dist/mcp/lifecycle.d.ts +41 -0
- package/dist/mcp/lifecycle.js +175 -0
- package/dist/mcp/process-transport.d.ts +21 -0
- package/dist/mcp/process-transport.js +59 -0
- package/dist/mcp/side-effect.d.ts +5 -0
- package/dist/mcp/side-effect.js +21 -0
- package/dist/mcp/system.d.ts +95 -0
- package/dist/mcp/system.js +279 -0
- package/dist/memory/companion-session.d.ts +22 -0
- package/dist/memory/companion-session.js +77 -0
- package/dist/memory/compression-boundary.d.ts +20 -0
- package/dist/memory/compression-boundary.js +40 -0
- package/dist/memory/conversation.d.ts +34 -0
- package/dist/memory/conversation.js +107 -0
- package/dist/memory/events.d.ts +42 -0
- package/dist/memory/events.js +56 -0
- package/dist/memory/index.d.ts +7 -0
- package/dist/memory/index.js +6 -0
- package/dist/memory/memory-store.d.ts +11 -0
- package/dist/memory/memory-store.js +51 -0
- package/dist/memory/session-allowlist.d.ts +11 -0
- package/dist/memory/session-allowlist.js +50 -0
- package/dist/memory/session.d.ts +48 -0
- package/dist/memory/session.js +275 -0
- package/dist/memory/stats.d.ts +23 -0
- package/dist/memory/stats.js +59 -0
- package/dist/memory/summary.d.ts +7 -0
- package/dist/memory/summary.js +23 -0
- package/dist/multimodal/index.d.ts +66 -0
- package/dist/multimodal/index.js +210 -0
- package/dist/orchestrator/index.d.ts +5 -0
- package/dist/orchestrator/index.js +4 -0
- package/dist/orchestrator/loop.d.ts +331 -0
- package/dist/orchestrator/loop.js +2443 -0
- package/dist/orchestrator/plan-store.d.ts +81 -0
- package/dist/orchestrator/plan-store.js +167 -0
- package/dist/orchestrator/planner.d.ts +20 -0
- package/dist/orchestrator/planner.js +34 -0
- package/dist/parser/index.d.ts +2 -0
- package/dist/parser/index.js +2 -0
- package/dist/parser/router.d.ts +30 -0
- package/dist/parser/router.js +61 -0
- package/dist/plugins/api.d.ts +39 -0
- package/dist/plugins/api.js +85 -0
- package/dist/plugins/define.d.ts +27 -0
- package/dist/plugins/define.js +32 -0
- package/dist/plugins/index.d.ts +9 -0
- package/dist/plugins/index.js +5 -0
- package/dist/plugins/loader.d.ts +39 -0
- package/dist/plugins/loader.js +128 -0
- package/dist/plugins/manager.d.ts +61 -0
- package/dist/plugins/manager.js +257 -0
- package/dist/plugins/types.d.ts +82 -0
- package/dist/plugins/types.js +2 -0
- package/dist/prompts/agents/code-reviewer.md +16 -0
- package/dist/prompts/agents/security-auditor.md +17 -0
- package/dist/prompts/agents/test-writer.md +15 -0
- package/dist/prompts/attention/attention.md +12 -0
- package/dist/prompts/environment/environment.md +18 -0
- package/dist/prompts/environment/feishu.md +107 -0
- package/dist/prompts/flows/bootstrap-confirm.md +14 -0
- package/dist/prompts/flows/bootstrap-identity.md +11 -0
- package/dist/prompts/flows/bootstrap-soul.md +19 -0
- package/dist/prompts/flows/bootstrap-user.md +11 -0
- package/dist/prompts/flows/spec-checklist.md +27 -0
- package/dist/prompts/flows/spec-define.md +64 -0
- package/dist/prompts/flows/spec-executing-checklist.md +15 -0
- package/dist/prompts/flows/spec-executing-tasks.md +15 -0
- package/dist/prompts/flows/spec-spec.md +51 -0
- package/dist/prompts/flows/spec-tasks.md +32 -0
- package/dist/prompts/flows/todo-execution.md +7 -0
- package/dist/prompts/flows/todo-planning.md +18 -0
- package/dist/prompts/framework/architecture.md +131 -0
- package/dist/prompts/identity/identity.md +2 -0
- package/dist/prompts/loader.d.ts +24 -0
- package/dist/prompts/loader.js +102 -0
- package/dist/prompts/loader.ts +119 -0
- package/dist/prompts/orchestration/summary.md +14 -0
- package/dist/prompts/persona/BOOTSTRAP.md +5 -0
- package/dist/prompts/persona/IDENTITY.md +16 -0
- package/dist/prompts/persona/PartnerMemory.md +5 -0
- package/dist/prompts/persona/PartnerSoul.md +7 -0
- package/dist/prompts/persona/SOUL.md +30 -0
- package/dist/prompts/persona/USER.md +16 -0
- package/dist/prompts/precise/analyze.md +23 -0
- package/dist/prompts/precise/persona.md +18 -0
- package/dist/prompts/safety/coding-standards.md +5 -0
- package/dist/prompts/safety/safety.md +4 -0
- package/dist/prompts/skills/code-review.md +4 -0
- package/dist/prompts/skills/debug.md +7 -0
- package/dist/prompts/skills/framework-reference.md +131 -0
- package/dist/prompts/skills/refactor.md +6 -0
- package/dist/prompts/summary.md +22 -0
- package/dist/prompts/tools/framework-capabilities.md +241 -0
- package/dist/prompts/tools/tool-rules.md +15 -0
- package/dist/provider/anthropic.d.ts +62 -0
- package/dist/provider/anthropic.js +361 -0
- package/dist/provider/catalog.d.ts +58 -0
- package/dist/provider/catalog.js +97 -0
- package/dist/provider/compatible.d.ts +89 -0
- package/dist/provider/compatible.js +328 -0
- package/dist/provider/config.d.ts +23 -0
- package/dist/provider/config.js +158 -0
- package/dist/provider/deepseek.d.ts +25 -0
- package/dist/provider/deepseek.js +37 -0
- package/dist/provider/fallback.d.ts +51 -0
- package/dist/provider/fallback.js +113 -0
- package/dist/provider/gemini.d.ts +27 -0
- package/dist/provider/gemini.js +170 -0
- package/dist/provider/index.d.ts +36 -0
- package/dist/provider/index.js +42 -0
- package/dist/provider/interface.d.ts +62 -0
- package/dist/provider/interface.js +2 -0
- package/dist/provider/local-config.d.ts +37 -0
- package/dist/provider/local-config.js +146 -0
- package/dist/provider/local.d.ts +45 -0
- package/dist/provider/local.js +248 -0
- package/dist/provider/manager.d.ts +67 -0
- package/dist/provider/manager.js +355 -0
- package/dist/provider/mimo.d.ts +19 -0
- package/dist/provider/mimo.js +30 -0
- package/dist/provider/minimax.d.ts +22 -0
- package/dist/provider/minimax.js +33 -0
- package/dist/provider/model-catalog-loader.d.ts +42 -0
- package/dist/provider/model-catalog-loader.js +89 -0
- package/dist/provider/model-channel-registry.d.ts +130 -0
- package/dist/provider/model-channel-registry.js +488 -0
- package/dist/provider/model-router.d.ts +60 -0
- package/dist/provider/model-router.js +87 -0
- package/dist/provider/openai.d.ts +54 -0
- package/dist/provider/openai.js +274 -0
- package/dist/provider/qwen.d.ts +19 -0
- package/dist/provider/qwen.js +30 -0
- package/dist/provider/resilient.d.ts +46 -0
- package/dist/provider/resilient.js +181 -0
- package/dist/provider/retry.d.ts +16 -0
- package/dist/provider/retry.js +78 -0
- package/dist/provider/router.d.ts +68 -0
- package/dist/provider/router.js +145 -0
- package/dist/provider/tool-args-recovery.d.ts +36 -0
- package/dist/provider/tool-args-recovery.js +91 -0
- package/dist/provider/user-id.d.ts +13 -0
- package/dist/provider/user-id.js +53 -0
- package/dist/provider/zhipu.d.ts +19 -0
- package/dist/provider/zhipu.js +32 -0
- package/dist/registry/agent.registry.d.ts +57 -0
- package/dist/registry/agent.registry.js +224 -0
- package/dist/registry/base.d.ts +54 -0
- package/dist/registry/base.js +99 -0
- package/dist/registry/channel.registry.d.ts +53 -0
- package/dist/registry/channel.registry.js +87 -0
- package/dist/registry/index.d.ts +9 -0
- package/dist/registry/index.js +10 -0
- package/dist/registry/mcp.registry.d.ts +2 -0
- package/dist/registry/mcp.registry.js +2 -0
- package/dist/registry/plugin.registry.d.ts +33 -0
- package/dist/registry/plugin.registry.js +66 -0
- package/dist/registry/provider.registry.d.ts +51 -0
- package/dist/registry/provider.registry.js +104 -0
- package/dist/registry/skill.registry.d.ts +33 -0
- package/dist/registry/skill.registry.js +95 -0
- package/dist/registry/tool.registry.d.ts +68 -0
- package/dist/registry/tool.registry.js +185 -0
- package/dist/repair/loop-guard.d.ts +98 -0
- package/dist/repair/loop-guard.js +217 -0
- package/dist/repair/scavenge.d.ts +19 -0
- package/dist/repair/scavenge.js +81 -0
- package/dist/repair/storm.d.ts +7 -0
- package/dist/repair/storm.js +7 -0
- package/dist/rollback/index.d.ts +5 -0
- package/dist/rollback/index.js +4 -0
- package/dist/rollback/rollback-tool.d.ts +13 -0
- package/dist/rollback/rollback-tool.js +167 -0
- package/dist/rollback/turn-recorder.d.ts +37 -0
- package/dist/rollback/turn-recorder.js +183 -0
- package/dist/rollback/turn-store.d.ts +29 -0
- package/dist/rollback/turn-store.js +114 -0
- package/dist/rollback/types.d.ts +51 -0
- package/dist/rollback/types.js +9 -0
- package/dist/runtime/config-center.d.ts +92 -0
- package/dist/runtime/config-center.js +467 -0
- package/dist/runtime/config-schema.d.ts +201 -0
- package/dist/runtime/config-schema.js +2 -0
- package/dist/runtime/defaults.d.ts +3 -0
- package/dist/runtime/defaults.js +146 -0
- package/dist/schedule/cron.d.ts +24 -0
- package/dist/schedule/cron.js +145 -0
- package/dist/schedule/index.d.ts +6 -0
- package/dist/schedule/index.js +4 -0
- package/dist/schedule/persistence.d.ts +33 -0
- package/dist/schedule/persistence.js +106 -0
- package/dist/schedule/scheduler.d.ts +85 -0
- package/dist/schedule/scheduler.js +630 -0
- package/dist/schedule/types.d.ts +185 -0
- package/dist/schedule/types.js +2 -0
- package/dist/setup/config.d.ts +189 -0
- package/dist/setup/config.js +253 -0
- package/dist/setup/index.d.ts +3 -0
- package/dist/setup/index.js +3 -0
- package/dist/setup/model-defaults.d.ts +13 -0
- package/dist/setup/model-defaults.js +87 -0
- package/dist/setup/persona-bootstrap.d.ts +42 -0
- package/dist/setup/persona-bootstrap.js +379 -0
- package/dist/setup/wizard.d.ts +32 -0
- package/dist/setup/wizard.js +384 -0
- package/dist/skills/index.d.ts +4 -0
- package/dist/skills/index.js +4 -0
- package/dist/skills/loader.d.ts +12 -0
- package/dist/skills/loader.js +83 -0
- package/dist/skills/registry.d.ts +2 -0
- package/dist/skills/registry.js +2 -0
- package/dist/skills/skill-tool.d.ts +20 -0
- package/dist/skills/skill-tool.js +49 -0
- package/dist/tools/archive.d.ts +17 -0
- package/dist/tools/archive.js +131 -0
- package/dist/tools/ask-user.d.ts +9 -0
- package/dist/tools/ask-user.js +62 -0
- package/dist/tools/background-registry.d.ts +45 -0
- package/dist/tools/background-registry.js +164 -0
- package/dist/tools/bash.d.ts +56 -0
- package/dist/tools/bash.js +391 -0
- package/dist/tools/bundle-registry.d.ts +42 -0
- package/dist/tools/bundle-registry.js +239 -0
- package/dist/tools/bundle-tools.d.ts +11 -0
- package/dist/tools/bundle-tools.js +168 -0
- package/dist/tools/channel-info.d.ts +5 -0
- package/dist/tools/channel-info.js +38 -0
- package/dist/tools/compression.d.ts +7 -0
- package/dist/tools/compression.js +21 -0
- package/dist/tools/config.d.ts +23 -0
- package/dist/tools/config.js +255 -0
- package/dist/tools/db-query.d.ts +12 -0
- package/dist/tools/db-query.js +107 -0
- package/dist/tools/diagnostics.d.ts +30 -0
- package/dist/tools/diagnostics.js +111 -0
- package/dist/tools/diff-channel.d.ts +9 -0
- package/dist/tools/diff-channel.js +17 -0
- package/dist/tools/diff-files.d.ts +17 -0
- package/dist/tools/diff-files.js +88 -0
- package/dist/tools/disk-usage.d.ts +34 -0
- package/dist/tools/disk-usage.js +258 -0
- package/dist/tools/edit.d.ts +30 -0
- package/dist/tools/edit.js +235 -0
- package/dist/tools/executor.d.ts +32 -0
- package/dist/tools/executor.js +66 -0
- package/dist/tools/file-tracker.d.ts +20 -0
- package/dist/tools/file-tracker.js +44 -0
- package/dist/tools/filtered-registry.d.ts +29 -0
- package/dist/tools/filtered-registry.js +50 -0
- package/dist/tools/flow.d.ts +10 -0
- package/dist/tools/flow.js +180 -0
- package/dist/tools/git-tool.d.ts +24 -0
- package/dist/tools/git-tool.js +113 -0
- package/dist/tools/glob.d.ts +29 -0
- package/dist/tools/glob.js +152 -0
- package/dist/tools/grep.d.ts +14 -0
- package/dist/tools/grep.js +325 -0
- package/dist/tools/http-request.d.ts +14 -0
- package/dist/tools/http-request.js +126 -0
- package/dist/tools/index.d.ts +43 -0
- package/dist/tools/index.js +76 -0
- package/dist/tools/injection-filter.d.ts +6 -0
- package/dist/tools/injection-filter.js +71 -0
- package/dist/tools/insert.d.ts +13 -0
- package/dist/tools/insert.js +61 -0
- package/dist/tools/interface.d.ts +30 -0
- package/dist/tools/interface.js +2 -0
- package/dist/tools/json-edit.d.ts +15 -0
- package/dist/tools/json-edit.js +122 -0
- package/dist/tools/multi-edit.d.ts +9 -0
- package/dist/tools/multi-edit.js +146 -0
- package/dist/tools/path-sandbox.d.ts +14 -0
- package/dist/tools/path-sandbox.js +60 -0
- package/dist/tools/process-tools.d.ts +15 -0
- package/dist/tools/process-tools.js +95 -0
- package/dist/tools/python-bridge/bridge.d.ts +24 -0
- package/dist/tools/python-bridge/bridge.js +39 -0
- package/dist/tools/python-bridge/executor.d.ts +6 -0
- package/dist/tools/python-bridge/executor.js +69 -0
- package/dist/tools/python-bridge/index.d.ts +5 -0
- package/dist/tools/python-bridge/index.js +4 -0
- package/dist/tools/python-bridge/parser.d.ts +21 -0
- package/dist/tools/python-bridge/parser.js +258 -0
- package/dist/tools/read.d.ts +16 -0
- package/dist/tools/read.js +276 -0
- package/dist/tools/registry.d.ts +2 -0
- package/dist/tools/registry.js +2 -0
- package/dist/tools/restart.d.ts +10 -0
- package/dist/tools/restart.js +46 -0
- package/dist/tools/result-buffer.d.ts +66 -0
- package/dist/tools/result-buffer.js +146 -0
- package/dist/tools/runtime-control.d.ts +163 -0
- package/dist/tools/runtime-control.js +1780 -0
- package/dist/tools/symbol-references.d.ts +5 -0
- package/dist/tools/symbol-references.js +331 -0
- package/dist/tools/system-info.d.ts +3 -0
- package/dist/tools/system-info.js +55 -0
- package/dist/tools/write.d.ts +18 -0
- package/dist/tools/write.js +118 -0
- package/dist/tools/xref/index.d.ts +25 -0
- package/dist/tools/xref/index.js +25 -0
- package/dist/tools/xref/manager.d.ts +85 -0
- package/dist/tools/xref/manager.js +948 -0
- package/dist/tools/xref/parser.d.ts +34 -0
- package/dist/tools/xref/parser.js +64 -0
- package/dist/tools/xref/regex-parser.d.ts +26 -0
- package/dist/tools/xref/regex-parser.js +446 -0
- package/dist/tools/xref/schema.d.ts +104 -0
- package/dist/tools/xref/schema.js +68 -0
- package/dist/tools/xref/ts-parser.d.ts +20 -0
- package/dist/tools/xref/ts-parser.js +403 -0
- package/dist/tools/xref/xref-build.d.ts +20 -0
- package/dist/tools/xref/xref-build.js +128 -0
- package/dist/tools/xref/xref-graph.d.ts +24 -0
- package/dist/tools/xref/xref-graph.js +88 -0
- package/dist/tools/xref/xref-query.d.ts +30 -0
- package/dist/tools/xref/xref-query.js +123 -0
- package/dist/types.d.ts +217 -0
- package/dist/types.js +2 -0
- package/dist/ui/assistant-message.d.ts +7 -0
- package/dist/ui/assistant-message.js +18 -0
- package/dist/ui/chat-log.d.ts +52 -0
- package/dist/ui/chat-log.js +246 -0
- package/dist/ui/command-registry.d.ts +73 -0
- package/dist/ui/command-registry.js +838 -0
- package/dist/ui/diff-component.d.ts +14 -0
- package/dist/ui/diff-component.js +42 -0
- package/dist/ui/hyperlink-markdown.d.ts +10 -0
- package/dist/ui/hyperlink-markdown.js +21 -0
- package/dist/ui/markdown-message.d.ts +10 -0
- package/dist/ui/markdown-message.js +16 -0
- package/dist/ui/osc8-hyperlinks.d.ts +4 -0
- package/dist/ui/osc8-hyperlinks.js +142 -0
- package/dist/ui/pi-tui-editor.d.ts +35 -0
- package/dist/ui/pi-tui-editor.js +79 -0
- package/dist/ui/slash-commands.d.ts +16 -0
- package/dist/ui/slash-commands.js +29 -0
- package/dist/ui/slash-panel.d.ts +54 -0
- package/dist/ui/slash-panel.js +199 -0
- package/dist/ui/theme.d.ts +120 -0
- package/dist/ui/theme.js +154 -0
- package/dist/ui/tool-display.d.ts +13 -0
- package/dist/ui/tool-display.js +85 -0
- package/dist/ui/tool-execution.d.ts +22 -0
- package/dist/ui/tool-execution.js +87 -0
- package/dist/ui/tui-formatters.d.ts +2 -0
- package/dist/ui/tui-formatters.js +145 -0
- package/dist/ui/user-message.d.ts +5 -0
- package/dist/ui/user-message.js +11 -0
- package/dist/update/check.d.ts +8 -0
- package/dist/update/check.js +28 -0
- package/dist/update/config.d.ts +6 -0
- package/dist/update/config.js +18 -0
- package/dist/update/download.d.ts +3 -0
- package/dist/update/download.js +27 -0
- package/dist/update/index.d.ts +6 -0
- package/dist/update/index.js +5 -0
- package/dist/update/install.d.ts +3 -0
- package/dist/update/install.js +33 -0
- package/dist/update/types.d.ts +16 -0
- package/dist/update/types.js +2 -0
- package/dist/utils/diff.d.ts +9 -0
- package/dist/utils/diff.js +45 -0
- package/dist/utils/misc.d.ts +12 -0
- package/dist/utils/misc.js +34 -0
- package/dist/world-engine/agent.d.ts +41 -0
- package/dist/world-engine/agent.js +385 -0
- package/dist/world-engine/index.d.ts +45 -0
- package/dist/world-engine/index.js +160 -0
- package/dist/world-engine/sim.d.ts +14 -0
- package/dist/world-engine/sim.js +120 -0
- package/dist/world-engine/store.d.ts +110 -0
- package/dist/world-engine/store.js +519 -0
- package/dist/world-engine/ticker.d.ts +37 -0
- package/dist/world-engine/ticker.js +214 -0
- package/dist/world-engine/tools.d.ts +6 -0
- package/dist/world-engine/tools.js +380 -0
- package/dist/world-engine/types.d.ts +202 -0
- package/dist/world-engine/types.js +56 -0
- package/docs/api.md +180 -0
- package/docs/architecture.md +206 -0
- package/docs/diagnostics/2026-06-08-config-prompt-guidance.md +67 -0
- package/docs/superpowers/plans/2026-06-08-global-bootstrap-mode.md +89 -0
- package/docs/superpowers/specs/2026-06-08-global-bootstrap-mode-design.md +174 -0
- package/docs/user-guide.md +226 -0
- package/package.json +63 -0
- package/plugins/example-greeter/index.js +55 -0
- package/plugins/example-greeter/plugin.json +8 -0
- package/pnpm-workspace.yaml +5 -0
- package/provider_arch.md +179 -0
- package/start-webui.sh +27 -0
- package/tsconfig.tsbuildinfo +1 -0
- package/webui-channel-design.md +789 -0
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
import { createLogger } from '../../logging/logger.js';
|
|
3
|
+
const logger = createLogger('python-parser');
|
|
4
|
+
/**
|
|
5
|
+
* 从 Python 文件的 docstring 中解析工具元信息。
|
|
6
|
+
*
|
|
7
|
+
* 支持格式:
|
|
8
|
+
* """
|
|
9
|
+
* name: my_tool
|
|
10
|
+
* description: 工具描述
|
|
11
|
+
* parameters:
|
|
12
|
+
* type: object
|
|
13
|
+
* properties:
|
|
14
|
+
* arg1: {type: string, description: 参数1}
|
|
15
|
+
* required: [arg1]
|
|
16
|
+
* """
|
|
17
|
+
*/
|
|
18
|
+
export function parsePythonToolMeta(filePath) {
|
|
19
|
+
let content;
|
|
20
|
+
try {
|
|
21
|
+
content = readFileSync(filePath, 'utf-8');
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
logger.warn(`Failed to read Python tool: ${filePath}`);
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
const docstring = extractDocstring(content);
|
|
28
|
+
if (!docstring) {
|
|
29
|
+
logger.debug(`No docstring found in ${filePath}`);
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
try {
|
|
33
|
+
const meta = parseYamlLike(docstring);
|
|
34
|
+
if (!meta.name || !meta.description) {
|
|
35
|
+
logger.warn(`Python tool ${filePath} missing required 'name' or 'description' in docstring`);
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
return meta;
|
|
39
|
+
}
|
|
40
|
+
catch (err) {
|
|
41
|
+
logger.warn(`Failed to parse docstring in ${filePath}: ${err.message}`);
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/** 提取第一个 triple-quoted docstring */
|
|
46
|
+
function extractDocstring(content) {
|
|
47
|
+
// 匹配 """...""" 或 '''...'''
|
|
48
|
+
const m = content.match(/"""([^"]*)"""/s) ?? content.match(/'''([^']*)'''/s);
|
|
49
|
+
return m ? m[1].trim() : null;
|
|
50
|
+
}
|
|
51
|
+
/** 简单 YAML-like 解析:缩进层级 + 键值对 + 大括号块 */
|
|
52
|
+
function parseYamlLike(text) {
|
|
53
|
+
const result = { name: '', description: '', inputSchema: { type: 'object', properties: {} } };
|
|
54
|
+
const lines = text.split('\n');
|
|
55
|
+
let i = 0;
|
|
56
|
+
while (i < lines.length) {
|
|
57
|
+
const line = lines[i];
|
|
58
|
+
// 跳过空行和注释
|
|
59
|
+
if (!line.trim() || line.trim().startsWith('#')) {
|
|
60
|
+
i++;
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
const colonIdx = line.indexOf(':');
|
|
64
|
+
if (colonIdx === -1) {
|
|
65
|
+
i++;
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
const key = line.slice(0, colonIdx).trim();
|
|
69
|
+
const rest = line.slice(colonIdx + 1).trim();
|
|
70
|
+
if (key === 'name') {
|
|
71
|
+
result.name = rest;
|
|
72
|
+
i++;
|
|
73
|
+
}
|
|
74
|
+
else if (key === 'description') {
|
|
75
|
+
let desc = rest;
|
|
76
|
+
// 多行描述:后续以同缩进或更深缩进开头的非键值行
|
|
77
|
+
const baseIndent = line.match(/^(\s*)/)?.[1].length ?? 0;
|
|
78
|
+
i++;
|
|
79
|
+
while (i < lines.length) {
|
|
80
|
+
const nextLine = lines[i];
|
|
81
|
+
const nextIndent = nextLine.match(/^(\s*)/)?.[1].length ?? 0;
|
|
82
|
+
const nextColon = nextLine.indexOf(':');
|
|
83
|
+
// 如果下一行缩进更深且不是新的键值对,追加到描述
|
|
84
|
+
if (nextIndent > baseIndent && (nextColon === -1 || nextIndent >= nextLine.indexOf(':'))) {
|
|
85
|
+
desc += '\n' + nextLine.trimStart();
|
|
86
|
+
i++;
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
break;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
result.description = desc;
|
|
93
|
+
}
|
|
94
|
+
else if (key === 'parameters') {
|
|
95
|
+
// 找 parameters 块:收集从下一行开始直到缩进回归的所有行
|
|
96
|
+
const blockLines = [];
|
|
97
|
+
const baseIndent = line.match(/^(\s*)/)?.[1].length ?? 0;
|
|
98
|
+
i++;
|
|
99
|
+
while (i < lines.length) {
|
|
100
|
+
const nextLine = lines[i];
|
|
101
|
+
const nextIndent = nextLine.match(/^(\s*)/)?.[1].length ?? 0;
|
|
102
|
+
if (nextIndent <= baseIndent && nextLine.trim())
|
|
103
|
+
break; // 缩进回归,参数块结束
|
|
104
|
+
blockLines.push(nextLine);
|
|
105
|
+
i++;
|
|
106
|
+
}
|
|
107
|
+
const schemaText = blockLines.join('\n').trim();
|
|
108
|
+
if (schemaText) {
|
|
109
|
+
try {
|
|
110
|
+
result.inputSchema = parseJsonLike(schemaText);
|
|
111
|
+
}
|
|
112
|
+
catch {
|
|
113
|
+
// 解析失败,保留默认 schema
|
|
114
|
+
logger.warn('Failed to parse parameters block, using default schema');
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
i++;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
return result;
|
|
123
|
+
}
|
|
124
|
+
/** 将缩进 YAML-like 的 parameters 块转为 JSON Schema 对象 */
|
|
125
|
+
function parseJsonLike(text) {
|
|
126
|
+
// Step 1: 将缩进格式转为 JSON 字符串
|
|
127
|
+
const lines = text.split('\n');
|
|
128
|
+
const jsonLines = convertToJsonLines(lines);
|
|
129
|
+
try {
|
|
130
|
+
return JSON.parse(jsonLines);
|
|
131
|
+
}
|
|
132
|
+
catch {
|
|
133
|
+
// 嵌套花括号可能被分割, 尝试手动构建
|
|
134
|
+
}
|
|
135
|
+
return { type: 'object', properties: {} };
|
|
136
|
+
}
|
|
137
|
+
function convertToJsonLines(lines) {
|
|
138
|
+
const parts = [];
|
|
139
|
+
let i = 0;
|
|
140
|
+
const indentStack = [];
|
|
141
|
+
// 标记:下一个 item 是否需要前导逗号
|
|
142
|
+
let needsComma = false;
|
|
143
|
+
while (i < lines.length) {
|
|
144
|
+
const line = lines[i];
|
|
145
|
+
const trimmed = line.trim();
|
|
146
|
+
if (!trimmed) {
|
|
147
|
+
i++;
|
|
148
|
+
continue;
|
|
149
|
+
}
|
|
150
|
+
const indent = line.match(/^(\s*)/)?.[1].length ?? 0;
|
|
151
|
+
// 关闭更深的块
|
|
152
|
+
while (indentStack.length > 0 && indent <= indentStack[indentStack.length - 1]) {
|
|
153
|
+
parts.push('}');
|
|
154
|
+
indentStack.pop();
|
|
155
|
+
needsComma = true; // 块关闭后,下一个同层 item 需要逗号
|
|
156
|
+
}
|
|
157
|
+
const colonIdx = trimmed.indexOf(':');
|
|
158
|
+
if (colonIdx === -1) {
|
|
159
|
+
i++;
|
|
160
|
+
continue;
|
|
161
|
+
}
|
|
162
|
+
const key = trimmed.slice(0, colonIdx).trim();
|
|
163
|
+
let val = trimmed.slice(colonIdx + 1).trim();
|
|
164
|
+
// 去掉尾部的逗号(支持 YAML-like trailing comma)
|
|
165
|
+
if (val.endsWith(','))
|
|
166
|
+
val = val.slice(0, -1);
|
|
167
|
+
if (val === '{') {
|
|
168
|
+
// 开始一个新的嵌套对象
|
|
169
|
+
const keyQuoted = /^\w+$/.test(key) ? `"${key}"` : key;
|
|
170
|
+
parts.push(`${needsComma ? ', ' : ''}${keyQuoted}: {`);
|
|
171
|
+
indentStack.push(indent);
|
|
172
|
+
needsComma = false; // 刚打开的块内部不需要逗号
|
|
173
|
+
}
|
|
174
|
+
else if (!val || (val.startsWith('{') && !val.endsWith('}'))) {
|
|
175
|
+
// 空值或残缺的内联对象 → 检查下一行是否有更深缩进
|
|
176
|
+
const hasDeeperBlock = i + 1 < lines.length &&
|
|
177
|
+
(lines[i + 1].match(/^(\s*)/)?.[1].length ?? 0) > indent;
|
|
178
|
+
if (hasDeeperBlock) {
|
|
179
|
+
const keyQuoted = /^\w+$/.test(key) ? `"${key}"` : key;
|
|
180
|
+
parts.push(`${needsComma ? ', ' : ''}${keyQuoted}: {`);
|
|
181
|
+
indentStack.push(indent);
|
|
182
|
+
needsComma = false;
|
|
183
|
+
}
|
|
184
|
+
else {
|
|
185
|
+
const keyQuoted = /^\w+$/.test(key) ? `"${key}"` : key;
|
|
186
|
+
parts.push(`${needsComma ? ', ' : ''}${keyQuoted}: ${formatJsonValue(val)}`);
|
|
187
|
+
needsComma = true;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
else if (val.startsWith('{') && val.endsWith('}')) {
|
|
191
|
+
// 单行对象: key: { ... }
|
|
192
|
+
const keyQuoted = /^\w+$/.test(key) ? `"${key}"` : key;
|
|
193
|
+
parts.push(`${needsComma ? ', ' : ''}${keyQuoted}: ${formatJsonValue(val)}`);
|
|
194
|
+
needsComma = true;
|
|
195
|
+
}
|
|
196
|
+
else if (val.startsWith('[') && val.endsWith(']')) {
|
|
197
|
+
// 数组值
|
|
198
|
+
const keyQuoted = /^\w+$/.test(key) ? `"${key}"` : key;
|
|
199
|
+
const arrItems = val.slice(1, -1).split(',').map(s => s.trim()).map(s => /^\w+$/.test(s) ? `"${s}"` : s).join(', ');
|
|
200
|
+
parts.push(`${needsComma ? ', ' : ''}${keyQuoted}: [${arrItems}]`);
|
|
201
|
+
needsComma = true;
|
|
202
|
+
}
|
|
203
|
+
else {
|
|
204
|
+
// 普通键值对
|
|
205
|
+
const keyQuoted = /^\w+$/.test(key) ? `"${key}"` : key;
|
|
206
|
+
parts.push(`${needsComma ? ', ' : ''}${keyQuoted}: ${formatJsonValue(val)}`);
|
|
207
|
+
needsComma = true;
|
|
208
|
+
}
|
|
209
|
+
i++;
|
|
210
|
+
}
|
|
211
|
+
// 关闭所有未闭合的块
|
|
212
|
+
while (indentStack.length > 0) {
|
|
213
|
+
parts.push('}');
|
|
214
|
+
indentStack.pop();
|
|
215
|
+
}
|
|
216
|
+
return `{${parts.join('')}}`;
|
|
217
|
+
}
|
|
218
|
+
function formatJsonValue(val) {
|
|
219
|
+
if (val === 'true' || val === 'false')
|
|
220
|
+
return val;
|
|
221
|
+
if (val === 'null')
|
|
222
|
+
return 'null';
|
|
223
|
+
if (/^-?\d+(\.\d+)?$/.test(val))
|
|
224
|
+
return val;
|
|
225
|
+
// 内联 YAML-like 对象: {key: val, key2: val2}
|
|
226
|
+
if (val.startsWith('{') && val.endsWith('}')) {
|
|
227
|
+
const obj = parseInlineYamlObject(val);
|
|
228
|
+
if (obj)
|
|
229
|
+
return JSON.stringify(obj);
|
|
230
|
+
}
|
|
231
|
+
// 字符串:引号包裹,转义内部引号
|
|
232
|
+
const escaped = val.replace(/"/g, '\\"');
|
|
233
|
+
return `"${escaped}"`;
|
|
234
|
+
}
|
|
235
|
+
/** 将内联 YAML-like 对象 {key: val, key: val} 解析为真正的 JS 对象 */
|
|
236
|
+
function parseInlineYamlObject(text) {
|
|
237
|
+
try {
|
|
238
|
+
const inner = text.slice(1, -1).trim();
|
|
239
|
+
if (!inner)
|
|
240
|
+
return {};
|
|
241
|
+
const result = {};
|
|
242
|
+
// 按逗号分割,但只在逗号后紧跟 "单词:" 模式时才算真正的分隔
|
|
243
|
+
const segments = inner.split(/,\s*(?=\w+\s*:)/);
|
|
244
|
+
for (const seg of segments) {
|
|
245
|
+
const colonIdx = seg.indexOf(':');
|
|
246
|
+
if (colonIdx === -1)
|
|
247
|
+
continue;
|
|
248
|
+
const key = seg.slice(0, colonIdx).trim();
|
|
249
|
+
const val = seg.slice(colonIdx + 1).trim();
|
|
250
|
+
result[key] = val;
|
|
251
|
+
}
|
|
252
|
+
return result;
|
|
253
|
+
}
|
|
254
|
+
catch {
|
|
255
|
+
return null;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
//# sourceMappingURL=parser.js.map
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { Tool } from './interface.js';
|
|
2
|
+
/** 图片处理器 — 将 read 工具输出的图片注入到 ImageStore */
|
|
3
|
+
export interface ImageHandler {
|
|
4
|
+
store(base64Data: string, mediaType: string, sourcePath: string): string;
|
|
5
|
+
inject(imgId: string, data: string, mediaType: string): void;
|
|
6
|
+
}
|
|
7
|
+
export declare class ReadTool implements Tool {
|
|
8
|
+
readonly name = "read";
|
|
9
|
+
readonly description = "Read a file from disk. Supports offset/limit for chunked reading. Images return dimensions, PDFs return page count. Max 2000 lines per read \u2014 use offset+limit for large files.";
|
|
10
|
+
readonly companionDescription = "\u9700\u8981\u770B\u70B9\u522B\u7684\u4E1C\u897F\u4E86\u3002";
|
|
11
|
+
readonly inputSchema: Record<string, unknown>;
|
|
12
|
+
private imageHandler;
|
|
13
|
+
setImageHandler(handler: ImageHandler): void;
|
|
14
|
+
execute(args: Record<string, unknown>): Promise<string>;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=read.d.ts.map
|
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
import { createReadStream, promises as fs } from 'node:fs';
|
|
2
|
+
import { createInterface } from 'node:readline';
|
|
3
|
+
import { recordFileRead } from './file-tracker.js';
|
|
4
|
+
// ── 常量 ────────────────────────────────────────────────────────
|
|
5
|
+
const DEFAULT_LIMIT = 2000;
|
|
6
|
+
const MAX_LIMIT = 2000;
|
|
7
|
+
const BINARY_SNIFF_BYTES = 512;
|
|
8
|
+
const TEXT_HINT_THRESHOLD = 10 * 1024 * 1024; // 10MB
|
|
9
|
+
const IMAGE_SIGNATURES = [
|
|
10
|
+
{ ext: 'png', mime: 'image/png', bytes: [0x89, 0x50, 0x4E, 0x47], offset: 0 },
|
|
11
|
+
{ ext: 'jpg', mime: 'image/jpeg', bytes: [0xFF, 0xD8, 0xFF], offset: 0 },
|
|
12
|
+
{ ext: 'gif', mime: 'image/gif', bytes: [0x47, 0x49, 0x46, 0x38], offset: 0 },
|
|
13
|
+
{ ext: 'webp', mime: 'image/webp', bytes: [0x52, 0x49, 0x46, 0x46], offset: 0 },
|
|
14
|
+
{ ext: 'bmp', mime: 'image/bmp', bytes: [0x42, 0x4D], offset: 0 },
|
|
15
|
+
];
|
|
16
|
+
// ── 二进制检测 ──────────────────────────────────────────────────
|
|
17
|
+
function hasNullBytes(buf, length) {
|
|
18
|
+
for (let i = 0; i < length; i++)
|
|
19
|
+
if (buf[i] === 0)
|
|
20
|
+
return true;
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
function matchSignature(buf, sig) {
|
|
24
|
+
if (buf.length < sig.offset + sig.bytes.length)
|
|
25
|
+
return false;
|
|
26
|
+
return sig.bytes.every((b, i) => buf[sig.offset + i] === b);
|
|
27
|
+
}
|
|
28
|
+
function detectImageType(buf) {
|
|
29
|
+
for (const sig of IMAGE_SIGNATURES) {
|
|
30
|
+
if (matchSignature(buf, sig)) {
|
|
31
|
+
if (sig.ext === 'webp' && buf.length >= 12) {
|
|
32
|
+
if (buf[8] === 0x57 && buf[9] === 0x45 && buf[10] === 0x42 && buf[11] === 0x50)
|
|
33
|
+
return sig;
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
return sig;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
function isPdf(buf) {
|
|
42
|
+
return buf.length >= 5 && buf[0] === 0x25 && buf[1] === 0x50 && buf[2] === 0x44 && buf[3] === 0x46;
|
|
43
|
+
}
|
|
44
|
+
// ── 图片尺寸提取(仅读文件头,不加载像素数据)───────────────────
|
|
45
|
+
async function getImageDimensions(filePath, type) {
|
|
46
|
+
try {
|
|
47
|
+
const fh = await fs.open(filePath, 'r');
|
|
48
|
+
try {
|
|
49
|
+
const buf = Buffer.alloc(64);
|
|
50
|
+
await fh.read(buf, 0, 64, 0);
|
|
51
|
+
switch (type) {
|
|
52
|
+
case 'png':
|
|
53
|
+
if (buf.length >= 24)
|
|
54
|
+
return { width: buf.readUInt32BE(16), height: buf.readUInt32BE(20) };
|
|
55
|
+
break;
|
|
56
|
+
case 'jpg':
|
|
57
|
+
for (let i = 2; i < buf.length - 9; i++) {
|
|
58
|
+
if (buf[i] === 0xFF && buf[i + 1] === 0xC0) {
|
|
59
|
+
return { height: buf.readUInt16BE(i + 5), width: buf.readUInt16BE(i + 7) };
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
break;
|
|
63
|
+
case 'gif':
|
|
64
|
+
if (buf.length >= 10)
|
|
65
|
+
return { width: buf.readUInt16LE(6), height: buf.readUInt16LE(8) };
|
|
66
|
+
break;
|
|
67
|
+
case 'bmp':
|
|
68
|
+
if (buf.length >= 26)
|
|
69
|
+
return { width: buf.readInt32LE(18), height: buf.readInt32LE(22) };
|
|
70
|
+
break;
|
|
71
|
+
case 'webp':
|
|
72
|
+
if (buf.length >= 30) {
|
|
73
|
+
if (buf[12] === 0x56 && buf[13] === 0x50 && buf[14] === 0x38 && buf[15] === 0x20) {
|
|
74
|
+
return { width: buf.readUInt16LE(26) & 0x3FFF, height: buf.readUInt16LE(28) & 0x3FFF };
|
|
75
|
+
}
|
|
76
|
+
if (buf[12] === 0x56 && buf[13] === 0x50 && buf[14] === 0x38 && buf[15] === 0x4C) {
|
|
77
|
+
const bits = buf.readUInt32LE(21);
|
|
78
|
+
return { width: (bits & 0x3FFF) + 1, height: ((bits >> 14) & 0x3FFF) + 1 };
|
|
79
|
+
}
|
|
80
|
+
if (buf[12] === 0x56 && buf[13] === 0x50 && buf[14] === 0x38 && buf[15] === 0x58) {
|
|
81
|
+
return { width: (buf.readUIntLE(24, 3) & 0xFFFFFF) + 1, height: (buf.readUIntLE(27, 3) & 0xFFFFFF) + 1 };
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
break;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
finally {
|
|
88
|
+
await fh.close();
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
catch { /* degrade */ }
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
94
|
+
// ── PDF trailer 页数(仅读尾部 8KB,不上全量)────────────────────
|
|
95
|
+
async function getPdfPageCount(filePath, fileSize) {
|
|
96
|
+
try {
|
|
97
|
+
const size = typeof fileSize === 'bigint' ? Number(fileSize) : fileSize;
|
|
98
|
+
const tailSize = Math.min(8192, size);
|
|
99
|
+
const fh = await fs.open(filePath, 'r');
|
|
100
|
+
try {
|
|
101
|
+
const buf = Buffer.alloc(tailSize);
|
|
102
|
+
await fh.read(buf, 0, tailSize, size - tailSize);
|
|
103
|
+
const tail = buf.toString('latin1');
|
|
104
|
+
const m = tail.match(/\/Count\s+(\d+)/);
|
|
105
|
+
if (m) {
|
|
106
|
+
const n = parseInt(m[1], 10);
|
|
107
|
+
if (n > 0)
|
|
108
|
+
return n;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
finally {
|
|
112
|
+
await fh.close();
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
catch { /* degrade */ }
|
|
116
|
+
return null;
|
|
117
|
+
}
|
|
118
|
+
// ── 格式化 ──────────────────────────────────────────────────────
|
|
119
|
+
function formatLines(startLine, lines) {
|
|
120
|
+
const width = String(startLine + lines.length - 1).length;
|
|
121
|
+
return lines.map((line, i) => String(startLine + i).padStart(width) + '→' + line).join('\n');
|
|
122
|
+
}
|
|
123
|
+
function formatFileSize(bytes) {
|
|
124
|
+
const n = typeof bytes === 'bigint' ? Number(bytes) : bytes;
|
|
125
|
+
if (n < 1024)
|
|
126
|
+
return `${n}B`;
|
|
127
|
+
if (n < 1024 * 1024)
|
|
128
|
+
return `${(n / 1024).toFixed(1)}KB`;
|
|
129
|
+
return `${(n / (1024 * 1024)).toFixed(2)}MB`;
|
|
130
|
+
}
|
|
131
|
+
// ── 流式文本读取 ────────────────────────────────────────────────
|
|
132
|
+
async function readTextLines(filePath, offset, limit, fileSize) {
|
|
133
|
+
const safeLimit = Math.max(1, Math.min(limit, MAX_LIMIT));
|
|
134
|
+
const startLine = Math.max(1, offset);
|
|
135
|
+
const endLine = startLine + safeLimit - 1;
|
|
136
|
+
const resultLines = [];
|
|
137
|
+
let totalLines = 0;
|
|
138
|
+
const rl = createInterface({
|
|
139
|
+
input: createReadStream(filePath, { encoding: 'utf-8' }),
|
|
140
|
+
crlfDelay: Infinity,
|
|
141
|
+
});
|
|
142
|
+
for await (const rawLine of rl) {
|
|
143
|
+
totalLines++;
|
|
144
|
+
if (totalLines >= startLine && totalLines <= endLine)
|
|
145
|
+
resultLines.push(rawLine);
|
|
146
|
+
if (totalLines >= endLine) {
|
|
147
|
+
rl.close();
|
|
148
|
+
break;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
rl.close();
|
|
152
|
+
if (resultLines.length === 0) {
|
|
153
|
+
return `(empty) offset=${offset} exceeds file (total: ${totalLines} lines)`;
|
|
154
|
+
}
|
|
155
|
+
const sizeNum = typeof fileSize === 'bigint' ? Number(fileSize) : fileSize;
|
|
156
|
+
let output = formatLines(startLine, resultLines);
|
|
157
|
+
if (sizeNum > TEXT_HINT_THRESHOLD && totalLines >= endLine) {
|
|
158
|
+
output += `\n\n(file ${formatFileSize(fileSize)}, lines ${startLine}-${startLine + resultLines.length - 1} of ${totalLines}+. Use offset=${startLine + resultLines.length} for next chunk)`;
|
|
159
|
+
}
|
|
160
|
+
return output;
|
|
161
|
+
}
|
|
162
|
+
// ── 图片 / PDF 读取 ─────────────────────────────────────────────
|
|
163
|
+
async function readImage(filePath, imageType, stat, returnBase64 = false, imageHandler) {
|
|
164
|
+
const dims = await getImageDimensions(filePath, imageType.ext);
|
|
165
|
+
const parts = [
|
|
166
|
+
`[Image: ${imageType.ext.toUpperCase()}]`,
|
|
167
|
+
`Size: ${formatFileSize(stat.size)}`,
|
|
168
|
+
];
|
|
169
|
+
if (dims)
|
|
170
|
+
parts.push(`Dimensions: ${dims.width}x${dims.height}px`);
|
|
171
|
+
else
|
|
172
|
+
parts.push(`Dimensions: (unable to parse)`);
|
|
173
|
+
if (returnBase64) {
|
|
174
|
+
const fh = await fs.open(filePath, 'r');
|
|
175
|
+
const buf = Buffer.alloc(stat.size);
|
|
176
|
+
await fh.read(buf, 0, stat.size, 0);
|
|
177
|
+
await fh.close();
|
|
178
|
+
const b64 = buf.toString('base64');
|
|
179
|
+
// 通过 ImageHandler 注入到 ImageStore,下一轮 compose 时自动作为 ImageContent 发送
|
|
180
|
+
if (imageHandler) {
|
|
181
|
+
const imgId = imageHandler.store(b64, imageType.mime, filePath);
|
|
182
|
+
imageHandler.inject(imgId, b64, imageType.mime);
|
|
183
|
+
parts.push(`Data: data:${imageType.mime};base64,${b64.slice(0, 200)}...`);
|
|
184
|
+
parts.push(`Image #${imgId} injected — visible to vision models in next response.`);
|
|
185
|
+
}
|
|
186
|
+
else {
|
|
187
|
+
parts.push(`Data: data:${imageType.mime};base64,${b64}`);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
else {
|
|
191
|
+
parts.push('(metadata only, pixel data not loaded — use return_base64:true for vision models)');
|
|
192
|
+
}
|
|
193
|
+
return parts.join('\n');
|
|
194
|
+
}
|
|
195
|
+
async function readPdf(filePath, stat) {
|
|
196
|
+
const pageCount = await getPdfPageCount(filePath, stat.size);
|
|
197
|
+
const parts = [
|
|
198
|
+
`[PDF Document]`,
|
|
199
|
+
`Size: ${formatFileSize(stat.size)}`,
|
|
200
|
+
];
|
|
201
|
+
if (pageCount !== null)
|
|
202
|
+
parts.push(`Pages: ${pageCount}`);
|
|
203
|
+
parts.push('(use a PDF MCP server for text/image extraction)');
|
|
204
|
+
return parts.join('\n');
|
|
205
|
+
}
|
|
206
|
+
// ── ReadTool ────────────────────────────────────────────────────
|
|
207
|
+
export class ReadTool {
|
|
208
|
+
name = 'read';
|
|
209
|
+
description = 'Read a file from disk. Supports offset/limit for chunked reading. Images return dimensions, PDFs return page count. Max 2000 lines per read — use offset+limit for large files.';
|
|
210
|
+
companionDescription = '需要看点别的东西了。';
|
|
211
|
+
inputSchema = {
|
|
212
|
+
type: 'object',
|
|
213
|
+
properties: {
|
|
214
|
+
file_path: {
|
|
215
|
+
type: 'string',
|
|
216
|
+
description: 'The absolute path to the file to read',
|
|
217
|
+
},
|
|
218
|
+
offset: {
|
|
219
|
+
type: 'number',
|
|
220
|
+
description: 'Line number to start reading from (1-based). Default 1.',
|
|
221
|
+
},
|
|
222
|
+
limit: {
|
|
223
|
+
type: 'number',
|
|
224
|
+
description: 'Maximum number of lines to read (1-2000, default 2000).',
|
|
225
|
+
},
|
|
226
|
+
return_base64: {
|
|
227
|
+
type: 'boolean',
|
|
228
|
+
description: 'For image files: return full base64-encoded data for use with vision models. For text files: ignored.',
|
|
229
|
+
},
|
|
230
|
+
},
|
|
231
|
+
required: ['file_path'],
|
|
232
|
+
};
|
|
233
|
+
imageHandler = null;
|
|
234
|
+
setImageHandler(handler) {
|
|
235
|
+
this.imageHandler = handler;
|
|
236
|
+
}
|
|
237
|
+
async execute(args) {
|
|
238
|
+
const filePath = args.file_path;
|
|
239
|
+
if (!filePath)
|
|
240
|
+
return '错误:缺少 file_path 参数。请提供文件的绝对路径。';
|
|
241
|
+
const offset = Math.max(1, args.offset ?? 1);
|
|
242
|
+
const limit = Math.max(1, Math.min(args.limit ?? DEFAULT_LIMIT, MAX_LIMIT));
|
|
243
|
+
let stat;
|
|
244
|
+
try {
|
|
245
|
+
stat = await fs.stat(filePath);
|
|
246
|
+
}
|
|
247
|
+
catch {
|
|
248
|
+
throw new Error(`File not found: ${filePath}`);
|
|
249
|
+
}
|
|
250
|
+
if (!stat.isFile())
|
|
251
|
+
throw new Error(`Path is not a file: ${filePath}`);
|
|
252
|
+
// 记录文件已被读取(支撑 write/edit 的 read-before-write 门控)
|
|
253
|
+
recordFileRead(filePath);
|
|
254
|
+
// sniff 512 bytes for type detection
|
|
255
|
+
try {
|
|
256
|
+
const sniffBuf = Buffer.alloc(BINARY_SNIFF_BYTES);
|
|
257
|
+
const sniffFh = await fs.open(filePath, 'r');
|
|
258
|
+
const { bytesRead } = await sniffFh.read(sniffBuf, 0, BINARY_SNIFF_BYTES, 0);
|
|
259
|
+
await sniffFh.close();
|
|
260
|
+
const imageType = detectImageType(sniffBuf);
|
|
261
|
+
if (imageType)
|
|
262
|
+
return readImage(filePath, imageType, stat, !!args.return_base64, this.imageHandler);
|
|
263
|
+
if (isPdf(sniffBuf))
|
|
264
|
+
return readPdf(filePath, stat);
|
|
265
|
+
if (hasNullBytes(sniffBuf, bytesRead)) {
|
|
266
|
+
return `[Binary File]\nSize: ${formatFileSize(stat.size)}\nBinary data detected, cannot display as text.`;
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
catch (err) {
|
|
270
|
+
if (err instanceof Error && err.message.startsWith('File not found'))
|
|
271
|
+
throw err;
|
|
272
|
+
}
|
|
273
|
+
return readTextLines(filePath, offset, limit, stat.size);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
//# sourceMappingURL=read.js.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Tool } from './interface.js';
|
|
2
|
+
export declare class RestartTool implements Tool {
|
|
3
|
+
private cwd;
|
|
4
|
+
readonly name = "restart";
|
|
5
|
+
readonly description: string;
|
|
6
|
+
readonly inputSchema: Record<string, unknown>;
|
|
7
|
+
constructor(cwd: string);
|
|
8
|
+
execute(args: Record<string, unknown>): Promise<string>;
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=restart.d.ts.map
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { writeFileSync, mkdirSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { homedir } from 'node:os';
|
|
4
|
+
const RESTART_EXIT_CODE = 42;
|
|
5
|
+
const RESTART_FILE = '.agent/.restart-session';
|
|
6
|
+
const CONTINUATION_FILE = '.agent/.restart-continuation';
|
|
7
|
+
export class RestartTool {
|
|
8
|
+
cwd;
|
|
9
|
+
name = 'restart';
|
|
10
|
+
description = 'Restart the Agent process. The current session is persisted and resumed automatically after restart. ' +
|
|
11
|
+
'Config is saved, child processes are stopped gracefully.\n' +
|
|
12
|
+
'Optional parameter "message": if provided, this message will be automatically sent after restart to continue work. ' +
|
|
13
|
+
'If omitted, the agent will wait for user input after restart.';
|
|
14
|
+
inputSchema = {
|
|
15
|
+
type: 'object',
|
|
16
|
+
properties: {
|
|
17
|
+
message: {
|
|
18
|
+
type: 'string',
|
|
19
|
+
description: 'Optional. After restart, this message will be automatically sent to continue working (e.g. "继续测试"). Omit to wait for user input.',
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
constructor(cwd) {
|
|
24
|
+
this.cwd = cwd;
|
|
25
|
+
}
|
|
26
|
+
async execute(args) {
|
|
27
|
+
const agentDir = join(homedir(), '.agent');
|
|
28
|
+
try {
|
|
29
|
+
mkdirSync(agentDir, { recursive: true });
|
|
30
|
+
// 标记文件告诉 guardian 使用 --continue
|
|
31
|
+
writeFileSync(join(agentDir, '.restart-session'), 'true', 'utf-8');
|
|
32
|
+
// 如果传了 message,保存续工指令
|
|
33
|
+
const message = args.message;
|
|
34
|
+
if (message) {
|
|
35
|
+
writeFileSync(join(agentDir, '.restart-continuation'), message, 'utf-8');
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
catch { }
|
|
39
|
+
setTimeout(() => process.exit(RESTART_EXIT_CODE), 500);
|
|
40
|
+
if (args.message) {
|
|
41
|
+
return `Restarting... "${args.message.slice(0, 60)}" will be executed after restart.`;
|
|
42
|
+
}
|
|
43
|
+
return 'Restarting... Session will be resumed.';
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=restart.js.map
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
export interface ResultBufferConfig {
|
|
2
|
+
/** Session directory for storing buffered files (auto-creates `buffered-results/` subdir). */
|
|
3
|
+
sessionDir: string;
|
|
4
|
+
/** Whether buffering is enabled. Default true. */
|
|
5
|
+
enabled?: boolean;
|
|
6
|
+
/** Size threshold in bytes. Results larger than this are buffered. Default 16384 (16 KB). */
|
|
7
|
+
threshold?: number;
|
|
8
|
+
/** Include a preview of the first N characters in the pointer message. Default true. */
|
|
9
|
+
includePreview?: boolean;
|
|
10
|
+
/** Number of characters to include in preview. Default 500. */
|
|
11
|
+
previewChars?: number;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* ToolResultBuffer — 通用工具结果中间层
|
|
15
|
+
*
|
|
16
|
+
* 所有工具(内置 / MCP / 插件 / Skill)的执行结果在注入对话历史前经过此类。
|
|
17
|
+
* 当结果字节数超过阈值时,将完整结果写入磁盘缓冲文件,对话中仅注入一条短的
|
|
18
|
+
* "指针消息"。LLM 通过已有的 `read` 工具(含 offset/limit 分页)按需读取。
|
|
19
|
+
*
|
|
20
|
+
* 对标 StormBreaker 模式:AgentLoop 构造函数内自初始化,不需要 factory.ts 注入。
|
|
21
|
+
*
|
|
22
|
+
* 七条原则自检(§0.5):
|
|
23
|
+
* ① 单一职责 — 只做"大结果→文件,小结果→透传"
|
|
24
|
+
* ② 零侵入 — 删除此文件 + 移除 loop.ts 调用→系统正常运行
|
|
25
|
+
* ③ 外部配置 — 阈值通过 configCenter 控制
|
|
26
|
+
* ④ 数据分离 — 数据(缓冲文件)/ 配置(阈值)/ 代码(buffer 逻辑)
|
|
27
|
+
* ⑤ 接口稳定 — 唯一入口 maybeBuffer(result, toolName): string
|
|
28
|
+
* ⑥ 可独立测试 — 构造字符串→调 maybeBuffer→验证文件和指针格式
|
|
29
|
+
* ⑦ 跨项目可移植 — 复制到任何 Agent 项目即可用
|
|
30
|
+
*/
|
|
31
|
+
export declare class ToolResultBuffer {
|
|
32
|
+
private sessionDir;
|
|
33
|
+
private enabled;
|
|
34
|
+
private threshold;
|
|
35
|
+
private includePreview;
|
|
36
|
+
private previewChars;
|
|
37
|
+
private bufferDir;
|
|
38
|
+
private initialized;
|
|
39
|
+
constructor(config: ResultBufferConfig);
|
|
40
|
+
/**
|
|
41
|
+
* 如果 `result` 超过阈值,写入磁盘并返回指针消息;否则原样返回。
|
|
42
|
+
* 先折叠连续重复行(日志/错误输出优化),再判断是否需要缓冲。
|
|
43
|
+
*
|
|
44
|
+
* @param result 工具执行返回的原始文本
|
|
45
|
+
* @param toolName 工具名(用于指针消息和文件名,如 `mcp__chrome-devtools__take_snapshot`)
|
|
46
|
+
* @returns 原始结果(≤阈值)或指针消息(>阈值)
|
|
47
|
+
*/
|
|
48
|
+
maybeBuffer(result: string, toolName: string): string;
|
|
49
|
+
/** 写入缓冲文件并生成指针消息。首次调用时懒创建缓冲目录。 */
|
|
50
|
+
private bufferToDisk;
|
|
51
|
+
private ensureDir;
|
|
52
|
+
/** 生成唯一文件名:`工具名-时间戳-短哈希.txt` */
|
|
53
|
+
private buildFilename;
|
|
54
|
+
/** FNV-1a 32-bit hash — 轻量、确定性、零依赖 */
|
|
55
|
+
private fnv32a;
|
|
56
|
+
/**
|
|
57
|
+
* 折叠连续重复行。当同一行连续出现 ≥5 次时,压缩为 "[×N] content"。
|
|
58
|
+
* 针对日志、错误输出等包含大量重复内容的场景,大幅减少 token 消耗。
|
|
59
|
+
*/
|
|
60
|
+
private foldRepeatedLines;
|
|
61
|
+
/** 获取缓冲目录路径(用于外部判断文件是否已缓冲)。 */
|
|
62
|
+
getBufferDir(): string;
|
|
63
|
+
/** 生成 LLM 可读的指针消息,引导其使用 `read` 工具按需读取。 */
|
|
64
|
+
private buildPointerMessage;
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=result-buffer.d.ts.map
|