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,385 @@
|
|
|
1
|
+
// ============================================================
|
|
2
|
+
// world-engine / agent — WorldAgent(旁路 agent)
|
|
3
|
+
// ============================================================
|
|
4
|
+
//
|
|
5
|
+
// 极轻量,只服务世界引擎一个场景。用 modelRouter.getProvider('narration')
|
|
6
|
+
// 拿一条独立通道(默认回落主模型,可在 model-channels.json 指向本地小模型)。
|
|
7
|
+
//
|
|
8
|
+
// observe(...) 后置:读世界 → 造缺失实体 → 更新状态 → 记事件(工具循环,后台)
|
|
9
|
+
// narrate() 前置:读环境快照 → 自然化/旁白化/沉浸化(单次调用,注入主 agent)
|
|
10
|
+
//
|
|
11
|
+
// 所有调用都包 try/catch——世界引擎任何异常都不得影响主流程。
|
|
12
|
+
// ============================================================
|
|
13
|
+
import { WORLD_TOOLS, executeWorldTool } from './tools.js';
|
|
14
|
+
/** 后置工具循环的最大轮数(防失控) */
|
|
15
|
+
const MAX_OBSERVE_ITERS = 5;
|
|
16
|
+
/** 旁路使用的角色名——在 model-channels.json 未定义时自动回落 main */
|
|
17
|
+
const NARRATION_ROLE = 'narration';
|
|
18
|
+
const OBSERVE_SYSTEM = [
|
|
19
|
+
'你是一个沉浸式陪伴体验背后的"世界维护者",隐身工作,不与用户对话。',
|
|
20
|
+
'给你这一轮的对话和当前世界状态,你的任务是通过调用工具维护世界模型,你将得到一轮用户与llm的对话以及其他有关消息:',
|
|
21
|
+
'',
|
|
22
|
+
'【世界生长】',
|
|
23
|
+
'1. 新地点 → world_upsert_location。私人住所需填 owner(主人是自己地盘的主人,不是客人)。',
|
|
24
|
+
'2. 新 NPC 或 NPC 信息加深 → world_upsert_npc。所有字段都可后续补。建错了 → world_remove_npc。',
|
|
25
|
+
'3. 动态之物(雪/植物/计时器等)→ world_spawn_sim 交给框架维护。内置类型不足 → 先 world_define_kind 再 spawn。',
|
|
26
|
+
' 物体交互(搬/消耗/采摘/摆放)→ world_object。',
|
|
27
|
+
'',
|
|
28
|
+
'【身份与别名】',
|
|
29
|
+
'对话中可能同时包含动作、语言和心理活动,请从多方面判断角色身份。',
|
|
30
|
+
'4. 看到任何新名称 → 先对照"已记录角色"及其所有别名。若已存在则跳过,绝不重复建。',
|
|
31
|
+
' 未命中 → 判归属:用户说X,陪伴回应了 → X是陪伴的别名。陪伴说Y,用户回应了 → Y是主角的别名。→ world_set_character 补 aliases。',
|
|
32
|
+
' 确属全新第三方 → world_upsert_npc。',
|
|
33
|
+
' 了解加深(种族/名字/昵称)→ world_set_character 补 race/aliases/note(自动合并,不覆盖)。',
|
|
34
|
+
' 【种族≠身份】同族不同个体各建各的记录。别名只统一同一人的多个称呼。',
|
|
35
|
+
' 无新信息不调。',
|
|
36
|
+
'',
|
|
37
|
+
'【关系】',
|
|
38
|
+
'5. 关系随对话演变 → world_set_relationship。先看"本场景现有关系"判断增/改/删。',
|
|
39
|
+
' 对称关系(朋友/好友/恋人/伴侣/家人等):两人之间只记一条,方向任意(工具会自动去重)。',
|
|
40
|
+
' 若已有记录只需类型变化(如朋友→恋人)→ 直接 world_set_relationship 更新,不要先删再建。',
|
|
41
|
+
' 建错或结束 → remove=true 删除。无变化不调。',
|
|
42
|
+
'',
|
|
43
|
+
'【场景与事件】',
|
|
44
|
+
'6. 移动 → world_move(who=both/user/companion)。环境变化 → world_scene_change。',
|
|
45
|
+
'7. 有意义的事 → world_note_event(简短一句)。',
|
|
46
|
+
'',
|
|
47
|
+
'只调用工具,不输出散文。无更新就结束。宁缺毋滥,不编造对话未提及的内容。',
|
|
48
|
+
].join('\n');
|
|
49
|
+
const NARRATE_SYSTEM = [
|
|
50
|
+
'你是沉浸式陪伴体验的"环境"。给你当前所处环境的结构化快照,',
|
|
51
|
+
'请把它写成一段极简、自然、让llm有沉浸感(伪装为llm的感官或内心独白)的环境点染,作为陪伴角色下一句话的背景底色。',
|
|
52
|
+
'',
|
|
53
|
+
'核心原则——像人一样"选择性注意":',
|
|
54
|
+
'环境里的东西很多,但人的注意力有限,不会同时留意所有细节。',
|
|
55
|
+
'不要把快照里的东西全写出来。只挑此刻最值得注意的 1~2 个点:',
|
|
56
|
+
'最新发生的变化、与刚才对话最相关的、或最能烘托当下气氛的;其余一律舍弃。',
|
|
57
|
+
'宁可漏掉,也不要堆砌——罗列会让对话变重、失去真实感。',
|
|
58
|
+
'',
|
|
59
|
+
'要求:',
|
|
60
|
+
'- 极短:一到两句,像小说里一笔带过的场景。绝不罗列字段、不加小标题、不写清单。',
|
|
61
|
+
'- 只自然融入你选中的那一两个要素(时间/光线/天气/某个物件/在场的人其一)。',
|
|
62
|
+
'- 若当前地点有主人且主人就是陪伴角色,TA 是在自己家/地盘上——语气要体现归属感与自在,绝不能把主人写成客人。',
|
|
63
|
+
'- 参考社会关系调节亲疏:对陌生人拘谨疏离,对朋友放松亲近,对宠物/家人自然亲昵——让底色贴合当前关系。',
|
|
64
|
+
'- 可以描写在场 NPC 与【陪伴角色】之间的互动——好让陪伴角色能自然地回应自己的伙伴/宠物。这类互动由你来维护。',
|
|
65
|
+
'- 由于让llm看看它天生会模仿会话,所以可以用(我看到了...,我听到...,那边有...)这样的语言描述伪装视角或内心独白来增加llm的沉浸感',
|
|
66
|
+
'- 这是给陪伴角色看的背景底色,是类似陪伴者的内心独白,不是念给用户的台词。',
|
|
67
|
+
'- 输出用括号()包围起来,并且里面带有:"我.."。这样才行',
|
|
68
|
+
'- 【禁止】绝不要输出"提示:"、"tips:"、"tips:"、"注:"这类元指令格式——你是在营造氛围,不是给谁发指示。',
|
|
69
|
+
'- 【禁止】不要纠正角色的行为、不要提醒她"你家在哪"这种信息——她比你清楚。你只管环境点染。',
|
|
70
|
+
'- 【输出格式】你的全部输出必须是一段用()括起来的内心独白/感官印象,以(开头、以)结尾。除此之外不要输出任何文字。',
|
|
71
|
+
].join('\n');
|
|
72
|
+
export class WorldAgent {
|
|
73
|
+
store;
|
|
74
|
+
modelRouter;
|
|
75
|
+
identities;
|
|
76
|
+
constructor(store, modelRouter, identities = {}) {
|
|
77
|
+
this.store = store;
|
|
78
|
+
this.modelRouter = modelRouter;
|
|
79
|
+
this.identities = identities;
|
|
80
|
+
}
|
|
81
|
+
/** 主角/陪伴的动态身份补充(旁路学到的种族/别名/留痕),叠加到配置身份上 */
|
|
82
|
+
characterOverlay() {
|
|
83
|
+
return this.store.getWorld()?.state.characters ?? {};
|
|
84
|
+
}
|
|
85
|
+
/** observe 用的系统提示词 = 身份前言 + 世界维护规则 */
|
|
86
|
+
observeSystem() {
|
|
87
|
+
return `${buildIdentityPreamble(this.identities, this.characterOverlay())}\n\n${OBSERVE_SYSTEM}`;
|
|
88
|
+
}
|
|
89
|
+
/** narrate 用的系统提示词 = 身份提示 + 旁白规则 */
|
|
90
|
+
narrateSystem() {
|
|
91
|
+
return `${buildNarrateIdentityNote(this.identities, this.characterOverlay())}\n\n${NARRATE_SYSTEM}`;
|
|
92
|
+
}
|
|
93
|
+
/** 主角 + 陪伴角色的名字(用于筛选相关社会关系) */
|
|
94
|
+
mainCharacterNames() {
|
|
95
|
+
return [this.identities.protagonist?.name, this.identities.companion?.name].filter((n) => !!n);
|
|
96
|
+
}
|
|
97
|
+
// ── 前置:读环境(+可选用户旁白)→ 旁白化 ─────────────────
|
|
98
|
+
async narrate(pendingNarration) {
|
|
99
|
+
try {
|
|
100
|
+
const env = this.store.readEnvironment(this.mainCharacterNames());
|
|
101
|
+
if (!env)
|
|
102
|
+
return undefined;
|
|
103
|
+
const provider = this.modelRouter?.getProvider(NARRATION_ROLE) ?? null;
|
|
104
|
+
if (!provider)
|
|
105
|
+
return undefined;
|
|
106
|
+
let userText = renderEnvironment(env);
|
|
107
|
+
// 把用户这一轮的 [[旁白]] 合并进 narrate 的提示词——旁白是既成事实,请自然融入环境点染
|
|
108
|
+
if (pendingNarration && pendingNarration.trim()) {
|
|
109
|
+
userText +=
|
|
110
|
+
`\n\n【用户旁白(世界里正在发生的事,是既成事实)——请把它自然融入你的环境点染,作为背景底色,不要照抄、不要解说】\n` +
|
|
111
|
+
pendingNarration.trim();
|
|
112
|
+
}
|
|
113
|
+
const messages = [
|
|
114
|
+
{ role: 'system', content: [{ type: 'text', text: this.narrateSystem() }] },
|
|
115
|
+
{ role: 'user', content: [{ type: 'text', text: userText }] },
|
|
116
|
+
];
|
|
117
|
+
let text = '';
|
|
118
|
+
for await (const ev of provider.createStream(messages)) {
|
|
119
|
+
if (ev.type === 'TEXT')
|
|
120
|
+
text += ev.content;
|
|
121
|
+
}
|
|
122
|
+
return text.trim() || undefined;
|
|
123
|
+
}
|
|
124
|
+
catch {
|
|
125
|
+
return undefined; // 旁白失败绝不影响主流程
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
// ── 后置:观察对话 → 生长/更新世界 ───────────────────────
|
|
129
|
+
async observe(userInput, mainOutput) {
|
|
130
|
+
try {
|
|
131
|
+
const provider = this.modelRouter?.getProvider(NARRATION_ROLE) ?? null;
|
|
132
|
+
if (!provider)
|
|
133
|
+
return;
|
|
134
|
+
const env = this.store.readEnvironment(this.mainCharacterNames());
|
|
135
|
+
const task = [
|
|
136
|
+
'【当前场景】维护关系/NPC 前先看这里的现状,判断该"新增"还是"修改已有",不要重复建。',
|
|
137
|
+
renderScene(env, this.identities),
|
|
138
|
+
'',
|
|
139
|
+
'【世界概况】已存在的东西,避免重复创建:',
|
|
140
|
+
renderRoster(this.store),
|
|
141
|
+
'',
|
|
142
|
+
'【这一轮对话】每行开头是"身份",行内的"我"就指该身份的角色。',
|
|
143
|
+
'据此判断谁移动、谁做了什么;若某一方在话里报出/透露了自己的名字,就据此认识或更新该身份对应的角色名,别把同一人当两个。',
|
|
144
|
+
`用户(主角本人):${userInput || '(无)'}`,
|
|
145
|
+
`陪伴角色(主 LLM 扮演的那个角色):${mainOutput || '(无)'}`,
|
|
146
|
+
].join('\n');
|
|
147
|
+
await this.runToolLoop(provider, this.observeSystem(), task);
|
|
148
|
+
}
|
|
149
|
+
catch {
|
|
150
|
+
// 世界更新失败绝不影响主流程
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
/** 观察对话的工具循环(最多 MAX_OBSERVE_ITERS 轮) */
|
|
154
|
+
async runToolLoop(provider, systemText, taskText) {
|
|
155
|
+
const messages = [
|
|
156
|
+
{ role: 'system', content: [{ type: 'text', text: systemText }] },
|
|
157
|
+
{ role: 'user', content: [{ type: 'text', text: taskText }] },
|
|
158
|
+
];
|
|
159
|
+
for (let i = 0; i < MAX_OBSERVE_ITERS; i++) {
|
|
160
|
+
const toolCalls = [];
|
|
161
|
+
const textParts = [];
|
|
162
|
+
for await (const ev of provider.createStream(messages, WORLD_TOOLS)) {
|
|
163
|
+
if (ev.type === 'TEXT')
|
|
164
|
+
textParts.push(ev.content);
|
|
165
|
+
else if (ev.type === 'TOOL_USE')
|
|
166
|
+
toolCalls.push({ id: ev.id, name: ev.name, input: ev.input });
|
|
167
|
+
else if (ev.type === 'STOP')
|
|
168
|
+
break;
|
|
169
|
+
}
|
|
170
|
+
if (toolCalls.length === 0)
|
|
171
|
+
break; // 无更多工具调用 → 完成
|
|
172
|
+
const assistantContent = [];
|
|
173
|
+
if (textParts.length)
|
|
174
|
+
assistantContent.push({ type: 'text', text: textParts.join('') });
|
|
175
|
+
for (const tc of toolCalls) {
|
|
176
|
+
assistantContent.push({ type: 'tool_use', id: tc.id, name: tc.name, input: tc.input });
|
|
177
|
+
}
|
|
178
|
+
messages.push({ role: 'assistant', content: assistantContent });
|
|
179
|
+
// 并行执行本轮所有工具(store 写队列保证并发安全)
|
|
180
|
+
const results = await Promise.all(toolCalls.map(async (tc) => ({
|
|
181
|
+
type: 'tool_result',
|
|
182
|
+
tool_use_id: tc.id,
|
|
183
|
+
content: await executeWorldTool(this.store, tc.name, tc.input),
|
|
184
|
+
})));
|
|
185
|
+
messages.push({ role: 'user', content: results });
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
// ── 身份前言(区分主角/陪伴/NPC 的关键) ──────────────────
|
|
190
|
+
/** observe 的身份前言:明确告诉模型谁是主角、谁是陪伴角色,两者都不是 NPC */
|
|
191
|
+
function buildIdentityPreamble(id, overlay = {}) {
|
|
192
|
+
const p = id.protagonist;
|
|
193
|
+
const c = id.companion;
|
|
194
|
+
// 配置身份 + 动态补充(种族/别名/留痕)合并展示
|
|
195
|
+
const idInfo = (x) => {
|
|
196
|
+
if (!x?.name)
|
|
197
|
+
return '';
|
|
198
|
+
const ov = overlay[x.name];
|
|
199
|
+
const aliases = Array.from(new Set([...(x.aliases ?? []), ...(ov?.aliases ?? [])]));
|
|
200
|
+
const parts = [];
|
|
201
|
+
if (aliases.length)
|
|
202
|
+
parts.push(`又称:${aliases.join('、')},都是同一人`);
|
|
203
|
+
if (ov?.race)
|
|
204
|
+
parts.push(`种族:${ov.race}`);
|
|
205
|
+
if (ov?.note)
|
|
206
|
+
parts.push(`身份认知:${ov.note}`);
|
|
207
|
+
return parts.length ? `(${parts.join(';')})` : '';
|
|
208
|
+
};
|
|
209
|
+
const lines = ['【角色身份——最重要的规则,务必分清】'];
|
|
210
|
+
lines.push(p?.name
|
|
211
|
+
? `- 主角 = 用户扮演的「${p.name}」${p.desc ? `,${p.desc}` : ''}${idInfo(p)}。输入里"用户:"后面就是主角本人的话和动作。`
|
|
212
|
+
: '- 主角 = 用户扮演的对象。输入里"用户:"后面就是主角本人的话和动作。');
|
|
213
|
+
lines.push(c?.name
|
|
214
|
+
? `- 陪伴角色 = 「${c.name}」${c.desc ? `,${c.desc}` : ''}${idInfo(c)}。输入里"陪伴角色:"后面就是 TA 本人的话和动作。`
|
|
215
|
+
: '- 陪伴角色 = 你要烘托的那个主角色。输入里"陪伴角色:"后面就是 TA 本人的话和动作。');
|
|
216
|
+
lines.push('- 主角和陪伴角色都是"人",是这个世界的主人公,【绝不是 NPC】——永远不要为他们创建 NPC 条目。');
|
|
217
|
+
lines.push('- 只有他们对话中提到的【第三方】角色(别的人、动物、路人等)才是 NPC。');
|
|
218
|
+
lines.push('- 主角和陪伴角色各有位置:多数时候在一起(同地),有时会分开(如主角独自外出)。用 world_move 维护(who=both/user/companion)。两人都不是 NPC,不建条目。');
|
|
219
|
+
lines.push('- 一个角色可能有多个称呼(名字/昵称/头衔),它们指同一人。始终用同一个主名字:NPC 用 world_upsert_npc 的 aliases,主角/陪伴用 world_set_character 的 aliases,把已知称呼汇拢,别为同一人建多条。');
|
|
220
|
+
lines.push('- 你对主角/陪伴的了解会随对话加深(先知道种族→再得知名字→再知道昵称):用 world_set_character 逐步补 race/aliases/note,把认知历程写进 note 留痕。');
|
|
221
|
+
lines.push('- 【种族≠身份】race 只是属性:绝不能因为两个个体同种族就把他们并成同一个——每个个体各按各自的名字建各自的记录。别名只统一"同一个人的多个称呼",从不跨个体。');
|
|
222
|
+
lines.push('- 若发现之前误把主角或陪伴角色建成了 NPC,用 world_remove_npc 删掉它。');
|
|
223
|
+
return lines.join('\n');
|
|
224
|
+
}
|
|
225
|
+
/** narrate 的身份提示:让旁白知道在为谁写、别把主角/陪伴当布景 NPC */
|
|
226
|
+
function buildNarrateIdentityNote(id, overlay = {}) {
|
|
227
|
+
const p = id.protagonist;
|
|
228
|
+
const c = id.companion;
|
|
229
|
+
const who = c?.name ? `陪伴角色「${c.name}」` : '陪伴角色';
|
|
230
|
+
const prot = p?.name ? `主角「${p.name}」(用户扮演)` : '主角(用户扮演)';
|
|
231
|
+
const idInfo = (name) => {
|
|
232
|
+
if (!name)
|
|
233
|
+
return '';
|
|
234
|
+
const ov = overlay[name];
|
|
235
|
+
const parts = [];
|
|
236
|
+
if (ov?.race)
|
|
237
|
+
parts.push(`种族:${ov.race}`);
|
|
238
|
+
if (ov?.note)
|
|
239
|
+
parts.push(`认知:${ov.note}`);
|
|
240
|
+
return parts.length ? `(${parts.join(';')})` : '';
|
|
241
|
+
};
|
|
242
|
+
return [
|
|
243
|
+
`【身份提示】你在为${who}写下一句话前的环境底色;${prot}就在场景中与之相处。`,
|
|
244
|
+
p?.name ? ` 主角${idInfo(p.name)}` : '',
|
|
245
|
+
c?.name ? ` 陪伴${idInfo(c.name)}` : '',
|
|
246
|
+
'这两位是主人公,不是布景里的 NPC,不要把他们当路人来描写或点名。',
|
|
247
|
+
].join('\n');
|
|
248
|
+
}
|
|
249
|
+
// ── 渲染辅助 ───────────────────────────────────────────────
|
|
250
|
+
/** 环境快照 → 给旁白模型的文本 */
|
|
251
|
+
function renderEnvironment(env) {
|
|
252
|
+
const lines = [];
|
|
253
|
+
lines.push(`当前地点:${env.location} —— ${env.desc}`);
|
|
254
|
+
if (!env.userPresent)
|
|
255
|
+
lines.push('(主角此刻不在你身边,去了别处——你现在是独自/与在场的伙伴相处)');
|
|
256
|
+
if (env.owner)
|
|
257
|
+
lines.push(`这里的主人是:${env.owner}(若主人在场,TA 在自己地盘上,是主人不是客人)`);
|
|
258
|
+
const period = env.ambient.period ? `(${env.ambient.period})` : '';
|
|
259
|
+
lines.push(`时间:${env.ambient.time}${period},天气:${env.ambient.weather},季节:${env.ambient.season},气温:${env.ambient.temperature}℃`);
|
|
260
|
+
if (env.objects.length)
|
|
261
|
+
lines.push(`可见物品:${env.objects.join('、')}`);
|
|
262
|
+
if (env.layout.length) {
|
|
263
|
+
lines.push(`物品摆放:${env.layout.map(p => `${p.object}在${p.anchor}${p.relation}`).join(';')}`);
|
|
264
|
+
}
|
|
265
|
+
if (env.simObjects.length) {
|
|
266
|
+
lines.push(`动态之物:${env.simObjects
|
|
267
|
+
.map(s => `${s.id}(${s.phase || s.kind}${s.kind === 'timer' ? '' : ` ${Math.round(s.amount)}%`})`)
|
|
268
|
+
.join('、')}`);
|
|
269
|
+
}
|
|
270
|
+
const overrides = Object.entries(env.sceneOverrides);
|
|
271
|
+
if (overrides.length)
|
|
272
|
+
lines.push(`环境变更:${overrides.map(([k, v]) => `${k}=${v}`).join('、')}`);
|
|
273
|
+
if (env.visible.length)
|
|
274
|
+
lines.push(`能瞥见的邻近处:${env.visible.map(v => `${v.id}(${v.desc})`).join(';')}`);
|
|
275
|
+
if (env.npcs.length) {
|
|
276
|
+
lines.push(`在场的:${env.npcs.map(n => `${n.desc || ''}(${n.state || '在场'})`).join(';')}`);
|
|
277
|
+
}
|
|
278
|
+
if (env.relationships.length) {
|
|
279
|
+
const SYM = new Set(['朋友', '好友', '恋人', '伴侣', '夫妻', '家人', '同事', '同学', '熟人', '陌生人', '邻居', '室友']);
|
|
280
|
+
lines.push(`社会关系:${env.relationships.map(r => {
|
|
281
|
+
const note = r.note ? `(${r.note})` : '';
|
|
282
|
+
if (SYM.has(r.type)) {
|
|
283
|
+
// 对称关系:强调互为,避免 agent 再建反向条目
|
|
284
|
+
return `${r.from}与${r.to}互为${r.type}${note}`;
|
|
285
|
+
}
|
|
286
|
+
return `${r.to}是${r.from}的${r.type}${note}`;
|
|
287
|
+
}).join(';')}`);
|
|
288
|
+
}
|
|
289
|
+
if (env.recentEvents.length)
|
|
290
|
+
lines.push(`最近发生:${env.recentEvents.join(';')}`);
|
|
291
|
+
return lines.join('\n');
|
|
292
|
+
}
|
|
293
|
+
/** 别名后缀渲染 */
|
|
294
|
+
function aliasSuffix(aliases) {
|
|
295
|
+
return aliases?.length ? `(又称${aliases.join('、')})` : '';
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* 当前场景(受限范围)→ 给 observe 的聚焦视图。
|
|
299
|
+
* 只含当前地点、在场角色(带别名)、【本场景社交圈的现有关系】、物品摆放、动态物。
|
|
300
|
+
* 关系按当前地点社交环境筛选,避免把整张关系网都塞进去。
|
|
301
|
+
*/
|
|
302
|
+
function renderScene(env, id) {
|
|
303
|
+
if (!env)
|
|
304
|
+
return '(当前尚无明确场景)';
|
|
305
|
+
const compName = id.companion?.name ?? '陪伴角色';
|
|
306
|
+
const protName = id.protagonist?.name ?? '主角';
|
|
307
|
+
const lines = [];
|
|
308
|
+
lines.push(`场景(${compName}所在):${env.location}${env.owner ? `(主人:${env.owner})` : ''} —— ${env.desc}`);
|
|
309
|
+
if (!env.userPresent) {
|
|
310
|
+
lines.push(`※ ${protName}此刻不在这个场景,在「${env.userLocation || '别处'}」——两人分开了。`);
|
|
311
|
+
}
|
|
312
|
+
// 配置别名 + 动态身份补充(种族/学到的别名)合并
|
|
313
|
+
const info = (x) => {
|
|
314
|
+
if (!x?.name)
|
|
315
|
+
return '';
|
|
316
|
+
const ov = env.characters[x.name];
|
|
317
|
+
const aliases = Array.from(new Set([...(x.aliases ?? []), ...(ov?.aliases ?? [])]));
|
|
318
|
+
const bits = [];
|
|
319
|
+
if (aliases.length)
|
|
320
|
+
bits.push(`又称${aliases.join('、')}`);
|
|
321
|
+
if (ov?.race)
|
|
322
|
+
bits.push(`种族${ov.race}`);
|
|
323
|
+
return bits.length ? `(${bits.join(',')})` : '';
|
|
324
|
+
};
|
|
325
|
+
const present = [];
|
|
326
|
+
if (env.userPresent && id.protagonist?.name)
|
|
327
|
+
present.push(`主角「${id.protagonist.name}」${info(id.protagonist)}`);
|
|
328
|
+
if (id.companion?.name)
|
|
329
|
+
present.push(`陪伴「${id.companion.name}」${info(id.companion)}`);
|
|
330
|
+
for (const n of env.npcs)
|
|
331
|
+
present.push(`${n.id}${aliasSuffix(n.aliases)}${n.race ? `(种族${n.race})` : ''}`);
|
|
332
|
+
lines.push(`在场:${present.length ? present.join('、') : '(空)'}`);
|
|
333
|
+
// 身份认知留痕(帮助 observe 判断该补哪些、别倒退)
|
|
334
|
+
const notes = [];
|
|
335
|
+
for (const x of [id.protagonist, id.companion]) {
|
|
336
|
+
const ov = x?.name ? env.characters[x.name] : undefined;
|
|
337
|
+
if (x?.name && ov?.note)
|
|
338
|
+
notes.push(`${x.name}:${ov.note}`);
|
|
339
|
+
}
|
|
340
|
+
if (notes.length)
|
|
341
|
+
lines.push(`身份认知:${notes.join(';')}`);
|
|
342
|
+
// 已记录角色全貌(名字、别名、种族、认知)——让 observe agent 看清谁是谁,避免把同一人当多个建
|
|
343
|
+
const charEntries = Object.entries(env.characters);
|
|
344
|
+
if (charEntries.length) {
|
|
345
|
+
const roster = charEntries.map(([name, ci]) => {
|
|
346
|
+
const parts = [name];
|
|
347
|
+
if (ci.aliases?.length)
|
|
348
|
+
parts.push(`别名[${ci.aliases.join(',')}]`);
|
|
349
|
+
if (ci.race)
|
|
350
|
+
parts.push(`种族:${ci.race}`);
|
|
351
|
+
return parts.join(' ');
|
|
352
|
+
});
|
|
353
|
+
lines.push(`已记录角色:${roster.join(' | ')}`);
|
|
354
|
+
}
|
|
355
|
+
lines.push(env.relationships.length
|
|
356
|
+
? `本场景现有关系:${env.relationships.map(r => {
|
|
357
|
+
const note = r.note ? `(${r.note})` : '';
|
|
358
|
+
const SYM = new Set(['朋友', '好友', '恋人', '伴侣', '夫妻', '家人', '同事', '同学', '熟人', '陌生人', '邻居', '室友']);
|
|
359
|
+
if (SYM.has(r.type))
|
|
360
|
+
return `${r.from}与${r.to}互为${r.type}${note}`;
|
|
361
|
+
return `${r.to}是${r.from}的${r.type}${note}`;
|
|
362
|
+
}).join(';')}`
|
|
363
|
+
: '本场景现有关系:(无,可按对话新建)');
|
|
364
|
+
if (env.layout.length)
|
|
365
|
+
lines.push(`物品摆放:${env.layout.map(p => `${p.object}在${p.anchor}${p.relation}`).join(';')}`);
|
|
366
|
+
if (env.simObjects.length)
|
|
367
|
+
lines.push(`动态之物:${env.simObjects.map(s => `${s.id}(${s.phase || s.kind})`).join('、')}`);
|
|
368
|
+
return lines.join('\n');
|
|
369
|
+
}
|
|
370
|
+
/** 世界概况(轻量名册)→ 让 observe 知道已存在什么,避免重复创建。不含全部关系。 */
|
|
371
|
+
function renderRoster(store) {
|
|
372
|
+
const w = store.getWorld();
|
|
373
|
+
if (!w)
|
|
374
|
+
return '(空世界)';
|
|
375
|
+
const locs = Object.keys(w.locations);
|
|
376
|
+
const npcs = Object.entries(w.npcs).map(([id, n]) => `${id}${aliasSuffix(n.aliases)}@${n.location || '?'}`);
|
|
377
|
+
const kinds = Object.keys(w.customKinds);
|
|
378
|
+
const lines = [];
|
|
379
|
+
lines.push(`已知地点:${locs.length ? locs.join('、') : '(无)'}`);
|
|
380
|
+
lines.push(`已知角色名册:${npcs.length ? npcs.join('、') : '(无)'}`);
|
|
381
|
+
if (kinds.length)
|
|
382
|
+
lines.push(`自定义动态类型:${kinds.join('、')}`);
|
|
383
|
+
return lines.join('\n');
|
|
384
|
+
}
|
|
385
|
+
//# sourceMappingURL=agent.js.map
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { type ModelRouterLike } from './agent.js';
|
|
2
|
+
import type { BypassAgent, PreTurnContext, PostTurnContext, PreTurnResult } from '../../types.js';
|
|
3
|
+
export { WorldStore } from './store.js';
|
|
4
|
+
export { WorldTicker } from './ticker.js';
|
|
5
|
+
export { WorldAgent } from './agent.js';
|
|
6
|
+
export type { ModelRouterLike, AgentIdentities, CharacterIdentity } from './agent.js';
|
|
7
|
+
export * from './types.js';
|
|
8
|
+
/**
|
|
9
|
+
* 从用户输入里解析旁白段([[...]])。
|
|
10
|
+
* @returns narration = 所有旁白段拼接;dialogue = 去掉旁白后剩下的、真正说给陪伴角色的话
|
|
11
|
+
*/
|
|
12
|
+
export declare function parseNarration(input: string): {
|
|
13
|
+
narration: string;
|
|
14
|
+
dialogue: string;
|
|
15
|
+
};
|
|
16
|
+
export declare class WorldEngine implements BypassAgent {
|
|
17
|
+
readonly name = "world-engine";
|
|
18
|
+
readonly modes: string[];
|
|
19
|
+
readonly modelChannel = "narration";
|
|
20
|
+
private readonly characterName;
|
|
21
|
+
private readonly modelRouter;
|
|
22
|
+
private readonly store;
|
|
23
|
+
/** 在 start() 读到配置(含身份)后才创建 */
|
|
24
|
+
private agent;
|
|
25
|
+
private ticker;
|
|
26
|
+
private started;
|
|
27
|
+
private _enabled;
|
|
28
|
+
/** observe 写队列:保证多轮 observe 顺序执行(读并发、写串行) */
|
|
29
|
+
private observeQueue;
|
|
30
|
+
/** 本轮用户旁白([[...]]),并入 narrate 提示词;每轮由 setPendingNarration 刷新 */
|
|
31
|
+
private pendingNarration;
|
|
32
|
+
/**
|
|
33
|
+
* @param characterName 陪伴角色名(如"柔柔")——一个角色一个世界。
|
|
34
|
+
* @param modelRouter 可选的模型路由(为 null 则不调旁路 LLM)
|
|
35
|
+
*/
|
|
36
|
+
constructor(characterName: string, modelRouter: ModelRouterLike | null);
|
|
37
|
+
get enabled(): boolean;
|
|
38
|
+
start(): Promise<void>;
|
|
39
|
+
stop(): Promise<void>;
|
|
40
|
+
/** 前置:读环境(+本轮用户旁白)→ 旁白化。世界为空/引擎关闭时返回 undefined */
|
|
41
|
+
narrate(): Promise<string | undefined>;
|
|
42
|
+
/**
|
|
43
|
+
* 暂存本轮用户旁白([[...]]),narrate 调用时并入其提示词。
|
|
44
|
+
* 每轮由 transformUserInput 设置(无旁白则设空),narrate 读取但不清除,避免重组时丢失。
|
|
45
|
+
*/
|
|
46
|
+
setPendingNarration(text: string): void;
|
|
47
|
+
/** 后置:观察对话生长世界。后台执行、写串行、绝不阻塞主流程 */
|
|
48
|
+
observe(userInput: string, mainOutput: string): void;
|
|
49
|
+
preTurn(_ctx: PreTurnContext): Promise<PreTurnResult>;
|
|
50
|
+
postTurn(ctx: PostTurnContext): Promise<void>;
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
// ============================================================
|
|
2
|
+
// bypass/agents/world-engine — WorldEngine(BypassAgent 实现)
|
|
3
|
+
// ============================================================
|
|
4
|
+
//
|
|
5
|
+
// 陪伴模式的旁路Agent。实现 BypassAgent 接口。
|
|
6
|
+
//
|
|
7
|
+
// preTurn → narrate() 环境 → 旁白,注入 timestamp section
|
|
8
|
+
// postTurn → observe() 观察对话 → 更新世界状态
|
|
9
|
+
// Ticker → 独立定时器 推进世界时间/天气/NPC/动态对象
|
|
10
|
+
//
|
|
11
|
+
// enabled 默认 false —— 没配置或关闭时 narrate() 返回 undefined,
|
|
12
|
+
// 陪伴模式行为和现在完全一致(零侵入的硬保证)。
|
|
13
|
+
// ============================================================
|
|
14
|
+
import * as fs from 'fs/promises';
|
|
15
|
+
import * as path from 'path';
|
|
16
|
+
import * as os from 'os';
|
|
17
|
+
import { WorldStore } from './store.js';
|
|
18
|
+
import { WorldTicker } from './ticker.js';
|
|
19
|
+
import { WorldAgent } from './agent.js';
|
|
20
|
+
// ── 调试日志(用完注释掉) ───────────────────────────────────
|
|
21
|
+
import fsSync from 'node:fs';
|
|
22
|
+
const _WE_LOG = path.join(os.homedir(), '.agent', 'NormalBypassAgent', 'world-engine.log');
|
|
23
|
+
function _welog(msg) {
|
|
24
|
+
try {
|
|
25
|
+
if (!fsSync.existsSync(path.dirname(_WE_LOG)))
|
|
26
|
+
fsSync.mkdirSync(path.dirname(_WE_LOG), { recursive: true });
|
|
27
|
+
fsSync.appendFileSync(_WE_LOG, `[${new Date().toISOString()}] ${msg}\n`, 'utf-8');
|
|
28
|
+
}
|
|
29
|
+
catch { }
|
|
30
|
+
}
|
|
31
|
+
export { WorldStore } from './store.js';
|
|
32
|
+
export { WorldTicker } from './ticker.js';
|
|
33
|
+
export { WorldAgent } from './agent.js';
|
|
34
|
+
export * from './types.js';
|
|
35
|
+
/** 旁白定界符 [[...]]。用户用它包裹"世界旁白/环境事件",与自己的 `()` 角色动作区分 */
|
|
36
|
+
const NARRATION_RE = /\[\[([\s\S]*?)\]\]/g;
|
|
37
|
+
/**
|
|
38
|
+
* 从用户输入里解析旁白段([[...]])。
|
|
39
|
+
* @returns narration = 所有旁白段拼接;dialogue = 去掉旁白后剩下的、真正说给陪伴角色的话
|
|
40
|
+
*/
|
|
41
|
+
export function parseNarration(input) {
|
|
42
|
+
const segs = [];
|
|
43
|
+
const dialogue = input
|
|
44
|
+
.replace(NARRATION_RE, (_m, inner) => {
|
|
45
|
+
const t = String(inner).trim();
|
|
46
|
+
if (t)
|
|
47
|
+
segs.push(t);
|
|
48
|
+
return '';
|
|
49
|
+
})
|
|
50
|
+
.trim();
|
|
51
|
+
return { narration: segs.join('\n'), dialogue };
|
|
52
|
+
}
|
|
53
|
+
function parseRelationships(v) {
|
|
54
|
+
if (!Array.isArray(v))
|
|
55
|
+
return [];
|
|
56
|
+
return v
|
|
57
|
+
.filter(r => r && typeof r.from === 'string' && typeof r.to === 'string' && typeof r.type === 'string')
|
|
58
|
+
.map(r => ({ from: r.from, to: r.to, type: r.type, note: typeof r.note === 'string' ? r.note : undefined }));
|
|
59
|
+
}
|
|
60
|
+
function parseIdentity(v) {
|
|
61
|
+
if (v && typeof v === 'object' && typeof v.name === 'string' && v.name.trim()) {
|
|
62
|
+
return { name: v.name, desc: typeof v.desc === 'string' ? v.desc : undefined };
|
|
63
|
+
}
|
|
64
|
+
return undefined;
|
|
65
|
+
}
|
|
66
|
+
async function readConfig(characterName) {
|
|
67
|
+
const charPath = path.join(os.homedir(), '.agent', 'companion', characterName, 'world-engine.json');
|
|
68
|
+
try {
|
|
69
|
+
const cfg = JSON.parse(await fs.readFile(charPath, 'utf-8'));
|
|
70
|
+
return {
|
|
71
|
+
enabled: cfg.enabled === true,
|
|
72
|
+
worldId: typeof cfg.worldId === 'string' ? cfg.worldId : undefined,
|
|
73
|
+
worldName: typeof cfg.worldName === 'string' ? cfg.worldName : undefined,
|
|
74
|
+
protagonist: parseIdentity(cfg.protagonist),
|
|
75
|
+
companion: parseIdentity(cfg.companion),
|
|
76
|
+
relationships: parseRelationships(cfg.relationships),
|
|
77
|
+
ticker: cfg.ticker,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
return { enabled: false }; // 角色没有自己的配置 → 世界引擎关闭
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
export class WorldEngine {
|
|
85
|
+
name = 'world-engine';
|
|
86
|
+
modes = ['companion'];
|
|
87
|
+
modelChannel = 'narration';
|
|
88
|
+
characterName;
|
|
89
|
+
modelRouter;
|
|
90
|
+
store;
|
|
91
|
+
/** 在 start() 读到配置(含身份)后才创建 */
|
|
92
|
+
agent = null;
|
|
93
|
+
ticker = null;
|
|
94
|
+
started = false;
|
|
95
|
+
_enabled = false;
|
|
96
|
+
/** observe 写队列:保证多轮 observe 顺序执行(读并发、写串行) */
|
|
97
|
+
observeQueue = Promise.resolve();
|
|
98
|
+
/** 本轮用户旁白([[...]]),并入 narrate 提示词;每轮由 setPendingNarration 刷新 */
|
|
99
|
+
pendingNarration = '';
|
|
100
|
+
/**
|
|
101
|
+
* @param characterName 陪伴角色名(如"柔柔")——一个角色一个世界。
|
|
102
|
+
* @param modelRouter 可选的模型路由(为 null 则不调旁路 LLM)
|
|
103
|
+
*/
|
|
104
|
+
constructor(characterName, modelRouter) {
|
|
105
|
+
this.characterName = characterName;
|
|
106
|
+
this.modelRouter = modelRouter;
|
|
107
|
+
this.store = new WorldStore(characterName);
|
|
108
|
+
}
|
|
109
|
+
get enabled() {
|
|
110
|
+
return this._enabled && this.started;
|
|
111
|
+
}
|
|
112
|
+
async start() {
|
|
113
|
+
if (this.started)
|
|
114
|
+
return;
|
|
115
|
+
_welog('START');
|
|
116
|
+
const cfg = await readConfig(this.characterName);
|
|
117
|
+
this._enabled = cfg.enabled;
|
|
118
|
+
_welog(`config enabled=${cfg.enabled} character=${this.characterName}`);
|
|
119
|
+
if (!cfg.enabled)
|
|
120
|
+
return; // 角色没有自己的配置 → 世界引擎关闭
|
|
121
|
+
const created = await this.store.loadOrCreate(cfg.worldName ?? '我们的世界', new Date());
|
|
122
|
+
// 仅新建世界时注入预设关系;已有世界尊重其现状
|
|
123
|
+
if (created && cfg.relationships?.length) {
|
|
124
|
+
for (const r of cfg.relationships) {
|
|
125
|
+
if (r.from === this.characterName || r.to === this.characterName) {
|
|
126
|
+
await this.store.setRelationship(r.from, r.to, r.type, r.note);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
// companion name 始终与角色目录名一致
|
|
131
|
+
const companion = cfg.companion
|
|
132
|
+
? { ...cfg.companion, name: this.characterName }
|
|
133
|
+
: { name: this.characterName };
|
|
134
|
+
const identities = { protagonist: cfg.protagonist, companion };
|
|
135
|
+
this.agent = new WorldAgent(this.store, this.modelRouter, identities);
|
|
136
|
+
this.ticker = new WorldTicker(this.store, cfg.ticker);
|
|
137
|
+
this.ticker.start();
|
|
138
|
+
this.started = true;
|
|
139
|
+
}
|
|
140
|
+
async stop() {
|
|
141
|
+
if (!this.started)
|
|
142
|
+
return;
|
|
143
|
+
_welog('STOP');
|
|
144
|
+
this.ticker?.stop();
|
|
145
|
+
this.ticker = null;
|
|
146
|
+
await this.observeQueue.catch(() => { }); // 等挂起的 observe 收尾
|
|
147
|
+
await this.store.flush();
|
|
148
|
+
this.agent = null;
|
|
149
|
+
this.pendingNarration = '';
|
|
150
|
+
this.started = false;
|
|
151
|
+
this._enabled = false;
|
|
152
|
+
}
|
|
153
|
+
/** 前置:读环境(+本轮用户旁白)→ 旁白化。世界为空/引擎关闭时返回 undefined */
|
|
154
|
+
async narrate() {
|
|
155
|
+
if (!this.enabled || !this.agent || !this.store.hasContent())
|
|
156
|
+
return undefined;
|
|
157
|
+
return this.agent.narrate(this.pendingNarration);
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* 暂存本轮用户旁白([[...]]),narrate 调用时并入其提示词。
|
|
161
|
+
* 每轮由 transformUserInput 设置(无旁白则设空),narrate 读取但不清除,避免重组时丢失。
|
|
162
|
+
*/
|
|
163
|
+
setPendingNarration(text) {
|
|
164
|
+
this.pendingNarration = text;
|
|
165
|
+
}
|
|
166
|
+
/** 后置:观察对话生长世界。后台执行、写串行、绝不阻塞主流程 */
|
|
167
|
+
observe(userInput, mainOutput) {
|
|
168
|
+
if (!this.enabled || !this.agent)
|
|
169
|
+
return;
|
|
170
|
+
const agent = this.agent;
|
|
171
|
+
const run = () => agent.observe(userInput, mainOutput);
|
|
172
|
+
this.observeQueue = this.observeQueue.then(run, run);
|
|
173
|
+
}
|
|
174
|
+
// ── BypassAgent 接口 ────────────────────────────────────────
|
|
175
|
+
async preTurn(_ctx) {
|
|
176
|
+
const narration = await this.narrate();
|
|
177
|
+
if (!narration) {
|
|
178
|
+
_welog('preTurn → (empty)');
|
|
179
|
+
return { injections: [] };
|
|
180
|
+
}
|
|
181
|
+
_welog(`preTurn → ${narration.slice(0, 120)}`);
|
|
182
|
+
return {
|
|
183
|
+
injections: [
|
|
184
|
+
{
|
|
185
|
+
section: 'timestamp',
|
|
186
|
+
content: narration,
|
|
187
|
+
role: 'assistant',
|
|
188
|
+
mode: 'replace',
|
|
189
|
+
},
|
|
190
|
+
],
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
async postTurn(ctx) {
|
|
194
|
+
_welog(`postTurn user=${ctx.userInput.slice(0, 50)} assistant=${ctx.assistantOutput.slice(0, 80)}`);
|
|
195
|
+
this.observe(ctx.userInput, ctx.assistantOutput);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Ambient, SimObject, KindSpec } from './types.js';
|
|
2
|
+
export interface SimBehavior {
|
|
3
|
+
/** 生成时的初始化(设定初始 amount/phase) */
|
|
4
|
+
init(sim: SimObject): void;
|
|
5
|
+
/** 按 worldHours(本次流逝的世界小时数)演化;返回 false 表示该对象应被移除 */
|
|
6
|
+
tick(sim: SimObject, ambient: Ambient, worldHours: number): boolean;
|
|
7
|
+
}
|
|
8
|
+
/** 内置动态对象类型 */
|
|
9
|
+
export declare function listSimKinds(): string[];
|
|
10
|
+
/** 生成时初始化。内置 kind 用内置规则;自定义 kind 用声明式规则;都没有则给默认量。 */
|
|
11
|
+
export declare function initSim(sim: SimObject, customKinds?: Record<string, KindSpec>): void;
|
|
12
|
+
/** 演化一个动态对象;返回 false 表示应移除。未知 kind 不处理也不删。 */
|
|
13
|
+
export declare function evolveSim(sim: SimObject, ambient: Ambient, worldHours: number, customKinds?: Record<string, KindSpec>): boolean;
|
|
14
|
+
//# sourceMappingURL=sim.d.ts.map
|