@elizaos/plugin-agent-orchestrator 2.0.0-alpha.9 → 2.0.0-beta.1
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/CHANGELOG.md +62 -0
- package/LICENSE +21 -0
- package/PROJECT.md +119 -0
- package/README.md +160 -0
- package/dist/browser/index.browser.js +21051 -0
- package/dist/browser/index.browser.js.map +29 -0
- package/dist/browser/index.d.ts +2 -0
- package/dist/cjs/index.d.ts +2 -0
- package/dist/cjs/index.node.cjs +20491 -0
- package/dist/cjs/index.node.js.map +72 -0
- package/dist/index.d.ts +2 -21
- package/dist/node/index.browser.d.ts +3 -0
- package/dist/node/index.browser.d.ts.map +1 -0
- package/dist/node/index.d.ts +2 -0
- package/dist/node/index.d.ts.map +1 -0
- package/dist/node/index.node.d.ts +4 -0
- package/dist/node/index.node.d.ts.map +1 -0
- package/dist/node/index.node.js +20471 -0
- package/dist/node/index.node.js.map +72 -0
- package/dist/node/src/actions/cancel-task.d.ts +3 -0
- package/dist/node/src/actions/cancel-task.d.ts.map +1 -0
- package/dist/node/src/actions/coding-task-handlers.d.ts +69 -0
- package/dist/node/src/actions/coding-task-handlers.d.ts.map +1 -0
- package/dist/node/src/actions/coding-task-helpers.d.ts +35 -0
- package/dist/node/src/actions/coding-task-helpers.d.ts.map +1 -0
- package/dist/node/src/actions/common.d.ts +56 -0
- package/dist/node/src/actions/common.d.ts.map +1 -0
- package/dist/node/src/actions/create-task.d.ts +8 -0
- package/dist/node/src/actions/create-task.d.ts.map +1 -0
- package/dist/node/src/actions/eval-metadata.d.ts +11 -0
- package/dist/node/src/actions/eval-metadata.d.ts.map +1 -0
- package/dist/node/src/actions/finalize-workspace.d.ts +11 -0
- package/dist/node/src/actions/finalize-workspace.d.ts.map +1 -0
- package/dist/node/src/actions/list-agents.d.ts +4 -0
- package/dist/node/src/actions/list-agents.d.ts.map +1 -0
- package/dist/node/src/actions/manage-issues.d.ts +11 -0
- package/dist/node/src/actions/manage-issues.d.ts.map +1 -0
- package/dist/node/src/actions/provision-workspace.d.ts +11 -0
- package/dist/node/src/actions/provision-workspace.d.ts.map +1 -0
- package/dist/node/src/actions/sandbox-stub.d.ts +21 -0
- package/dist/node/src/actions/sandbox-stub.d.ts.map +1 -0
- package/dist/node/src/actions/send-to-agent.d.ts +4 -0
- package/dist/node/src/actions/send-to-agent.d.ts.map +1 -0
- package/dist/node/src/actions/spawn-agent.d.ts +8 -0
- package/dist/node/src/actions/spawn-agent.d.ts.map +1 -0
- package/dist/node/src/actions/stop-agent.d.ts +4 -0
- package/dist/node/src/actions/stop-agent.d.ts.map +1 -0
- package/dist/node/src/actions/task-control.d.ts +3 -0
- package/dist/node/src/actions/task-control.d.ts.map +1 -0
- package/dist/node/src/actions/task-history.d.ts +3 -0
- package/dist/node/src/actions/task-history.d.ts.map +1 -0
- package/dist/node/src/actions/task-share.d.ts +3 -0
- package/dist/node/src/actions/task-share.d.ts.map +1 -0
- package/dist/node/src/actions/task-thread-target.d.ts +11 -0
- package/dist/node/src/actions/task-thread-target.d.ts.map +1 -0
- package/dist/node/src/actions/tasks.d.ts +88 -0
- package/dist/node/src/actions/tasks.d.ts.map +1 -0
- package/dist/node/src/api/agent-routes.d.ts +18 -0
- package/dist/node/src/api/agent-routes.d.ts.map +1 -0
- package/dist/node/src/api/bridge-routes.d.ts +32 -0
- package/dist/node/src/api/bridge-routes.d.ts.map +1 -0
- package/dist/node/src/api/coordinator-routes.d.ts +22 -0
- package/dist/node/src/api/coordinator-routes.d.ts.map +1 -0
- package/dist/node/src/api/hook-routes.d.ts +18 -0
- package/dist/node/src/api/hook-routes.d.ts.map +1 -0
- package/dist/node/src/api/issue-routes.d.ts +17 -0
- package/dist/node/src/api/issue-routes.d.ts.map +1 -0
- package/dist/node/src/api/parent-context-routes.d.ts +17 -0
- package/dist/node/src/api/parent-context-routes.d.ts.map +1 -0
- package/dist/node/src/api/route-utils.d.ts +18 -0
- package/dist/node/src/api/route-utils.d.ts.map +1 -0
- package/dist/node/src/api/routes.d.ts +23 -0
- package/dist/node/src/api/routes.d.ts.map +1 -0
- package/dist/node/src/api/workspace-routes.d.ts +17 -0
- package/dist/node/src/api/workspace-routes.d.ts.map +1 -0
- package/dist/node/src/index.d.ts +32 -0
- package/dist/node/src/index.d.ts.map +1 -0
- package/dist/node/src/providers/action-examples.d.ts +14 -0
- package/dist/node/src/providers/action-examples.d.ts.map +1 -0
- package/dist/node/src/providers/active-sub-agents.d.ts +15 -0
- package/dist/node/src/providers/active-sub-agents.d.ts.map +1 -0
- package/dist/node/src/providers/active-workspace-context.d.ts +13 -0
- package/dist/node/src/providers/active-workspace-context.d.ts.map +1 -0
- package/dist/node/src/providers/available-agents.d.ts +4 -0
- package/dist/node/src/providers/available-agents.d.ts.map +1 -0
- package/dist/node/src/register-routes.d.ts +11 -0
- package/dist/node/src/register-routes.d.ts.map +1 -0
- package/dist/node/src/routes/coding-agents-fallback-routes.d.ts +19 -0
- package/dist/node/src/routes/coding-agents-fallback-routes.d.ts.map +1 -0
- package/dist/node/src/services/acp-service.d.ts +61 -0
- package/dist/node/src/services/acp-service.d.ts.map +1 -0
- package/dist/node/src/services/acpx-subprocess.d.ts +3 -0
- package/dist/node/src/services/acpx-subprocess.d.ts.map +1 -0
- package/dist/node/src/services/agent-credentials.d.ts +23 -0
- package/dist/node/src/services/agent-credentials.d.ts.map +1 -0
- package/dist/node/src/services/agent-metrics.d.ts +30 -0
- package/dist/node/src/services/agent-metrics.d.ts.map +1 -0
- package/dist/node/src/services/agent-selection.d.ts +53 -0
- package/dist/node/src/services/agent-selection.d.ts.map +1 -0
- package/dist/node/src/services/ansi-utils.d.ts +64 -0
- package/dist/node/src/services/ansi-utils.d.ts.map +1 -0
- package/dist/node/src/services/claude-code-skill-installer.d.ts +33 -0
- package/dist/node/src/services/claude-code-skill-installer.d.ts.map +1 -0
- package/dist/node/src/services/config-env.d.ts +23 -0
- package/dist/node/src/services/config-env.d.ts.map +1 -0
- package/dist/node/src/services/coordinator-event-normalizer.d.ts +50 -0
- package/dist/node/src/services/coordinator-event-normalizer.d.ts.map +1 -0
- package/dist/node/src/services/custom-validator-runner.d.ts +66 -0
- package/dist/node/src/services/custom-validator-runner.d.ts.map +1 -0
- package/dist/node/src/services/debug-capture.d.ts +38 -0
- package/dist/node/src/services/debug-capture.d.ts.map +1 -0
- package/dist/node/src/services/json-model-output.d.ts +2 -0
- package/dist/node/src/services/json-model-output.d.ts.map +1 -0
- package/dist/node/src/services/parent-agent-broker.d.ts +21 -0
- package/dist/node/src/services/parent-agent-broker.d.ts.map +1 -0
- package/dist/node/src/services/pty-auto-response.d.ts +30 -0
- package/dist/node/src/services/pty-auto-response.d.ts.map +1 -0
- package/dist/node/src/services/pty-init.d.ts +55 -0
- package/dist/node/src/services/pty-init.d.ts.map +1 -0
- package/dist/node/src/services/pty-service.d.ts +218 -0
- package/dist/node/src/services/pty-service.d.ts.map +1 -0
- package/dist/node/src/services/pty-session-io.d.ts +49 -0
- package/dist/node/src/services/pty-session-io.d.ts.map +1 -0
- package/dist/node/src/services/pty-spawn.d.ts +104 -0
- package/dist/node/src/services/pty-spawn.d.ts.map +1 -0
- package/dist/node/src/services/pty-types.d.ts +94 -0
- package/dist/node/src/services/pty-types.d.ts.map +1 -0
- package/dist/node/src/services/repo-input.d.ts +16 -0
- package/dist/node/src/services/repo-input.d.ts.map +1 -0
- package/dist/node/src/services/session-event-queue.d.ts +25 -0
- package/dist/node/src/services/session-event-queue.d.ts.map +1 -0
- package/dist/node/src/services/session-store.d.ts +107 -0
- package/dist/node/src/services/session-store.d.ts.map +1 -0
- package/dist/node/src/services/skill-callback-bridge.d.ts +78 -0
- package/dist/node/src/services/skill-callback-bridge.d.ts.map +1 -0
- package/dist/node/src/services/skill-essentials.d.ts +16 -0
- package/dist/node/src/services/skill-essentials.d.ts.map +1 -0
- package/dist/node/src/services/skill-lifeops-context-broker.d.ts +20 -0
- package/dist/node/src/services/skill-lifeops-context-broker.d.ts.map +1 -0
- package/dist/node/src/services/skill-manifest.d.ts +48 -0
- package/dist/node/src/services/skill-manifest.d.ts.map +1 -0
- package/dist/node/src/services/skill-recommender.d.ts +51 -0
- package/dist/node/src/services/skill-recommender.d.ts.map +1 -0
- package/dist/node/src/services/spawn-trajectory.d.ts +23 -0
- package/dist/node/src/services/spawn-trajectory.d.ts.map +1 -0
- package/dist/node/src/services/stall-classifier.d.ts +69 -0
- package/dist/node/src/services/stall-classifier.d.ts.map +1 -0
- package/dist/node/src/services/structured-proof-bridge.d.ts +99 -0
- package/dist/node/src/services/structured-proof-bridge.d.ts.map +1 -0
- package/dist/node/src/services/sub-agent-router.d.ts +38 -0
- package/dist/node/src/services/sub-agent-router.d.ts.map +1 -0
- package/dist/node/src/services/swarm-coordinator-prompts.d.ts +93 -0
- package/dist/node/src/services/swarm-coordinator-prompts.d.ts.map +1 -0
- package/dist/node/src/services/swarm-coordinator.d.ts +473 -0
- package/dist/node/src/services/swarm-coordinator.d.ts.map +1 -0
- package/dist/node/src/services/swarm-decision-loop.d.ts +69 -0
- package/dist/node/src/services/swarm-decision-loop.d.ts.map +1 -0
- package/dist/node/src/services/swarm-event-triage.d.ts +49 -0
- package/dist/node/src/services/swarm-event-triage.d.ts.map +1 -0
- package/dist/node/src/services/swarm-history.d.ts +27 -0
- package/dist/node/src/services/swarm-history.d.ts.map +1 -0
- package/dist/node/src/services/swarm-idle-watchdog.d.ts +22 -0
- package/dist/node/src/services/swarm-idle-watchdog.d.ts.map +1 -0
- package/dist/node/src/services/task-acceptance.d.ts +8 -0
- package/dist/node/src/services/task-acceptance.d.ts.map +1 -0
- package/dist/node/src/services/task-agent-auth.d.ts +69 -0
- package/dist/node/src/services/task-agent-auth.d.ts.map +1 -0
- package/dist/node/src/services/task-agent-frameworks.d.ts +90 -0
- package/dist/node/src/services/task-agent-frameworks.d.ts.map +1 -0
- package/dist/node/src/services/task-kind.d.ts +3 -0
- package/dist/node/src/services/task-kind.d.ts.map +1 -0
- package/dist/node/src/services/task-policy.d.ts +17 -0
- package/dist/node/src/services/task-policy.d.ts.map +1 -0
- package/dist/node/src/services/task-registry.d.ts +550 -0
- package/dist/node/src/services/task-registry.d.ts.map +1 -0
- package/dist/node/src/services/task-share.d.ts +18 -0
- package/dist/node/src/services/task-share.d.ts.map +1 -0
- package/dist/node/src/services/task-validation.d.ts +69 -0
- package/dist/node/src/services/task-validation.d.ts.map +1 -0
- package/dist/node/src/services/task-verifier-runner.d.ts +5 -0
- package/dist/node/src/services/task-verifier-runner.d.ts.map +1 -0
- package/dist/node/src/services/trajectory-context.d.ts +73 -0
- package/dist/node/src/services/trajectory-context.d.ts.map +1 -0
- package/dist/node/src/services/trajectory-feedback.d.ts +53 -0
- package/dist/node/src/services/trajectory-feedback.d.ts.map +1 -0
- package/dist/node/src/services/types.d.ts +152 -0
- package/dist/node/src/services/types.d.ts.map +1 -0
- package/dist/node/src/services/workspace-git-ops.d.ts +28 -0
- package/dist/node/src/services/workspace-git-ops.d.ts.map +1 -0
- package/dist/node/src/services/workspace-github.d.ts +60 -0
- package/dist/node/src/services/workspace-github.d.ts.map +1 -0
- package/dist/node/src/services/workspace-lifecycle.d.ts +18 -0
- package/dist/node/src/services/workspace-lifecycle.d.ts.map +1 -0
- package/dist/node/src/services/workspace-service.d.ts +122 -0
- package/dist/node/src/services/workspace-service.d.ts.map +1 -0
- package/dist/node/src/services/workspace-types.d.ts +81 -0
- package/dist/node/src/services/workspace-types.d.ts.map +1 -0
- package/dist/node/src/setup-routes.d.ts +9 -0
- package/dist/node/src/setup-routes.d.ts.map +1 -0
- package/dist/node/vitest.config.d.ts +3 -0
- package/dist/node/vitest.config.d.ts.map +1 -0
- package/docs/default-eliza-skills-and-agent-bridge-plan.md +231 -0
- package/docs/sub-agent-routing.md +197 -0
- package/package.json +113 -37
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -21120
- package/dist/index.js.map +0 -109
- package/dist/src/actions/messaging.d.ts +0 -24
- package/dist/src/actions/messaging.d.ts.map +0 -1
- package/dist/src/actions/peek-subagent.d.ts +0 -3
- package/dist/src/actions/peek-subagent.d.ts.map +0 -1
- package/dist/src/actions/subagent-management.d.ts +0 -7
- package/dist/src/actions/subagent-management.d.ts.map +0 -1
- package/dist/src/actions/task-management.d.ts +0 -9
- package/dist/src/actions/task-management.d.ts.map +0 -1
- package/dist/src/config.d.ts +0 -4
- package/dist/src/config.d.ts.map +0 -1
- package/dist/src/providers/orchestrator-config.d.ts +0 -80
- package/dist/src/providers/orchestrator-config.d.ts.map +0 -1
- package/dist/src/providers/task-context.d.ts +0 -3
- package/dist/src/providers/task-context.d.ts.map +0 -1
- package/dist/src/services/agent-orchestrator-service.d.ts +0 -59
- package/dist/src/services/agent-orchestrator-service.d.ts.map +0 -1
- package/dist/src/services/messaging-service.d.ts +0 -111
- package/dist/src/services/messaging-service.d.ts.map +0 -1
- package/dist/src/services/sandbox-service.d.ts +0 -103
- package/dist/src/services/sandbox-service.d.ts.map +0 -1
- package/dist/src/services/subagent-service.d.ts +0 -140
- package/dist/src/services/subagent-service.d.ts.map +0 -1
- package/dist/src/sub-agents/adapter.d.ts +0 -13
- package/dist/src/sub-agents/adapter.d.ts.map +0 -1
- package/dist/src/sub-agents/claude-agent-sdk-sub-agent.d.ts +0 -18
- package/dist/src/sub-agents/claude-agent-sdk-sub-agent.d.ts.map +0 -1
- package/dist/src/sub-agents/codex-sdk-sub-agent.d.ts +0 -18
- package/dist/src/sub-agents/codex-sdk-sub-agent.d.ts.map +0 -1
- package/dist/src/sub-agents/eliza-sub-agent.d.ts +0 -27
- package/dist/src/sub-agents/eliza-sub-agent.d.ts.map +0 -1
- package/dist/src/sub-agents/elizaos-native-sub-agent.d.ts +0 -61
- package/dist/src/sub-agents/elizaos-native-sub-agent.d.ts.map +0 -1
- package/dist/src/sub-agents/index.d.ts +0 -10
- package/dist/src/sub-agents/index.d.ts.map +0 -1
- package/dist/src/sub-agents/opencode-sub-agent.d.ts +0 -44
- package/dist/src/sub-agents/opencode-sub-agent.d.ts.map +0 -1
- package/dist/src/sub-agents/registry.d.ts +0 -3
- package/dist/src/sub-agents/registry.d.ts.map +0 -1
- package/dist/src/sub-agents/sweagent-sub-agent.d.ts +0 -19
- package/dist/src/sub-agents/sweagent-sub-agent.d.ts.map +0 -1
- package/dist/src/sub-agents/tools.d.ts +0 -15
- package/dist/src/sub-agents/tools.d.ts.map +0 -1
- package/dist/src/sub-agents/types.d.ts +0 -170
- package/dist/src/sub-agents/types.d.ts.map +0 -1
- package/dist/src/types/index.d.ts +0 -12
- package/dist/src/types/index.d.ts.map +0 -1
- package/dist/src/types/messaging.d.ts +0 -202
- package/dist/src/types/messaging.d.ts.map +0 -1
- package/dist/src/types/sandbox.d.ts +0 -228
- package/dist/src/types/sandbox.d.ts.map +0 -1
- package/dist/src/types/subagent.d.ts +0 -232
- package/dist/src/types/subagent.d.ts.map +0 -1
- package/dist/src/types.d.ts +0 -138
- package/dist/src/types.d.ts.map +0 -1
- package/dist/src/utils/index.d.ts +0 -7
- package/dist/src/utils/index.d.ts.map +0 -1
- package/dist/src/utils/session.d.ts +0 -184
- package/dist/src/utils/session.d.ts.map +0 -1
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/services/config-env.ts", "../../src/services/agent-credentials.ts", "../../src/services/agent-metrics.ts", "../../src/services/ansi-utils.ts", "../../src/services/claude-code-skill-installer.ts", "../../src/services/coordinator-event-normalizer.ts", "../../src/services/debug-capture.ts", "../../src/services/pty-auto-response.ts", "../../src/services/pty-init.ts", "../../src/services/pty-session-io.ts", "../../src/services/task-agent-frameworks.ts", "../../src/services/pty-spawn.ts", "../../src/services/pty-types.ts", "../../src/services/skill-essentials.ts", "../../src/services/spawn-trajectory.ts", "../../src/services/json-model-output.ts", "../../src/services/trajectory-context.ts", "../../src/services/stall-classifier.ts", "../../src/services/structured-proof-bridge.ts", "../../src/services/custom-validator-runner.ts", "../../src/services/swarm-coordinator-prompts.ts", "../../src/services/swarm-event-triage.ts", "../../src/services/task-validation.ts", "../../src/services/task-verifier-runner.ts", "../../src/services/swarm-decision-loop.ts", "../../src/services/swarm-history.ts", "../../src/services/swarm-idle-watchdog.ts", "../../src/services/task-acceptance.ts", "../../src/services/task-kind.ts", "../../src/services/task-registry.ts", "../../src/services/swarm-coordinator.ts", "../../src/services/task-agent-auth.ts", "../../src/services/pty-service.ts", "../../src/services/task-share.ts", "../../src/services/workspace-github.ts", "../../src/services/repo-input.ts", "../../src/services/workspace-git-ops.ts", "../../src/services/workspace-lifecycle.ts", "../../src/services/workspace-service.ts", "../../src/providers/active-workspace-context.ts", "../../src/actions/eval-metadata.ts", "../../src/api/route-utils.ts", "../../src/api/agent-routes.ts", "../../src/api/bridge-routes.ts", "../../src/api/coordinator-routes.ts", "../../src/api/hook-routes.ts", "../../src/api/issue-routes.ts", "../../src/api/parent-context-routes.ts", "../../src/api/workspace-routes.ts", "../../src/api/routes.ts", "../../src/index.ts", "../../src/actions/sandbox-stub.ts", "../../src/actions/tasks.ts", "../../src/services/task-policy.ts", "../../src/actions/common.ts", "../../src/actions/task-thread-target.ts", "../../src/providers/action-examples.ts", "../../src/providers/active-sub-agents.ts", "../../src/providers/available-agents.ts", "../../src/services/acp-service.ts", "../../src/services/session-store.ts", "../../src/services/sub-agent-router.ts", "../../index.node.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"/**\n * Read settings from the eliza/eliza config file's env section.\n *\n * runtime.getSetting() checks character.settings but NOT the config's env\n * section which is where the UI writes settings. This reads the config\n * file directly so settings take effect without restart.\n *\n * @module services/config-env\n */\n\nimport { readFileSync } from \"node:fs\";\nimport * as path from \"node:path\";\nimport { getElizaNamespace, resolveStateDir } from \"@elizaos/core\";\n\nfunction readConfig(): Record<string, unknown> | undefined {\n try {\n const namespace = getElizaNamespace();\n const filename = namespace === \"eliza\" ? \"eliza.json\" : `${namespace}.json`;\n const configPath = path.join(resolveStateDir(), filename);\n const raw = readFileSync(configPath, \"utf-8\");\n return JSON.parse(raw);\n } catch {\n return undefined;\n }\n}\n\nexport function readConfigEnvKey(key: string): string | undefined {\n const config = readConfig();\n const val = (config?.env as Record<string, unknown> | undefined)?.[key];\n return typeof val === \"string\" ? val : undefined;\n}\n\n/** Read a key from the cloud section of the config (e.g. \"apiKey\"). */\nexport function readConfigCloudKey(key: string): string | undefined {\n const config = readConfig();\n const val = (config?.cloud as Record<string, unknown> | undefined)?.[key];\n return typeof val === \"string\" ? val : undefined;\n}\n\n/**\n * Read the `agents.defaults.orchestrator.codexSubscriptionRestrictedToCodexFramework`\n * flag from Eliza's config. Returns false when the flag is unset or the\n * config file is missing/malformed.\n *\n * When true, Codex (ChatGPT Plus/Pro) subscription tokens are only usable when\n * the orchestrator targets the `codex` framework — other frameworks\n * (claude/gemini/aider) must fall back to API keys instead.\n */\nexport function readConfigCodexSubscriptionRestrictedToCodexFramework(): boolean {\n const config = readConfig();\n if (!config || typeof config !== \"object\") return false;\n const agents = (config as Record<string, unknown>).agents;\n if (!agents || typeof agents !== \"object\" || Array.isArray(agents))\n return false;\n const defaults = (agents as Record<string, unknown>).defaults;\n if (!defaults || typeof defaults !== \"object\" || Array.isArray(defaults))\n return false;\n const orchestrator = (defaults as Record<string, unknown>).orchestrator;\n if (\n !orchestrator ||\n typeof orchestrator !== \"object\" ||\n Array.isArray(orchestrator)\n )\n return false;\n const flag = (orchestrator as Record<string, unknown>)\n .codexSubscriptionRestrictedToCodexFramework;\n return flag === true;\n}\n",
|
|
6
|
+
"import type { IAgentRuntime } from \"@elizaos/core\";\nimport type { AgentCredentials } from \"coding-agent-adapters\";\nimport { readConfigCloudKey, readConfigEnvKey } from \"./config-env.js\";\n\nconst ELIZA_CLOUD_ANTHROPIC_BASE = \"https://www.elizacloud.ai/api\";\nconst ELIZA_CLOUD_OPENAI_BASE = \"https://www.elizacloud.ai/api/v1\";\n\nconst OPENCODE_LOCAL_DEFAULT_BASE_URL = \"http://localhost:11434/v1\";\nconst OPENCODE_OPENAI_COMPATIBLE_NPM = \"@ai-sdk/openai-compatible\";\n\n/**\n * Codex per-spawn config.toml snippet that forces a custom OpenAI provider\n * with `supports_websockets = false`.\n *\n * Why this is needed: Codex 0.118+ tries to upgrade `/v1/responses` to a\n * WebSocket before falling back to POST streaming. Eliza Cloud's Next.js\n * route and Vercel AI Gateway both 405 the upgrade, causing ~7 seconds of\n * \"Reconnecting…\" + a URL-error banner before the fallback kicks in.\n *\n * Why a custom provider (not [features]): The TOML `[features]` flags\n * `responses_websockets` / `responses_websockets_v2` were removed from\n * Codex's `responses_websocket_enabled()` gate in newer builds. The only\n * remaining knobs are `provider.supports_websockets` and a runtime\n * AtomicBool latched after the first WS failure. We can't override the\n * built-in `openai` provider directly because Codex's config loader uses\n * `or_insert` (built-ins win), so we define a NEW provider key and\n * select it via top-level `model_provider`.\n *\n * The custom provider keeps `name = \"OpenAI\"` so Codex's `is_openai()`\n * checks still trigger any openai-specific code paths, and copies\n * `wire_api = \"responses\"` / `requires_openai_auth = true` from the\n * built-in. `base_url` is set to the cloud proxy URL so requests still\n * hit the proxy.\n */\nfunction buildCodexCloudProviderToml(baseUrl: string): string {\n return (\n `model_provider = \"elizacloud\"\\n` +\n `\\n` +\n `[model_providers.elizacloud]\\n` +\n `name = \"OpenAI\"\\n` +\n `base_url = \"${baseUrl}\"\\n` +\n `wire_api = \"responses\"\\n` +\n `requires_openai_auth = true\\n` +\n `supports_websockets = false\\n`\n );\n}\n\ntype ExtendedAgentCredentials = AgentCredentials & {\n anthropicBaseUrl?: string;\n openaiBaseUrl?: string;\n extraConfigToml?: string;\n};\n\nfunction compactCredentials(\n credentials: ExtendedAgentCredentials,\n): ExtendedAgentCredentials {\n return Object.fromEntries(\n Object.entries(credentials).filter(([, value]) => value !== undefined),\n ) as ExtendedAgentCredentials;\n}\n\nexport function isAnthropicOAuthToken(\n value: string | undefined,\n): value is string {\n return typeof value === \"string\" && value.startsWith(\"sk-ant-oat\");\n}\n\nexport function sanitizeCustomCredentials(\n customCredentials: Record<string, string> | undefined,\n blockedValues: string[] = [],\n): Record<string, string> | undefined {\n if (!customCredentials) {\n return undefined;\n }\n\n const blocked = new Set(blockedValues.filter(Boolean));\n const filtered = Object.entries(customCredentials).filter(\n ([, value]) => !blocked.has(value),\n );\n return filtered.length > 0 ? Object.fromEntries(filtered) : undefined;\n}\n\nexport function buildAgentCredentials(\n runtime: IAgentRuntime,\n): AgentCredentials {\n const llmProvider =\n readConfigEnvKey(\"PARALLAX_LLM_PROVIDER\") || \"subscription\";\n\n if (llmProvider === \"cloud\") {\n const cloudKey = readConfigCloudKey(\"apiKey\");\n if (!cloudKey) {\n throw new Error(\n \"Eliza Cloud is selected as the LLM provider but no cloud.apiKey is paired. Pair your account in the Cloud settings section first.\",\n );\n }\n const cloudCredentials = compactCredentials({\n anthropicKey: cloudKey,\n openaiKey: cloudKey,\n googleKey: undefined,\n anthropicBaseUrl: ELIZA_CLOUD_ANTHROPIC_BASE,\n openaiBaseUrl: ELIZA_CLOUD_OPENAI_BASE,\n githubToken: runtime.getSetting(\"GITHUB_TOKEN\") as string | undefined,\n // Disable Codex's Responses-API WebSocket transport when proxying\n // through cloud — see buildCodexCloudProviderToml doc for why this\n // requires a custom provider definition rather than [features].\n extraConfigToml: buildCodexCloudProviderToml(ELIZA_CLOUD_OPENAI_BASE),\n });\n return cloudCredentials;\n }\n\n const subscriptionMode = llmProvider === \"subscription\";\n const rawAnthropicKey = runtime.getSetting(\"ANTHROPIC_API_KEY\") as\n | string\n | undefined;\n const anthropicKey = isAnthropicOAuthToken(rawAnthropicKey)\n ? undefined\n : rawAnthropicKey;\n const directCredentials = compactCredentials({\n anthropicKey: subscriptionMode ? undefined : anthropicKey,\n openaiKey: runtime.getSetting(\"OPENAI_API_KEY\") as string | undefined,\n googleKey: runtime.getSetting(\"GOOGLE_GENERATIVE_AI_API_KEY\") as\n | string\n | undefined,\n githubToken: runtime.getSetting(\"GITHUB_TOKEN\") as string | undefined,\n anthropicBaseUrl: subscriptionMode\n ? undefined\n : anthropicKey\n ? (runtime.getSetting(\"ANTHROPIC_BASE_URL\") as string | undefined)\n : undefined,\n openaiBaseUrl: runtime.getSetting(\"OPENAI_BASE_URL\") as string | undefined,\n });\n return directCredentials;\n}\n\nexport interface OpencodeSpawnConfig {\n configContent: string;\n providerLabel: string;\n providerId: string;\n model: string;\n smallModel?: string;\n}\n\n/**\n * Build the per-spawn OpenCode config (fed via OPENCODE_CONFIG_CONTENT).\n * Three modes — verified live against an OpenAI-compatible Eliza-1 endpoint:\n * 1. Cloud: PARALLAX_LLM_PROVIDER=cloud + paired Eliza Cloud key.\n * 2. Local: PARALLAX_OPENCODE_LOCAL=1 (and/or PARALLAX_OPENCODE_BASE_URL).\n * 3. User-config: PARALLAX_OPENCODE_MODEL_POWERFUL alone — defers to\n * whatever providers the user has in ~/.config/opencode/opencode.json.\n * Returns null when no mode can produce a usable config.\n */\nexport function buildOpencodeSpawnConfig(\n runtime: IAgentRuntime,\n): OpencodeSpawnConfig | null {\n const llmProvider =\n readConfigEnvKey(\"PARALLAX_LLM_PROVIDER\") || \"subscription\";\n const customBaseUrl = readConfigEnvKey(\"PARALLAX_OPENCODE_BASE_URL\");\n const localOptIn =\n readConfigEnvKey(\"PARALLAX_OPENCODE_LOCAL\") === \"1\" ||\n readConfigEnvKey(\"PARALLAX_OPENCODE_LOCAL\")?.toLowerCase() === \"true\";\n const userPowerful =\n (runtime.getSetting(\"PARALLAX_OPENCODE_MODEL_POWERFUL\") as\n | string\n | undefined) || readConfigEnvKey(\"PARALLAX_OPENCODE_MODEL_POWERFUL\");\n const userFast =\n (runtime.getSetting(\"PARALLAX_OPENCODE_MODEL_FAST\") as\n | string\n | undefined) || readConfigEnvKey(\"PARALLAX_OPENCODE_MODEL_FAST\");\n\n if (llmProvider === \"cloud\") {\n const cloudKey = readConfigCloudKey(\"apiKey\");\n if (!cloudKey) return null;\n const providerId = \"elizacloud\";\n const powerful = userPowerful?.trim() || \"claude-opus-4-7\";\n const fast = userFast?.trim() || \"claude-haiku-4-5\";\n const config = {\n $schema: \"https://opencode.ai/config.json\",\n provider: {\n [providerId]: {\n npm: OPENCODE_OPENAI_COMPATIBLE_NPM,\n name: \"Eliza Cloud\",\n options: { baseURL: ELIZA_CLOUD_OPENAI_BASE, apiKey: cloudKey },\n models: {\n [powerful]: { name: powerful },\n ...(fast && fast !== powerful ? { [fast]: { name: fast } } : {}),\n },\n },\n },\n model: `${providerId}/${powerful}`,\n ...(fast && fast !== powerful\n ? { small_model: `${providerId}/${fast}` }\n : {}),\n };\n return {\n configContent: JSON.stringify(config),\n providerLabel: \"Eliza Cloud\",\n providerId,\n model: `${providerId}/${powerful}`,\n smallModel:\n fast && fast !== powerful ? `${providerId}/${fast}` : undefined,\n };\n }\n\n if (localOptIn || customBaseUrl?.trim()) {\n const baseURL = customBaseUrl?.trim() || OPENCODE_LOCAL_DEFAULT_BASE_URL;\n const apiKey = readConfigEnvKey(\"PARALLAX_OPENCODE_API_KEY\");\n const providerId = \"eliza-local\";\n const powerful = userPowerful?.trim() || \"eliza-1-9b\";\n const fast = userFast?.trim();\n const config = {\n $schema: \"https://opencode.ai/config.json\",\n provider: {\n [providerId]: {\n npm: OPENCODE_OPENAI_COMPATIBLE_NPM,\n name: \"Local model\",\n options: { baseURL, ...(apiKey ? { apiKey } : {}) },\n models: {\n [powerful]: { name: powerful },\n ...(fast && fast !== powerful ? { [fast]: { name: fast } } : {}),\n },\n },\n },\n model: `${providerId}/${powerful}`,\n ...(fast && fast !== powerful\n ? { small_model: `${providerId}/${fast}` }\n : {}),\n };\n return {\n configContent: JSON.stringify(config),\n providerLabel: `Local (${baseURL})`,\n providerId,\n model: `${providerId}/${powerful}`,\n smallModel:\n fast && fast !== powerful ? `${providerId}/${fast}` : undefined,\n };\n }\n\n if (!userPowerful?.trim()) return null;\n const config: Record<string, unknown> = {\n $schema: \"https://opencode.ai/config.json\",\n model: userPowerful.trim(),\n ...(userFast?.trim() ? { small_model: userFast.trim() } : {}),\n };\n return {\n configContent: JSON.stringify(config),\n providerLabel: \"User-configured opencode.json\",\n providerId: \"user\",\n model: userPowerful.trim(),\n smallModel: userFast?.trim() || undefined,\n };\n}\n",
|
|
7
|
+
"/**\n * Lightweight per-agent-type metrics for observability.\n *\n * Self-contained tracker — no dependencies on PTYService state.\n *\n * @module services/agent-metrics\n */\n\nexport interface AgentMetrics {\n spawned: number;\n completed: number;\n completedViaFastPath: number;\n completedViaClassifier: number;\n completedViaOutputReconcile: number;\n stallCount: number;\n avgCompletionMs: number;\n totalCompletionMs: number;\n}\n\nexport type CompletionMethod = \"fast-path\" | \"classifier\" | \"output-reconcile\";\n\nexport class AgentMetricsTracker {\n private metrics: Map<string, AgentMetrics> = new Map();\n\n /** Get (or lazily initialize) metrics for a given agent type. */\n get(agentType: string): AgentMetrics {\n let m = this.metrics.get(agentType);\n if (!m) {\n m = {\n spawned: 0,\n completed: 0,\n completedViaFastPath: 0,\n completedViaClassifier: 0,\n completedViaOutputReconcile: 0,\n stallCount: 0,\n avgCompletionMs: 0,\n totalCompletionMs: 0,\n };\n this.metrics.set(agentType, m);\n }\n return m;\n }\n\n /** Record a task completion and update rolling average duration. */\n recordCompletion(\n agentType: string,\n method: CompletionMethod,\n durationMs: number,\n ): void {\n const m = this.get(agentType);\n m.completed++;\n if (method === \"fast-path\") m.completedViaFastPath++;\n else if (method === \"classifier\") m.completedViaClassifier++;\n else m.completedViaOutputReconcile++;\n m.totalCompletionMs += durationMs;\n m.avgCompletionMs = Math.round(m.totalCompletionMs / m.completed);\n }\n\n /** Increment the stall counter for an agent type. */\n incrementStalls(agentType: string): void {\n this.get(agentType).stallCount++;\n }\n\n /** Return a serializable copy of all metrics (for API endpoints). */\n getAll(): Record<string, Omit<AgentMetrics, \"totalCompletionMs\">> {\n const result: Record<string, Omit<AgentMetrics, \"totalCompletionMs\">> = {};\n for (const [type, m] of this.metrics) {\n const { totalCompletionMs: _, ...rest } = m;\n result[type] = { ...rest };\n }\n return result;\n }\n}\n",
|
|
8
|
+
"/**\n * ANSI/terminal utility functions for processing PTY output.\n *\n * Pure functions — no state, no dependencies beyond the standard library.\n *\n * @module services/ansi-utils\n */\n\n// ANSI escape sequence patterns for terminal output stripping.\n// These intentionally match control characters (\\x1b, \\x00-\\x1f, \\x7f).\n/* eslint-disable no-control-regex */\n// biome-ignore lint/suspicious/noControlCharactersInRegex: ANSI stripping requires control chars\nconst CURSOR_MOVEMENT = /\\x1b\\[\\d*[CDABGdEF]/g;\n// biome-ignore lint/suspicious/noControlCharactersInRegex: ANSI stripping requires control chars\nconst CURSOR_POSITION = /\\x1b\\[\\d*(?:;\\d+)?[Hf]/g;\n// biome-ignore lint/suspicious/noControlCharactersInRegex: ANSI stripping requires control chars\nconst ERASE = /\\x1b\\[\\d*[JK]/g;\n// biome-ignore lint/suspicious/noControlCharactersInRegex: ANSI stripping requires control chars\nconst OSC = /\\x1b\\][^\\x07\\x1b]*(?:\\x07|\\x1b\\\\)/g;\n// biome-ignore lint/suspicious/noControlCharactersInRegex: ANSI stripping requires control chars\nconst ALL_ANSI = /\\x1B(?:[@-Z\\\\-_]|\\[[0-?]*[ -/]*[@-~])/g;\n// biome-ignore lint/suspicious/noControlCharactersInRegex: ANSI stripping requires control chars\nconst CONTROL_CHARS = /[\\x00-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]/g;\n/** Orphaned SGR fragments left when buffer boundaries split `\\x1b[...m` sequences. */\nconst ORPHAN_SGR = /\\[[\\d;]*m/g;\nconst LONG_SPACES = / {3,}/g;\n\n/** Apply all ANSI stripping patterns to a string */\nfunction applyAnsiStrip(input: string): string {\n return (\n input\n // Pre-process: rejoin SGR sequences split across lines by chunk boundaries.\n // e.g. \"[38;2;153;\\n153;153m\" → \"[38;2;153;153;153m\"\n .replace(/(\\[[\\d;]*)\\r?\\n([\\d;]*m)/g, \"$1$2\")\n .replace(CURSOR_MOVEMENT, \" \")\n .replace(CURSOR_POSITION, \" \")\n .replace(ERASE, \"\")\n .replace(OSC, \"\")\n .replace(ALL_ANSI, \"\")\n .replace(CONTROL_CHARS, \"\")\n .replace(ORPHAN_SGR, \"\")\n .replace(LONG_SPACES, \" \")\n .trim()\n );\n}\n\n/**\n * Strip ANSI escape sequences from raw terminal output for readable text.\n * Replaces cursor-forward codes with spaces (TUI uses these instead of actual spaces).\n */\nexport function stripAnsi(raw: string): string {\n return applyAnsiStrip(raw);\n}\n\n// ─── Chat-Ready Output Cleaning ───\n\n/** Unicode spinner, box-drawing, and decorative characters used by CLI TUIs. */\nconst TUI_DECORATIVE =\n /[│╭╰╮╯─═╌║╔╗╚╝╠╣╦╩╬┌┐└┘├┤┬┴┼●○❮❯▶◀⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏⣾⣽⣻⢿⡿⣟⣯⣷✽✻✶✳✢⏺←→↑↓⬆⬇◆▪▫■□▲△▼▽◈⟨⟩⌘⏎⏏⌫⌦⇧⇪⌥·⎿✔◼█▌▐▖▗▘▝▛▜▟▙◐◑◒◓⏵]/g;\n\n/**\n * Lines that are just CLI loading/thinking status — no meaningful content.\n * Claude Code uses random gerund spinner words (\"Tomfoolering…\", \"Recombobulating…\")\n * that rotate frequently. Requires an ellipsis (…/...) or status suffix\n * (parenthetical / \"for Ns\") — plain words like \"Completed\" won't match.\n */\nconst LOADING_LINE =\n /^\\s*(?:[A-Z][a-z]+(?:-[a-z]+)?(?:ing|ed)\\w*|thinking|Loading|processing)(?:…|\\.{3})(?:\\s*\\(.*\\)|\\s+for\\s+\\d+[smh](?:\\s+\\d+[smh])*)?\\s*$|^\\s*(?:[A-Z][a-z]+(?:-[a-z]+)?(?:ing|ed)\\w*|thinking|Loading|processing)\\s+for\\s+\\d+[smh](?:\\s+\\d+[smh])*\\s*$/;\n\n/** Lines that are just token/timing metadata from the spinner status bar. */\nconst STATUS_LINE =\n /^\\s*(?:\\d+[smh]\\s+\\d+s?\\s*·|↓\\s*[\\d.]+k?\\s*tokens|·\\s*↓|esc\\s+to\\s+interrupt|[Uu]pdate available|ate available|Run:\\s+brew|brew\\s+upgrade|\\d+\\s+files?\\s+\\+\\d+\\s+-\\d+|ctrl\\+\\w|\\+\\d+\\s+lines|Wrote\\s+\\d+\\s+lines\\s+to|\\?\\s+for\\s+shortcuts|Cooked for|Baked for|Cogitated for)/i;\n\n/** Claude Code tool execution markers — not meaningful for coordination decisions. */\nconst TOOL_MARKER_LINE =\n /^\\s*(?:Bash|Write|Read|Edit|Glob|Grep|Search|TodoWrite|Agent)\\s*\\(.*\\)\\s*$/;\n\n/** Git status/diff noise that's not meaningful for coordination. */\nconst GIT_NOISE_LINE =\n /^\\s*(?:On branch\\s+\\w|Your branch is|modified:|new file:|deleted:|renamed:|Untracked files:|Changes (?:not staged|to be committed)|\\d+\\s+files?\\s+changed.*(?:insertion|deletion))/i;\nconst PATCH_MARKER_LINE =\n /^(?:diff --git\\b|index\\s+[a-f0-9]{7,}\\.\\.[a-f0-9]{7,}|@@\\s|---\\s+[ab]\\/|\\+\\+\\+\\s+[ab]\\/)/;\nconst PATCH_ADDED_REMOVED_LINE = /^[+-]\\s/;\nconst SOURCE_PUNCTUATION_LINE =\n /[{}();=]|\\b(?:const|let|var|function|return|class|import|export)\\b/;\nconst PUBLIC_URL_RE =\n /https?:\\/\\/(?:[a-z0-9-]+\\.)+[a-z]{2,}(?:\\/[^\\s<>\"'`)\\]]*)?/gi;\nconst ASSISTANT_FINAL_MARKER_LINE =\n /^(?:codex|claude|claude code|gemini|opencode|openai)$/i;\nconst FINAL_BLOCK_STOP_LINE =\n /^(?:diff --git\\b|exec\\b|tokens used\\b|thinking\\b|error:\\s|warning:\\s|index\\s+[a-f0-9]{7,}\\.\\.[a-f0-9]{7,}|@@\\s|---\\s+[ab]\\/|\\+\\+\\+\\s+[ab]\\/)/i;\n/** Codex/Claude launcher banners and trust screens that pollute failover prompts. */\nconst SESSION_BOOTSTRAP_NOISE_PATTERNS = [\n /^OpenAI Codex\\b/i,\n /^model:\\s/i,\n /^directory:\\s/i,\n /^Tip:\\s+New Try the Codex App\\b/i,\n /^until .*Run ['\"]codex app['\"]/i,\n /Do you trust the contents of this directory/i,\n /higher risk of prompt injection/i,\n /Yes,\\s*continue.*No,\\s*quit/i,\n /^Press enter to continue$/i,\n /^Quick safety check:/i,\n /^Claude Code can make mistakes\\./i,\n /^Claude Code(?:'ll| will)\\s+be able to read, edit, and execute files here\\.?$/i,\n /^\\d+\\.\\s+Yes,\\s*I trust this folder$/i,\n /^\\d+\\.\\s+No,\\s*exit$/i,\n /^Enter to confirm(?:\\s+Esc to cancel)?$/i,\n /^Welcome back .*Run \\/init to create a CLAUDE\\.md file with instructions for Claude\\./i,\n /^Your bash commands will be sandboxed\\. Disable with \\/sandbox\\./i,\n];\n\nfunction isSessionBootstrapNoiseLine(line: string): boolean {\n return SESSION_BOOTSTRAP_NOISE_PATTERNS.some((pattern) => pattern.test(line));\n}\n\nfunction isLikelyRawPatchOrSourceDump(text: string): boolean {\n const lines = text\n .split(\"\\n\")\n .map((line) => line.trim())\n .filter(Boolean);\n if (lines.length < 8) return false;\n\n if (lines.some((line) => PATCH_MARKER_LINE.test(line))) {\n return true;\n }\n\n const patchLines = lines.filter((line) =>\n PATCH_ADDED_REMOVED_LINE.test(line),\n );\n const addedPatchLines = patchLines.filter((line) => line.startsWith(\"+ \"));\n const removedPatchLines = patchLines.filter((line) => line.startsWith(\"- \"));\n const sourceLikePatchLines = patchLines.filter((line) =>\n SOURCE_PUNCTUATION_LINE.test(line),\n );\n return (\n (addedPatchLines.length > 0 || removedPatchLines.length > 0) &&\n patchLines.length >= 5 &&\n patchLines.length / lines.length >= 0.8 &&\n sourceLikePatchLines.length >=\n Math.max(3, Math.ceil(patchLines.length * 0.6))\n );\n}\n\nfunction extractAssistantFinalBlock(lines: string[]): string {\n for (let i = lines.length - 1; i >= 0; i--) {\n if (!ASSISTANT_FINAL_MARKER_LINE.test(lines[i])) continue;\n const block: string[] = [];\n for (let j = i + 1; j < lines.length; j++) {\n const line = lines[j].trim();\n if (!line) {\n if (block.length > 0) block.push(\"\");\n continue;\n }\n if (FINAL_BLOCK_STOP_LINE.test(line)) break;\n block.push(line);\n }\n const text = block.join(\"\\n\").trim();\n if (\n text &&\n !isLikelyRawPatchOrSourceDump(text) &&\n !isSessionBootstrapNoiseLine(text)\n ) {\n return formatMarkdownTablesForChat(\n closeUnbalancedMarkdownFences(\n dedupeCompletionBlockLines(block).join(\"\\n\").trim(),\n ),\n );\n }\n }\n return \"\";\n}\n\nfunction lineContainsPublicUrl(line: string): boolean {\n PUBLIC_URL_RE.lastIndex = 0;\n return PUBLIC_URL_RE.test(line);\n}\n\nfunction normalizeUrlForDedupe(url: string): string {\n return url.trim().replace(/[`.,;:!?]+$/u, \"\");\n}\n\nfunction unwrapInlineCodeUrls(line: string): string {\n return line.replace(\n /`(https?:\\/\\/(?:[a-z0-9-]+\\.)+[a-z]{2,}(?:\\/[^`\\s<>\"')\\]]*)?)`/giu,\n \"$1\",\n );\n}\n\nfunction normalizeCompletionLineForDedupe(line: string): string {\n return unwrapInlineCodeUrls(line)\n .replace(PUBLIC_URL_RE, (url) => normalizeUrlForDedupe(url).toLowerCase())\n .replace(/[→←]/g, \" \")\n .replace(/[`*_~]/g, \"\")\n .replace(/[^\\p{L}\\p{N}:/#.-]+/gu, \" \")\n .replace(/\\s+/g, \" \")\n .trim()\n .toLowerCase();\n}\n\nfunction shouldDedupeCompletionLine(line: string, key: string): boolean {\n return key.length >= 8 || line.includes(\":\") || lineContainsPublicUrl(line);\n}\n\nfunction compactCompletionBlankLines(lines: string[]): string[] {\n const compacted: string[] = [];\n for (const line of lines) {\n if (!line.trim()) {\n if (compacted.length > 0 && compacted.at(-1)?.trim()) {\n compacted.push(\"\");\n }\n continue;\n }\n compacted.push(line);\n }\n\n while (compacted.length > 0 && !compacted.at(-1)?.trim()) {\n compacted.pop();\n }\n\n return compacted;\n}\n\nfunction isMarkdownTableRow(line: string): boolean {\n const trimmed = line.trim();\n return (\n trimmed.startsWith(\"|\") &&\n trimmed.endsWith(\"|\") &&\n trimmed.slice(1, -1).includes(\"|\")\n );\n}\n\nfunction parseMarkdownTableRow(line: string): string[] {\n return line\n .trim()\n .slice(1, -1)\n .split(\"|\")\n .map((cell) => cell.trim());\n}\n\nfunction isMarkdownTableSeparatorRow(line: string): boolean {\n const cells = parseMarkdownTableRow(line);\n return (\n cells.length >= 2 &&\n cells.every((cell) => /^:?-{3,}:?$/u.test(cell.replace(/\\s+/g, \"\")))\n );\n}\n\nfunction formatMarkdownTableRowsForChat(rows: string[]): string[] {\n if (rows.length < 2 || isMarkdownTableSeparatorRow(rows[0])) {\n return rows;\n }\n\n const headers = parseMarkdownTableRow(rows[0]);\n const bodyRows = rows\n .slice(isMarkdownTableSeparatorRow(rows[1]) ? 2 : 1)\n .filter((row) => !isMarkdownTableSeparatorRow(row))\n .map(parseMarkdownTableRow);\n\n if (headers.length < 2 || bodyRows.length === 0) {\n return rows;\n }\n\n const formattedRows = bodyRows.map((row) => {\n const rowLabel = row[0] || headers[0] || \"row\";\n const details = headers\n .slice(1)\n .map((header, index) => {\n const value = row[index + 1];\n return value ? `${header || `column ${index + 2}`}: ${value}` : \"\";\n })\n .filter(Boolean);\n return details.length > 0 ? `- ${rowLabel}: ${details.join(\", \")}` : \"\";\n });\n\n return formattedRows.every(Boolean) ? formattedRows : rows;\n}\n\nexport function formatMarkdownTablesForChat(text: string): string {\n const lines = text.split(\"\\n\");\n const result: string[] = [];\n let inFence = false;\n\n for (let index = 0; index < lines.length; index++) {\n const line = lines[index];\n const fence = line.trim();\n if (fence.startsWith(\"```\")) {\n inFence = !inFence || !/^```\\s*$/u.test(fence);\n result.push(line);\n continue;\n }\n\n if (!inFence && isMarkdownTableRow(line)) {\n const tableRows = [line];\n while (index + 1 < lines.length && isMarkdownTableRow(lines[index + 1])) {\n tableRows.push(lines[index + 1]);\n index += 1;\n }\n result.push(...formatMarkdownTableRowsForChat(tableRows));\n continue;\n }\n\n result.push(line);\n }\n\n return result\n .join(\"\\n\")\n .replace(/\\n{3,}/g, \"\\n\\n\")\n .trim();\n}\n\nfunction isBareUrlLineAfterValueHeading(\n line: string,\n previousLine: string,\n): boolean {\n const matches = line.match(PUBLIC_URL_RE) ?? [];\n if (\n matches.length !== 1 ||\n line.trim() !== normalizeUrlForDedupe(matches[0])\n ) {\n return false;\n }\n return isSummarySectionHeadingLine(previousLine);\n}\n\nfunction isSummaryLabelLine(line: string): boolean {\n return /^(?:[-*]\\s+)?[\\p{L}\\p{N}][^:\\n]{0,80}:\\s+\\S/u.test(\n unwrapInlineCodeUrls(line).trim(),\n );\n}\n\nfunction isBulletSummaryLine(line: string): boolean {\n return /^[-*]\\s+\\S/u.test(unwrapInlineCodeUrls(line).trim());\n}\n\nfunction isSummarySectionHeadingLine(line: string): boolean {\n const trimmed = unwrapInlineCodeUrls(line).trim();\n return (\n trimmed.length > 1 &&\n trimmed.length <= 120 &&\n /[\\p{L}\\p{N}]/u.test(trimmed) &&\n /:\\s*$/u.test(trimmed) &&\n !SOURCE_PUNCTUATION_LINE.test(trimmed)\n );\n}\n\nfunction isConciseHeadingValueLine(line: string): boolean {\n const trimmed = unwrapInlineCodeUrls(line).trim();\n if (!trimmed || trimmed.length > 280 || !/[\\p{L}\\p{N}]/u.test(trimmed)) {\n return false;\n }\n if (\n PATCH_MARKER_LINE.test(trimmed) ||\n TOOL_MARKER_LINE.test(trimmed) ||\n GIT_NOISE_LINE.test(trimmed) ||\n FINAL_BLOCK_STOP_LINE.test(trimmed)\n ) {\n return false;\n }\n if (\n /^\\s*(?:const|let|var|function|return|class|import|export)\\b/u.test(trimmed)\n ) {\n return false;\n }\n if (/[;=]\\s*$/u.test(trimmed)) {\n return false;\n }\n return true;\n}\n\nfunction isSentenceLikeSummaryLine(line: string): boolean {\n const trimmed = unwrapInlineCodeUrls(line).trim();\n return (\n trimmed.length <= 280 &&\n /[\\p{L}\\p{N}]/u.test(trimmed) &&\n /[.!?]$/u.test(trimmed)\n );\n}\n\nfunction isStructuredSummaryLine(line: string): boolean {\n const trimmed = unwrapInlineCodeUrls(line).trim();\n return (\n lineContainsPublicUrl(trimmed) ||\n isSummaryLabelLine(trimmed) ||\n isSummarySectionHeadingLine(trimmed) ||\n isBulletSummaryLine(trimmed) ||\n isSentenceLikeSummaryLine(trimmed)\n );\n}\n\nfunction isConciseUserFacingSummary(\n text: string,\n lines: readonly string[],\n): boolean {\n if (!text || text.length > 4000 || lines.length < 1 || lines.length > 24) {\n return false;\n }\n if (isLikelyRawPatchOrSourceDump(text)) {\n return false;\n }\n if (\n lines.some(\n (line) =>\n PATCH_MARKER_LINE.test(line) ||\n TOOL_MARKER_LINE.test(line) ||\n GIT_NOISE_LINE.test(line),\n )\n ) {\n return false;\n }\n\n const meaningfulLines = lines.filter((line) => /[\\p{L}\\p{N}]/u.test(line));\n if (meaningfulLines.length === 0) {\n return false;\n }\n\n if (meaningfulLines.some(lineContainsPublicUrl)) {\n return true;\n }\n\n const summaryShapedLines = meaningfulLines.filter(\n (line) =>\n isSummaryLabelLine(line) ||\n isBulletSummaryLine(line) ||\n isSentenceLikeSummaryLine(line),\n );\n const mostlyShortLines =\n meaningfulLines.filter((line) => line.length <= 280).length /\n meaningfulLines.length >=\n 0.75;\n\n return (\n mostlyShortLines &&\n summaryShapedLines.length >= Math.min(2, meaningfulLines.length)\n );\n}\n\nfunction dedupeCompletionBlockLines(lines: string[]): string[] {\n const urlsWithContext = new Set<string>();\n const seenUrls = new Set<string>();\n const seenLineKeys = new Set<string>();\n const result: string[] = [];\n const normalizedLines = lines.map(unwrapInlineCodeUrls);\n\n for (const line of normalizedLines) {\n const matches = line.match(PUBLIC_URL_RE) ?? [];\n const normalizedMatches = matches.map(normalizeUrlForDedupe);\n const isBareUrlLine =\n normalizedMatches.length === 1 && line.trim() === normalizedMatches[0];\n if (isBareUrlLine) continue;\n\n for (const normalized of normalizedMatches) {\n urlsWithContext.add(normalized);\n }\n }\n\n let inFence = false;\n let previousMeaningfulLine = \"\";\n for (const line of normalizedLines) {\n const fence = line.trim();\n if (fence.startsWith(\"```\")) {\n inFence = !inFence || !/^```\\s*$/.test(fence);\n result.push(line);\n if (line.trim()) previousMeaningfulLine = line;\n continue;\n }\n\n const matches = line.match(PUBLIC_URL_RE) ?? [];\n const normalizedMatches = matches.map(normalizeUrlForDedupe);\n const isBareHeadingValueUrl = isBareUrlLineAfterValueHeading(\n line,\n previousMeaningfulLine,\n );\n const isBareRepeatedUrl =\n normalizedMatches.length === 1 &&\n line.trim() === normalizedMatches[0] &&\n !isBareHeadingValueUrl &&\n (seenUrls.has(normalizedMatches[0]) ||\n urlsWithContext.has(normalizedMatches[0]));\n if (isBareRepeatedUrl) continue;\n\n if (!inFence && line.trim()) {\n const key = normalizeCompletionLineForDedupe(line);\n if (\n key &&\n seenLineKeys.has(key) &&\n shouldDedupeCompletionLine(line, key)\n ) {\n continue;\n }\n if (key && shouldDedupeCompletionLine(line, key)) {\n seenLineKeys.add(key);\n }\n }\n\n result.push(line);\n if (line.trim()) previousMeaningfulLine = line;\n for (const normalized of normalizedMatches) {\n seenUrls.add(normalized);\n }\n }\n\n return compactCompletionBlankLines(result);\n}\n\nfunction markdownFenceInfo(line: string): string | null {\n const match = line.trim().match(/^```\\s*([^\\s`]*)/u);\n return match ? match[1].toLowerCase() : null;\n}\n\nfunction isPlainTextOutputFence(info: string): boolean {\n return (\n info === \"\" ||\n info === \"text\" ||\n info === \"txt\" ||\n info === \"output\" ||\n info === \"log\" ||\n info === \"console\" ||\n info === \"terminal\"\n );\n}\n\nfunction isLikelyCommandOutputLine(line: string): boolean {\n const trimmed = line.trim();\n if (!trimmed) return false;\n if (/[.!?]$/u.test(trimmed)) return false;\n const columns = trimmed.split(/\\s+/);\n if (columns.length < 4) return false;\n return /(?:\\d|%|\\/|:)/u.test(trimmed);\n}\n\nfunction shouldCloseTextFenceBeforeSummaryLine(\n fenceInfo: string,\n fenceLines: readonly string[],\n line: string,\n): boolean {\n if (!isPlainTextOutputFence(fenceInfo)) return false;\n\n const meaningfulFenceLines = fenceLines.filter((fenceLine) =>\n fenceLine.trim(),\n );\n if (meaningfulFenceLines.length < 1) return false;\n if (!meaningfulFenceLines.some(isLikelyCommandOutputLine)) return false;\n\n const trimmed = unwrapInlineCodeUrls(line).trim();\n if (!trimmed || isLikelyCommandOutputLine(trimmed)) return false;\n return (\n isSummaryLabelLine(trimmed) ||\n isBulletSummaryLine(trimmed) ||\n isSentenceLikeSummaryLine(trimmed)\n );\n}\n\nexport function closeUnbalancedMarkdownFences(text: string): string {\n const trimmed = text.trim();\n if (!trimmed) return \"\";\n\n const fixedLines: string[] = [];\n let openFence = false;\n let openFenceInfo = \"\";\n let openFenceLines: string[] = [];\n\n for (const line of trimmed.split(\"\\n\")) {\n const fence = line.trim();\n if (!fence.startsWith(\"```\")) {\n if (\n openFence &&\n shouldCloseTextFenceBeforeSummaryLine(\n openFenceInfo,\n openFenceLines,\n line,\n )\n ) {\n fixedLines.push(\"```\");\n openFence = false;\n openFenceInfo = \"\";\n openFenceLines = [];\n }\n fixedLines.push(line);\n if (openFence) {\n openFenceLines.push(line);\n }\n continue;\n }\n\n if (!openFence) {\n openFence = true;\n openFenceInfo = markdownFenceInfo(line) ?? \"\";\n openFenceLines = [];\n fixedLines.push(line);\n continue;\n }\n\n if (/^```\\s*$/.test(fence)) {\n openFence = false;\n openFenceInfo = \"\";\n openFenceLines = [];\n fixedLines.push(line);\n continue;\n }\n\n // A second fenced opener such as ```text while already inside a fence is\n // usually a model-generated missing close. Close the previous block before\n // preserving the next one.\n fixedLines.push(\"```\");\n fixedLines.push(line);\n openFenceInfo = markdownFenceInfo(line) ?? \"\";\n openFenceLines = [];\n }\n\n if (openFence) {\n fixedLines.push(\"```\");\n }\n\n return fixedLines.join(\"\\n\").trim();\n}\n\nfunction extractStructuredCompletionBlock(lines: string[]): string {\n const normalized = lines.map((line) => line.trim());\n for (let i = normalized.length - 1; i >= 0; i--) {\n const line = normalized[i];\n if (!lineContainsPublicUrl(line)) continue;\n\n let start = i;\n const scanFloor = Math.max(0, i - 30);\n for (let j = i; j >= scanFloor; j--) {\n const current = normalized[j];\n if (!current) continue;\n if (FINAL_BLOCK_STOP_LINE.test(current)) break;\n if (isStructuredSummaryLine(current)) {\n start = j;\n continue;\n }\n if (\n j > 0 &&\n isSummarySectionHeadingLine(normalized[j - 1]) &&\n isConciseHeadingValueLine(current)\n ) {\n start = j - 1;\n j -= 1;\n continue;\n }\n if (j < i) break;\n }\n\n const block: string[] = [];\n for (let j = start; j < normalized.length; j++) {\n const current = normalized[j];\n if (!current) {\n if (block.length > 0) block.push(\"\");\n continue;\n }\n if (block.length > 0 && FINAL_BLOCK_STOP_LINE.test(current)) break;\n block.push(current);\n }\n\n const text = dedupeCompletionBlockLines(block).join(\"\\n\").trim();\n const textLines = text.split(\"\\n\").filter((textLine) => textLine.trim());\n if (\n lineContainsPublicUrl(text) &&\n isConciseUserFacingSummary(text, textLines)\n ) {\n return formatMarkdownTablesForChat(closeUnbalancedMarkdownFences(text));\n }\n }\n return \"\";\n}\n\n/**\n * Clean terminal output for display in chat messages.\n *\n * Goes beyond {@link stripAnsi} by also removing:\n * - Unicode spinner/box-drawing/decorative characters from CLI TUIs\n * - Lines that are only loading/thinking status text\n * - Spinner status bar metadata (token counts, timing)\n * - Consecutive blank lines (collapsed to one)\n */\nexport function cleanForChat(raw: string): string {\n const stripped = applyAnsiStrip(raw);\n return stripped\n .replace(TUI_DECORATIVE, \" \")\n .replace(/\\xa0/g, \" \")\n .split(\"\\n\")\n .filter((line) => {\n const trimmed = line.trim();\n if (!trimmed) return false; // blank line — will re-add separators below\n if (LOADING_LINE.test(trimmed)) return false;\n if (STATUS_LINE.test(trimmed)) return false;\n if (TOOL_MARKER_LINE.test(trimmed)) return false;\n if (GIT_NOISE_LINE.test(trimmed)) return false;\n if (isSessionBootstrapNoiseLine(trimmed)) return false;\n // Lines with only whitespace/punctuation and no alphanumeric content\n if (!/[a-zA-Z0-9]/.test(trimmed)) return false;\n // Very short lines (≤3 chars) are likely TUI fragments\n if (trimmed.length <= 3) return false;\n return true;\n })\n .map((line) => line.replace(/ {2,}/g, \" \").trim())\n .filter((line) => line.length > 0)\n .join(\"\\n\")\n .replace(/\\n{3,}/g, \"\\n\\n\")\n .trim();\n}\n\nconst FAILOVER_CONTEXT_NOISE_PATTERNS = [\n /^Accessing workspace:?$/i,\n /work from your team\\)\\. If not, take a moment to review what's in this folder first\\.$/i,\n /(?:se)?curity guide$/i,\n /^Yes,\\s*I trust this folder$/i,\n /^Claude Code v[\\d.]+$/i,\n /^Tips for getting started$/i,\n /^Welcome back .*Run \\/init to create a CLAUDE\\.md file with instructions for Claude\\.?$/i,\n /^Recent activity$/i,\n /^No recent activity$/i,\n /^.*\\(\\d+[MK]? context\\)\\s+Claude\\b.*$/i,\n /^don'?t ask on \\(shift\\+tab to cycle\\)$/i,\n /^\\w+\\s+\\/effort$/i,\n];\n\nfunction isWorkdirEchoLine(line: string, workdir?: string): boolean {\n if (!workdir) return false;\n const normalizedWorkdir = workdir.trim();\n if (!normalizedWorkdir) return false;\n if (line === normalizedWorkdir || line === `/private${normalizedWorkdir}`) {\n return true;\n }\n const basename = normalizedWorkdir.split(\"/\").filter(Boolean).at(-1);\n return Boolean(\n basename &&\n line.includes(basename) &&\n (/^\\/(?:private\\/)?/.test(line) || /^\\/…\\//.test(line)),\n );\n}\n\n/**\n * Failover prompts need stricter transcript sanitization than chat messages.\n * The replacement agent already gets the workspace path and failure reason\n * separately, so Claude/Codex trust screens, onboarding banners, and echoed\n * workspace selectors should be dropped here instead of being forwarded.\n */\nexport function cleanForFailoverContext(raw: string, workdir?: string): string {\n return cleanForChat(raw)\n .split(\"\\n\")\n .map((line) => line.trim())\n .filter((line) => line.length > 0)\n .filter(\n (line) =>\n !FAILOVER_CONTEXT_NOISE_PATTERNS.some((pattern) => pattern.test(line)),\n )\n .filter((line) => !isWorkdirEchoLine(line, workdir))\n .join(\"\\n\")\n .trim();\n}\n\n/**\n * Extract meaningful artifacts (PR URLs, commit hashes, key results) from raw\n * terminal output. Returns a compact summary suitable for chat messages,\n * without dumping raw TUI output.\n */\nexport function extractCompletionSummary(raw: string): string {\n const stripped = applyAnsiStrip(raw);\n const strippedLines = stripped.split(\"\\n\").map((line) => line.trim());\n const assistantFinalBlock = extractAssistantFinalBlock(strippedLines);\n if (assistantFinalBlock) {\n return assistantFinalBlock;\n }\n const structuredCompletionBlock =\n extractStructuredCompletionBlock(strippedLines);\n if (structuredCompletionBlock) {\n return structuredCompletionBlock;\n }\n const lines: string[] = [];\n const artifactText = strippedLines.slice(-80).join(\"\\n\");\n\n // PR / issue URLs\n const prUrls = artifactText.match(\n /https?:\\/\\/github\\.com\\/[\\w.-]+\\/[\\w.-]+\\/pull\\/\\d+/g,\n );\n if (prUrls) {\n for (const url of [...new Set(prUrls)]) lines.push(url);\n }\n\n // \"Created pull request #N\" style messages\n const prCreated = artifactText.match(\n /(?:Created|Opened)\\s+pull\\s+request\\s+#\\d+[^\\n]*/gi,\n );\n if (prCreated && !prUrls) {\n for (const m of prCreated) lines.push(m.trim());\n }\n\n // Commit hashes\n const commits = artifactText.match(/(?:committed|commit)\\s+[a-f0-9]{7,40}/gi);\n if (commits) {\n for (const m of new Set(commits)) lines.push(m.trim());\n }\n\n // Files changed summary (e.g. \"2 files changed, 15 insertions(+), 3 deletions(-)\")\n const diffStat = artifactText.match(\n /\\d+\\s+files?\\s+changed.*?(?:insertion|deletion)[^\\n]*/gi,\n );\n if (diffStat) {\n for (const m of diffStat) lines.push(m.trim());\n }\n\n const publicUrls = artifactText.match(PUBLIC_URL_RE);\n if (publicUrls) {\n for (const url of new Set(publicUrls)) {\n const normalizedUrl = normalizeUrlForDedupe(url);\n const alreadyIncluded = lines.some((line) =>\n line.includes(normalizedUrl),\n );\n if (!url.includes(\"github.com/\") && !alreadyIncluded) {\n lines.push(url);\n }\n }\n }\n\n return formatMarkdownTablesForChat(\n closeUnbalancedMarkdownFences(lines.join(\"\\n\")),\n );\n}\n\nexport function summarizeUserFacingTurnOutput(raw: string): string {\n const strippedLines = applyAnsiStrip(raw)\n .split(\"\\n\")\n .map((line) => line.trim());\n const assistantFinalBlock = extractAssistantFinalBlock(strippedLines);\n if (assistantFinalBlock) {\n return assistantFinalBlock;\n }\n const structuredCompletionBlock =\n extractStructuredCompletionBlock(strippedLines);\n if (structuredCompletionBlock) {\n return structuredCompletionBlock;\n }\n\n const cleanedLines = cleanForChat(raw)\n .split(\"\\n\")\n .map((line) => line.trim())\n .filter((line) => line.length > 0);\n const cleaned = formatMarkdownTablesForChat(\n closeUnbalancedMarkdownFences(\n dedupeCompletionBlockLines(cleanedLines).join(\"\\n\").trim(),\n ),\n );\n\n if (isConciseUserFacingSummary(cleaned, cleanedLines)) {\n return cleaned;\n }\n\n const artifactSummary = extractCompletionSummary(raw).trim();\n if (artifactSummary) {\n return artifactSummary;\n }\n\n if (!cleaned) {\n return \"\";\n }\n\n if (isLikelyRawPatchOrSourceDump(cleaned)) {\n return \"Task agent completed but did not produce a user-facing final summary.\";\n }\n\n return cleaned;\n}\n\n/**\n * Extract a dev server URL from recent terminal output, if present.\n *\n * Looks for common patterns like:\n * - http://localhost:3000\n * - http://127.0.0.1:8080\n * - http://0.0.0.0:5173\n * - https://localhost:4200\n *\n * Returns the first match, or null if no dev server URL is found.\n */\nexport function extractDevServerUrl(raw: string): string | null {\n const stripped = applyAnsiStrip(raw);\n // Match local dev server URLs with a port number\n const match = stripped.match(\n /https?:\\/\\/(?:localhost|127\\.0\\.0\\.1|0\\.0\\.0\\.0):\\d{1,5}[^\\s)}\\]'\"`,]*/,\n );\n return match ? match[0] : null;\n}\n\n/**\n * Capture the agent's output since the last task was sent, cleaned for chat display.\n * Returns readable text with TUI noise removed, or empty string if no marker exists.\n *\n * Mutates `markers` by deleting the entry for `sessionId` after capture.\n */\nexport function captureTaskResponse(\n sessionId: string,\n buffers: Map<string, string[]>,\n markers: Map<string, number>,\n): string {\n const buffer = buffers.get(sessionId);\n const marker = markers.get(sessionId);\n if (!buffer || marker === undefined) return \"\";\n\n const responseLines = buffer.slice(marker);\n markers.delete(sessionId);\n\n return cleanForChat(responseLines.join(\"\\n\"));\n}\n\n/**\n * Peek at the current task response without consuming the marker.\n * Useful for state reconciliation paths that need to inspect a response\n * before deciding whether to emit a synthetic completion event.\n */\nexport function peekTaskResponse(\n sessionId: string,\n buffers: Map<string, string[]>,\n markers: Map<string, number>,\n): string {\n const buffer = buffers.get(sessionId);\n const marker = markers.get(sessionId);\n if (!buffer || marker === undefined) return \"\";\n return cleanForChat(buffer.slice(marker).join(\"\\n\"));\n}\n",
|
|
9
|
+
"/**\n * Install bundled Claude Code skills into the host's `~/.claude/skills/` so\n * sub-agents Eliza spawns automatically have access to them.\n *\n * The orchestrator ships skill content under `assets/claude-code-skills/`\n * inside this package. On PTY service init, the installer copies any\n * directory tree under that path into the host's `~/.claude/skills/<id>/`\n * if the destination does not already exist. Subsequent runs are no-ops\n * unless the destination has been removed.\n *\n * Why \"skip if exists\" rather than \"always overwrite\":\n * - Skills are user-modifiable. If a user customized eliza-runtime locally\n * (added their own scripts, edited a reference), the orchestrator should\n * not silently stomp their edits on every restart.\n * - The cost of a stale skill is that new orchestrator features the skill\n * should advertise won't be available until the user refreshes manually.\n * That's the right trade-off for v1; future versions can use a version\n * marker file to detect \"I have an older copy, please update.\"\n *\n * The installer is best-effort — failures (missing source dir, can't write\n * to home, etc.) log a warning and return; they never block PTY start.\n */\n\nimport { cpSync, existsSync, mkdirSync, readdirSync, statSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport type { Logger } from \"@elizaos/core\";\n\n/**\n * Where the bundled skill source lives inside this package. Resolved by\n * walking upward from this module's location until we find the assets dir.\n *\n * The walk-up handles the three concrete shapes this code runs in:\n * - source dev: src/services/claude-code-skill-installer.ts → walk up 2\n * - bun-bundled: dist/index.js (everything flattened) → walk up 1\n * - tsc-emitted: dist/services/claude-code-skill-installer.js → walk up 2\n *\n * Search-by-presence is more robust than counting `..`s and avoids breaking\n * silently when the bundler shape changes.\n */\nfunction resolveBundledSkillsRoot(): string | null {\n try {\n const here = fileURLToPath(import.meta.url);\n let dir = dirname(here);\n for (let i = 0; i < 5; i++) {\n const candidate = join(dir, \"assets\", \"claude-code-skills\");\n if (existsSync(candidate)) {\n return candidate;\n }\n const parent = dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n return null;\n } catch {\n return null;\n }\n}\n\nfunction resolveClaudeSkillsDir(home: () => string = homedir): string {\n return join(home(), \".claude\", \"skills\");\n}\n\n/**\n * Copy each top-level directory under `assets/claude-code-skills/` into\n * `~/.claude/skills/<dirname>/`, skipping any destination that already\n * exists. Returns the list of skill ids that were freshly installed (empty\n * array means everything was already present or the source was missing).\n */\nexport function ensureBundledClaudeCodeSkills(\n logger: Pick<Logger, \"info\" | \"warn\">,\n options: { home?: () => string } = {},\n): string[] {\n const installed: string[] = [];\n const sourceRoot = resolveBundledSkillsRoot();\n if (!sourceRoot) {\n // No bundled skills shipped — silent return is fine.\n return installed;\n }\n\n let entries: string[];\n try {\n entries = readdirSync(sourceRoot);\n } catch (err) {\n logger.warn(\n `[claude-code-skill-installer] could not list ${sourceRoot}: ${err instanceof Error ? err.message : String(err)}`,\n );\n return installed;\n }\n\n const home = options.home ?? homedir;\n const destRoot = resolveClaudeSkillsDir(home);\n\n for (const entry of entries) {\n if (entry.startsWith(\".\")) continue;\n const sourceDir = join(sourceRoot, entry);\n try {\n if (!statSync(sourceDir).isDirectory()) continue;\n } catch {\n continue;\n }\n\n const destDir = join(destRoot, entry);\n if (existsSync(destDir)) {\n // Already there — leave any user customizations alone.\n continue;\n }\n\n try {\n mkdirSync(destRoot, { recursive: true });\n cpSync(sourceDir, destDir, { recursive: true });\n installed.push(entry);\n logger.info(\n `[claude-code-skill-installer] installed ${entry} → ${destDir}`,\n );\n } catch (err) {\n logger.warn(\n `[claude-code-skill-installer] failed to install ${entry}: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n }\n\n return installed;\n}\n",
|
|
10
|
+
"import type { SessionEventName } from \"./pty-types.js\";\n\nexport type CoordinatorEventSource =\n | \"pty_manager\"\n | \"adapter_fast_path\"\n | \"session_ready_forward\"\n | \"hook\"\n | \"unknown\";\n\nexport interface CoordinatorSessionSnapshot {\n id: string;\n type?: string;\n status?: string;\n}\n\ninterface CoordinatorEventBase<TName extends SessionEventName> {\n sessionId: string;\n name: TName;\n source: CoordinatorEventSource;\n timestamp: number;\n rawData: unknown;\n session?: CoordinatorSessionSnapshot;\n}\n\nexport interface CoordinatorReadyEvent extends CoordinatorEventBase<\"ready\"> {}\n\nexport interface CoordinatorBlockedEvent\n extends CoordinatorEventBase<\"blocked\"> {\n promptText: string;\n promptType?: string;\n promptInfo?: Record<string, unknown>;\n autoResponded: boolean;\n}\n\nexport interface CoordinatorLoginRequiredEvent\n extends CoordinatorEventBase<\"login_required\"> {\n instructions?: string;\n url?: string;\n deviceCode?: string;\n method?: string;\n promptSnippet?: string;\n}\n\nexport interface CoordinatorTaskCompleteEvent\n extends CoordinatorEventBase<\"task_complete\"> {\n response: string;\n}\n\nexport interface CoordinatorToolRunningEvent\n extends CoordinatorEventBase<\"tool_running\"> {\n toolName?: string;\n description?: string;\n}\n\nexport interface CoordinatorStoppedEvent\n extends CoordinatorEventBase<\"stopped\"> {\n reason?: string;\n}\n\nexport interface CoordinatorErrorEvent extends CoordinatorEventBase<\"error\"> {\n message: string;\n}\n\nexport interface CoordinatorMessageEvent\n extends CoordinatorEventBase<\"message\"> {\n content?: string;\n}\n\nexport type CoordinatorNormalizedEvent =\n | CoordinatorReadyEvent\n | CoordinatorBlockedEvent\n | CoordinatorLoginRequiredEvent\n | CoordinatorTaskCompleteEvent\n | CoordinatorToolRunningEvent\n | CoordinatorStoppedEvent\n | CoordinatorErrorEvent\n | CoordinatorMessageEvent;\n\nfunction normalizeSource(data: unknown): CoordinatorEventSource {\n const source =\n typeof (data as { source?: unknown } | undefined)?.source === \"string\"\n ? ((data as { source: string }).source as string)\n : \"\";\n switch (source) {\n case \"pty_manager\":\n case \"adapter_fast_path\":\n case \"session_ready_forward\":\n case \"hook\":\n return source;\n default:\n return \"unknown\";\n }\n}\n\nfunction normalizeSessionSnapshot(\n data: unknown,\n): CoordinatorSessionSnapshot | undefined {\n const session = (data as { session?: unknown } | undefined)?.session;\n if (!session || typeof session !== \"object\" || Array.isArray(session)) {\n return undefined;\n }\n const record = session as Record<string, unknown>;\n const id = typeof record.id === \"string\" ? record.id : undefined;\n if (!id) return undefined;\n return {\n id,\n ...(typeof record.type === \"string\" ? { type: record.type } : {}),\n ...(typeof record.status === \"string\" ? { status: record.status } : {}),\n };\n}\n\nexport function normalizeCoordinatorEvent(\n sessionId: string,\n event: string,\n data: unknown,\n): CoordinatorNormalizedEvent | null {\n const timestamp =\n typeof (data as { timestamp?: unknown } | undefined)?.timestamp === \"number\"\n ? ((data as { timestamp: number }).timestamp as number)\n : Date.now();\n const source = normalizeSource(data);\n const session = normalizeSessionSnapshot(data);\n\n switch (event as SessionEventName) {\n case \"ready\":\n return {\n sessionId,\n name: \"ready\",\n source,\n timestamp,\n rawData: data,\n ...(session ? { session } : {}),\n };\n case \"blocked\": {\n const promptInfo = (data as { promptInfo?: unknown } | undefined)\n ?.promptInfo;\n const promptRecord =\n promptInfo &&\n typeof promptInfo === \"object\" &&\n !Array.isArray(promptInfo)\n ? (promptInfo as Record<string, unknown>)\n : undefined;\n const promptText =\n (typeof promptRecord?.prompt === \"string\" && promptRecord.prompt) ||\n (typeof promptRecord?.instructions === \"string\" &&\n promptRecord.instructions) ||\n \"\";\n return {\n sessionId,\n name: \"blocked\",\n source,\n timestamp,\n rawData: data,\n ...(session ? { session } : {}),\n promptText,\n ...(typeof promptRecord?.type === \"string\"\n ? { promptType: promptRecord.type }\n : {}),\n ...(promptRecord ? { promptInfo: promptRecord } : {}),\n autoResponded:\n (data as { autoResponded?: unknown } | undefined)?.autoResponded ===\n true,\n };\n }\n case \"login_required\":\n return {\n sessionId,\n name: \"login_required\",\n source,\n timestamp,\n rawData: data,\n ...(session ? { session } : {}),\n ...(typeof (data as { instructions?: unknown } | undefined)\n ?.instructions === \"string\"\n ? {\n instructions: (data as { instructions: string }).instructions,\n }\n : {}),\n ...(typeof (data as { url?: unknown } | undefined)?.url === \"string\"\n ? {\n url: (data as { url: string }).url,\n }\n : {}),\n ...(typeof (data as { deviceCode?: unknown } | undefined)\n ?.deviceCode === \"string\"\n ? {\n deviceCode: (data as { deviceCode: string }).deviceCode,\n }\n : {}),\n ...(typeof (data as { method?: unknown } | undefined)?.method ===\n \"string\"\n ? {\n method: (data as { method: string }).method,\n }\n : {}),\n ...(typeof (data as { promptSnippet?: unknown } | undefined)\n ?.promptSnippet === \"string\"\n ? {\n promptSnippet: (data as { promptSnippet: string }).promptSnippet,\n }\n : {}),\n };\n case \"task_complete\":\n return {\n sessionId,\n name: \"task_complete\",\n source,\n timestamp,\n rawData: data,\n ...(session ? { session } : {}),\n response:\n typeof (data as { response?: unknown } | undefined)?.response ===\n \"string\"\n ? (data as { response: string }).response\n : \"\",\n };\n case \"tool_running\":\n return {\n sessionId,\n name: \"tool_running\",\n source,\n timestamp,\n rawData: data,\n ...(session ? { session } : {}),\n ...(typeof (data as { toolName?: unknown } | undefined)?.toolName ===\n \"string\"\n ? { toolName: (data as { toolName: string }).toolName }\n : {}),\n ...(typeof (data as { description?: unknown } | undefined)\n ?.description === \"string\"\n ? { description: (data as { description: string }).description }\n : {}),\n };\n case \"stopped\":\n return {\n sessionId,\n name: \"stopped\",\n source,\n timestamp,\n rawData: data,\n ...(session ? { session } : {}),\n ...(typeof (data as { reason?: unknown } | undefined)?.reason ===\n \"string\"\n ? { reason: (data as { reason: string }).reason }\n : {}),\n };\n case \"error\":\n return {\n sessionId,\n name: \"error\",\n source,\n timestamp,\n rawData: data,\n ...(session ? { session } : {}),\n message:\n typeof (data as { message?: unknown } | undefined)?.message ===\n \"string\"\n ? (data as { message: string }).message\n : \"unknown error\",\n };\n case \"message\":\n return {\n sessionId,\n name: \"message\",\n source,\n timestamp,\n rawData: data,\n ...(session ? { session } : {}),\n ...(typeof (data as { content?: unknown } | undefined)?.content ===\n \"string\"\n ? { content: (data as { content: string }).content }\n : {}),\n };\n default:\n return null;\n }\n}\n",
|
|
11
|
+
"/**\n * Debug PTY Capture — optional session recording for offline analysis.\n *\n * Activated by setting `PARALLAX_DEBUG_CAPTURE=1`. When enabled, all PTY\n * output and stdin are recorded per-session using `pty-state-capture`.\n * Capture files persist in `.parallax/pty-captures/<sessionId>/` after\n * the agent session is killed, enabling post-mortem analysis of state\n * transitions, stall classifications, and coordinator timing.\n *\n * The `pty-state-capture` package is dynamically imported — if not\n * installed, capture is silently disabled. This means it can stay out\n * of production dependencies entirely.\n *\n * @module services/debug-capture\n */\n\nimport { logger } from \"@elizaos/core\";\n\n/** Re-export the types we use so callers don't need to import pty-state-capture directly. */\ninterface CaptureManagerLike {\n openSession(\n sessionId: string,\n overrides?: { source?: string },\n ): Promise<unknown>;\n feed(\n sessionId: string,\n chunk: string,\n direction?: \"stdout\" | \"stderr\" | \"stdin\",\n ): Promise<unknown>;\n lifecycle(sessionId: string, event: string, detail?: string): Promise<void>;\n snapshot(sessionId: string): unknown | null;\n}\n\nlet captureManager: CaptureManagerLike | null = null;\nlet initAttempted = false;\n\n/**\n * Returns true if debug capture is enabled via environment variable.\n */\nexport function isDebugCaptureEnabled(): boolean {\n return process.env.PARALLAX_DEBUG_CAPTURE === \"1\";\n}\n\n/**\n * Lazily initialize the capture manager. Returns null if:\n * - PARALLAX_DEBUG_CAPTURE is not set to \"1\"\n * - pty-state-capture is not installed\n * - Initialization fails for any reason\n */\nasync function ensureCaptureManager(): Promise<CaptureManagerLike | null> {\n if (captureManager) return captureManager;\n if (initAttempted) return null;\n initAttempted = true;\n\n if (!isDebugCaptureEnabled()) return null;\n\n try {\n const mod = await import(\"pty-state-capture\");\n const { PTYStateCaptureManager } = mod;\n captureManager = new PTYStateCaptureManager({\n outputRootDir: \".parallax/pty-captures\",\n defaultRows: 80,\n defaultCols: 220,\n });\n logger.info(\n \"[debug-capture] PTY state capture enabled — writing to .parallax/pty-captures/\",\n );\n return captureManager;\n } catch {\n logger.debug(\n \"[debug-capture] pty-state-capture not available — capture disabled\",\n );\n return null;\n }\n}\n\n/**\n * Open a capture session for a PTY session. Call this when spawning.\n */\nexport async function captureSessionOpen(\n sessionId: string,\n agentType: string,\n): Promise<void> {\n const mgr = await ensureCaptureManager();\n if (!mgr) return;\n try {\n await mgr.openSession(sessionId, { source: agentType });\n } catch (err) {\n logger.debug(`[debug-capture] Failed to open session ${sessionId}: ${err}`);\n }\n}\n\n/**\n * Feed PTY output data to the capture. Call this on every data chunk.\n */\nexport async function captureFeed(\n sessionId: string,\n chunk: string,\n direction: \"stdout\" | \"stderr\" | \"stdin\" = \"stdout\",\n): Promise<void> {\n if (!captureManager) return;\n try {\n await captureManager.feed(sessionId, chunk, direction);\n } catch (err) {\n logger.debug(`[debug-capture] Feed error for ${sessionId}: ${err}`);\n }\n}\n\n/**\n * Record a lifecycle event (session_ready, session_stopped, etc.).\n */\nexport async function captureLifecycle(\n sessionId: string,\n event:\n | \"session_started\"\n | \"session_ready\"\n | \"session_stopped\"\n | \"session_error\",\n detail?: string,\n): Promise<void> {\n if (!captureManager) return;\n try {\n await captureManager.lifecycle(sessionId, event, detail);\n } catch (err) {\n logger.debug(`[debug-capture] Lifecycle error for ${sessionId}: ${err}`);\n }\n}\n\n/**\n * Get a snapshot of a capture session's current state.\n */\nexport function captureSnapshot(sessionId: string): unknown | null {\n if (!captureManager) return null;\n try {\n return captureManager.snapshot(sessionId);\n } catch (err) {\n logger.debug(`[debug-capture] Snapshot error for ${sessionId}: ${err}`);\n return null;\n }\n}\n\n/** @internal Reset module state for testing only. */\nexport function _resetForTesting(): void {\n captureManager = null;\n initAttempted = false;\n}\n",
|
|
12
|
+
"/**\n * Auto-response rule management for PTY sessions (bypass-fix).\n *\n * Contains logic for pushing default auto-response rules per agent type\n * and handling Gemini authentication flow.\n *\n * @module services/pty-auto-response\n */\n\nimport type { IAgentRuntime } from \"@elizaos/core\";\nimport type {\n AutoResponseRule,\n BunCompatiblePTYManager,\n PTYManager,\n} from \"pty-manager\";\nimport { readConfigEnvKey } from \"./config-env.js\";\n\nexport interface AutoResponseContext {\n manager: PTYManager | BunCompatiblePTYManager;\n usingBunWorker: boolean;\n runtime: IAgentRuntime;\n log: (msg: string) => void;\n}\n\nconst CODEX_KEEP_CURRENT_MODEL_NEVER_PROMPT_RE =\n /keep\\s+current\\s+model\\s*\\(never\\s+show\\s+again\\)|hide\\s+future\\s+rate\\s+limit\\s+reminders\\s+about\\s+switching\\s+models/i;\nconst CODEX_KEEP_CURRENT_MODEL_PROMPT_RE =\n /^(?![\\s\\S]*(?:never\\s+show\\s+again|hide\\s+future\\s+rate\\s+limit\\s+reminders))(?=[\\s\\S]*\\bkeep\\s+current\\s+model\\b)(?=[\\s\\S]*(?:efficient\\s+model|less\\s+capable|faster|rate\\s+limit|switching\\s+models))/i;\nconst CODEX_DEFAULT_ACCOUNT_SELECTION_PROMPT_RE =\n /(?:organization|account|team)\\s+selection|select\\s+(?:an?\\s+)?(?:organization|account|team)\\b/i;\n\n/**\n * Push session-specific auto-response rules that depend on runtime config.\n * Trust prompts, update notices, and other static rules are handled by\n * adapter built-in rules (coding-agent-adapters). This only pushes rules\n * that need runtime values (e.g. API keys).\n */\nexport async function pushDefaultRules(\n ctx: AutoResponseContext,\n sessionId: string,\n agentType: string,\n): Promise<void> {\n const rules: AutoResponseRule[] = [];\n\n // Codex sometimes renders the workspace trust screen incrementally.\n // The upstream adapter rule is one-shot; if it fires before the menu is fully\n // interactive, Codex can keep showing the same prompt and block the session.\n // Keep this session rule active until the prompt actually clears.\n if (agentType === \"codex\") {\n rules.push({\n pattern: CODEX_KEEP_CURRENT_MODEL_NEVER_PROMPT_RE,\n type: \"config\",\n response: \"\",\n responseType: \"keys\" as const,\n keys: [\"3\", \"enter\"],\n description:\n \"Keep the current Codex model and hide future model-switch reminders\",\n safe: true,\n });\n rules.push({\n pattern: CODEX_KEEP_CURRENT_MODEL_PROMPT_RE,\n type: \"config\",\n response: \"\",\n responseType: \"keys\" as const,\n keys: [\"2\", \"enter\"],\n description:\n \"Keep the current Codex model when a routine model-switch reminder appears\",\n safe: true,\n });\n rules.push({\n pattern:\n /higher.?risk.?of.?prompt.?injection|yes,?.?continue.*no,?.?quit|do.?you.?trust.?the.?contents|trust.?this.?directory|allow.?codex.?to.?work.?in.?this.?folder|without.?asking.?for.?approval/i,\n type: \"permission\",\n response: \"\",\n responseType: \"keys\" as const,\n keys: [\"1\", \"enter\"],\n description:\n \"Retry Codex workspace trust approval with option 1 ('Yes, continue') until the prompt clears\",\n safe: true,\n });\n rules.push({\n pattern: CODEX_DEFAULT_ACCOUNT_SELECTION_PROMPT_RE,\n type: \"config\",\n response: \"\",\n responseType: \"keys\" as const,\n keys: [\"enter\"],\n description:\n \"Accept Codex's default organization/account selection for non-interactive subscription sessions\",\n safe: true,\n });\n }\n\n // Aider gitignore prompt\n if (agentType === \"aider\") {\n rules.push({\n pattern: /\\.aider\\*.*\\.gitignore.*\\(Y\\)es\\/\\(N\\)o/i,\n type: \"config\",\n response: \"y\",\n description: \"Auto-accept adding .aider* to .gitignore\",\n safe: true,\n });\n }\n\n // Claude: API key confirmation prompt (appears when ANTHROPIC_API_KEY is set\n // alongside a subscription login, or in CLAUDE_CODE_SIMPLE mode)\n if (agentType === \"claude\") {\n const llmProvider =\n readConfigEnvKey(\"PARALLAX_LLM_PROVIDER\") || \"subscription\";\n if (llmProvider === \"api_keys\" || llmProvider === \"cloud\") {\n rules.push({\n pattern:\n /Do you want to use this API key|(?:custom|detected).*API key.*environment/i,\n type: \"config\",\n response: \"\",\n responseType: \"keys\" as const,\n keys: [\"up\", \"enter\"],\n description: \"Accept detected ANTHROPIC_API_KEY from environment\",\n safe: true,\n once: true,\n });\n }\n\n // Bypass Permissions warning: fresh workdirs trigger a one-time\n // \"Yes, I accept / No, exit\" confirmation. pty-manager's TUI-aware\n // default for permission rules without explicit keys presses Enter,\n // which resolves to option 1 \"No, exit\" and kills claude with exit\n // code 1 before any work runs. Encode the response as explicit keys\n // so the worker types \"2\" + Enter. No `once`: TUI may redraw the\n // dialog before the selection is committed.\n //\n // Covers failure mode: seedClaudeTrustForWorkdir couldn't write\n // ~/.claude.json (file locked / read-only / concurrent write) AND the\n // session is non-coordinator (adapter auto-response still on).\n rules.push({\n pattern:\n /WARNING.{0,200}Bypass Permissions mode|Bypass Permissions mode.{0,200}accept all responsibility/is,\n type: \"permission\",\n response: \"\",\n responseType: \"keys\" as const,\n keys: [\"2\", \"enter\"],\n description:\n \"Accept Claude Bypass Permissions dialog (option 2: 'Yes, I accept')\",\n safe: true,\n });\n }\n\n // Gemini: auth flow (update notices are informational, don't need a response)\n if (agentType === \"gemini\") {\n // Auth menu detection: select API key or Google login based on available credentials\n const geminiApiKey = ctx.runtime.getSetting(\"GENERATIVE_AI_API_KEY\") as\n | string\n | undefined;\n\n if (geminiApiKey) {\n // Have API key → select option 2 \"Use an API key\"\n rules.push({\n pattern:\n /Log in with Google|Use an API key|Use Vertex AI|gemini api key/i,\n type: \"config\",\n response: \"2\",\n description: \"Select 'Use an API key' from Gemini auth menu\",\n safe: true,\n });\n\n // Step 2: API key input prompt. Send the actual key value.\n // Tight regex: only matches the Gemini CLI's exact prompt format\n // to prevent exfiltration via crafted terminal output.\n // once: fire at most once per session to prevent repeated credential injection.\n rules.push({\n pattern:\n /^(?:\\s|[>$#])*(?:Enter|Paste) (?:your )?(?:Google AI|Gemini) API key:/i,\n type: \"config\",\n response: geminiApiKey,\n description: \"Input Gemini API key from Gemini CLI auth prompt\",\n safe: true,\n once: true,\n });\n } else {\n // No API key → select option 1 \"Log in with Google\" (opens browser OAuth)\n rules.push({\n pattern:\n /Log in with Google|Use an API key|Use Vertex AI|gemini api key/i,\n type: \"config\",\n response: \"1\",\n description:\n \"Select 'Log in with Google' from Gemini auth menu (browser OAuth)\",\n safe: true,\n });\n }\n }\n\n if (rules.length === 0) return;\n\n // Push rules to the session via the runtime API\n try {\n if (ctx.usingBunWorker) {\n for (const rule of rules) {\n await (ctx.manager as BunCompatiblePTYManager).addAutoResponseRule(\n sessionId,\n rule,\n );\n }\n } else {\n const nodeManager = ctx.manager as PTYManager;\n for (const rule of rules) {\n nodeManager.addAutoResponseRule(sessionId, rule);\n }\n }\n ctx.log(\n `Pushed ${rules.length} auto-response rules to session ${sessionId}`,\n );\n\n // Note: No retroactive check needed here. The worker's tryAutoResponse()\n // runs on every data chunk and checks the full output buffer against all\n // active rules. Once rules are pushed, the next data chunk will trigger\n // matching. The old retroactive check caused ghost responses because it\n // bypassed the worker's TUI-aware response logic (sendKeys vs writeRaw).\n } catch (err) {\n ctx.log(`Failed to push rules to session ${sessionId}: ${err}`);\n }\n}\n\n/**\n * Handle Gemini authentication when login_required fires.\n * Sends /auth to start the auth flow; auto-response rules\n * then handle menu selection and API key input.\n */\nexport async function handleGeminiAuth(\n ctx: AutoResponseContext,\n sessionId: string,\n sendKeysToSession: (\n sessionId: string,\n keys: string | string[],\n ) => Promise<void>,\n): Promise<void> {\n const apiKey = ctx.runtime.getSetting(\"GENERATIVE_AI_API_KEY\") as\n | string\n | undefined;\n\n if (apiKey) {\n ctx.log(\n `Gemini auth: API key available, sending /auth to start API key flow`,\n );\n } else {\n ctx.log(\n `Gemini auth: no API key configured, sending /auth for Google OAuth flow`,\n );\n }\n\n // Send /auth via sendKeys to avoid send() which sets status to \"busy\".\n // We need to stay in \"authenticating\" so detectReady fires after auth completes.\n try {\n await sendKeysToSession(sessionId, \"/auth\");\n await new Promise((r) => setTimeout(r, 50));\n await sendKeysToSession(sessionId, \"enter\");\n } catch (err) {\n ctx.log(`Gemini auth: failed to send /auth: ${err}`);\n }\n}\n",
|
|
13
|
+
"/**\n * PTY manager initialization — extracted from PTYService.initialize().\n *\n * Creates either a BunCompatiblePTYManager (for Bun runtime) or PTYManager\n * (for Node), wires up event handlers, and returns the configured manager.\n *\n * @module services/pty-init\n */\n\nimport { existsSync, readdirSync } from \"node:fs\";\nimport { readFile } from \"node:fs/promises\";\nimport { createRequire } from \"node:module\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport type {\n AuthRequiredInfo,\n BunCompatiblePTYManager as BunCompatiblePTYManagerType,\n PTYManagerConfig,\n PTYManager as PTYManagerType,\n SessionHandle,\n SessionMessage,\n StallClassification,\n ToolRunningInfo,\n WorkerSessionHandle,\n} from \"pty-manager\";\nimport type { CompletionMethod } from \"./agent-metrics.js\";\nimport { captureTaskResponse, cleanForChat } from \"./ansi-utils.js\";\nimport type { PTYServiceConfig } from \"./pty-types.js\";\n\n// Stall detector silence threshold. 60s — long enough that a bash, git,\n// WebSearch, or multi-step tool call can complete without tripping the\n// classifier, short enough to still catch real hangs within a minute.\n// Previously 4000ms, which misfired for every long tool call on claude-code\n// agents and caused completion re-injection loops on open-ended tasks.\nconst STALL_TIMEOUT_MS = 60_000;\n\n// Resolve absolute path to coding-agent-adapters so the Node worker process\n// can load it regardless of its cwd. The worker uses require() which does\n// cwd-relative resolution — passing the bare module name \"coding-agent-adapters\"\n// fails when the worker's cwd doesn't contain node_modules.\nconst _require = createRequire(import.meta.url);\nconst { BunCompatiblePTYManager, isBun, PTYManager, ShellAdapter } = _require(\n \"pty-manager\",\n) as typeof import(\"pty-manager\");\nlet resolvedAdapterModule = \"coding-agent-adapters\";\ntry {\n resolvedAdapterModule = _require.resolve(\"coding-agent-adapters\");\n} catch {\n // Fallback to bare specifier if resolve fails (shouldn't happen)\n}\nconst moduleDir = path.dirname(fileURLToPath(import.meta.url));\nfor (const candidate of [\n path.resolve(moduleDir, \"../scripts/codex-exec-adapters.cjs\"),\n path.resolve(moduleDir, \"../../scripts/codex-exec-adapters.cjs\"),\n]) {\n if (existsSync(candidate)) {\n resolvedAdapterModule = candidate;\n break;\n }\n}\nconst { createAllAdapters } = _require(\n resolvedAdapterModule,\n) as typeof import(\"coding-agent-adapters\");\nlet resolvedPtyWorkerPath: string | undefined;\ntry {\n resolvedPtyWorkerPath = _require.resolve(\"pty-manager/worker\");\n} catch {\n resolvedPtyWorkerPath = undefined;\n}\n\nfunction resolveNodeWorkerPath(): string {\n const explicitCandidates = [\n process.env.NODE,\n process.env.NODE_BINARY,\n \"/opt/homebrew/bin/node\",\n \"/usr/local/bin/node\",\n ].filter((value): value is string => Boolean(value?.trim()));\n\n for (const candidate of explicitCandidates) {\n if (existsSync(candidate)) {\n return candidate;\n }\n }\n\n const nvmVersionsDir = path.join(os.homedir(), \".nvm\", \"versions\", \"node\");\n if (existsSync(nvmVersionsDir)) {\n const versions = readdirSync(nvmVersionsDir)\n .filter((entry) => entry.startsWith(\"v\"))\n .sort((a, b) =>\n b.localeCompare(a, undefined, {\n numeric: true,\n sensitivity: \"base\",\n }),\n );\n for (const version of versions) {\n const candidate = path.join(nvmVersionsDir, version, \"bin\", \"node\");\n if (existsSync(candidate)) {\n return candidate;\n }\n }\n }\n\n return \"node\";\n}\n\n/**\n * All callbacks and state that the initialization logic needs\n * from the surrounding PTYService instance.\n */\nexport interface InitContext {\n serviceConfig: PTYServiceConfig;\n classifyStall: (\n sessionId: string,\n recentOutput: string,\n ) => Promise<StallClassification | null>;\n emitEvent: (sessionId: string, event: string, data: unknown) => void;\n handleGeminiAuth: (sessionId: string) => void;\n sessionMetadata: Map<string, Record<string, unknown>>;\n sessionOutputBuffers: Map<string, string[]>;\n taskResponseMarkers: Map<string, number>;\n metricsTracker: {\n recordCompletion(\n type: string,\n method: CompletionMethod,\n durationMs: number,\n ): void;\n };\n traceEntries: Array<string | Record<string, unknown>>;\n maxTraceEntries: number;\n log: (msg: string) => void;\n handleWorkerExit?: (info: {\n code: number | null;\n signal: string | null;\n }) => void;\n /** Check if a session has an active task in the coordinator. */\n hasActiveTask?: (sessionId: string) => boolean;\n /** Check if a session's task has started work (task delivered or decisions made). */\n hasTaskActivity?: (sessionId: string) => boolean;\n /** Mark a session's task as delivered (initial ready event processed). */\n markTaskDelivered?: (sessionId: string) => void;\n}\n\nasync function readCodexExecOutputFile(\n ctx: InitContext,\n sessionId: string,\n outputFile: string,\n): Promise<string> {\n const maxAttempts = 10;\n for (let attempt = 0; attempt < maxAttempts; attempt++) {\n try {\n const fromFile = cleanForChat(await readFile(outputFile, \"utf8\"));\n if (fromFile.trim()) {\n return fromFile.trim();\n }\n } catch (error) {\n const code =\n error && typeof error === \"object\" && \"code\" in error\n ? String((error as { code?: unknown }).code)\n : \"\";\n if (code !== \"ENOENT\") {\n ctx.log(\n `Failed to read Codex exec output file for ${sessionId}: ${error}`,\n );\n return \"\";\n }\n }\n\n await new Promise((resolve) => setTimeout(resolve, 100));\n }\n\n return \"\";\n}\n\nasync function captureFastPathTaskResponse(\n ctx: InitContext,\n sessionId: string,\n): Promise<string> {\n const outputFile = ctx.sessionMetadata.get(sessionId)?.codexExecOutputFile;\n if (typeof outputFile === \"string\" && outputFile.trim()) {\n const fromFile = await readCodexExecOutputFile(ctx, sessionId, outputFile);\n if (fromFile) {\n return fromFile;\n }\n }\n\n return captureTaskResponse(\n sessionId,\n ctx.sessionOutputBuffers,\n ctx.taskResponseMarkers,\n );\n}\n\n// NOTE: A previous implementation defined `forwardReadyAsTaskComplete` here,\n// which re-emitted every `session_ready` event as `task_complete` if the\n// session had an active task. That was incorrect: Claude Code's TUI briefly\n// enters a ready state between every tool call (after Bash, WebSearch, git,\n// edit, etc.), so ready ≠ done. It caused the coordinator to run its\n// turn-complete decision pipeline dozens of times per real session, each of\n// which would re-inject the original prompt via \"Turn done, continuing\",\n// creating an infinite retry loop on any long multi-step task.\n//\n// Task completion is now signaled authoritatively by the agent's own hook\n// system, routed through pty-service.handleHookEvent. The jsonl-based\n// completion watcher in the eliza package provides a defense-in-depth\n// ground-truth signal. `session_ready` is still emitted for consumers that\n// want to know when the PTY prompt is visible, but it is not a completion\n// signal.\n\n/** Value returned by {@link initializePTYManager}. */\nexport interface InitResult {\n manager: PTYManagerType | BunCompatiblePTYManagerType;\n usingBunWorker: boolean;\n}\n\n/**\n * Create and configure a PTY manager for the current runtime.\n *\n * - **Bun**: instantiates a {@link BunCompatiblePTYManager} that spawns a\n * Node worker process and communicates via JSON-RPC over stdio.\n * - **Node**: instantiates a {@link PTYManager} directly and registers\n * all built-in adapters in-process.\n */\nexport async function initializePTYManager(\n ctx: InitContext,\n): Promise<InitResult> {\n const usingBunWorker = isBun();\n const recentStructuredAuth = new Map<string, number>();\n const AUTH_EVENT_DEDUPE_MS = 5_000;\n\n const emitStructuredAuthRequired = (\n session: { id: string; type?: string },\n info: AuthRequiredInfo,\n ): void => {\n recentStructuredAuth.set(session.id, Date.now());\n if (session.type === \"gemini\") {\n ctx.handleGeminiAuth(session.id);\n }\n ctx.emitEvent(session.id, \"login_required\", {\n instructions: info.instructions,\n url: info.url,\n deviceCode: info.deviceCode,\n method: info.method,\n promptSnippet: info.promptSnippet,\n session,\n source: \"pty_manager\",\n });\n };\n\n const shouldSuppressDuplicateLoginRequired = (sessionId: string): boolean => {\n const at = recentStructuredAuth.get(sessionId);\n if (!at) return false;\n if (Date.now() - at > AUTH_EVENT_DEDUPE_MS) {\n recentStructuredAuth.delete(sessionId);\n return false;\n }\n return true;\n };\n\n if (usingBunWorker) {\n // Use Bun-compatible manager that spawns a Node worker\n ctx.log(\"Detected Bun runtime, using BunCompatiblePTYManager\");\n ctx.log(`Resolved adapter module: ${resolvedAdapterModule}`);\n const bunManager = new BunCompatiblePTYManager({\n adapterModules: [resolvedAdapterModule],\n nodePath: resolveNodeWorkerPath(),\n ...(resolvedPtyWorkerPath ? { workerPath: resolvedPtyWorkerPath } : {}),\n stallDetectionEnabled: true,\n stallTimeoutMs: STALL_TIMEOUT_MS,\n onStallClassify: async (\n sessionId: string,\n recentOutput: string,\n _stallDurationMs: number,\n ) => {\n return ctx.classifyStall(sessionId, recentOutput);\n },\n });\n\n // Set up event forwarding for worker-based manager. session_ready means\n // the PTY prompt is visible again — it does NOT mean the agent is done\n // (see the forwardReadyAsTaskComplete note above).\n bunManager.on(\"session_ready\", (session: WorkerSessionHandle) => {\n ctx.log(\n `session_ready event received for ${session.id} (type: ${session.type}, status: ${session.status})`,\n );\n ctx.emitEvent(session.id, \"ready\", { session, source: \"pty_manager\" });\n ctx.markTaskDelivered?.(session.id);\n });\n\n const handleWorkerStopped = async (\n sessionOrId: WorkerSessionHandle | string,\n reasonOrCode?: string | number,\n signal?: string | number,\n ): Promise<void> => {\n const metadata =\n typeof sessionOrId === \"string\"\n ? ctx.sessionMetadata.get(sessionOrId)\n : undefined;\n const session =\n typeof sessionOrId === \"string\"\n ? ({\n id: sessionOrId,\n type:\n typeof metadata?.agentType === \"string\"\n ? metadata.agentType\n : \"unknown\",\n status: \"stopped\",\n } as WorkerSessionHandle)\n : sessionOrId;\n const id = session.id;\n const code =\n typeof reasonOrCode === \"number\"\n ? reasonOrCode\n : typeof session.exitCode === \"number\"\n ? session.exitCode\n : undefined;\n const reason =\n typeof reasonOrCode === \"string\"\n ? reasonOrCode\n : typeof code === \"number\"\n ? `exit code ${code}`\n : signal\n ? `signal ${String(signal)}`\n : \"session stopped\";\n const cleanExit = code === 0 || /\\bexit code 0\\b/i.test(reason);\n\n if (cleanExit && ctx.sessionMetadata.get(id)?.codexExecMode === true) {\n const response = await captureFastPathTaskResponse(ctx, id);\n ctx.metricsTracker.recordCompletion(\"codex\", \"fast-path\", 0);\n ctx.log(\n `Task complete for ${id} (codex exec exit), response: ${response.length} chars`,\n );\n ctx.emitEvent(id, \"task_complete\", {\n session,\n response,\n source: \"adapter_fast_path\",\n });\n return;\n }\n\n ctx.emitEvent(id, \"stopped\", {\n reason,\n source: \"pty_manager\",\n });\n };\n\n bunManager.on(\n \"session_stopped\",\n (\n session: WorkerSessionHandle,\n reasonOrCode?: string | number,\n signal?: string | number,\n ) => {\n void handleWorkerStopped(session, reasonOrCode, signal);\n },\n );\n\n // Older pty-manager builds exposed this event name.\n bunManager.on(\"session_exit\", (id: string, code: number) => {\n void handleWorkerStopped(id, code);\n });\n\n bunManager.on(\"session_error\", (id: string, error: string) => {\n ctx.emitEvent(id, \"error\", { message: error, source: \"pty_manager\" });\n });\n\n bunManager.on(\n \"blocking_prompt\",\n (\n session: WorkerSessionHandle,\n promptInfo: unknown,\n autoResponded: boolean,\n ) => {\n const info = promptInfo as\n | { type?: string; prompt?: string }\n | undefined;\n ctx.log(\n `blocking_prompt for ${session.id}: type=${info?.type}, autoResponded=${autoResponded}, prompt=\"${(info?.prompt ?? \"\").slice(0, 80)}\"`,\n );\n ctx.emitEvent(session.id, \"blocked\", {\n promptInfo,\n autoResponded,\n source: \"pty_manager\",\n });\n },\n );\n\n bunManager.on(\n \"auth_required\",\n (session: WorkerSessionHandle, info: AuthRequiredInfo) => {\n emitStructuredAuthRequired(session, info);\n },\n );\n\n bunManager.on(\n \"login_required\",\n (session: WorkerSessionHandle, instructions?: string, url?: string) => {\n if (shouldSuppressDuplicateLoginRequired(session.id)) {\n return;\n }\n // Auto-handle Gemini auth flow\n if (session.type === \"gemini\") {\n ctx.handleGeminiAuth(session.id);\n }\n ctx.emitEvent(session.id, \"login_required\", {\n instructions,\n url,\n source: \"pty_manager\",\n });\n },\n );\n\n bunManager.on(\"task_complete\", async (session: WorkerSessionHandle) => {\n const response = await captureFastPathTaskResponse(ctx, session.id);\n const durationMs = session.startedAt\n ? Date.now() - new Date(session.startedAt).getTime()\n : 0;\n ctx.metricsTracker.recordCompletion(\n session.type,\n \"fast-path\",\n durationMs,\n );\n ctx.log(\n `Task complete for ${session.id} (adapter fast-path), response: ${response.length} chars`,\n );\n ctx.emitEvent(session.id, \"task_complete\", {\n session,\n response,\n source: \"adapter_fast_path\",\n });\n });\n\n bunManager.on(\n \"tool_running\",\n (session: WorkerSessionHandle, info: ToolRunningInfo) => {\n ctx.log(\n `tool_running for ${session.id}: ${info.toolName}${info.description ? ` — ${info.description}` : \"\"}`,\n );\n ctx.emitEvent(session.id, \"tool_running\", {\n session,\n ...info,\n source: \"pty_manager\",\n });\n },\n );\n\n bunManager.on(\"message\", (message: SessionMessage) => {\n ctx.emitEvent(message.sessionId, \"message\", {\n ...message,\n source: \"pty_manager\",\n });\n });\n\n // Log worker-level stderr (pino logs from pty-manager worker process).\n // Strip the \"Invalid JSON from worker:\" prefix that BunCompatiblePTYManager\n // adds when stderr lines aren't valid JSON-RPC responses.\n bunManager.on(\"worker_error\", (err: unknown) => {\n const raw = typeof err === \"string\" ? err : String(err);\n const msg = raw.replace(/^Invalid JSON from worker:\\s*/i, \"\").trim();\n if (!msg) return;\n // Capture task completion trace entries for timeline analysis\n if (msg.includes(\"Task completion trace\")) {\n ctx.traceEntries.push(msg);\n if (ctx.traceEntries.length > ctx.maxTraceEntries) {\n ctx.traceEntries.splice(\n 0,\n ctx.traceEntries.length - ctx.maxTraceEntries,\n );\n }\n }\n // Show operational logs at info level (suppress noisy loading-suppression messages)\n if (msg.includes(\"suppressing stall emission\")) {\n // Loading pattern suppression fires every few seconds — too noisy for console\n return;\n }\n if (\n msg.includes(\"ready\") ||\n msg.includes(\"blocking\") ||\n msg.includes(\"auto-response\") ||\n msg.includes(\"Auto-responding\") ||\n msg.includes(\"detectReady\") ||\n msg.includes(\"stall\") ||\n msg.includes(\"Stall\") ||\n msg.includes(\"Task completion\") ||\n msg.includes(\"Spawning\") ||\n msg.includes(\"PTY session\")\n ) {\n console.log(\"[PTYService/Worker]\", msg);\n } else {\n console.error(\"[PTYService/Worker]\", msg.slice(0, 200));\n }\n });\n\n bunManager.on(\n \"worker_exit\",\n (info: { code: number | null; signal: string | null }) => {\n ctx.handleWorkerExit?.(info);\n console.error(\"[PTYService] Worker exited:\", info);\n },\n );\n\n await bunManager.waitForReady();\n return { manager: bunManager, usingBunWorker: true };\n }\n\n // Use native PTYManager directly in Node\n ctx.log(\"Using native PTYManager\");\n const managerConfig: PTYManagerConfig = {\n maxLogLines: ctx.serviceConfig.maxLogLines,\n stallDetectionEnabled: true,\n stallTimeoutMs: STALL_TIMEOUT_MS,\n onStallClassify: async (\n sessionId: string,\n recentOutput: string,\n _stallDurationMs: number,\n ) => {\n return ctx.classifyStall(sessionId, recentOutput);\n },\n };\n\n const nodeManager = new PTYManager(managerConfig);\n\n // Register built-in adapters\n nodeManager.registerAdapter(new ShellAdapter());\n\n // Register coding agent adapters (claude, gemini, codex, aider).\n // Pi currently routes through the generic shell adapter.\n if (ctx.serviceConfig.registerCodingAdapters) {\n const codingAdapters = createAllAdapters();\n for (const adapter of codingAdapters) {\n nodeManager.registerAdapter(adapter);\n ctx.log(`Registered ${adapter.adapterType} adapter`);\n }\n }\n\n // Set up event forwarding. session_ready means the PTY prompt is visible\n // again — NOT that the agent is done (see the forwardReadyAsTaskComplete\n // note above).\n nodeManager.on(\"session_ready\", (session: SessionHandle) => {\n ctx.emitEvent(session.id, \"ready\", { session, source: \"pty_manager\" });\n ctx.markTaskDelivered?.(session.id);\n });\n\n nodeManager.on(\n \"blocking_prompt\",\n (session: SessionHandle, promptInfo: unknown, autoResponded: boolean) => {\n ctx.emitEvent(session.id, \"blocked\", {\n promptInfo,\n autoResponded,\n source: \"pty_manager\",\n });\n },\n );\n\n nodeManager.on(\n \"auth_required\",\n (session: SessionHandle, info: AuthRequiredInfo) => {\n emitStructuredAuthRequired(session, info);\n },\n );\n\n nodeManager.on(\n \"login_required\",\n (session: SessionHandle, instructions?: string, url?: string) => {\n if (shouldSuppressDuplicateLoginRequired(session.id)) {\n return;\n }\n if (session.type === \"gemini\") {\n ctx.handleGeminiAuth(session.id);\n }\n ctx.emitEvent(session.id, \"login_required\", {\n instructions,\n url,\n source: \"pty_manager\",\n });\n },\n );\n\n nodeManager.on(\"task_complete\", async (session: SessionHandle) => {\n const response = await captureFastPathTaskResponse(ctx, session.id);\n const durationMs = session.startedAt\n ? Date.now() - new Date(session.startedAt).getTime()\n : 0;\n ctx.metricsTracker.recordCompletion(session.type, \"fast-path\", durationMs);\n ctx.log(\n `Task complete for ${session.id} (adapter fast-path), response: ${response.length} chars`,\n );\n ctx.emitEvent(session.id, \"task_complete\", {\n session,\n response,\n source: \"adapter_fast_path\",\n });\n });\n\n nodeManager.on(\n \"tool_running\",\n (session: SessionHandle, info: ToolRunningInfo) => {\n ctx.log(\n `tool_running for ${session.id}: ${info.toolName}${info.description ? ` — ${info.description}` : \"\"}`,\n );\n ctx.emitEvent(session.id, \"tool_running\", {\n session,\n ...info,\n source: \"pty_manager\",\n });\n },\n );\n\n nodeManager.on(\n \"session_stopped\",\n async (session: SessionHandle, reason: string) => {\n const stoppedCleanly =\n (session as { exitCode?: number }).exitCode === 0 ||\n /exit code 0/i.test(reason);\n if (\n session.type === \"codex\" &&\n ctx.sessionMetadata.get(session.id)?.codexExecMode === true &&\n stoppedCleanly\n ) {\n const response = await captureFastPathTaskResponse(ctx, session.id);\n const durationMs = session.startedAt\n ? Date.now() - new Date(session.startedAt).getTime()\n : 0;\n ctx.metricsTracker.recordCompletion(\"codex\", \"fast-path\", durationMs);\n ctx.log(\n `Task complete for ${session.id} (codex exec stopped), response: ${response.length} chars`,\n );\n ctx.emitEvent(session.id, \"task_complete\", {\n session,\n response,\n source: \"adapter_fast_path\",\n });\n return;\n }\n ctx.emitEvent(session.id, \"stopped\", { reason, source: \"pty_manager\" });\n },\n );\n\n nodeManager.on(\"session_error\", (session: SessionHandle, error: string) => {\n ctx.emitEvent(session.id, \"error\", {\n message: error,\n source: \"pty_manager\",\n });\n });\n\n nodeManager.on(\"message\", (message: SessionMessage) => {\n ctx.emitEvent(message.sessionId, \"message\", {\n ...message,\n source: \"pty_manager\",\n });\n });\n\n return { manager: nodeManager, usingBunWorker: false };\n}\n",
|
|
14
|
+
"/**\n * Session I/O helpers — extracted from PTYService for maintainability.\n *\n * Standalone functions for sending input/keys to sessions and stopping\n * sessions. Each function takes a {@link SessionIOContext} that provides\n * the manager instance and shared state maps.\n *\n * @module services/pty-session-io\n */\n\nimport { readFile, rm, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport type {\n BunCompatiblePTYManager,\n PTYManager,\n SessionMessage,\n} from \"pty-manager\";\n\n/**\n * Shared context required by all session I/O functions.\n * Built inline from PTYService instance fields.\n */\nexport interface SessionIOContext {\n manager: PTYManager | BunCompatiblePTYManager;\n usingBunWorker: boolean;\n sessionOutputBuffers: Map<string, string[]>;\n taskResponseMarkers: Map<string, number>;\n outputUnsubscribers: Map<string, () => void>;\n}\n\n/**\n * Send text input to a session.\n *\n * Marks the buffer position for task response capture, then writes the\n * input via the appropriate manager API.\n */\nexport async function sendToSession(\n ctx: SessionIOContext,\n sessionId: string,\n input: string,\n): Promise<SessionMessage | undefined> {\n const session = ctx.manager.get(sessionId);\n if (!session) {\n throw new Error(`Session ${sessionId} not found`);\n }\n\n // Mark buffer position for task response capture\n const buffer = ctx.sessionOutputBuffers.get(sessionId);\n if (buffer) {\n ctx.taskResponseMarkers.set(sessionId, buffer.length);\n }\n\n if (ctx.usingBunWorker) {\n // BunCompatiblePTYManager.send returns void\n await (ctx.manager as BunCompatiblePTYManager).send(sessionId, input);\n return;\n } else {\n // PTYManager.send returns SessionMessage\n return (ctx.manager as PTYManager).send(sessionId, input);\n }\n}\n\n/**\n * Send key sequences to a session (for special keys like arrows, enter, etc.).\n */\nexport async function sendKeysToSession(\n ctx: SessionIOContext,\n sessionId: string,\n keys: string | string[],\n): Promise<void> {\n if (ctx.usingBunWorker) {\n await (ctx.manager as BunCompatiblePTYManager).sendKeys(sessionId, keys);\n } else {\n const ptySession = (ctx.manager as PTYManager).getSession(sessionId);\n if (!ptySession) {\n throw new Error(`Session ${sessionId} not found`);\n }\n ptySession.sendKeys(keys);\n }\n}\n\n/**\n * Stop a PTY session and clean up all associated state.\n *\n * @param force - When true, sends SIGKILL immediately instead of SIGTERM.\n * Use for sessions whose task is already complete — there's nothing to save.\n */\nexport async function stopSession(\n ctx: SessionIOContext,\n sessionId: string,\n sessionMetadata: Map<string, Record<string, unknown>>,\n sessionWorkdirs: Map<string, string>,\n log: (msg: string) => void,\n force = false,\n): Promise<void> {\n try {\n const session = ctx.manager.get(sessionId);\n if (!session) {\n throw new Error(`Session ${sessionId} not found`);\n }\n\n if (ctx.usingBunWorker) {\n if (force) {\n await (ctx.manager as BunCompatiblePTYManager).kill(\n sessionId,\n \"SIGKILL\",\n );\n } else {\n await (ctx.manager as BunCompatiblePTYManager).kill(sessionId);\n }\n } else {\n if (force) {\n await (ctx.manager as PTYManager).stop(sessionId, { force: true });\n } else {\n await (ctx.manager as PTYManager).stop(sessionId);\n }\n }\n } finally {\n // Clean up state even if the kill/stop call throws or the session was\n // already gone — prevents leaked subscribers and stale metadata.\n try {\n const unsubscribe = ctx.outputUnsubscribers.get(sessionId);\n if (unsubscribe) {\n unsubscribe();\n }\n } catch {\n // Ignore — unsubscribe may fail on a destroyed session\n }\n ctx.outputUnsubscribers.delete(sessionId);\n\n // Remove injected hooks from agent settings so they don't\n // leak to other CLI instances using the same workdir.\n const workdir = sessionWorkdirs.get(sessionId);\n if (workdir) {\n try {\n await cleanupAgentHooks(workdir, log);\n } catch {\n // Best-effort — don't block shutdown\n }\n }\n\n const metadata = sessionMetadata.get(sessionId);\n const codexExecOutputDir = metadata?.codexExecOutputDir;\n if (typeof codexExecOutputDir === \"string\") {\n try {\n await rm(codexExecOutputDir, { recursive: true, force: true });\n } catch (err) {\n log(\n `Failed to remove Codex exec output dir ${codexExecOutputDir}: ${err}`,\n );\n }\n }\n\n sessionMetadata.delete(sessionId);\n sessionWorkdirs.delete(sessionId);\n ctx.sessionOutputBuffers.delete(sessionId);\n ctx.taskResponseMarkers.delete(sessionId);\n log(`Stopped session ${sessionId}`);\n }\n}\n\n/**\n * Remove injected hooks from a workspace's agent settings files.\n * Cleans both .claude/settings.json and .gemini/settings.json.\n * Best-effort — errors are logged but not thrown.\n */\nasync function cleanupAgentHooks(\n workdir: string,\n log: (msg: string) => void,\n): Promise<void> {\n const settingsPaths = [\n join(workdir, \".claude\", \"settings.json\"),\n join(workdir, \".gemini\", \"settings.json\"),\n ];\n for (const settingsPath of settingsPaths) {\n try {\n const raw = await readFile(settingsPath, \"utf-8\");\n const settings = JSON.parse(raw) as Record<string, unknown>;\n if (!settings.hooks) continue;\n delete settings.hooks;\n await writeFile(settingsPath, JSON.stringify(settings, null, 2), \"utf-8\");\n log(`Cleaned up hooks from ${settingsPath}`);\n } catch (err: unknown) {\n // ENOENT (file doesn't exist) is expected — silently ignore.\n // Other errors (parse failure, permission denied) are logged.\n const code = (err as { code?: string }).code;\n if (code !== \"ENOENT\") {\n log(`Failed to clean up hooks from ${settingsPath}: ${err}`);\n }\n }\n }\n}\n\n/**\n * Subscribe to live output from a session.\n * Returns an unsubscribe function.\n */\nexport function subscribeToOutput(\n ctx: SessionIOContext,\n sessionId: string,\n callback: (data: string) => void,\n): () => void {\n if (ctx.usingBunWorker) {\n const unsubscribe = (ctx.manager as BunCompatiblePTYManager).onSessionData(\n sessionId,\n callback,\n );\n ctx.outputUnsubscribers.set(sessionId, unsubscribe);\n return unsubscribe;\n }\n const ptySession = (ctx.manager as PTYManager).getSession(sessionId);\n if (!ptySession) {\n throw new Error(`Session ${sessionId} not found`);\n }\n ptySession.on(\"output\", callback);\n const unsubscribe = () => ptySession.off(\"output\", callback);\n ctx.outputUnsubscribers.set(sessionId, unsubscribe);\n return unsubscribe;\n}\n\n/**\n * Get buffered or logged output from a session.\n */\nexport async function getSessionOutput(\n ctx: SessionIOContext,\n sessionId: string,\n lines?: number,\n): Promise<string> {\n if (ctx.usingBunWorker) {\n const buffer = ctx.sessionOutputBuffers.get(sessionId);\n if (!buffer) return \"\";\n const tail = lines ?? buffer.length;\n return buffer.slice(-tail).join(\"\\n\");\n }\n\n const output: string[] = [];\n for await (const line of (ctx.manager as PTYManager).logs(sessionId, {\n tail: lines,\n })) {\n output.push(line);\n }\n return output.join(\"\\n\");\n}\n",
|
|
15
|
+
"/**\n * Task-agent framework discovery and preference resolution.\n *\n * Detects installed CLIs, available auth, and Eliza subscription preferences so\n * the orchestrator can choose the best framework when the caller does not\n * specify one explicitly.\n *\n * @module services/task-agent-frameworks\n */\n\nimport { execFileSync } from \"node:child_process\";\nimport fs from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport {\n getElizaNamespace,\n type IAgentRuntime,\n resolveStateDir,\n resolveUserPath,\n} from \"@elizaos/core\";\nimport type { PreflightResult } from \"coding-agent-adapters\";\nimport type { AgentMetrics } from \"./agent-metrics.js\";\nimport {\n readConfigCloudKey,\n readConfigCodexSubscriptionRestrictedToCodexFramework,\n readConfigEnvKey,\n} from \"./config-env.js\";\n\nexport type SupportedTaskAgentAdapter = \"claude\" | \"codex\" | \"gemini\" | \"aider\";\nexport type TaskAgentFrameworkId =\n | SupportedTaskAgentAdapter\n | \"pi\"\n | \"opencode\";\n\nexport interface TaskAgentModelPrefs {\n powerful?: string;\n fast?: string;\n}\n\nexport interface TaskAgentFrameworkAvailability {\n id: TaskAgentFrameworkId;\n label: string;\n installed: boolean;\n authReady: boolean;\n subscriptionReady: boolean;\n temporarilyDisabled: boolean;\n temporarilyDisabledUntil?: number;\n temporarilyDisabledReason?: string;\n recommended: boolean;\n reason: string;\n installCommand?: string;\n docsUrl?: string;\n selectionScore?: number;\n selectionSignals?: Record<string, number>;\n}\n\nexport interface PreferredTaskAgent {\n id: TaskAgentFrameworkId;\n reason: string;\n}\n\nexport interface TaskAgentFrameworkState {\n configuredSubscriptionProvider?: string;\n frameworks: TaskAgentFrameworkAvailability[];\n preferred: PreferredTaskAgent;\n}\n\nexport interface TaskAgentFrameworkProbe {\n checkAvailableAgents?: (\n types?: SupportedTaskAgentAdapter[],\n ) => Promise<PreflightResult[]>;\n getAgentMetrics?: () => Record<\n string,\n Omit<AgentMetrics, \"totalCompletionMs\">\n >;\n}\n\nexport type TaskAgentTaskKind =\n | \"coding\"\n | \"research\"\n | \"planning\"\n | \"ops\"\n | \"mixed\";\n\nexport interface TaskAgentTaskProfileInput {\n task?: string;\n repo?: string;\n workdir?: string;\n threadKind?: TaskAgentTaskKind;\n subtaskCount?: number;\n acceptanceCriteria?: string[];\n}\n\nexport interface TaskAgentTaskProfile {\n text: string;\n kind: TaskAgentTaskKind;\n subtaskCount: number;\n repoPresent: boolean;\n signals: {\n implementation: number;\n research: number;\n planning: number;\n ops: number;\n verification: number;\n coordination: number;\n repoWork: number;\n fastIteration: number;\n };\n}\n\ninterface FrameworkCapabilityProfile {\n implementation: number;\n research: number;\n planning: number;\n ops: number;\n verification: number;\n coordination: number;\n repoWork: number;\n fastIteration: number;\n}\n\nconst RESEARCH_SIGNAL_RE =\n /\\b(research|investigate|analy[sz]e|analysis|compare|evaluate|review|study|summari[sz]e|deep research|look into|explore)\\b/i;\nconst PLANNING_SIGNAL_RE =\n /\\b(plan|planning|roadmap|strategy|spec|architecture|design|scope|milestone|sequence|timeline)\\b/i;\nconst OPS_SIGNAL_RE =\n /\\b(deploy|release|ship|rollback|monitor|incident|infra|infrastructure|configure|setup|docker|kubernetes|ci|cd|runbook)\\b/i;\nconst IMPLEMENTATION_SIGNAL_RE =\n /\\b(code|coding|implement|fix|debug|refactor|write|build|patch|feature|server|api|component|function|typescrip?t|javascript|react)\\b/i;\nconst VERIFICATION_SIGNAL_RE =\n /\\b(test|tests|verify|validation|prove|acceptance|check|regression|benchmark|lint|typecheck|qa)\\b/i;\nconst COORDINATION_SIGNAL_RE =\n /\\b(parallel|delegate|subagent|sub-agent|swarm|coordinate|coordination|handoff|mailbox|scheduler|orchestrate)\\b/i;\nconst REPO_SIGNAL_RE =\n /\\b(repo|repository|branch|commit|pull request|pr|diff|workspace|file|directory|codebase)\\b/i;\nconst FAST_ITERATION_SIGNAL_RE =\n /\\b(fix|debug|patch|flaky|quick|fast|iterate|loop|unblock|repair)\\b/i;\n\nconst FRAMEWORK_CAPABILITY_PROFILES: Record<\n TaskAgentFrameworkId,\n FrameworkCapabilityProfile\n> = {\n claude: {\n implementation: 0.95,\n research: 0.95,\n planning: 1,\n ops: 0.8,\n verification: 0.85,\n coordination: 1,\n repoWork: 0.9,\n fastIteration: 0.75,\n },\n codex: {\n implementation: 1,\n research: 0.8,\n planning: 0.75,\n ops: 0.85,\n verification: 1,\n coordination: 0.9,\n repoWork: 1,\n fastIteration: 0.95,\n },\n gemini: {\n implementation: 0.7,\n research: 1,\n planning: 0.95,\n ops: 0.7,\n verification: 0.6,\n coordination: 0.7,\n repoWork: 0.65,\n fastIteration: 0.7,\n },\n aider: {\n implementation: 0.9,\n research: 0.45,\n planning: 0.45,\n ops: 0.75,\n verification: 0.85,\n coordination: 0.35,\n repoWork: 0.95,\n fastIteration: 1,\n },\n pi: {\n implementation: 0.55,\n research: 0.5,\n planning: 0.55,\n ops: 0.5,\n verification: 0.5,\n coordination: 0.35,\n repoWork: 0.5,\n fastIteration: 0.5,\n },\n opencode: {\n implementation: 0.85,\n research: 0.75,\n planning: 0.75,\n ops: 0.7,\n verification: 0.8,\n coordination: 0.7,\n repoWork: 0.85,\n fastIteration: 0.85,\n },\n};\n\nconst FRAMEWORK_LABELS: Record<TaskAgentFrameworkId, string> = {\n claude: \"Claude Code\",\n codex: \"Codex\",\n gemini: \"Gemini CLI\",\n aider: \"Aider\",\n pi: \"Pi\",\n opencode: \"OpenCode\",\n};\n\nconst STANDARD_FRAMEWORKS: SupportedTaskAgentAdapter[] = [\n \"claude\",\n \"codex\",\n \"gemini\",\n \"aider\",\n];\n\nconst DEFAULT_FRAMEWORK_PREFLIGHT_TIMEOUT_MS = 5_000;\n\nfunction resolveFrameworkPreflightTimeoutMs(): number {\n const raw = process.env.PARALLAX_FRAMEWORK_PREFLIGHT_TIMEOUT_MS?.trim();\n if (!raw) return DEFAULT_FRAMEWORK_PREFLIGHT_TIMEOUT_MS;\n const parsed = Number.parseInt(raw, 10);\n return Number.isFinite(parsed) && parsed >= 250\n ? parsed\n : DEFAULT_FRAMEWORK_PREFLIGHT_TIMEOUT_MS;\n}\n\nasync function withTimeout<T>(\n promise: Promise<T>,\n timeoutMs: number,\n label: string,\n): Promise<T> {\n let timeout: ReturnType<typeof setTimeout> | undefined;\n try {\n return await Promise.race([\n promise,\n new Promise<never>((_, reject) => {\n timeout = setTimeout(() => {\n reject(new Error(`${label} timed out after ${timeoutMs}ms`));\n }, timeoutMs);\n }),\n ]);\n } finally {\n if (timeout) clearTimeout(timeout);\n }\n}\n\nconst TASK_AGENT_MODEL_PREF_SETTING_KEYS: Record<\n SupportedTaskAgentAdapter | \"opencode\",\n { powerful: string; fast: string }\n> = {\n claude: {\n powerful: \"PARALLAX_CLAUDE_MODEL_POWERFUL\",\n fast: \"PARALLAX_CLAUDE_MODEL_FAST\",\n },\n codex: {\n powerful: \"PARALLAX_CODEX_MODEL_POWERFUL\",\n fast: \"PARALLAX_CODEX_MODEL_FAST\",\n },\n gemini: {\n powerful: \"PARALLAX_GEMINI_MODEL_POWERFUL\",\n fast: \"PARALLAX_GEMINI_MODEL_FAST\",\n },\n aider: {\n powerful: \"PARALLAX_AIDER_MODEL_POWERFUL\",\n fast: \"PARALLAX_AIDER_MODEL_FAST\",\n },\n opencode: {\n powerful: \"PARALLAX_OPENCODE_MODEL_POWERFUL\",\n fast: \"PARALLAX_OPENCODE_MODEL_FAST\",\n },\n};\n\nexport const TASK_AGENT_DEFAULT_MODEL_PREFS: Record<\n SupportedTaskAgentAdapter | \"opencode\",\n TaskAgentModelPrefs\n> = {\n claude: { powerful: \"claude-opus-4-7\" },\n codex: { powerful: \"gpt-5.5\", fast: \"gpt-5.4-mini\" },\n gemini: {},\n aider: {},\n opencode: {},\n};\n\nconst TASK_AGENT_COMPLEXITY_RE =\n /\\b(repo|repository|code|coding|debug|fix|implement|investigate|research|analyze|analysis|summarize|summary|write|draft|document|plan|workflow|automation|parallel|delegate|subtask|agent|orchestrate|coordinate|compare|test|tests|pull request|pr\\b|branch|commit)\\b/i;\n\nlet frameworkStateCache:\n | {\n expiresAt: number;\n value: {\n configuredSubscriptionProvider?: string;\n frameworks: TaskAgentFrameworkAvailability[];\n };\n }\n | undefined;\nconst frameworkCooldowns = new Map<\n SupportedTaskAgentAdapter,\n { until: number; reason: string }\n>();\nconst TASK_AGENT_USAGE_EXHAUSTED_RE =\n /\\b(insufficient(?:[_\\s]+(?:credits?|quota))|insufficient_quota|out of credits|credit balance|usage (?:has )?(?:reached|exceeded)|(?:you(?:'ve| have)? hit your usage limits?)|usage[-\\s]?limits?|quota exceeded|payment required|status(?:code)?[:\\s]*402)\\b/i;\n\nfunction normalizePreflightAdapterId(\n value: string | undefined,\n): SupportedTaskAgentAdapter | null {\n const normalized = value?.trim().toLowerCase();\n switch (normalized) {\n case \"claude\":\n case \"claude code\":\n return \"claude\";\n case \"codex\":\n case \"openai codex\":\n return \"codex\";\n case \"gemini\":\n case \"gemini cli\":\n return \"gemini\";\n case \"aider\":\n return \"aider\";\n default:\n return null;\n }\n}\n\nfunction safeGetSetting(\n runtime: IAgentRuntime | undefined,\n key: string,\n): string | undefined {\n // Check the config file first (UI writes here, takes effect without restart),\n // then fall back to runtime/character settings.\n try {\n const fromConfig = readConfigEnvKey(key);\n if (fromConfig?.trim()) return fromConfig.trim();\n } catch {\n // ignore — fall through to runtime\n }\n if (!runtime) return undefined;\n try {\n const value = runtime.getSetting(key);\n return typeof value === \"string\" && value.trim() ? value.trim() : undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction trimModelPref(value: unknown): string | undefined {\n return typeof value === \"string\" && value.trim() ? value.trim() : undefined;\n}\n\nexport function readTaskAgentModelPrefs(\n value: unknown,\n): TaskAgentModelPrefs | undefined {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) {\n return undefined;\n }\n const record = value as Record<string, unknown>;\n return compactTaskAgentModelPrefs({\n powerful: trimModelPref(record.powerful),\n fast: trimModelPref(record.fast),\n });\n}\n\nfunction compactTaskAgentModelPrefs(\n prefs: TaskAgentModelPrefs | undefined,\n): TaskAgentModelPrefs | undefined {\n const powerful = trimModelPref(prefs?.powerful);\n const fast = trimModelPref(prefs?.fast);\n if (!powerful && !fast) return undefined;\n return {\n ...(powerful ? { powerful } : {}),\n ...(fast ? { fast } : {}),\n };\n}\n\nexport function mergeTaskAgentModelPrefs(\n ...prefs: Array<TaskAgentModelPrefs | undefined>\n): TaskAgentModelPrefs | undefined {\n let merged: TaskAgentModelPrefs | undefined;\n for (const pref of prefs) {\n const compact = compactTaskAgentModelPrefs(pref);\n if (!compact) continue;\n merged = { ...merged, ...compact };\n }\n return compactTaskAgentModelPrefs(merged);\n}\n\nfunction normalizeTaskAgentAdapterForModelPrefs(\n agentType: string | undefined,\n): SupportedTaskAgentAdapter | \"opencode\" | undefined {\n const normalized = agentType?.trim().toLowerCase();\n switch (normalized) {\n case \"claude\":\n case \"claude-code\":\n case \"claude code\":\n return \"claude\";\n case \"codex\":\n case \"openai\":\n case \"openai-codex\":\n case \"openai codex\":\n return \"codex\";\n case \"opencode\":\n case \"open-code\":\n case \"open code\":\n return \"opencode\";\n case \"gemini\":\n case \"google\":\n case \"gemini-cli\":\n case \"gemini cli\":\n return \"gemini\";\n case \"aider\":\n return \"aider\";\n default:\n return undefined;\n }\n}\n\nexport function getTaskAgentModelPrefs(\n runtime: IAgentRuntime | undefined,\n agentType: string | undefined,\n spawnPrefs?: TaskAgentModelPrefs,\n): TaskAgentModelPrefs | undefined {\n const adapter = normalizeTaskAgentAdapterForModelPrefs(agentType);\n if (!adapter) return undefined;\n\n const keys = TASK_AGENT_MODEL_PREF_SETTING_KEYS[adapter];\n const runtimePrefs = compactTaskAgentModelPrefs({\n powerful: safeGetSetting(runtime, keys.powerful),\n fast: safeGetSetting(runtime, keys.fast),\n });\n\n return mergeTaskAgentModelPrefs(\n TASK_AGENT_DEFAULT_MODEL_PREFS[adapter],\n spawnPrefs,\n runtimePrefs,\n );\n}\n\nfunction getPreflightAuthStatus(\n result: PreflightResult | undefined,\n): \"authenticated\" | \"unauthenticated\" | \"unknown\" {\n const auth = (result as PreflightResult & { auth?: { status?: unknown } })\n ?.auth;\n const status = typeof auth?.status === \"string\" ? auth.status : \"\";\n if (status === \"authenticated\" || status === \"unauthenticated\") {\n return status;\n }\n return \"unknown\";\n}\n\nfunction getUserHomeDir(): string {\n return (\n process.env.HOME?.trim() || process.env.USERPROFILE?.trim() || os.homedir()\n );\n}\n\nfunction readJsonFile(filePath: string): unknown {\n try {\n return JSON.parse(fs.readFileSync(filePath, \"utf8\"));\n } catch {\n return null;\n }\n}\n\nfunction extractOauthAccessToken(value: unknown): string | undefined {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) return;\n const record = value as Record<string, unknown>;\n const direct = record.accessToken ?? record.access_token;\n if (typeof direct === \"string\" && direct.trim()) {\n return direct.trim();\n }\n for (const nested of Object.values(record)) {\n const token = extractOauthAccessToken(nested);\n if (token) return token;\n }\n return;\n}\n\nfunction resolveElizaConfigPath(): string {\n const explicit = process.env.ELIZA_CONFIG_PATH?.trim();\n if (explicit) return resolveUserPath(explicit);\n\n const namespace = getElizaNamespace();\n const filename = namespace === \"eliza\" ? \"eliza.json\" : `${namespace}.json`;\n return path.join(resolveStateDir(), filename);\n}\n\nfunction readConfiguredSubscriptionProvider(): string | undefined {\n const config = readJsonFile(resolveElizaConfigPath());\n if (!config || typeof config !== \"object\" || Array.isArray(config)) return;\n const agents = (config as Record<string, unknown>).agents;\n if (!agents || typeof agents !== \"object\" || Array.isArray(agents)) return;\n const defaults = (agents as Record<string, unknown>).defaults;\n if (!defaults || typeof defaults !== \"object\" || Array.isArray(defaults))\n return;\n const provider = (defaults as Record<string, unknown>).subscriptionProvider;\n return typeof provider === \"string\" && provider.trim()\n ? provider.trim()\n : undefined;\n}\n\nfunction hasClaudeSubscriptionAuth(): boolean {\n const credentialsPath = path.join(\n getUserHomeDir(),\n \".claude\",\n \".credentials.json\",\n );\n const fileToken = extractOauthAccessToken(readJsonFile(credentialsPath));\n if (fileToken) return true;\n\n if (process.platform !== \"darwin\") return false;\n try {\n const raw = execFileSync(\n \"security\",\n [\"find-generic-password\", \"-s\", \"Claude Code-credentials\", \"-w\"],\n { encoding: \"utf8\", timeout: 3000, stdio: [\"ignore\", \"pipe\", \"ignore\"] },\n ).trim();\n if (!raw) return false;\n return Boolean(extractOauthAccessToken(JSON.parse(raw)));\n } catch {\n return false;\n }\n}\n\nfunction hasClaudeApiKey(runtime?: IAgentRuntime): boolean {\n return Boolean(\n process.env.ANTHROPIC_API_KEY?.trim() ||\n safeGetSetting(runtime, \"ANTHROPIC_API_KEY\"),\n );\n}\n\nfunction hasCodexSubscriptionAuth(): boolean {\n const authPath = path.join(getUserHomeDir(), \".codex\", \"auth.json\");\n const auth = readJsonFile(authPath);\n if (!auth || typeof auth !== \"object\" || Array.isArray(auth)) return false;\n const key = (auth as Record<string, unknown>).OPENAI_API_KEY;\n return typeof key === \"string\" && key.trim().length > 0;\n}\n\nfunction hasCodexApiKey(runtime?: IAgentRuntime): boolean {\n return Boolean(\n process.env.OPENAI_API_KEY?.trim() ||\n safeGetSetting(runtime, \"OPENAI_API_KEY\"),\n );\n}\n\nfunction hasGeminiCredential(runtime?: IAgentRuntime): boolean {\n return Boolean(\n process.env.GOOGLE_GENERATIVE_AI_API_KEY?.trim() ||\n process.env.GOOGLE_API_KEY?.trim() ||\n safeGetSetting(runtime, \"GOOGLE_GENERATIVE_AI_API_KEY\") ||\n safeGetSetting(runtime, \"GOOGLE_API_KEY\"),\n );\n}\n\n/**\n * Check whether eliza has a paired Eliza Cloud API key. Used to mark\n * Anthropic/OpenAI-backed task agents as auth-ready when LLM provider is\n * \"cloud\" — they'll route through the cloud proxy at spawn time.\n */\nfunction hasElizaCloudApiKey(): boolean {\n return Boolean(readConfigCloudKey(\"apiKey\"));\n}\n\nfunction hasPiBinary(): boolean {\n return hasBinaryOnPath(\"pi\");\n}\n\nfunction hasOpencodeBinary(): boolean {\n return hasBinaryOnPath(\"opencode\");\n}\n\nfunction isOpencodeLocalMode(): boolean {\n const flag = readConfigEnvKey(\"PARALLAX_OPENCODE_LOCAL\");\n return flag === \"1\" || flag?.toLowerCase() === \"true\";\n}\n\nfunction hasBinaryOnPath(binaryName: string): boolean {\n const command = process.platform === \"win32\" ? \"where\" : \"which\";\n const args = [binaryName];\n try {\n execFileSync(command, args, {\n encoding: \"utf8\",\n timeout: 1500,\n stdio: [\"ignore\", \"pipe\", \"ignore\"],\n });\n return true;\n } catch {\n return false;\n }\n}\n\nfunction hasFrameworkBinary(id: SupportedTaskAgentAdapter): boolean {\n switch (id) {\n case \"claude\":\n return hasBinaryOnPath(\"claude\");\n case \"codex\":\n return hasBinaryOnPath(\"codex\");\n case \"gemini\":\n return hasBinaryOnPath(\"gemini\");\n case \"aider\":\n return hasBinaryOnPath(\"aider\");\n }\n}\n\nfunction getFrameworkCooldown(\n id: SupportedTaskAgentAdapter,\n): { until: number; reason: string } | undefined {\n const cooldown = frameworkCooldowns.get(id);\n if (!cooldown) return undefined;\n if (cooldown.until <= Date.now()) {\n frameworkCooldowns.delete(id);\n return undefined;\n }\n return cooldown;\n}\n\nasync function computeTaskAgentFrameworkState(\n runtime: IAgentRuntime,\n probe?: TaskAgentFrameworkProbe,\n profileInput?: TaskAgentTaskProfileInput,\n): Promise<TaskAgentFrameworkState> {\n const configuredSubscriptionProvider = readConfiguredSubscriptionProvider();\n const preflightByAdapter = new Map<\n SupportedTaskAgentAdapter,\n PreflightResult\n >();\n\n if (probe?.checkAvailableAgents) {\n try {\n const results = await withTimeout(\n probe.checkAvailableAgents(STANDARD_FRAMEWORKS),\n resolveFrameworkPreflightTimeoutMs(),\n \"task-agent framework preflight\",\n );\n // checkAdapters returns `adapter` as the human-readable display name\n // (e.g. \"Claude Code\", \"OpenAI Codex\"), not the lowercase ID. Map back\n // to the canonical framework ID via case-insensitive substring match.\n for (const result of results) {\n const adapterId = normalizePreflightAdapterId(result.adapter);\n if (adapterId) {\n preflightByAdapter.set(adapterId, result);\n }\n }\n } catch {\n // Keep status surfaces alive even if preflight fails transiently.\n }\n }\n\n // When the user has selected Eliza Cloud as the LLM provider and has a\n // paired cloud.apiKey, treat Claude/Codex/Aider as fully auth-ready —\n // they'll route through the cloud proxy at spawn time.\n const llmProvider =\n readConfigEnvKey(\"PARALLAX_LLM_PROVIDER\") || \"subscription\";\n const cloudReady = llmProvider === \"cloud\" && hasElizaCloudApiKey();\n\n const claudePreflightAuth = getPreflightAuthStatus(\n preflightByAdapter.get(\"claude\"),\n );\n const codexPreflightAuth = getPreflightAuthStatus(\n preflightByAdapter.get(\"codex\"),\n );\n const geminiPreflightAuth = getPreflightAuthStatus(\n preflightByAdapter.get(\"gemini\"),\n );\n const aiderPreflightAuth = getPreflightAuthStatus(\n preflightByAdapter.get(\"aider\"),\n );\n\n // When the user opts in to restricting the Codex subscription to the codex\n // framework only, non-codex frameworks must not treat Codex sub availability\n // as contributing to `subscriptionReady` or `authReady` (so scoring and\n // fallback logic skip the Codex-sub path). Claude subscription tokens are\n // already restricted upstream to the claude CLI, so no gate is needed there.\n const codexSubRestrictedToCodexFramework =\n readConfigCodexSubscriptionRestrictedToCodexFramework();\n\n const claudeSubscriptionReady =\n claudePreflightAuth === \"authenticated\" || hasClaudeSubscriptionAuth();\n const claudeAuthReady =\n cloudReady || claudeSubscriptionReady || hasClaudeApiKey(runtime);\n const codexSubscriptionReady =\n codexPreflightAuth === \"authenticated\" || hasCodexSubscriptionAuth();\n const codexAuthReady =\n cloudReady || codexSubscriptionReady || hasCodexApiKey(runtime);\n // When the flag is set, drop Codex sub from aider's fallback chain — aider\n // must use its own API key (claude/gemini subs are already restricted or\n // non-existent for aider's path, and the Codex API key path still works).\n const codexAuthReadyForNonCodex = codexSubRestrictedToCodexFramework\n ? cloudReady || hasCodexApiKey(runtime)\n : codexAuthReady;\n // Eliza Cloud doesn't proxy Gemini, so cloud mode does NOT make Gemini auth-ready\n const geminiAuthReady =\n geminiPreflightAuth === \"authenticated\" || hasGeminiCredential(runtime);\n const aiderAuthReady =\n cloudReady ||\n aiderPreflightAuth === \"authenticated\" ||\n claudeAuthReady ||\n codexAuthReadyForNonCodex ||\n geminiAuthReady;\n const piReady = hasPiBinary();\n\n const providerPrefersClaude =\n configuredSubscriptionProvider === \"anthropic-subscription\";\n const providerPrefersCodex =\n configuredSubscriptionProvider === \"openai-codex\" ||\n configuredSubscriptionProvider === \"openai-subscription\";\n const providerPrefersGemini =\n configuredSubscriptionProvider === \"gemini-cli\" ||\n configuredSubscriptionProvider === \"gemini-subscription\";\n\n const inventory: TaskAgentFrameworkAvailability[] = STANDARD_FRAMEWORKS.map(\n (id) => {\n const preflight = preflightByAdapter.get(id);\n const cooldown = getFrameworkCooldown(id);\n const installed = preflight?.installed === true || hasFrameworkBinary(id);\n const subscriptionReady =\n id === \"claude\"\n ? claudeSubscriptionReady\n : id === \"codex\"\n ? codexSubscriptionReady\n : id === \"gemini\"\n ? providerPrefersGemini && geminiPreflightAuth === \"authenticated\"\n : false;\n const authReady =\n id === \"claude\"\n ? claudeAuthReady\n : id === \"codex\"\n ? codexAuthReady\n : id === \"gemini\"\n ? geminiAuthReady\n : aiderAuthReady;\n const reason =\n id === \"claude\" && subscriptionReady\n ? \"ready to use the user's Claude subscription\"\n : id === \"codex\" && subscriptionReady\n ? \"ready to use the user's OpenAI subscription\"\n : id === \"gemini\" && subscriptionReady\n ? \"ready to use the user's Gemini CLI subscription\"\n : installed\n ? authReady\n ? \"installed with credentials available\"\n : \"installed but credentials were not detected\"\n : \"CLI not detected\";\n return {\n id,\n label: FRAMEWORK_LABELS[id],\n installed,\n authReady,\n subscriptionReady,\n temporarilyDisabled: Boolean(cooldown),\n temporarilyDisabledUntil: cooldown?.until,\n temporarilyDisabledReason: cooldown?.reason,\n recommended: false,\n reason: cooldown\n ? `${reason}; temporarily disabled after a provider failure: ${cooldown.reason}`\n : reason,\n installCommand: preflight?.installCommand,\n docsUrl: preflight?.docsUrl,\n };\n },\n );\n\n inventory.push({\n id: \"pi\",\n label: FRAMEWORK_LABELS.pi,\n installed: piReady,\n authReady: piReady,\n subscriptionReady: false,\n temporarilyDisabled: false,\n recommended: false,\n reason: piReady ? \"CLI detected\" : \"CLI not detected\",\n });\n\n const opencodeReady = hasOpencodeBinary();\n const opencodeLocalMode = isOpencodeLocalMode();\n const opencodeAuthReady =\n opencodeReady &&\n (cloudReady ||\n opencodeLocalMode ||\n Boolean(readConfigEnvKey(\"PARALLAX_OPENCODE_BASE_URL\")));\n const opencodeReason = !opencodeReady\n ? \"CLI not detected\"\n : opencodeAuthReady\n ? cloudReady\n ? \"ready to use Eliza Cloud as the model provider\"\n : opencodeLocalMode\n ? \"ready to use a local model provider (PARALLAX_OPENCODE_LOCAL)\"\n : \"ready to use the configured OpenCode provider\"\n : \"installed but no model provider is configured (set PARALLAX_OPENCODE_LOCAL=1 for local Ollama, pair Eliza Cloud, or set PARALLAX_OPENCODE_BASE_URL)\";\n inventory.push({\n id: \"opencode\",\n label: FRAMEWORK_LABELS.opencode,\n installed: opencodeReady,\n authReady: opencodeAuthReady,\n subscriptionReady: false,\n temporarilyDisabled: false,\n recommended: false,\n reason: opencodeReason,\n installCommand: \"curl -fsSL https://opencode.ai/install | bash\",\n docsUrl: \"https://opencode.ai/docs/\",\n });\n\n const frameworks = inventory.map((framework) => ({\n ...framework,\n recommended: false,\n }));\n const metrics = probe?.getAgentMetrics?.() ?? {};\n const profile = buildTaskAgentTaskProfile(profileInput);\n const explicitDefault = safeGetSetting(runtime, \"PARALLAX_DEFAULT_AGENT_TYPE\")\n ?.toLowerCase()\n .trim();\n const selectable = frameworks.filter(\n (framework) => framework.installed && !framework.temporarilyDisabled,\n );\n const candidates =\n selectable.length > 0\n ? selectable\n : frameworks.filter((framework) => framework.installed);\n\n const scoredCandidates = candidates.map((framework) => {\n const explicitOverride =\n explicitDefault === framework.id\n ? framework.installed && !framework.temporarilyDisabled\n ? 40\n : 0\n : 0;\n const providerPreference =\n providerPrefersClaude && framework.id === \"claude\"\n ? framework.subscriptionReady\n ? 18\n : 6\n : providerPrefersCodex && framework.id === \"codex\"\n ? framework.subscriptionReady\n ? 18\n : 6\n : providerPrefersGemini && framework.id === \"gemini\"\n ? framework.subscriptionReady\n ? 18\n : 6\n : 0;\n const availabilityScore =\n (framework.installed ? 40 : -100) +\n (framework.authReady ? 18 : -25) +\n (framework.subscriptionReady ? 8 : 0) +\n (framework.temporarilyDisabled ? -80 : 0);\n const profileScore = computeProfileFitScore(framework.id, profile);\n const metricsScore = computeMetricsScore(\n metrics[framework.id],\n profile.signals.fastIteration,\n );\n const selectionSignals = {\n availability: availabilityScore,\n profile: profileScore,\n provider: providerPreference,\n metrics: metricsScore,\n explicitOverride,\n };\n return {\n framework,\n score: Object.values(selectionSignals).reduce(\n (sum, value) => sum + value,\n 0,\n ),\n selectionSignals,\n };\n });\n\n const fallback =\n candidates[0] ??\n frameworks.find((framework) => framework.installed) ??\n frameworks[0];\n const preferredCandidate =\n scoredCandidates.sort((left, right) => {\n if (right.score !== left.score) {\n return right.score - left.score;\n }\n return left.framework.id.localeCompare(right.framework.id);\n })[0]?.framework ?? fallback;\n const preferredSignals =\n scoredCandidates.find(\n (entry) => entry.framework.id === preferredCandidate.id,\n )?.selectionSignals ?? {};\n const preferred: PreferredTaskAgent = {\n id: preferredCandidate.id,\n reason: buildPreferredReason(\n preferredCandidate,\n profile,\n preferredSignals,\n explicitDefault,\n configuredSubscriptionProvider,\n ),\n };\n\n for (const framework of frameworks) {\n framework.recommended = framework.id === preferred.id;\n const scored = scoredCandidates.find(\n (entry) => entry.framework.id === framework.id,\n );\n if (scored) {\n framework.selectionScore = scored.score;\n framework.selectionSignals = scored.selectionSignals;\n }\n }\n\n return {\n configuredSubscriptionProvider,\n frameworks,\n preferred,\n };\n}\n\nexport async function getTaskAgentFrameworkState(\n runtime: IAgentRuntime,\n probe?: TaskAgentFrameworkProbe,\n profileInput?: TaskAgentTaskProfileInput,\n): Promise<TaskAgentFrameworkState> {\n if (frameworkStateCache && frameworkStateCache.expiresAt > Date.now()) {\n return computeTaskAgentFrameworkStateFromInventory(\n runtime,\n frameworkStateCache.value,\n probe,\n profileInput,\n );\n }\n const value = await computeTaskAgentFrameworkState(\n runtime,\n probe,\n profileInput,\n );\n if (!profileInput) {\n frameworkStateCache = {\n expiresAt: Date.now() + 15_000,\n value: {\n configuredSubscriptionProvider: value.configuredSubscriptionProvider,\n frameworks: value.frameworks.map((framework) => ({\n ...framework,\n recommended: false,\n selectionScore: undefined,\n selectionSignals: undefined,\n })),\n },\n };\n }\n return value;\n}\n\nfunction computeTaskAgentFrameworkStateFromInventory(\n runtime: IAgentRuntime,\n inventory: {\n configuredSubscriptionProvider?: string;\n frameworks: TaskAgentFrameworkAvailability[];\n },\n probe?: TaskAgentFrameworkProbe,\n profileInput?: TaskAgentTaskProfileInput,\n): TaskAgentFrameworkState {\n const clonedProbe = {\n ...probe,\n checkAvailableAgents: undefined,\n };\n frameworkStateCache = {\n expiresAt: Date.now() + 15_000,\n value: inventory,\n };\n return {\n ...computeTaskAgentFrameworkStateFromCachedInventory(\n runtime,\n inventory,\n clonedProbe,\n profileInput,\n ),\n };\n}\n\nfunction computeTaskAgentFrameworkStateFromCachedInventory(\n runtime: IAgentRuntime,\n inventory: {\n configuredSubscriptionProvider?: string;\n frameworks: TaskAgentFrameworkAvailability[];\n },\n probe?: TaskAgentFrameworkProbe,\n profileInput?: TaskAgentTaskProfileInput,\n): TaskAgentFrameworkState {\n const metrics = probe?.getAgentMetrics?.() ?? {};\n const frameworks = inventory.frameworks.map((framework) => ({\n ...framework,\n recommended: false,\n }));\n const profile = buildTaskAgentTaskProfile(profileInput);\n const configuredSubscriptionProvider =\n inventory.configuredSubscriptionProvider;\n const providerPrefersClaude =\n configuredSubscriptionProvider === \"anthropic-subscription\";\n const providerPrefersCodex =\n configuredSubscriptionProvider === \"openai-codex\" ||\n configuredSubscriptionProvider === \"openai-subscription\";\n const providerPrefersGemini =\n configuredSubscriptionProvider === \"gemini-cli\" ||\n configuredSubscriptionProvider === \"gemini-subscription\";\n const explicitDefault = safeGetSetting(runtime, \"PARALLAX_DEFAULT_AGENT_TYPE\")\n ?.toLowerCase()\n .trim();\n const candidates =\n frameworks.filter(\n (framework) => framework.installed && !framework.temporarilyDisabled,\n ).length > 0\n ? frameworks.filter(\n (framework) => framework.installed && !framework.temporarilyDisabled,\n )\n : frameworks.filter((framework) => framework.installed);\n const scoredCandidates = candidates.map((framework) => {\n const explicitOverride =\n explicitDefault === framework.id\n ? framework.installed && !framework.temporarilyDisabled\n ? 40\n : 0\n : 0;\n const providerPreference =\n providerPrefersClaude && framework.id === \"claude\"\n ? framework.subscriptionReady\n ? 18\n : 6\n : providerPrefersCodex && framework.id === \"codex\"\n ? framework.subscriptionReady\n ? 18\n : 6\n : providerPrefersGemini && framework.id === \"gemini\"\n ? framework.subscriptionReady\n ? 18\n : 6\n : 0;\n const availabilityScore =\n (framework.installed ? 40 : -100) +\n (framework.authReady ? 18 : -25) +\n (framework.subscriptionReady ? 8 : 0) +\n (framework.temporarilyDisabled ? -80 : 0);\n const profileScore = computeProfileFitScore(framework.id, profile);\n const metricsScore = computeMetricsScore(\n metrics[framework.id],\n profile.signals.fastIteration,\n );\n const selectionSignals = {\n availability: availabilityScore,\n profile: profileScore,\n provider: providerPreference,\n metrics: metricsScore,\n explicitOverride,\n };\n return {\n framework,\n score: Object.values(selectionSignals).reduce(\n (sum, value) => sum + value,\n 0,\n ),\n selectionSignals,\n };\n });\n const fallback =\n candidates[0] ??\n frameworks.find((framework) => framework.installed) ??\n frameworks[0];\n const preferredCandidate =\n scoredCandidates.sort((left, right) => {\n if (right.score !== left.score) {\n return right.score - left.score;\n }\n return left.framework.id.localeCompare(right.framework.id);\n })[0]?.framework ?? fallback;\n const preferredSignals =\n scoredCandidates.find(\n (entry) => entry.framework.id === preferredCandidate.id,\n )?.selectionSignals ?? {};\n const preferred = {\n id: preferredCandidate.id,\n reason: buildPreferredReason(\n preferredCandidate,\n profile,\n preferredSignals,\n explicitDefault,\n configuredSubscriptionProvider,\n ),\n };\n for (const framework of frameworks) {\n framework.recommended = framework.id === preferred.id;\n const scored = scoredCandidates.find(\n (entry) => entry.framework.id === framework.id,\n );\n if (scored) {\n framework.selectionScore = scored.score;\n framework.selectionSignals = scored.selectionSignals;\n }\n }\n frameworkStateCache = {\n expiresAt: Date.now() + 15_000,\n value: inventory,\n };\n return {\n configuredSubscriptionProvider,\n frameworks,\n preferred,\n };\n}\n\nfunction clampSignal(value: number): number {\n return Math.max(0, Math.min(1, value));\n}\n\nfunction kindBoost(kind: TaskAgentTaskKind, target: TaskAgentTaskKind): number {\n if (kind === \"mixed\") return 0.25;\n return kind === target ? 0.4 : 0;\n}\n\nexport function buildTaskAgentTaskProfile(\n input?: TaskAgentTaskProfileInput,\n): TaskAgentTaskProfile {\n const text = [\n input?.task?.trim(),\n input?.repo?.trim(),\n ...(input?.acceptanceCriteria ?? []).map((value) => value.trim()),\n ]\n .filter((value): value is string => Boolean(value))\n .join(\"\\n\");\n const inferredKind: TaskAgentTaskKind =\n input?.threadKind ??\n (OPS_SIGNAL_RE.test(text)\n ? \"ops\"\n : PLANNING_SIGNAL_RE.test(text)\n ? \"planning\"\n : RESEARCH_SIGNAL_RE.test(text) && !IMPLEMENTATION_SIGNAL_RE.test(text)\n ? \"research\"\n : IMPLEMENTATION_SIGNAL_RE.test(text)\n ? \"coding\"\n : RESEARCH_SIGNAL_RE.test(text)\n ? \"mixed\"\n : \"coding\");\n const repoPresent = Boolean(input?.repo?.trim() || input?.workdir?.trim());\n const subtaskCount = Math.max(1, input?.subtaskCount ?? 1);\n const signals = {\n implementation: clampSignal(\n (IMPLEMENTATION_SIGNAL_RE.test(text) ? 0.7 : 0.2) +\n (repoPresent ? 0.15 : 0) +\n kindBoost(inferredKind, \"coding\"),\n ),\n research: clampSignal(\n (RESEARCH_SIGNAL_RE.test(text) ? 0.7 : 0.1) +\n kindBoost(inferredKind, \"research\"),\n ),\n planning: clampSignal(\n (PLANNING_SIGNAL_RE.test(text) ? 0.75 : 0.1) +\n kindBoost(inferredKind, \"planning\"),\n ),\n ops: clampSignal(\n (OPS_SIGNAL_RE.test(text) ? 0.75 : 0.05) + kindBoost(inferredKind, \"ops\"),\n ),\n verification: clampSignal(\n (VERIFICATION_SIGNAL_RE.test(text) ? 0.8 : 0.15) +\n ((input?.acceptanceCriteria?.length ?? 0) > 0 ? 0.15 : 0),\n ),\n coordination: clampSignal(\n (COORDINATION_SIGNAL_RE.test(text) ? 0.7 : 0.05) +\n (subtaskCount > 1 ? 0.25 : 0),\n ),\n repoWork: clampSignal(\n (REPO_SIGNAL_RE.test(text) ? 0.7 : 0.1) + (repoPresent ? 0.25 : 0),\n ),\n fastIteration: clampSignal(\n (FAST_ITERATION_SIGNAL_RE.test(text) ? 0.75 : 0.15) +\n (inferredKind === \"coding\" ? 0.1 : 0),\n ),\n };\n return {\n text,\n kind: inferredKind,\n subtaskCount,\n repoPresent,\n signals,\n };\n}\n\nfunction computeProfileFitScore(\n frameworkId: TaskAgentFrameworkId,\n profile: TaskAgentTaskProfile,\n): number {\n const capability = FRAMEWORK_CAPABILITY_PROFILES[frameworkId];\n const weightedSum =\n profile.signals.implementation * capability.implementation * 18 +\n profile.signals.research * capability.research * 16 +\n profile.signals.planning * capability.planning * 14 +\n profile.signals.ops * capability.ops * 12 +\n profile.signals.verification * capability.verification * 14 +\n profile.signals.coordination * capability.coordination * 14 +\n profile.signals.repoWork * capability.repoWork * 10 +\n profile.signals.fastIteration * capability.fastIteration * 10;\n return Math.round(weightedSum);\n}\n\nfunction computeMetricsScore(\n metrics: Omit<AgentMetrics, \"totalCompletionMs\"> | undefined,\n fastIterationSignal: number,\n): number {\n if (!metrics || metrics.spawned === 0) {\n return 0;\n }\n const successRate =\n metrics.spawned > 0 ? metrics.completed / metrics.spawned : 0;\n const stallRate =\n metrics.spawned > 0 ? metrics.stallCount / metrics.spawned : 0;\n const durationBonus =\n metrics.completed > 0\n ? Math.max(\n -8,\n Math.min(\n 8,\n ((120_000 - metrics.avgCompletionMs) / 120_000) *\n (4 + fastIterationSignal * 4),\n ),\n )\n : 0;\n return Math.round(successRate * 14 - stallRate * 12 + durationBonus);\n}\n\nfunction buildPreferredReason(\n framework: TaskAgentFrameworkAvailability,\n profile: TaskAgentTaskProfile,\n selectionSignals: Record<string, number>,\n explicitDefault: string | undefined,\n configuredSubscriptionProvider: string | undefined,\n): string {\n const dominantSignals = Object.entries(profile.signals)\n .sort((left, right) => right[1] - left[1])\n .slice(0, 2)\n .map(([key]) => key);\n if (\n explicitDefault === framework.id &&\n selectionSignals.explicitOverride > 0\n ) {\n return `explicit PARALLAX_DEFAULT_AGENT_TYPE override, with ${FRAMEWORK_LABELS[framework.id]} still scoring well for ${dominantSignals.join(\" + \")} work`;\n }\n if (\n configuredSubscriptionProvider === \"anthropic-subscription\" &&\n framework.id === \"claude\" &&\n framework.subscriptionReady\n ) {\n return `best fit for ${dominantSignals.join(\" + \")} work while honoring the configured Claude subscription`;\n }\n if (\n (configuredSubscriptionProvider === \"openai-codex\" ||\n configuredSubscriptionProvider === \"openai-subscription\") &&\n framework.id === \"codex\" &&\n framework.subscriptionReady\n ) {\n return `best fit for ${dominantSignals.join(\" + \")} work while honoring the configured OpenAI subscription`;\n }\n if (\n (configuredSubscriptionProvider === \"gemini-cli\" ||\n configuredSubscriptionProvider === \"gemini-subscription\") &&\n framework.id === \"gemini\" &&\n framework.subscriptionReady\n ) {\n return `best fit for ${dominantSignals.join(\" + \")} work while honoring the configured Gemini CLI subscription`;\n }\n if (framework.subscriptionReady) {\n return `best overall score for ${dominantSignals.join(\" + \")} work with subscription-backed auth already available`;\n }\n if (framework.authReady) {\n return `best overall score for ${dominantSignals.join(\" + \")} work with credentials already available`;\n }\n return `selected as the highest-scoring installed framework for ${dominantSignals.join(\" + \")} work`;\n}\n\nexport function clearTaskAgentFrameworkStateCache(): void {\n frameworkStateCache = undefined;\n}\n\nexport function isUsageExhaustedTaskAgentError(text: string): boolean {\n return TASK_AGENT_USAGE_EXHAUSTED_RE.test(text);\n}\n\nexport function markTaskAgentFrameworkUnavailable(\n id: SupportedTaskAgentAdapter,\n reason: string,\n cooldownMs = 30 * 60 * 1000,\n): void {\n frameworkCooldowns.set(id, {\n until: Date.now() + cooldownMs,\n reason,\n });\n clearTaskAgentFrameworkStateCache();\n}\n\nexport function markTaskAgentFrameworkHealthy(\n id: SupportedTaskAgentAdapter,\n): void {\n if (frameworkCooldowns.delete(id)) {\n clearTaskAgentFrameworkStateCache();\n }\n}\n\nexport function formatTaskAgentFrameworkLine(\n framework: TaskAgentFrameworkAvailability,\n): string {\n const parts = [\n framework.installed ? \"installed\" : \"not installed\",\n framework.authReady ? \"credentials ready\" : \"credentials missing\",\n ];\n if (framework.subscriptionReady) {\n parts.push(\"uses the user's subscription\");\n }\n if (framework.temporarilyDisabled) {\n parts.push(\"temporarily disabled\");\n }\n if (framework.recommended) {\n parts.push(\"recommended\");\n }\n return `- ${framework.label}: ${parts.join(\", \")}. ${framework.reason}.`;\n}\n\nexport function looksLikeTaskAgentRequest(text: string): boolean {\n return TASK_AGENT_COMPLEXITY_RE.test(text);\n}\n\nexport function formatTaskAgentStatus(status: string): string {\n switch (status) {\n case \"ready\":\n return \"idle\";\n case \"busy\":\n return \"working\";\n case \"starting\":\n return \"starting\";\n case \"authenticating\":\n return \"authenticating\";\n default:\n return status;\n }\n}\n\nexport function truncateTaskAgentText(text: string, max = 120): string {\n const trimmed = text.trim().replace(/\\s+/g, \" \");\n return trimmed.length > max ? `${trimmed.slice(0, max - 1)}...` : trimmed;\n}\n\nexport function rewriteTaskAgentText(text: string): string {\n return text\n .replace(/\\bcoding agents\\b/gi, \"task agents\")\n .replace(/\\bcoding agent\\b/gi, \"task agent\")\n .replace(/\\bcoding sessions\\b/gi, \"task-agent sessions\")\n .replace(/\\bcoding session\\b/gi, \"task-agent session\");\n}\n\nexport { FRAMEWORK_LABELS as TASK_AGENT_FRAMEWORK_LABELS };\n",
|
|
16
|
+
"/**\n * PTY session spawning logic — extracted from PTYService for maintainability.\n *\n * Contains the deferred task delivery, retry logic, per-agent settle delays,\n * and session buffer setup that runs during spawnSession().\n *\n * @module services/pty-spawn\n */\n\nimport type { AdapterType, BaseCodingAdapter } from \"coding-agent-adapters\";\nimport type {\n BunCompatiblePTYManager,\n PTYManager,\n SessionHandle,\n SpawnConfig,\n WorkerSessionHandle,\n} from \"pty-manager\";\nimport { cleanForChat } from \"./ansi-utils.js\";\nimport type {\n PTYServiceConfig,\n SessionInfo,\n SpawnSessionOptions,\n} from \"./pty-types.js\";\nimport { readTaskAgentModelPrefs } from \"./task-agent-frameworks.js\";\n\nconst CODEX_UPDATE_RULE_PATTERN_SOURCE =\n \"update.?available.*->|update.?now|skip.?until.?next.?version\";\nconst CODEX_TRUST_RULE_PATTERN_SOURCE =\n \"do.?you.?trust.?the.?contents|trust.?this.?directory|yes,?.?continue|prompt.?injection\";\nconst CODEX_KEEP_CURRENT_MODEL_NEVER_RULE_PATTERN_SOURCE =\n \"keep\\\\s+current\\\\s+model\\\\s*\\\\(never\\\\s+show\\\\s+again\\\\)|hide\\\\s+future\\\\s+rate\\\\s+limit\\\\s+reminders\\\\s+about\\\\s+switching\\\\s+models\";\nconst CODEX_KEEP_CURRENT_MODEL_RULE_PATTERN_SOURCE =\n \"keep\\\\s+current\\\\s+model[\\\\s\\\\S]*(?:efficient\\\\s+model|less\\\\s+capable|faster|rate\\\\s+limit|switching\\\\s+models)|(?:efficient\\\\s+model|less\\\\s+capable|faster|rate\\\\s+limit|switching\\\\s+models)[\\\\s\\\\S]*keep\\\\s+current\\\\s+model\";\n\nconst CODEX_ADAPTER_RULE_OVERRIDES: NonNullable<SpawnConfig[\"ruleOverrides\"]> =\n {\n [CODEX_UPDATE_RULE_PATTERN_SOURCE]: {\n response: \"\",\n responseType: \"keys\",\n keys: [\"2\", \"enter\"],\n description: 'Skip Codex CLI update prompt (option 2: \"Skip\")',\n once: true,\n },\n [CODEX_KEEP_CURRENT_MODEL_NEVER_RULE_PATTERN_SOURCE]: {\n response: \"\",\n responseType: \"keys\",\n keys: [\"3\", \"enter\"],\n description:\n \"Keep the current Codex model and hide future model-switch reminders\",\n },\n [CODEX_KEEP_CURRENT_MODEL_RULE_PATTERN_SOURCE]: {\n response: \"\",\n responseType: \"keys\",\n keys: [\"2\", \"enter\"],\n description:\n \"Keep the current Codex model when a routine model-switch reminder appears\",\n },\n [CODEX_TRUST_RULE_PATTERN_SOURCE]: {\n response: \"\",\n responseType: \"keys\",\n keys: [\"1\", \"enter\"],\n description: 'Trust Codex workspace prompt (option 1: \"Yes, continue\")',\n once: true,\n },\n };\n\n/**\n * Inspect a chunk of session output for auth-related failure signatures.\n * Returns the kind of failure detected (or null) so the caller can mark\n * the supplied `accountId` via the pool. Pattern matching is best-effort\n * and intentionally narrow: we only flag accounts when we're confident\n * the subprocess saw a real auth error.\n */\nexport function detectAuthFailureKind(\n data: string,\n): \"rate-limited\" | \"invalid\" | \"needs-reauth\" | null {\n if (!data) return null;\n if (/\\binvalid_grant\\b/i.test(data)) return \"needs-reauth\";\n if (/\\b401\\b|\\bunauthorized\\b/i.test(data)) return \"invalid\";\n if (/rate[\\s_-]*limit/i.test(data) || /\\b429\\b/.test(data)) {\n return \"rate-limited\";\n }\n return null;\n}\n\n/**\n * System environment variables safe to pass to spawned agents.\n * Everything else (API keys, tokens, cloud credentials) is stripped.\n */\nconst ENV_ALLOWLIST = [\n \"PATH\",\n \"HOME\",\n \"USER\",\n \"SHELL\",\n \"LANG\",\n \"LC_ALL\",\n \"LC_CTYPE\",\n \"TERM\",\n \"COLORTERM\",\n \"TZ\",\n \"TMPDIR\",\n \"XDG_RUNTIME_DIR\",\n \"NODE_OPTIONS\",\n \"BUN_INSTALL\",\n // Forward the user's preferred Claude model so spawned `claude` inherits it\n // (claude-cli reads ANTHROPIC_MODEL on startup). Without this, the subagent\n // falls back to its default sonnet even when the parent runtime is on opus.\n \"ANTHROPIC_MODEL\",\n \"ANTHROPIC_SMALL_FAST_MODEL\",\n // Forward the user's GitHub PAT to spawned agents so `git`, `gh`, and\n // `curl` against the GitHub API all work without each adapter having to\n // know about the on-disk credential file. The token is opt-in: it only\n // appears in process.env when the user has saved it through the host's\n // GitHub connection card (or set it explicitly via shell), so passthrough\n // here matches an explicit user grant rather than blanket leakage.\n \"GITHUB_TOKEN\",\n \"GH_TOKEN\",\n // Container app builds may need opt-in registry credentials/config before\n // Cloud can pull an image. These are forwarded only when the parent runtime\n // explicitly provides them.\n \"GHCR_TOKEN\",\n \"CR_PAT\",\n \"ELIZA_APP_IMAGE_REGISTRY\",\n \"ELIZA_APP_IMAGE_NAMESPACE\",\n \"ELIZA_APP_IMAGE_REPOSITORY\",\n // Cloud app builds need the parent-provided Cloud endpoint and API key to\n // register apps, enable monetization, and prepare domain offers.\n \"ELIZAOS_CLOUD_API_KEY\",\n \"ELIZA_CLOUD_BASE_URL\",\n \"ELIZA_CLOUD_PUBLIC_URL\",\n \"ELIZA_CLOUD_URL\",\n \"ELIZA_AFFILIATE_CODE\",\n];\n\n/**\n * Build a sanitized base environment from process.env, keeping only\n * safe system variables. Agent-specific credentials are injected\n * separately by the adapter's getEnv().\n *\n * On Windows, the sanitized env may have lost the per-package-manager bin\n * directories that hold `claude.cmd` / `codex.cmd` (npm global, Codex\n * managed install, scoop shims, chocolatey bin). Route through\n * `appendWindowsPathFallbacks` to add those back after the allowlist copy.\n */\nexport function buildSanitizedBaseEnv(): Record<string, string> {\n const env: Record<string, string> = {};\n for (const key of ENV_ALLOWLIST) {\n const val = process.env[key];\n if (val) env[key] = val;\n }\n if (!env.TERM || env.TERM.toLowerCase() === \"dumb\") {\n env.TERM = \"xterm-256color\";\n }\n if (!env.COLORTERM) {\n env.COLORTERM = \"truecolor\";\n }\n const mergedPath = appendWindowsPathFallbacks(env.PATH);\n if (mergedPath) {\n env.PATH = mergedPath;\n }\n return env;\n}\n\n/**\n * Directories that Windows package managers drop `claude.cmd` / `codex.cmd`\n * / `codex.exe` into. We append these to the sanitized PATH so `cmd.exe`\n * (via the `shell: true` flag on execFile/spawn for win32) can resolve the\n * CLI binaries even when the user's PATH has been stripped down by the\n * ENV_ALLOWLIST-then-systemd-unit chain or otherwise missing the install\n * location. Each entry is a no-op on non-Windows and a no-op when the\n * parent env var the path depends on is unset.\n *\n * Coverage, in order of popularity for claude/codex installs:\n * - npm global (%APPDATA%\\npm) — the official CLAUDE_CODE install path\n * - Codex managed install (%LOCALAPPDATA%\\OpenAI\\Codex\\bin)\n * - Scoop (%USERPROFILE%\\scoop\\shims)\n * - Chocolatey (%ProgramData%\\chocolatey\\bin)\n * - Bun global (%USERPROFILE%\\.bun\\bin)\n */\nexport function getWindowsPathFallbacks(): string[] {\n if (process.platform !== \"win32\") return [];\n const appData = process.env.APPDATA;\n const localAppData = process.env.LOCALAPPDATA;\n const userProfile = process.env.USERPROFILE;\n const programData = process.env.ProgramData ?? process.env.PROGRAMDATA;\n const candidates: (string | undefined)[] = [\n appData ? `${appData}\\\\npm` : undefined,\n localAppData ? `${localAppData}\\\\OpenAI\\\\Codex\\\\bin` : undefined,\n userProfile ? `${userProfile}\\\\scoop\\\\shims` : undefined,\n programData ? `${programData}\\\\chocolatey\\\\bin` : undefined,\n userProfile ? `${userProfile}\\\\.bun\\\\bin` : undefined,\n ];\n return candidates.filter((v): v is string => !!v && v.trim().length > 0);\n}\n\n/**\n * Append each fallback path to `currentPath` if it isn't already present.\n * Windows PATH matching is case-insensitive, so dedupe on the lowercased\n * form but preserve the original casing in the output. Returns `undefined`\n * when the resulting PATH would be empty (neither argument had content), so\n * callers can skip assigning an empty string.\n */\nexport function appendWindowsPathFallbacks(\n currentPath: string | undefined,\n): string | undefined {\n return mergePathEntries(currentPath, getWindowsPathFallbacks(), {\n delimiter: process.platform === \"win32\" ? \";\" : \":\",\n caseInsensitive: process.platform === \"win32\",\n });\n}\n\n/**\n * Pure PATH-merge helper: dedupe existing + extras, preserve insertion\n * order and casing. Exported for unit tests so we can exercise the merge\n * logic without stubbing `process.platform`.\n */\nexport function mergePathEntries(\n currentPath: string | undefined,\n extras: readonly string[],\n opts: { delimiter: string; caseInsensitive: boolean },\n): string | undefined {\n const normalize = (v: string) => (opts.caseInsensitive ? v.toLowerCase() : v);\n const existing = (currentPath ?? \"\")\n .split(opts.delimiter)\n .map((entry) => entry.trim())\n .filter(Boolean);\n const seen = new Set(existing.map(normalize));\n const merged: string[] = [...existing];\n for (const extra of extras) {\n const key = normalize(extra);\n if (seen.has(key)) continue;\n seen.add(key);\n merged.push(extra);\n }\n return merged.length > 0 ? merged.join(opts.delimiter) : undefined;\n}\n\nexport interface SpawnContext {\n manager: PTYManager | BunCompatiblePTYManager;\n usingBunWorker: boolean;\n serviceConfig: PTYServiceConfig;\n sessionMetadata: Map<string, Record<string, unknown>>;\n sessionWorkdirs: Map<string, string>;\n sessionOutputBuffers: Map<string, string[]>;\n outputUnsubscribers: Map<string, () => void>;\n taskResponseMarkers: Map<string, number>;\n getAdapter: (agentType: AdapterType) => BaseCodingAdapter;\n sendToSession: (sessionId: string, input: string) => Promise<unknown>;\n sendKeysToSession: (\n sessionId: string,\n keys: string | string[],\n ) => Promise<void>;\n writeRawToSession: (sessionId: string, data: string) => Promise<void>;\n pushDefaultRules: (sessionId: string, agentType: string) => Promise<void>;\n toSessionInfo: (\n session: SessionHandle | WorkerSessionHandle,\n workdir?: string,\n ) => SessionInfo;\n log: (msg: string) => void;\n /** Mark a session's task as delivered in the coordinator. */\n markTaskDelivered: (sessionId: string) => void;\n}\n\nexport function shouldUseCodexExecMode(options: {\n agentType: string;\n initialTask?: string;\n}): boolean {\n return options.agentType === \"codex\" && Boolean(options.initialTask?.trim());\n}\n\nconst CURSOR_POSITION_QUERY = \"\\x1b[6n\";\nconst CURSOR_POSITION_RESPONSE = \"\\x1b[1;1R\";\n\nasync function maybeRespondToTerminalQueries(\n ctx: SpawnContext,\n sessionId: string,\n data: string,\n): Promise<void> {\n if (!data.includes(CURSOR_POSITION_QUERY)) {\n return;\n }\n try {\n await ctx.writeRawToSession(sessionId, CURSOR_POSITION_RESPONSE);\n ctx.log(`Session ${sessionId} — answered terminal cursor-position query`);\n } catch (error) {\n ctx.log(\n `Session ${sessionId} — failed to answer terminal cursor-position query: ${error}`,\n );\n }\n}\n\n/**\n * Set up session output buffering for Bun worker path.\n */\nexport function setupOutputBuffer(ctx: SpawnContext, sessionId: string): void {\n const buffer: string[] = [];\n ctx.sessionOutputBuffers.set(sessionId, buffer);\n const unsubscribe = (ctx.manager as BunCompatiblePTYManager).onSessionData(\n sessionId,\n (data: string) => {\n void maybeRespondToTerminalQueries(ctx, sessionId, data);\n const lines = data.split(\"\\n\");\n buffer.push(...lines);\n while (buffer.length > (ctx.serviceConfig.maxLogLines ?? 1000)) {\n buffer.shift();\n }\n },\n );\n ctx.outputUnsubscribers.set(sessionId, unsubscribe);\n}\n\n/**\n * Set up deferred task delivery with retry logic.\n * IMPORTANT: Must be called BEFORE pushDefaultRules (which has a 1500ms sleep),\n * otherwise session_ready fires during pushDefaultRules and the listener misses it.\n */\nexport function setupDeferredTaskDelivery(\n ctx: SpawnContext,\n session: SessionHandle | WorkerSessionHandle,\n task: string,\n agentType: string,\n): void {\n const sid = session.id;\n // Per-agent post-ready delay. Claude Code has a heavy TUI that\n // renders update notices, shortcuts, and /ide hints in bursts after\n // the initial ready pattern — 300ms isn't enough to clear them all.\n const POST_READY_DELAY: Record<string, number> = {\n claude: 800,\n gemini: 300,\n codex: 2000,\n aider: 200,\n };\n const settleMs = POST_READY_DELAY[agentType] ?? 300;\n const MIN_NEW_LINES_BY_AGENT: Record<string, number> = {\n claude: 1,\n gemini: 10,\n codex: 15,\n aider: 8,\n };\n\n const VERIFY_DELAY_MS = 5000; // how long to wait before checking acceptance\n const MAX_RETRIES = agentType === \"codex\" ? 0 : 2;\n const minNewLines = MIN_NEW_LINES_BY_AGENT[agentType] ?? 15;\n const READY_PROBE_INTERVAL_MS = 500;\n const isAdapterBackedAgent =\n agentType === \"claude\" ||\n agentType === \"gemini\" ||\n agentType === \"codex\" ||\n agentType === \"aider\";\n const adapter = isAdapterBackedAgent\n ? ctx.getAdapter(agentType as AdapterType)\n : null;\n\n const sendTaskWithRetry = (attempt: number) => {\n const buffer = ctx.sessionOutputBuffers.get(sid);\n const baselineLength = buffer?.length ?? 0;\n\n ctx.log(\n `Session ${sid} — sending task (attempt ${attempt + 1}, ${settleMs}ms settle, baseline ${baselineLength} lines)`,\n );\n\n ctx\n .sendToSession(sid, task)\n .catch((err) =>\n ctx.log(`Failed to send deferred task to ${sid}: ${err}`),\n );\n\n // After a delay, verify the agent actually started working.\n // If the buffer barely grew, the TUI likely swallowed the input.\n if (attempt < MAX_RETRIES) {\n setTimeout(() => {\n const currentLength = buffer?.length ?? 0;\n const newLines = currentLength - baselineLength;\n const newOutput = buffer?.slice(baselineLength).join(\"\\n\") ?? \"\";\n const accepted =\n newLines >= minNewLines ||\n (adapter?.detectLoading?.(newOutput) ?? false) ||\n cleanForChat(newOutput).length >= 32;\n if (!accepted) {\n ctx.log(\n `Session ${sid} — task may not have been accepted (only ${newLines} new lines after ${VERIFY_DELAY_MS}ms). Retrying (attempt ${attempt + 2}/${MAX_RETRIES + 1})`,\n );\n sendTaskWithRetry(attempt + 1);\n } else {\n ctx.log(\n `Session ${sid} — task accepted (${newLines} new lines after ${VERIFY_DELAY_MS}ms)`,\n );\n }\n }, VERIFY_DELAY_MS);\n }\n };\n\n const READY_TIMEOUT_MS = 30_000;\n let taskSent = false;\n let taskDeliveredMarked = false;\n let readyTimeout: ReturnType<typeof setTimeout> | undefined;\n let readyProbe: ReturnType<typeof setInterval> | undefined;\n const clearPendingReadyWait = () => {\n if (readyTimeout) {\n clearTimeout(readyTimeout);\n readyTimeout = undefined;\n }\n if (readyProbe) {\n clearInterval(readyProbe);\n readyProbe = undefined;\n }\n };\n const sendTask = () => {\n if (taskSent) return;\n taskSent = true;\n clearPendingReadyWait();\n // Delay to let TUI finish rendering after ready detection.\n // Without this, Claude Code's TUI can swallow the Enter key\n // if it arrives during a render cycle.\n setTimeout(() => {\n if (!taskDeliveredMarked) {\n ctx.markTaskDelivered(sid);\n taskDeliveredMarked = true;\n }\n sendTaskWithRetry(0);\n }, settleMs);\n if (ctx.usingBunWorker) {\n (ctx.manager as BunCompatiblePTYManager).removeListener(\n \"session_ready\",\n onReady,\n );\n } else {\n (ctx.manager as PTYManager).removeListener(\"session_ready\", onReady);\n }\n };\n const onReady = (readySession: WorkerSessionHandle | SessionHandle) => {\n if (readySession.id !== sid) return;\n sendTask();\n };\n\n if (session.status === \"ready\") {\n sendTask();\n } else {\n if (ctx.usingBunWorker) {\n (ctx.manager as BunCompatiblePTYManager).on(\"session_ready\", onReady);\n } else {\n (ctx.manager as PTYManager).on(\"session_ready\", onReady);\n }\n readyTimeout = setTimeout(() => {\n if (!taskSent) {\n ctx.log(\n `Session ${sid} — ready event not received within ${READY_TIMEOUT_MS}ms, forcing task delivery`,\n );\n sendTask();\n }\n }, READY_TIMEOUT_MS);\n\n if (ctx.usingBunWorker && isAdapterBackedAgent && adapter) {\n readyProbe = setInterval(() => {\n if (taskSent) return;\n const buffer = ctx.sessionOutputBuffers.get(sid);\n if (!buffer || buffer.length === 0) return;\n const output = buffer.join(\"\\n\");\n const cleanedOutput = cleanForChat(output);\n if (adapter.detectLoading?.(output)) return;\n if (adapter.detectLogin(output).required) return;\n if (adapter.detectBlockingPrompt(output).detected) return;\n const promptVisible =\n adapter.detectReady(output) ||\n (agentType === \"codex\" &&\n /›\\s+(?:Ask Codex to do anything|\\S.*)/.test(cleanedOutput));\n if (!promptVisible) return;\n ctx.log(\n `Session ${sid} — detected ready prompt from buffered output, delivering task before timeout`,\n );\n sendTask();\n }, READY_PROBE_INTERVAL_MS);\n }\n }\n}\n\n/**\n * Build the SpawnConfig and env vars from SpawnSessionOptions.\n */\nexport function buildSpawnConfig(\n sessionId: string,\n options: SpawnSessionOptions,\n workdir: string,\n): SpawnConfig & { id: string } {\n const codexExecMode = shouldUseCodexExecMode(options);\n const codexExecOutputFile =\n typeof options.metadata?.codexExecOutputFile === \"string\" &&\n options.metadata.codexExecOutputFile.trim()\n ? options.metadata.codexExecOutputFile.trim()\n : undefined;\n\n // Map model preferences to adapter-specific env vars\n const modelPrefs = readTaskAgentModelPrefs(options.metadata?.modelPrefs);\n let modelEnv: Record<string, string> | undefined;\n if (modelPrefs?.powerful) {\n const envKeyMap: Record<string, string> = {\n claude: \"ANTHROPIC_MODEL\",\n gemini: \"GEMINI_MODEL\",\n codex: \"OPENAI_MODEL\",\n aider: \"AIDER_MODEL\",\n };\n const key = envKeyMap[options.agentType];\n if (key) modelEnv = { [key]: modelPrefs.powerful };\n }\n\n return {\n id: sessionId,\n name: options.name,\n type: options.agentType,\n workdir,\n inheritProcessEnv: false,\n env: {\n ...buildSanitizedBaseEnv(),\n ...options.env,\n ...modelEnv,\n PARALLAX_SESSION_ID: sessionId,\n },\n ...(options.skipAdapterAutoResponse\n ? { skipAdapterAutoResponse: true }\n : {}),\n ...(options.agentType === \"codex\"\n ? { ruleOverrides: CODEX_ADAPTER_RULE_OVERRIDES }\n : {}),\n adapterConfig: {\n ...(options.credentials as Record<string, unknown> | undefined),\n ...(options.customCredentials\n ? { custom: options.customCredentials }\n : {}),\n interactive: !codexExecMode,\n ...(codexExecMode\n ? {\n initialPrompt: options.initialTask?.trim(),\n skipGitRepoCheck: true,\n ...(codexExecOutputFile\n ? { outputLastMessage: codexExecOutputFile }\n : {}),\n }\n : {}),\n approvalPreset:\n options.agentType === \"codex\" && !codexExecMode\n ? undefined\n : options.approvalPreset,\n // Forward adapter-relevant metadata (e.g. provider preference for Aider)\n ...(options.metadata?.provider\n ? { provider: options.metadata.provider }\n : {}),\n ...(options.metadata?.modelTier\n ? { modelTier: options.metadata.modelTier }\n : {}),\n },\n };\n}\n",
|
|
17
|
+
"/**\n * Shared types and helpers for the PTY service layer.\n *\n * Extracted from pty-service.ts to keep that module lean and allow\n * other modules (pty-spawn, pty-init, actions) to import lightweight\n * type-only dependencies without pulling in the full PTYService class.\n *\n * @module services/pty-types\n */\n\nimport type {\n AdapterType,\n AgentCredentials,\n ApprovalPreset,\n} from \"coding-agent-adapters\";\nimport type { SessionHandle } from \"pty-manager\";\n\nexport interface PTYServiceConfig {\n /** Maximum output lines to keep per session (default: 1000) */\n maxLogLines?: number;\n /** Enable debug logging */\n debug?: boolean;\n /** Auto-register task-agent adapters (default: true) */\n registerCodingAdapters?: boolean;\n /** Maximum concurrent PTY sessions (default: 8) */\n maxConcurrentSessions?: number;\n /**\n * Default approval preset for task agents when not specified per-spawn.\n * Controls what tools the agent can use without asking for permission.\n * - \"readonly\" — Read-only tools only\n * - \"standard\" — Read + write, asks for shell/network\n * - \"permissive\" — Most tools auto-approved, asks for destructive ops\n * - \"autonomous\" — All tools auto-approved (yolo mode)\n * Default: \"autonomous\"\n */\n defaultApprovalPreset?: ApprovalPreset;\n}\n\n/** Available task-agent types */\nexport type CodingAgentType = \"shell\" | \"pi\" | \"opencode\" | AdapterType;\n\nconst PI_AGENT_ALIASES = new Set([\"pi\", \"pi-coding-agent\", \"picodingagent\"]);\nconst OPENCODE_AGENT_ALIASES = new Set([\n \"opencode\",\n \"open-code\",\n \"opencodeagent\",\n]);\n\n/** True when the user requested the Pi coding agent. */\nexport const isPiAgentType = (input: string | undefined | null): boolean => {\n if (!input) return false;\n return PI_AGENT_ALIASES.has(input.toLowerCase().trim());\n};\n\n/** True when the user requested the OpenCode agent. */\nexport const isOpencodeAgentType = (\n input: string | undefined | null,\n): boolean => {\n if (!input) return false;\n return OPENCODE_AGENT_ALIASES.has(input.toLowerCase().trim());\n};\n\n/** Normalize user-provided agent type string to a valid CodingAgentType */\nexport const normalizeAgentType = (input: string): CodingAgentType => {\n const normalized = input.toLowerCase().trim();\n if (isPiAgentType(normalized)) {\n // PI currently runs through the generic shell adapter.\n return \"shell\";\n }\n if (isOpencodeAgentType(normalized)) {\n // OpenCode also runs through the generic shell adapter — see toOpencodeCommand.\n return \"shell\";\n }\n const mapping: Record<string, CodingAgentType> = {\n claude: \"claude\",\n \"claude-code\": \"claude\",\n claudecode: \"claude\",\n codex: \"codex\",\n openai: \"codex\",\n \"openai-codex\": \"codex\",\n gemini: \"gemini\",\n google: \"gemini\",\n aider: \"aider\",\n shell: \"shell\",\n bash: \"shell\",\n };\n return mapping[normalized] ?? \"claude\";\n};\n\n/** Build the initial shell command for Pi agent sessions. */\nexport const toPiCommand = (task: string | undefined): string => {\n const trimmed = task?.trim();\n if (!trimmed) return \"pi\";\n const shellSafe = `'${trimmed.replace(/'/g, `'\"'\"'`)}'`;\n return `pi ${shellSafe}`;\n};\n\n/**\n * Build the initial shell command for OpenCode agent sessions.\n *\n * `--dangerously-skip-permissions` is a flag of the `run` subcommand\n * (NOT the top-level opencode command), so it must come AFTER `run` —\n * verified live with opencode 1.14.33 + an OpenAI-compatible Eliza-1 endpoint.\n *\n * Model + provider selection comes from the OPENCODE_CONFIG_CONTENT env\n * var that the spawn pipeline injects — see buildOpencodeSpawnConfig in\n * `agent-credentials.ts`.\n */\nexport const toOpencodeCommand = (task: string | undefined): string => {\n const trimmed = task?.trim();\n if (!trimmed) return \"opencode\";\n const shellSafe = `'${trimmed.replace(/'/g, `'\"'\"'`)}'`;\n return `opencode run --dangerously-skip-permissions ${shellSafe}`;\n};\n\nexport interface SpawnSessionOptions {\n /** Human-readable session name */\n name: string;\n /** Adapter type: \"shell\" | \"pi\" | \"opencode\" | \"claude\" | \"gemini\" | \"codex\" | \"aider\" */\n agentType: CodingAgentType;\n /** Working directory for the session */\n workdir?: string;\n /** Initial command/task to send */\n initialTask?: string;\n /** Environment variables */\n env?: Record<string, string>;\n /** Session metadata for tracking */\n metadata?: Record<string, unknown>;\n /** Credentials for coding agents (API keys, tokens) */\n credentials?: AgentCredentials;\n /** Memory/instructions content to write to the agent's memory file before spawning */\n memoryContent?: string;\n /** Approval preset controlling tool permissions (readonly, standard, permissive, autonomous) */\n approvalPreset?: ApprovalPreset;\n /** Custom credentials for MCP servers or other integrations */\n customCredentials?: Record<string, string>;\n /** When true, adapter-level blocking prompts (tool permissions, file access)\n * are emitted with autoResponded=false instead of being auto-handled.\n * Used by the swarm coordinator to route decisions through its LLM loop. */\n skipAdapterAutoResponse?: boolean;\n}\n\nexport interface SessionInfo {\n id: string;\n name: string;\n agentType: string;\n workdir: string;\n status: SessionHandle[\"status\"];\n createdAt: Date;\n lastActivityAt: Date;\n metadata?: Record<string, unknown>;\n}\n\n/** Known event names emitted by the PTY layer. */\nexport type SessionEventName =\n | \"ready\"\n | \"blocked\"\n | \"login_required\"\n | \"task_complete\"\n | \"tool_running\"\n | \"stopped\"\n | \"error\"\n | \"message\";\n\ntype SessionEventCallback = (\n sessionId: string,\n event: string,\n data: unknown,\n) => void;\n\nexport type { SessionEventCallback };\n",
|
|
18
|
+
"/**\n * Auto-injected subset of `assets/claude-code-skills/eliza-runtime/SKILL.md`\n * that ships verbatim in the workspace-lock brief for claude sub-agents.\n *\n * Why a separate constant (and not just a Read of SKILL.md at runtime):\n * sub-agents on the Claude.ai consumer-tier OAuth do not have the `Skill`\n * tool, so the skill auto-load mechanism is unavailable to them. Inlining\n * the must-have sections into the spawn brief gives them the operating\n * manual upfront with zero file I/O.\n *\n * Keep this in sync with SKILL.md: when you edit one, edit both. SKILL.md\n * remains the canonical / extended manual (spawn-variants table, helper\n * scripts, references). This constant is the always-injected minimum.\n */\nexport const CLAUDE_SKILL_ESSENTIALS = `Tool availability varies by Claude Code build and account tier — enumerate your actual tools (read \\`.claude/settings.json\\`'s \\`permissions.allow\\`, or use \\`ToolSearch\\` if present) before deciding you can't do a thing.\n\n# DECISION protocol\n\nThe orchestrator greps your stdout for lines starting with \\`DECISION:\\`. Use them when you make an architectural choice not covered by the brief, or when reporting a hard limitation. Examples:\n\n\\`\\`\\`\nDECISION: chose /api/v1/messages/ over /messages/ to match existing eliza-cloud route prefix.\nDECISION: cannot run shell commands — this session has Read/Grep/Glob but no Bash, Monitor, or run_shell_command. Reported what I could find statically.\n\\`\\`\\`\n\nALWAYS-on, no shell tool required — just print the line.\n\n# What you should NEVER do\n\n- Refuse a task as \"no shell available\" without first enumerating your actual tool list (settings.json + ToolSearch). Different tiers ship different shell tools — \\`Bash\\`, \\`Monitor\\`, \\`run_shell_command\\` — at least one is usually present.\n- Say \"use the \\`!\\` prefix\" or \"run this in your terminal\" — there is no terminal in your face.\n- Ask the human to clarify or provide input — there is no human in your session.\n- Push to remotes, write outside workdir, print env tokens.\n- Treat partial information as a blocker — produce the best output you can with what you have.\n\n# Bridge endpoints (parent state, read-only)\n\nWhen HTTP hooks are wired (variants \\`swarm\\` and \\`repo\\`), GET these to query parent state:\n- \\`http://localhost:\\${ELIZA_HOOK_PORT:-2138}/api/coding-agents/$PARALLAX_SESSION_ID/parent-context\\` — agent character, originating room, original task\n- \\`.../memory?q=<query>&limit=<N>\\` — recent messages from the originating room\n- \\`.../active-workspaces\\` — sibling sub-agents (swarm only)\n\nAuth is the path-embedded session id. Loopback-only, GET-only, read-only.\n\n# Constraints\n\n- Sealed env: only an allowlist of vars is forwarded (PATH, HOME, USER, SHELL, ANTHROPIC_MODEL, GITHUB_TOKEN, PARALLAX_SESSION_ID, ELIZA_HOOK_PORT, etc.).\n- Workspace-only writes: write only inside your workdir.\n- Don't push to git remotes — Eliza handles git push, PR creation, cross-repo coordination.\n- Don't print secrets — PTY output is captured. Reference secrets by env-var name.\n\nFor deeper context (spawn-variants table, helper scripts, references) see \\`~/.claude/skills/eliza-runtime/SKILL.md\\`.`;\n",
|
|
19
|
+
"import {\n type IAgentRuntime,\n type SpawnTrajectoryHandle,\n spawnWithTrajectoryLink,\n} from \"@elizaos/core\";\n\nexport const TRAJECTORY_PARENT_STEP_METADATA_KEY = \"parentTrajectoryStepId\";\nexport const TRAJECTORY_CHILD_STEP_METADATA_KEY = \"trajectoryChildStepId\";\nexport const TRAJECTORY_LINK_SOURCE_METADATA_KEY = \"trajectoryLinkSource\";\nexport const TRAJECTORY_PARENT_STEP_ENV_KEY =\n \"MILADY_PARENT_TRAJECTORY_STEP_ID\";\nexport const TRAJECTORY_CHILD_STEP_ENV_KEY = \"MILADY_TRAJECTORY_CHILD_STEP_ID\";\n\nexport interface LinkedSpawnContext {\n parentStepId?: string;\n metadata: Record<string, unknown>;\n env: Record<string, string> | undefined;\n linkChild: SpawnTrajectoryHandle[\"linkChild\"];\n}\n\ninterface WithLinkedSpawnOptions<T> {\n source: string;\n metadata?: Record<string, unknown>;\n env?: Record<string, string>;\n childId?: (result: T) => string | undefined;\n}\n\nfunction cleanParentStepId(handle: SpawnTrajectoryHandle): string | undefined {\n const parentStepId = handle.parentStepId?.trim();\n return parentStepId && parentStepId.length > 0 ? parentStepId : undefined;\n}\n\nexport function buildLinkedSpawnMetadata(\n metadata: Record<string, unknown> | undefined,\n handle: SpawnTrajectoryHandle,\n source: string,\n): Record<string, unknown> {\n const parentStepId = cleanParentStepId(handle);\n return {\n ...metadata,\n ...(parentStepId\n ? {\n [TRAJECTORY_PARENT_STEP_METADATA_KEY]: parentStepId,\n [TRAJECTORY_LINK_SOURCE_METADATA_KEY]: source,\n }\n : {}),\n };\n}\n\nexport function buildLinkedSpawnEnv(\n env: Record<string, string> | undefined,\n handle: SpawnTrajectoryHandle,\n): Record<string, string> | undefined {\n const parentStepId = cleanParentStepId(handle);\n if (!parentStepId) return env;\n return {\n ...env,\n [TRAJECTORY_PARENT_STEP_ENV_KEY]: parentStepId,\n };\n}\n\nexport async function withLinkedSpawn<T>(\n runtime: IAgentRuntime | null | undefined,\n options: WithLinkedSpawnOptions<T>,\n spawn: (context: LinkedSpawnContext) => Promise<T> | T,\n): Promise<T> {\n return spawnWithTrajectoryLink(\n runtime,\n { source: options.source, metadata: options.metadata },\n async (handle) => {\n const context: LinkedSpawnContext = {\n parentStepId: cleanParentStepId(handle),\n metadata: buildLinkedSpawnMetadata(\n options.metadata,\n handle,\n options.source,\n ),\n env: buildLinkedSpawnEnv(options.env, handle),\n linkChild: handle.linkChild,\n };\n const result = await spawn(context);\n const childStepId = options.childId?.(result)?.trim();\n if (childStepId) {\n await handle.linkChild(childStepId);\n }\n return result;\n },\n );\n}\n",
|
|
20
|
+
"export function parseJsonObjectResponse<T = Record<string, unknown>>(\n raw: string,\n): T | null {\n try {\n const trimmed = raw.trim();\n const fenced = trimmed.match(/```(?:json)?\\s*([\\s\\S]*?)\\s*```/i);\n const candidate = (fenced?.[1] ?? trimmed).trim();\n const firstBrace = candidate.indexOf(\"{\");\n const lastBrace = candidate.lastIndexOf(\"}\");\n if (firstBrace < 0 || lastBrace <= firstBrace) return null;\n const parsed = JSON.parse(candidate.slice(firstBrace, lastBrace + 1));\n if (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n return null;\n }\n return parsed as T;\n } catch {\n return null;\n }\n}\n",
|
|
21
|
+
"/**\n * Trajectory Context — Tag orchestrator LLM calls for trajectory logging.\n *\n * Sets a lightweight context object on the runtime before `useModel()` calls\n * so the trajectory logger can identify orchestrator-specific LLM invocations\n * (coordination decisions, stall classification, idle checks, etc.) and tag\n * them with meaningful metadata instead of the generic \"action\" / \"runtime.useModel\".\n *\n * The eliza trajectory-persistence layer reads `runtime.__orchestratorTrajectoryCtx`\n * in its `appendLlmCall` patch and writes the context into the trajectory record.\n *\n * @module services/trajectory-context\n */\n\n/**\n * Any runtime-like object. We accept both `AgentRuntime` and `IAgentRuntime`\n * since different call sites use different types. Using a minimal interface\n * avoids index-signature incompatibilities with ElizaOS types.\n */\ntype RuntimeLike = object;\n\n/**\n * Orchestrator decision types that map to specific LLM call sites.\n */\nexport type OrchestratorDecisionType =\n | \"coordination\"\n | \"turn-complete\"\n | \"idle-check\"\n | \"stall-classification\"\n | \"stall-classify-decide\"\n | \"swarm-context-generation\"\n | \"event-triage\"\n | \"launch-failure-message\"\n | \"task-validation\"\n | \"acceptance-verifier\";\n\nexport interface OrchestratorTrajectoryContext {\n /** Source identifier — always \"orchestrator\" */\n source: \"orchestrator\";\n /** Which decision type triggered this LLM call */\n decisionType: OrchestratorDecisionType;\n /** PTY session ID of the agent being evaluated */\n sessionId?: string;\n /** Durable task thread identifier */\n threadId?: string;\n /** Acceptance verifier job identifier */\n verifierJobId?: string;\n /** Human-readable task label */\n taskLabel?: string;\n /** Repository URL or identifier (for trajectory feedback filtering) */\n repo?: string;\n /** Workspace directory path */\n workdir?: string;\n /** Original task description assigned to the agent */\n originalTask?: string;\n}\n\nconst CTX_KEY = \"__orchestratorTrajectoryCtx\";\n\n/**\n * Set orchestrator trajectory context on the runtime.\n * Call this before `runtime.useModel()` and clear it after.\n */\nexport function setTrajectoryContext(\n runtime: RuntimeLike,\n ctx: OrchestratorTrajectoryContext,\n): void {\n (runtime as Record<string, unknown>)[CTX_KEY] = ctx;\n}\n\n/**\n * Clear orchestrator trajectory context from the runtime.\n */\nexport function clearTrajectoryContext(runtime: RuntimeLike): void {\n (runtime as Record<string, unknown>)[CTX_KEY] = undefined;\n}\n\n/**\n * Read the current orchestrator trajectory context (if any).\n * Used by the trajectory logger on the eliza side.\n */\nexport function readTrajectoryContext(\n runtime: unknown,\n): OrchestratorTrajectoryContext | undefined {\n if (!runtime || typeof runtime !== \"object\") return undefined;\n const ctx = (runtime as Record<string, unknown>)[CTX_KEY];\n if (!ctx || typeof ctx !== \"object\") return undefined;\n const candidate = ctx as Partial<OrchestratorTrajectoryContext>;\n if (candidate.source !== \"orchestrator\" || !candidate.decisionType)\n return undefined;\n return candidate as OrchestratorTrajectoryContext;\n}\n\n/**\n * Wrap a `useModel()` call with trajectory context tagging.\n * Ensures the context is always cleared, even if the call throws.\n *\n * @example\n * ```ts\n * const result = await withTrajectoryContext(\n * ctx.runtime,\n * { source: \"orchestrator\", decisionType: \"coordination\", sessionId },\n * () => ctx.runtime.useModel(ModelType.TEXT_SMALL, { prompt }),\n * );\n * ```\n */\nexport async function withTrajectoryContext<T>(\n runtime: RuntimeLike,\n ctx: OrchestratorTrajectoryContext,\n fn: () => Promise<T>,\n): Promise<T> {\n setTrajectoryContext(runtime, ctx);\n try {\n return await fn();\n } finally {\n clearTrajectoryContext(runtime);\n }\n}\n",
|
|
22
|
+
"/**\n * Stall classification subsystem — determines what a \"stalled\" task agent\n * session is doing (finished, waiting for input, still working, or errored).\n *\n * Extracted as standalone functions that receive dependencies as parameters,\n * making them easy to test without coupling to PTYService.\n *\n * @module services/stall-classifier\n */\n\nimport { type IAgentRuntime, ModelType } from \"@elizaos/core\";\nimport {\n buildTaskCompletionTimeline,\n extractTaskCompletionTraceRecords,\n type StallClassification,\n} from \"pty-manager\";\nimport type { AgentMetricsTracker } from \"./agent-metrics.js\";\nimport { stripAnsi } from \"./ansi-utils.js\";\nimport { parseJsonObjectResponse } from \"./json-model-output.js\";\nimport type {\n DecisionHistoryEntry,\n TaskContextSummary,\n} from \"./swarm-coordinator-prompts.js\";\nimport { withTrajectoryContext } from \"./trajectory-context.js\";\n\n/** Everything the classifier needs, passed in from PTYService. */\nexport interface StallClassifierContext {\n sessionId: string;\n recentOutput: string;\n agentType: string;\n buffers: Map<string, string[]>;\n traceEntries: Array<string | Record<string, unknown>>;\n runtime: IAgentRuntime;\n manager: {\n get(id: string): { startedAt?: string | Date } | null | undefined;\n } | null;\n metricsTracker: AgentMetricsTracker;\n /** Write debug snapshots to ~/.eliza/debug/ on stall (default: false) */\n debugSnapshots?: boolean;\n /** Most recent text input sent into the session, used to ignore echoed prompts. */\n lastSentInput?: string;\n log: (msg: string) => void;\n}\n\nconst STATUS_NOISE_LINE =\n /messages to be submitted after next tool call|working \\(\\d+s .*esc to interrupt\\)|\\b\\d+% left\\b|context left|use \\/skills to list available skills/i;\nconst STATUS_PATH_LINE = /(\\/private\\/|\\/var\\/folders\\/|\\/Users\\/|\\/tmp\\/)/;\nconst SPINNER_FRAGMENT_TOKEN =\n /^(?:w|wo|wor|work|worki|workin|working|orking|rking|king|ing|ng|g|\\d+|[•·])$/i;\n\nfunction normalizeForComparison(value: string): string {\n return stripAnsi(value).replace(/\\s+/g, \" \").trim().toLowerCase();\n}\n\nfunction looksLikeSpinnerFragments(line: string): boolean {\n const tokens = line\n .replace(/[^\\w/%@.:\\-/ ]+/g, \" \")\n .split(/\\s+/)\n .filter(Boolean);\n if (tokens.length === 0) return false;\n const fragmentTokens = tokens.filter((token) =>\n SPINNER_FRAGMENT_TOKEN.test(token),\n );\n return (\n fragmentTokens.length >= 4 &&\n fragmentTokens.length >= Math.ceil(tokens.length * 0.6)\n );\n}\n\nfunction isStatusNoiseLine(line: string): boolean {\n const compact = line.replace(/\\s+/g, \" \").trim();\n if (!compact) return true;\n if (compact.startsWith(\"› \")) return true;\n if (STATUS_NOISE_LINE.test(compact)) return true;\n if (looksLikeSpinnerFragments(compact)) return true;\n if (STATUS_PATH_LINE.test(compact) && /\\b\\d+% left\\b/i.test(compact))\n return true;\n if (STATUS_PATH_LINE.test(compact) && looksLikeSpinnerFragments(compact))\n return true;\n return false;\n}\n\nfunction sanitizeOutputForClassification(\n output: string,\n lastSentInput?: string,\n): {\n sanitized: string;\n removedEchoLines: number;\n removedStatusLines: number;\n} {\n const normalizedInput = lastSentInput\n ? normalizeForComparison(lastSentInput)\n : \"\";\n let removedEchoLines = 0;\n let removedStatusLines = 0;\n const sanitized = stripAnsi(output)\n .split(\"\\n\")\n .map((line) => line.replace(/\\s+/g, \" \").trim())\n .filter((line) => {\n if (!line) return false;\n const normalizedLine = line.toLowerCase();\n if (\n normalizedInput &&\n normalizedLine.length >= 12 &&\n normalizedInput.includes(normalizedLine)\n ) {\n removedEchoLines += 1;\n return false;\n }\n if (isStatusNoiseLine(line)) {\n removedStatusLines += 1;\n return false;\n }\n return true;\n })\n .join(\"\\n\")\n .trim();\n return { sanitized, removedEchoLines, removedStatusLines };\n}\n\nfunction promptLooksLikeFalseBlockedNoise(\n prompt: string | undefined,\n lastSentInput?: string,\n): boolean {\n if (!prompt) return false;\n const normalizedPrompt = normalizeForComparison(prompt);\n if (!normalizedPrompt) return false;\n if (lastSentInput) {\n const normalizedInput = normalizeForComparison(lastSentInput);\n if (\n normalizedPrompt.length >= 12 &&\n normalizedInput.includes(normalizedPrompt)\n ) {\n return true;\n }\n }\n return isStatusNoiseLine(prompt) || looksLikeSpinnerFragments(prompt);\n}\n\n/**\n * Build the LLM system prompt used to classify stalled output.\n */\nexport function buildStallClassificationPrompt(\n agentType: string,\n sessionId: string,\n output: string,\n): string {\n return (\n `You are Eliza, an AI orchestrator managing task-agent sessions. ` +\n `A ${agentType} task agent (session: ${sessionId}) appears to have stalled — ` +\n `it has stopped producing output while in a busy state.\\n\\n` +\n `Here is the recent terminal output:\\n` +\n `---\\n${output.slice(-1500)}\\n---\\n\\n` +\n `Classify what's happening. Read the output carefully and choose the MOST specific match:\\n\\n` +\n `1. \"task_complete\" — The agent FINISHED its task and returned to its idle prompt. ` +\n `Strong indicators: a summary of completed work (\"Done\", \"All done\", \"Here's what was completed\"), ` +\n `timing info (\"Baked for\", \"Churned for\", \"Crunched for\", \"Cooked for\", \"Worked for\"), ` +\n `or the agent's main prompt symbol (❯) appearing AFTER completion output. ` +\n `If the output contains evidence of completed work followed by an idle prompt, this is ALWAYS task_complete, ` +\n `even though the agent is technically \"waiting\" — it is waiting for a NEW task, not asking a question.\\n\\n` +\n `2. \"waiting_for_input\" — The agent is MID-TASK and blocked on a specific question or permission prompt. ` +\n `The agent has NOT finished its work — it needs a response to continue. ` +\n `Examples: Y/n confirmation, file permission dialogs, \"Do you want to proceed?\", ` +\n `tool approval prompts, or interactive menus. ` +\n `This is NOT the same as the agent sitting at its idle prompt after finishing work.\\n\\n` +\n `3. \"still_working\" — The agent is actively processing (API call, compilation, thinking, etc.) ` +\n `and has not produced final output yet. No prompt or completion summary visible.\\n\\n` +\n `4. \"error\" — The agent hit an error state (crash, unrecoverable error, stack trace).\\n\\n` +\n `5. \"tool_running\" — The agent is using an external tool (browser automation, ` +\n `MCP tool, etc.). Indicators: \"Claude in Chrome\", \"javascript_tool\", ` +\n `\"computer_tool\", \"screenshot\", \"navigate\", tool execution output. ` +\n `The agent is actively working but the terminal may be quiet.\\n\\n` +\n `IMPORTANT: If you see BOTH completed work output AND an idle prompt (❯), choose \"task_complete\". ` +\n `Only choose \"waiting_for_input\" if the agent is clearly asking a question mid-task. ` +\n `Ignore echoed user input, copied prior transcripts, spinner fragments, and status rows like ` +\n `\"Working (12s • esc to interrupt)\" or \"97% left\" — those mean the agent is still working, not blocked.\\n\\n` +\n `If \"waiting_for_input\", also provide:\\n` +\n `- \"prompt\": the text of what it's asking\\n` +\n `- \"suggestedResponse\": what to type/send. Use \"keys:enter\" for TUI menu confirmation, ` +\n `\"keys:down,enter\" to select a non-default option, or plain text like \"y\" for text prompts.\\n\\n` +\n `Respond with JSON only:\\n` +\n `{\"state\":\"waiting_for_input\",\"prompt\":\"The exact prompt text, or blank if none.\",\"suggestedResponse\":\"y\"}`\n );\n}\n\n/**\n * Write a debug snapshot to ~/.eliza/debug/ for offline stall analysis.\n */\nexport async function writeStallSnapshot(\n sessionId: string,\n agentType: string,\n recentOutput: string,\n effectiveOutput: string,\n buffers: Map<string, string[]>,\n traceEntries: Array<string | Record<string, unknown>>,\n log: (msg: string) => void,\n): Promise<void> {\n try {\n const fs = await import(\"node:fs\");\n const os = await import(\"node:os\");\n const path = await import(\"node:path\");\n const snapshotDir = path.join(os.homedir(), \".eliza\", \"debug\");\n fs.mkdirSync(snapshotDir, { recursive: true });\n const ourBuffer = buffers.get(sessionId);\n const ourTail = ourBuffer\n ? ourBuffer.slice(-100).join(\"\\n\")\n : \"(no buffer)\";\n void ourTail; // used in snapshot context but not directly printed\n let traceTimeline = \"(no trace entries)\";\n try {\n const records = extractTaskCompletionTraceRecords(traceEntries);\n const timeline = buildTaskCompletionTimeline(records, {\n adapterType: agentType,\n });\n traceTimeline = JSON.stringify(timeline, null, 2);\n } catch (e) {\n traceTimeline = `(trace error: ${e})`;\n }\n const snapshot = [\n `=== STALL SNAPSHOT @ ${new Date().toISOString()} ===`,\n `Session: ${sessionId} | Agent: ${agentType}`,\n `recentOutput length: ${recentOutput.length} | effectiveOutput length: ${effectiveOutput.length}`,\n ``,\n `--- effectiveOutput (what LLM sees) ---`,\n effectiveOutput.slice(-1500),\n ``,\n `--- trace timeline ---`,\n traceTimeline,\n ``,\n `--- raw trace entries (last 20 of ${traceEntries.length}) ---`,\n traceEntries.slice(-20).join(\"\\n\"),\n ``,\n ].join(\"\\n\");\n const snapshotPath = path.join(\n snapshotDir,\n `stall-snapshot-${sessionId}.txt`,\n );\n fs.writeFileSync(snapshotPath, snapshot);\n log(`Stall snapshot → ${snapshotPath}`);\n } catch (_) {\n /* best-effort */\n }\n}\n\n/**\n * Main stall classification logic. Determines what a stalled session is doing\n * by checking the buffer, building a prompt, and asking the LLM.\n */\nexport async function classifyStallOutput(\n ctx: StallClassifierContext,\n): Promise<StallClassification | null> {\n const {\n sessionId,\n recentOutput,\n agentType,\n buffers,\n traceEntries,\n runtime,\n metricsTracker,\n log,\n } = ctx;\n\n metricsTracker.incrementStalls(agentType);\n\n // Use our own buffer if pty-manager's recentOutput is empty or too short.\n let effectiveOutput = recentOutput;\n if (!recentOutput || recentOutput.trim().length < 200) {\n const ourBuffer = buffers.get(sessionId);\n if (ourBuffer && ourBuffer.length > 0) {\n const rawTail = ourBuffer.slice(-100).join(\"\\n\");\n const stripped = stripAnsi(rawTail);\n if (stripped.length > effectiveOutput.length) {\n effectiveOutput = stripped;\n log(\n `Using own buffer for stall classification (${effectiveOutput.length} chars after stripping, pty-manager had ${recentOutput.length})`,\n );\n }\n }\n }\n\n const {\n sanitized: sanitizedOutput,\n removedEchoLines,\n removedStatusLines,\n } = sanitizeOutputForClassification(effectiveOutput, ctx.lastSentInput);\n if (removedEchoLines > 0 || removedStatusLines > 0) {\n log(\n `Sanitized stall output for ${sessionId}: removed ${removedEchoLines} echoed lines and ${removedStatusLines} status lines`,\n );\n }\n if (!sanitizedOutput && removedEchoLines + removedStatusLines > 0) {\n log(\n `Stall classification short-circuit for ${sessionId}: only echoed input / status noise remained`,\n );\n return { state: \"still_working\" };\n }\n\n const systemPrompt = buildStallClassificationPrompt(\n agentType,\n sessionId,\n sanitizedOutput || effectiveOutput,\n );\n\n // Dump debug snapshot for offline analysis (opt-in via PTYServiceConfig.debug)\n if (ctx.debugSnapshots) {\n await writeStallSnapshot(\n sessionId,\n agentType,\n recentOutput,\n effectiveOutput,\n buffers,\n traceEntries,\n log,\n );\n }\n\n try {\n log(`Stall detected for ${sessionId}, asking LLM to classify...`);\n const result = await withTrajectoryContext(\n runtime,\n {\n source: \"orchestrator\",\n decisionType: \"stall-classification\",\n sessionId,\n },\n () => runtime.useModel(ModelType.TEXT_SMALL, { prompt: systemPrompt }),\n );\n\n const parsed = parseStallClassificationResponse(result);\n if (!parsed) {\n log(`Stall classification: no parseable JSON in LLM response`);\n return null;\n }\n // Map tool_running → still_working (StallClassification doesn't have tool_running).\n //\n // Also downgrade task_complete → still_working. The stall classifier LLM\n // guesses from raw stripped-ANSI terminal buffer text, which cannot\n // reliably distinguish \"agent is truly finished\" from \"shell prompt\n // showed up between tool calls\" or \"intermediate command exited with a\n // summary\". Treating this LLM's task_complete guess as a completion\n // signal causes the coordinator's turn-complete pipeline to fire\n // mid-work and re-inject the original prompt, creating an infinite\n // retry loop for long open-ended tasks.\n //\n // Task completion is signaled authoritatively by the agent's own hook\n // system (routed through pty-service.handleHookEvent) and by the\n // jsonl-based completion watcher in the eliza package. The stall\n // classifier is still useful for detecting waiting_for_input and error\n // states, which is why we don't short-circuit those paths.\n let mappedState: StallClassification[\"state\"];\n if (parsed.state === \"tool_running\" || parsed.state === \"task_complete\") {\n mappedState = \"still_working\";\n if (parsed.state === \"task_complete\") {\n log(\n `Stall classification for ${sessionId}: LLM said task_complete — downgrading to still_working (authoritative completion comes from hooks, not buffer guessing)`,\n );\n }\n } else {\n mappedState = parsed.state as StallClassification[\"state\"];\n }\n const classification: StallClassification = {\n state: mappedState,\n prompt: parsed.prompt,\n suggestedResponse: parsed.suggestedResponse,\n };\n if (\n classification.state === \"waiting_for_input\" &&\n promptLooksLikeFalseBlockedNoise(classification.prompt, ctx.lastSentInput)\n ) {\n log(\n `Stall classification override for ${sessionId}: prompt looked like echoed input / status noise`,\n );\n return { state: \"still_working\" };\n }\n log(\n `Stall classification for ${sessionId}: ${classification.state}${classification.suggestedResponse ? ` → \"${classification.suggestedResponse}\"` : \"\"}`,\n );\n return classification;\n } catch (err) {\n log(`Stall classification failed: ${err}`);\n return null;\n }\n}\n\n// ─── Combined Classify + Decide (for coordinator-managed autonomous sessions) ───\n\n/** Context for the combined classify-and-decide call. */\nexport interface CoordinatorClassifyContext extends StallClassifierContext {\n taskContext: TaskContextSummary;\n decisionHistory?: DecisionHistoryEntry[];\n}\n\nconst validStallStates = [\n \"waiting_for_input\",\n \"still_working\",\n \"task_complete\",\n \"error\",\n \"tool_running\",\n];\n\nfunction normalizeNullableString(value: unknown): string | undefined {\n if (typeof value !== \"string\") return undefined;\n const trimmed = value.trim();\n if (!trimmed || trimmed.toLowerCase() === \"null\") return undefined;\n return value;\n}\n\nfunction parseStallClassificationResponse(\n result: string,\n): { state: string; prompt?: string; suggestedResponse?: string } | null {\n const parsedJson = parseJsonObjectResponse<Record<string, unknown>>(result);\n if (parsedJson && validStallStates.includes(String(parsedJson.state))) {\n return {\n state: String(parsedJson.state),\n prompt: normalizeNullableString(parsedJson.prompt),\n suggestedResponse: normalizeNullableString(parsedJson.suggestedResponse),\n };\n }\n\n return null;\n}\n\n/**\n * Build a combined prompt that classifies the stall AND decides how to respond,\n * merging stall classification with coordinator decision guidelines.\n *\n * Used for coordinator-managed sessions in autonomous mode to eliminate the\n * redundant second LLM call in the coordinator's handleBlocked path.\n */\nexport function buildCombinedClassifyDecidePrompt(\n agentType: string,\n sessionId: string,\n output: string,\n taskContext: TaskContextSummary,\n decisionHistory: DecisionHistoryEntry[],\n): string {\n const historySection =\n decisionHistory.length > 0\n ? `\\nPrevious decisions for this session:\\n${decisionHistory\n .slice(-5)\n .map(\n (d, i) =>\n ` ${i + 1}. [${d.event}] prompt=\"${d.promptText}\" → ${d.action}${d.response ? ` (\"${d.response}\")` : \"\"} — ${d.reasoning}`,\n )\n .join(\"\\n\")}\\n`\n : \"\";\n\n return (\n `You are Eliza, an AI orchestrator managing task-agent sessions. ` +\n `A ${agentType} task agent (session: ${sessionId}) appears to have stalled — ` +\n `it has stopped producing output while in a busy state.\\n\\n` +\n `Original task: \"${taskContext.originalTask}\"\\n` +\n `Working directory: ${taskContext.workdir}\\n` +\n `Repository: ${taskContext.repo ?? \"none (scratch directory)\"}\\n` +\n historySection +\n `\\nHere is the recent terminal output:\\n` +\n `---\\n${output.slice(-1500)}\\n---\\n\\n` +\n `Classify what's happening AND decide how to respond. Read the output carefully.\\n\\n` +\n `Classification states:\\n\\n` +\n `1. \"task_complete\" — The agent FINISHED its task and returned to its idle prompt. ` +\n `Strong indicators: a summary of completed work, timing info, ` +\n `or the agent's main prompt symbol (❯) appearing AFTER completion output.\\n\\n` +\n `2. \"waiting_for_input\" — The agent is MID-TASK and blocked on a specific question or permission prompt. ` +\n `Examples: Y/n confirmation, file permission dialogs, tool approval prompts, interactive menus.\\n\\n` +\n `3. \"still_working\" — The agent is actively processing (API call, compilation, thinking). ` +\n `No prompt or completion summary visible.\\n\\n` +\n `4. \"error\" — The agent hit an error state (crash, unrecoverable error, stack trace).\\n\\n` +\n `5. \"tool_running\" — The agent is using an external tool (browser automation, MCP tool, etc.).\\n\\n` +\n `Ignore echoed user input, copied prior transcripts, spinner fragments, and status rows like ` +\n `\"Working (12s • esc to interrupt)\" or \"97% left\" — those indicate active work, not a live prompt.\\n\\n` +\n `If \"waiting_for_input\", you must also decide how to respond. Guidelines:\\n` +\n `- IMPORTANT: If the prompt asks to approve access to files or directories OUTSIDE the working ` +\n `directory (${taskContext.workdir}), DECLINE the request. Respond with \"n\" and tell the agent: ` +\n `\"That path is outside your workspace. Use ${taskContext.workdir} instead.\"\\n` +\n `- For tool approval prompts (file writes, shell commands), respond \"y\" or use \"keys:enter\".\\n` +\n `- For Y/n confirmations that align with the original task, respond \"y\".\\n` +\n `- For TUI menus, use \"keys:enter\" for default or \"keys:down,enter\" for non-default.\\n` +\n `- If the prompt asks for information NOT in the original task, set suggestedResponse to null ` +\n `(this will escalate to the human).\\n` +\n `- If a PR was just created, the task is likely done — classify as \"task_complete\".\\n\\n` +\n `Respond with JSON only:\\n` +\n `{\"state\":\"waiting_for_input\",\"prompt\":\"The exact prompt text, or blank if none.\",\"suggestedResponse\":\"y\"}`\n );\n}\n\n/**\n * Combined classify-and-decide for coordinator-managed autonomous sessions.\n *\n * Performs classification AND coordinator-quality response decision in a single\n * LLM call. The suggestedResponse is kept intact (not stripped), so pty-manager\n * auto-responds and the coordinator receives autoResponded: true — skipping\n * the second LLM call in handleBlocked().\n */\nexport async function classifyAndDecideForCoordinator(\n ctx: CoordinatorClassifyContext,\n): Promise<StallClassification | null> {\n const {\n sessionId,\n recentOutput,\n agentType,\n buffers,\n traceEntries,\n runtime,\n manager,\n metricsTracker,\n taskContext,\n decisionHistory = [],\n log,\n } = ctx;\n\n metricsTracker.incrementStalls(agentType);\n\n // Buffer fallback — same logic as classifyStallOutput\n let effectiveOutput = recentOutput;\n if (!recentOutput || recentOutput.trim().length < 200) {\n const ourBuffer = buffers.get(sessionId);\n if (ourBuffer && ourBuffer.length > 0) {\n const rawTail = ourBuffer.slice(-100).join(\"\\n\");\n const stripped = stripAnsi(rawTail);\n if (stripped.length > effectiveOutput.length) {\n effectiveOutput = stripped;\n log(\n `Using own buffer for combined classify+decide (${effectiveOutput.length} chars after stripping, pty-manager had ${recentOutput.length})`,\n );\n }\n }\n }\n\n const {\n sanitized: sanitizedOutput,\n removedEchoLines,\n removedStatusLines,\n } = sanitizeOutputForClassification(effectiveOutput, ctx.lastSentInput);\n if (removedEchoLines > 0 || removedStatusLines > 0) {\n log(\n `Sanitized combined stall output for ${sessionId}: removed ${removedEchoLines} echoed lines and ${removedStatusLines} status lines`,\n );\n }\n if (!sanitizedOutput && removedEchoLines + removedStatusLines > 0) {\n log(\n `Combined classify+decide short-circuit for ${sessionId}: only echoed input / status noise remained`,\n );\n return { state: \"still_working\" };\n }\n\n const systemPrompt = buildCombinedClassifyDecidePrompt(\n agentType,\n sessionId,\n sanitizedOutput || effectiveOutput,\n taskContext,\n decisionHistory,\n );\n\n if (ctx.debugSnapshots) {\n await writeStallSnapshot(\n sessionId,\n agentType,\n recentOutput,\n effectiveOutput,\n buffers,\n traceEntries,\n log,\n );\n }\n\n try {\n log(\n `Stall detected for coordinator-managed ${sessionId}, combined classify+decide...`,\n );\n const result = await withTrajectoryContext(\n runtime,\n {\n source: \"orchestrator\",\n decisionType: \"stall-classify-decide\",\n sessionId,\n taskLabel: taskContext.label,\n repo: taskContext.repo,\n workdir: taskContext.workdir,\n originalTask: taskContext.originalTask,\n },\n () => runtime.useModel(ModelType.TEXT_SMALL, { prompt: systemPrompt }),\n );\n\n const parsed = parseStallClassificationResponse(result);\n if (!parsed) {\n log(`Combined classify+decide: no parseable JSON in LLM response`);\n return null;\n }\n\n // Same downgrade rationale as classifyStallOutput: the LLM's task_complete\n // guess from buffer text is unreliable on long multi-step tasks. Authoritative\n // completion comes from the agent's hook system (pty-service.handleHookEvent)\n // and the jsonl-based completion watcher in the eliza package.\n let mappedState: StallClassification[\"state\"];\n if (parsed.state === \"tool_running\" || parsed.state === \"task_complete\") {\n mappedState = \"still_working\";\n if (parsed.state === \"task_complete\") {\n log(\n `Combined classify+decide for ${sessionId}: LLM said task_complete — downgrading to still_working (authoritative completion comes from hooks)`,\n );\n }\n } else {\n mappedState = parsed.state as StallClassification[\"state\"];\n }\n\n // Deterministic safety guard: if the LLM approved access to a path\n // outside the workspace, override with a decline. This runs before\n // pty-manager auto-responds, so the unsafe approval never reaches the agent.\n if (mappedState === \"waiting_for_input\" && parsed.suggestedResponse) {\n const promptText = typeof parsed.prompt === \"string\" ? parsed.prompt : \"\";\n const responseText = parsed.suggestedResponse.trim().toLowerCase();\n const approving = [\"y\", \"yes\", \"keys:enter\", \"keys:down,enter\"].includes(\n responseText,\n );\n const hasAbsPath = /(?:^|[\\s\"'`])\\/[^\\s\"'`]+/.test(promptText);\n if (\n approving &&\n hasAbsPath &&\n !promptText.includes(taskContext.workdir)\n ) {\n log(\n `Combined classify+decide: overriding out-of-scope approval for ${sessionId}`,\n );\n parsed.suggestedResponse = `n — That path is outside your workspace. Use ${taskContext.workdir} instead.`;\n }\n }\n\n const classification: StallClassification = {\n state: mappedState,\n prompt: parsed.prompt,\n suggestedResponse: parsed.suggestedResponse,\n };\n if (\n classification.state === \"waiting_for_input\" &&\n promptLooksLikeFalseBlockedNoise(classification.prompt, ctx.lastSentInput)\n ) {\n log(\n `Combined classify+decide override for ${sessionId}: prompt looked like echoed input / status noise`,\n );\n return { state: \"still_working\" };\n }\n log(\n `Combined classify+decide for ${sessionId}: ${classification.state}${classification.suggestedResponse ? ` → \"${classification.suggestedResponse}\"` : \"\"}`,\n );\n if (classification.state === \"task_complete\") {\n const session = manager?.get(sessionId);\n const durationMs = session?.startedAt\n ? Date.now() - new Date(session.startedAt).getTime()\n : 0;\n metricsTracker.recordCompletion(agentType, \"classifier\", durationMs);\n }\n return classification;\n } catch (err) {\n log(`Combined classify+decide failed: ${err}`);\n return null;\n }\n}\n",
|
|
23
|
+
"/**\n * Structured proof bridge — captures `APP_CREATE_DONE` / `PLUGIN_CREATE_DONE`\n * sentinels emitted by spawned task agents and persists the structured claim\n * onto the owning task's session metadata so the custom validator can\n * cross-check the claim against actual disk state.\n *\n * Sibling to `skill-callback-bridge.ts`. Unlike the skill bridge, this bridge\n * never dispatches anything back into the runtime — it only records the\n * proof and echoes a brief acknowledgement to the PTY so the agent knows\n * the orchestrator saw it.\n *\n * Sentinel grammar (one per session, on its own line):\n *\n * APP_CREATE_DONE {\"appName\":\"foo\",\"files\":[...],\"tests\":{\"passed\":N,\"failed\":0},\"lint\":\"ok\",\"typecheck\":\"ok\"}\n * PLUGIN_CREATE_DONE {\"pluginName\":\"plugin-bar\",\"files\":[...],\"tests\":{\"passed\":N,\"failed\":0},\"lint\":\"ok\",\"typecheck\":\"ok\"}\n *\n * @module services/structured-proof-bridge\n */\n\nimport type { IAgentRuntime, Logger } from \"@elizaos/core\";\nimport type { PTYService } from \"./pty-service.js\";\nimport type { TaskRegistry } from \"./task-registry.js\";\n\nconst LOG_PREFIX = \"[StructuredProof]\";\nconst LEGACY_PROOF_FIELDS = [\"name\", \"testsPassed\", \"lintClean\"] as const;\n\nconst STRUCTURED_PROOF_DIRECTIVE_RE =\n /^[\\t ]*(APP_CREATE_DONE|PLUGIN_CREATE_DONE)[\\t ]+(\\{[\\s\\S]*?\\})[\\t ]*$/m;\n\nexport type StructuredProofKind = \"APP_CREATE_DONE\" | \"PLUGIN_CREATE_DONE\";\nexport type StructuredProofStatus = \"ok\";\n\nexport interface StructuredProofTests {\n passed: number;\n failed: number;\n}\n\ninterface BaseStructuredProofClaim {\n /** Kind of completion sentinel emitted by the child. */\n kind: StructuredProofKind;\n /** Relative paths the child claims to have created/modified. Required. */\n files: string[];\n /** Test result summary from the child verification run. */\n tests: StructuredProofTests;\n /** Lint status. Completion proofs only accept \"ok\". */\n lint: StructuredProofStatus;\n /** Typecheck status. Completion proofs only accept \"ok\". */\n typecheck: StructuredProofStatus;\n /** Wall-clock timestamp when this proof was recorded. */\n recordedAt: number;\n /** Any other JSON fields the child included. */\n extra?: Record<string, unknown>;\n}\n\nexport interface AppStructuredProofClaim extends BaseStructuredProofClaim {\n kind: \"APP_CREATE_DONE\";\n appName: string;\n}\n\nexport interface PluginStructuredProofClaim extends BaseStructuredProofClaim {\n kind: \"PLUGIN_CREATE_DONE\";\n pluginName: string;\n}\n\nexport type StructuredProofClaim =\n | AppStructuredProofClaim\n | PluginStructuredProofClaim;\n\ntype ParsedStructuredProof =\n | { kind: \"APP_CREATE_DONE\"; claim: AppStructuredProofClaim }\n | { kind: \"PLUGIN_CREATE_DONE\"; claim: PluginStructuredProofClaim };\n\ntype StructuredProofLogger = Pick<Logger, \"info\" | \"warn\" | \"error\">;\n\nconst NOOP_LOGGER: StructuredProofLogger = {\n info: () => undefined,\n warn: () => undefined,\n error: () => undefined,\n};\n\nfunction getLogger(runtime: IAgentRuntime): StructuredProofLogger {\n const candidate = (runtime as { logger?: StructuredProofLogger }).logger;\n return candidate ?? NOOP_LOGGER;\n}\n\nfunction isPlainStringArray(value: unknown): value is string[] {\n return (\n Array.isArray(value) && value.every((entry) => typeof entry === \"string\")\n );\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return Boolean(value) && typeof value === \"object\" && !Array.isArray(value);\n}\n\nfunction hasOwnField(obj: Record<string, unknown>, field: string): boolean {\n return Object.hasOwn(obj, field);\n}\n\nfunction isNonNegativeInteger(value: unknown): value is number {\n return (\n typeof value === \"number\" &&\n Number.isInteger(value) &&\n Number.isFinite(value) &&\n value >= 0\n );\n}\n\nfunction parseStructuredProofTests(\n value: unknown,\n): { ok: true; tests: StructuredProofTests } | { ok: false; reason: string } {\n if (!isPlainObject(value)) {\n return { ok: false, reason: \"'tests' must be an object\" };\n }\n const passed = value.passed;\n const failed = value.failed;\n if (!isNonNegativeInteger(passed)) {\n return {\n ok: false,\n reason: \"'tests.passed' must be a non-negative integer\",\n };\n }\n if (!isNonNegativeInteger(failed)) {\n return {\n ok: false,\n reason: \"'tests.failed' must be a non-negative integer\",\n };\n }\n if (failed !== 0) {\n return { ok: false, reason: \"'tests.failed' must be 0\" };\n }\n return { ok: true, tests: { passed, failed } };\n}\n\nfunction getNameField(kind: StructuredProofKind): \"appName\" | \"pluginName\" {\n return kind === \"APP_CREATE_DONE\" ? \"appName\" : \"pluginName\";\n}\n\nfunction getOppositeNameField(\n kind: StructuredProofKind,\n): \"appName\" | \"pluginName\" {\n return kind === \"APP_CREATE_DONE\" ? \"pluginName\" : \"appName\";\n}\n\nfunction getStructuredProofName(claim: StructuredProofClaim): string {\n return claim.kind === \"APP_CREATE_DONE\" ? claim.appName : claim.pluginName;\n}\n\nfunction buildParsedStructuredProof(\n kind: StructuredProofKind,\n canonicalName: string,\n files: string[],\n tests: StructuredProofTests,\n extra: Record<string, unknown> | undefined,\n): ParsedStructuredProof {\n const base = {\n files,\n tests,\n lint: \"ok\" as const,\n typecheck: \"ok\" as const,\n recordedAt: Date.now(),\n ...(extra ? { extra } : {}),\n };\n if (kind === \"APP_CREATE_DONE\") {\n return {\n kind,\n claim: {\n kind,\n appName: canonicalName,\n ...base,\n },\n };\n }\n return {\n kind,\n claim: {\n kind,\n pluginName: canonicalName,\n ...base,\n },\n };\n}\n\n/**\n * Parse the first APP_CREATE_DONE / PLUGIN_CREATE_DONE directive in a chunk\n * of agent output, if any. The directive must be on its own line (after\n * optional whitespace) and the JSON must include all required fields:\n * `appName`/`pluginName`, `files`, `tests`, `lint`, and `typecheck`.\n * Anything missing returns a structured \"invalid\" result so the bridge can\n * log without persisting.\n */\nexport function parseStructuredProofDirective(\n text: string,\n):\n | { ok: true; parsed: ParsedStructuredProof }\n | { ok: false; reason: string }\n | null {\n if (!text) return null;\n const match = STRUCTURED_PROOF_DIRECTIVE_RE.exec(text);\n if (!match) return null;\n const kind = match[1] as StructuredProofKind;\n const jsonRaw = match[2];\n let payload: unknown;\n try {\n payload = JSON.parse(jsonRaw);\n } catch (err) {\n return {\n ok: false,\n reason: `JSON parse failed: ${\n err instanceof Error ? err.message : String(err)\n }`,\n };\n }\n if (!isPlainObject(payload)) {\n return { ok: false, reason: \"payload must be a JSON object\" };\n }\n const obj = payload;\n for (const field of LEGACY_PROOF_FIELDS) {\n if (hasOwnField(obj, field)) {\n return {\n ok: false,\n reason: `field '${field}' is not supported`,\n };\n }\n }\n const nameField = getNameField(kind);\n const oppositeNameField = getOppositeNameField(kind);\n if (hasOwnField(obj, oppositeNameField)) {\n return {\n ok: false,\n reason: `'${oppositeNameField}' is not valid for ${kind}`,\n };\n }\n const rawName = obj[nameField];\n const files = obj.files;\n if (typeof rawName !== \"string\" || rawName.trim().length === 0) {\n return { ok: false, reason: `missing or empty '${nameField}'` };\n }\n if (!isPlainStringArray(files)) {\n return { ok: false, reason: \"'files' must be string[]\" };\n }\n const parsedTests = parseStructuredProofTests(obj.tests);\n if (!parsedTests.ok) {\n return parsedTests;\n }\n if (obj.lint !== \"ok\") {\n return { ok: false, reason: \"'lint' must be \\\"ok\\\"\" };\n }\n if (obj.typecheck !== \"ok\") {\n return { ok: false, reason: \"'typecheck' must be \\\"ok\\\"\" };\n }\n // Preserve any unknown JSON fields under `extra` so downstream validators\n // can read them without re-parsing the line.\n const known = new Set([nameField, \"files\", \"tests\", \"lint\", \"typecheck\"]);\n const extra: Record<string, unknown> = {};\n let hasExtra = false;\n for (const [key, value] of Object.entries(obj)) {\n if (known.has(key)) continue;\n extra[key] = value;\n hasExtra = true;\n }\n const parsed = buildParsedStructuredProof(\n kind,\n rawName.trim(),\n files,\n parsedTests.tests,\n hasExtra ? extra : undefined,\n );\n return { ok: true, parsed };\n}\n\ninterface BridgeDeps {\n runtime: IAgentRuntime;\n ptyService: PTYService;\n /** Optional override for tests / non-default registries. */\n taskRegistry?: TaskRegistry;\n}\n\n/**\n * Per-runtime install guard — prevents stacking duplicate listeners when\n * many spawn calls fire concurrently. Mirrors the skill bridge.\n */\nconst installedRuntimes = new WeakSet<object>();\n\n/**\n * Per-session idempotency: only persist the FIRST structured proof we see\n * for a given session. Subsequent sentinels are logged and skipped so a\n * looping agent cannot rewrite its own claim. Cleared on session teardown\n * (the entry naturally drops at process exit; we do not aggressively GC).\n */\nconst persistedSessions = new Set<string>();\n\n/**\n * Reset per-session state. Tests use this to assert idempotency cleanly.\n * Production callers can call this when a session is recycled, but the\n * bridge is robust either way — duplicates are just logged.\n */\nexport function _resetStructuredProofBridge(): void {\n persistedSessions.clear();\n}\n\nfunction resolveTaskRegistry(deps: BridgeDeps): TaskRegistry | null {\n if (deps.taskRegistry) return deps.taskRegistry;\n const coordinator = deps.ptyService.coordinator;\n return coordinator?.taskRegistry ?? null;\n}\n\n/**\n * Ensure the bridge is installed exactly once for this runtime+PTY pair.\n * Safe to call from PTYService.start() and from every task spawn.\n */\nexport function ensureStructuredProofBridge(\n runtime: IAgentRuntime,\n ptyService: PTYService,\n): void {\n const runtimeKey = runtime as object;\n if (installedRuntimes.has(runtimeKey)) return;\n installedRuntimes.add(runtimeKey);\n installStructuredProofBridge({ runtime, ptyService });\n}\n\n/**\n * Install the structured-proof bridge. Returns a teardown function. Safe to\n * call multiple times — the caller is responsible for deduplication via\n * `ensureStructuredProofBridge` (or by tracking the returned teardown).\n */\nexport function installStructuredProofBridge(deps: BridgeDeps): () => void {\n const { runtime, ptyService } = deps;\n const log = getLogger(runtime);\n\n const recordProof = async (\n sessionId: string,\n parsed: ParsedStructuredProof,\n ): Promise<void> => {\n const proofName = getStructuredProofName(parsed.claim);\n if (persistedSessions.has(sessionId)) {\n log.info?.(\n `${LOG_PREFIX} duplicate ${parsed.kind} for session ${sessionId} (name=${proofName}); skipping`,\n );\n // Echo back so the agent doesn't think the orchestrator missed it,\n // but make it explicit that this is a duplicate.\n await ptyService.sendToSession(\n sessionId,\n `--- structured proof duplicate ignored (${parsed.kind}, ${proofName}) ---`,\n );\n return;\n }\n\n const registry = resolveTaskRegistry(deps);\n if (!registry) {\n log.warn?.(\n `${LOG_PREFIX} no task registry available; cannot persist proof for session ${sessionId}`,\n );\n return;\n }\n\n // Mark as persisted BEFORE the await so concurrent sentinels in the\n // same buffer chunk don't both win the idempotency check.\n persistedSessions.add(sessionId);\n\n await registry.updateSession(sessionId, {\n metadata: {\n structuredProof: parsed.claim,\n },\n });\n log.info?.(\n `${LOG_PREFIX} recorded ${parsed.kind} for session ${sessionId} ` +\n `(name=${proofName}, files=${parsed.claim.files.length}, ` +\n `tests.passed=${parsed.claim.tests.passed}, ` +\n `tests.failed=${parsed.claim.tests.failed}, ` +\n `lint=${parsed.claim.lint}, typecheck=${parsed.claim.typecheck})`,\n );\n await ptyService.sendToSession(\n sessionId,\n `--- structured proof recorded (${parsed.kind}, ${proofName}) ---`,\n );\n };\n\n const unsubscribe = ptyService.onSessionEvent((sessionId, event, data) => {\n if (event !== \"task_complete\" && event !== \"message\") return;\n const responseText =\n typeof (data as { response?: unknown })?.response === \"string\"\n ? (data as { response: string }).response\n : typeof (data as { text?: unknown })?.text === \"string\"\n ? (data as { text: string }).text\n : \"\";\n const parseResult = parseStructuredProofDirective(responseText);\n if (!parseResult) return;\n if (!parseResult.ok) {\n log.warn?.(\n `${LOG_PREFIX} session ${sessionId} emitted malformed structured proof: ${parseResult.reason}`,\n );\n return;\n }\n\n void recordProof(sessionId, parseResult.parsed).catch((err) => {\n // Roll back the idempotency mark on failure so a retry can succeed.\n persistedSessions.delete(sessionId);\n log.error?.(\n `${LOG_PREFIX} failed to persist proof for session ${sessionId}: ${\n err instanceof Error ? err.message : String(err)\n }`,\n );\n });\n });\n\n log.info?.(`${LOG_PREFIX} structured-proof bridge installed`);\n\n return () => {\n if (typeof unsubscribe === \"function\") unsubscribe();\n };\n}\n",
|
|
24
|
+
"/**\n * Custom validator runner — sibling to `task-validation.ts`.\n *\n * The default validator (`validateTaskCompletion`) runs an LLM-based pass\n * over the agent's turn output and workspace evidence. That works for the\n * generic case, but specialized task types (APP.create, PLUGIN.create, etc.)\n * own their own verification surface — disk layout, manifest shape, lint\n * results, test exit codes — and the orchestrator should defer to that\n * verification rather than reasoning over it through an LLM.\n *\n * `runCustomValidator` resolves a runtime service by name, calls the named\n * method with the supplied params (plus the structured-proof claim, if any),\n * and returns a normalized `{ verdict, retryablePromptForChild }` result the\n * decision loop can act on. Every failure path returns `verdict: \"fail\"`\n * with a concrete `retryablePromptForChild` so the loop never crashes on a\n * misconfigured spec.\n *\n * @module services/custom-validator-runner\n */\n\nimport type { IAgentRuntime } from \"@elizaos/core\";\n\nexport interface CustomValidatorSpec {\n /** Runtime service name passed to `runtime.getService(...)`. */\n service: string;\n /** Method name to invoke on the resolved service. */\n method: string;\n /**\n * Free-form params object the orchestrator passes through to the\n * validator. Validators are responsible for typing this on their side.\n */\n params: Record<string, unknown>;\n}\n\nexport type CustomValidatorVerdict = \"pass\" | \"fail\";\n\nexport interface CustomValidatorResult {\n verdict: CustomValidatorVerdict;\n /**\n * Concrete next-turn prompt the orchestrator will send back to the child\n * when the verdict is \"fail\". When the verdict is \"pass\" this field is\n * still populated for trace/log purposes but the orchestrator ignores it.\n */\n retryablePromptForChild: string;\n /**\n * Pass-through structured details from the validator service. Persisted\n * on the validation report and surfaced on escalation events.\n */\n details?: unknown;\n}\n\n/**\n * Resolve `ELIZA_APP_VERIFICATION_MAX_RETRIES`. Per-task `maxRetries`\n * override wins; otherwise the env var; otherwise the documented default\n * of 3. A negative value falls through to the next source.\n */\nexport function getMaxRetries(taskOverride?: number): number {\n if (typeof taskOverride === \"number\" && taskOverride >= 0)\n return taskOverride;\n const env = process.env.ELIZA_APP_VERIFICATION_MAX_RETRIES;\n const parsed = env ? Number.parseInt(env, 10) : Number.NaN;\n return Number.isFinite(parsed) && parsed >= 0 ? parsed : 3;\n}\n\ninterface ServiceMethodMap {\n [method: string]: (params: Record<string, unknown>) => unknown;\n}\n\nfunction isCallableMethod(\n service: unknown,\n method: string,\n): service is ServiceMethodMap {\n return (\n typeof service === \"object\" &&\n service !== null &&\n typeof (service as Record<string, unknown>)[method] === \"function\"\n );\n}\n\nfunction failResult(\n retryablePromptForChild: string,\n details?: unknown,\n): CustomValidatorResult {\n return details === undefined\n ? { verdict: \"fail\", retryablePromptForChild }\n : { verdict: \"fail\", retryablePromptForChild, details };\n}\n\nfunction normalizeVerdict(value: unknown): CustomValidatorVerdict | null {\n return value === \"pass\" || value === \"fail\" ? value : null;\n}\n\nfunction extractRetryPrompt(payload: Record<string, unknown>): string {\n const candidate = payload.retryablePromptForChild;\n if (typeof candidate === \"string\" && candidate.trim().length > 0) {\n return candidate;\n }\n // Some validators may use a slightly different field name; tolerate the\n // common alternate \"followUpPrompt\" so we don't lose a useful prompt.\n const alt = payload.followUpPrompt;\n if (typeof alt === \"string\" && alt.trim().length > 0) return alt;\n return \"Verification failed but no follow-up prompt was supplied.\";\n}\n\n/**\n * Invoke a custom validator service+method and normalize the result. Never\n * throws — every failure path collapses into `verdict: \"fail\"` with a\n * descriptive `retryablePromptForChild` so the decision loop can stay on\n * the happy path.\n *\n * @param runtime Eliza runtime for `getService`.\n * @param spec `{ service, method, params }` from the task metadata.\n * @param structuredProof Optional claim recorded by the structured-proof\n * bridge. Validators that want to cross-check claims\n * against disk receive this under `params.structuredProof`.\n */\nexport async function runCustomValidator(\n runtime: IAgentRuntime,\n spec: CustomValidatorSpec,\n structuredProof?: unknown,\n): Promise<CustomValidatorResult> {\n const service = runtime.getService(spec.service);\n if (!service) {\n return failResult(\n `Validator service '${spec.service}' is not registered on the runtime. ` +\n `Cannot verify completion for method '${spec.method}'. ` +\n `If you are the agent, surface this to the user — the orchestrator cannot self-recover.`,\n );\n }\n if (!isCallableMethod(service, spec.method)) {\n return failResult(\n `Validator service '${spec.service}' has no callable method '${spec.method}'. ` +\n `Cannot verify completion. Surface this to the user.`,\n );\n }\n\n const callParams: Record<string, unknown> =\n structuredProof === undefined\n ? { ...spec.params }\n : { ...spec.params, structuredProof };\n\n let raw: unknown;\n try {\n raw = await service[spec.method](callParams);\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n return failResult(\n `Verification call to ${spec.service}.${spec.method} threw: ${message}. ` +\n `Re-attempt the work and resolve the underlying error before claiming completion.`,\n );\n }\n\n if (!raw || typeof raw !== \"object\" || Array.isArray(raw)) {\n return failResult(\n `Verification call to ${spec.service}.${spec.method} returned a non-object result. ` +\n `Treating as failure.`,\n raw,\n );\n }\n\n const payload = raw as Record<string, unknown>;\n const verdict = normalizeVerdict(payload.verdict);\n if (verdict === null) {\n return failResult(\n `Verification call to ${spec.service}.${spec.method} returned an invalid verdict ` +\n `(expected \"pass\" or \"fail\"). Treating as failure.`,\n raw,\n );\n }\n\n const retryablePromptForChild = extractRetryPrompt(payload);\n // `details` is whatever the validator chose to attach (checks[], summary,\n // etc.). We pass through the entire payload so callers don't have to chase\n // missing fields one by one.\n const result: CustomValidatorResult = {\n verdict,\n retryablePromptForChild,\n details: raw,\n };\n return result;\n}\n",
|
|
25
|
+
"/**\n * Prompt construction and response parsing for the Swarm Coordinator's\n * LLM-driven coordination decisions.\n *\n * Pure functions — no side effects, easy to test.\n * Pattern follows stall-classifier.ts:buildStallClassificationPrompt().\n *\n * @module services/swarm-coordinator-prompts\n */\n\nimport { parseJsonObjectResponse } from \"./json-model-output.js\";\n\n/** Per-session task context provided to the LLM for decision-making. */\nexport interface TaskContextSummary {\n sessionId: string;\n agentType: string;\n label: string;\n originalTask: string;\n workdir: string;\n repo?: string;\n}\n\n/** A previous coordination decision, included for context continuity. */\nexport interface DecisionHistoryEntry {\n event: string;\n promptText: string;\n action: string;\n response?: string;\n reasoning: string;\n}\n\n/** Summary of a sibling task in the same swarm — for cross-task context. */\nexport interface SiblingTaskSummary {\n label: string;\n agentType: string;\n originalTask: string;\n status: string;\n /** Last significant decision or action taken by this sibling. */\n lastKeyDecision?: string;\n /** Summary of what the sibling accomplished (populated on completion). */\n completionSummary?: string;\n}\n\n/** A significant creative or architectural decision made by an agent in the swarm. */\nexport interface SharedDecision {\n /** Which agent made this decision. */\n agentLabel: string;\n /** Brief description of the decision. */\n summary: string;\n /** When it was recorded. */\n timestamp: number;\n}\n\n/**\n * Build a context section describing sibling tasks in the same swarm.\n * Helps the coordinator make decisions with awareness of the broader project.\n */\nfunction buildSiblingSection(siblings?: SiblingTaskSummary[]): string {\n if (!siblings || siblings.length === 0) return \"\";\n const lines = siblings.map((s) => {\n let line = ` - [${s.status}] \"${s.label}\" (${s.agentType}): ${s.originalTask}`;\n if (s.completionSummary) {\n line += `\\n Result: ${s.completionSummary}`;\n } else if (s.lastKeyDecision) {\n line += `\\n Latest: ${s.lastKeyDecision}`;\n }\n return line;\n });\n return (\n `\\nOther agents in this swarm:\\n` +\n lines.join(\"\\n\") +\n `\\nUse this context when the agent asks creative or architectural questions — ` +\n `your answer should be consistent with what sibling agents are doing.\\n`\n );\n}\n\n/**\n * Build a context section describing significant decisions made by other agents.\n * Helps maintain consistency across the swarm regardless of task type.\n */\nfunction buildSharedDecisionsSection(decisions?: SharedDecision[]): string {\n if (!decisions || decisions.length === 0) return \"\";\n return (\n `\\nKey decisions made by other agents in this swarm:\\n` +\n decisions\n .slice(-10)\n .map((d) => ` - [${d.agentLabel}] ${d.summary}`)\n .join(\"\\n\") +\n `\\nAlign with these decisions for consistency — don't contradict them unless the task requires it.\\n`\n );\n}\n\n/** Build a project context section from the swarm planning phase. */\nfunction buildSwarmContextSection(swarmContext?: string): string {\n if (!swarmContext) return \"\";\n return `\\nProject context (from planning phase):\\n${swarmContext}\\n`;\n}\n\n/** Parsed LLM response for a coordination decision. */\nexport interface CoordinationLLMResponse {\n action: \"respond\" | \"escalate\" | \"ignore\" | \"complete\";\n /** Text to send (for action=respond with plain text input). */\n response?: string;\n /** Whether to use sendKeysToSession instead of sendToSession. */\n useKeys?: boolean;\n /** Key sequence to send (for TUI interactions). e.g. [\"enter\"] or [\"down\",\"enter\"]. */\n keys?: string[];\n /** LLM's reasoning for the decision. */\n reasoning: string;\n /** Brief summary of a significant creative/architectural decision the agent made, if any. */\n keyDecision?: string;\n}\n\n/**\n * Build the LLM prompt for making a coordination decision about a blocked agent.\n */\nexport function buildCoordinationPrompt(\n taskCtx: TaskContextSummary,\n promptText: string,\n recentOutput: string,\n decisionHistory: DecisionHistoryEntry[],\n siblingTasks?: SiblingTaskSummary[],\n sharedDecisions?: SharedDecision[],\n swarmContext?: string,\n): string {\n const historySection =\n decisionHistory.length > 0\n ? `\\nPrevious decisions for this session:\\n${decisionHistory\n .slice(-5)\n .map(\n (d, i) =>\n ` ${i + 1}. [${d.event}] prompt=\"${d.promptText}\" → ${d.action}${d.response ? ` (\"${d.response}\")` : \"\"} — ${d.reasoning}`,\n )\n .join(\"\\n\")}\\n`\n : \"\";\n\n return (\n `You are Eliza, an AI orchestrator managing a swarm of task agents. ` +\n `A ${taskCtx.agentType} task agent (\"${taskCtx.label}\", session: ${taskCtx.sessionId}) ` +\n `is blocked and waiting for input.\\n\\n` +\n `Original task: \"${taskCtx.originalTask}\"\\n` +\n `Working directory: ${taskCtx.workdir}\\n` +\n `Repository: ${taskCtx.repo ?? \"none (scratch directory)\"}\\n` +\n buildSwarmContextSection(swarmContext) +\n buildSiblingSection(siblingTasks) +\n buildSharedDecisionsSection(sharedDecisions) +\n historySection +\n `\\nRecent terminal output (last 50 lines):\\n` +\n `---\\n${recentOutput.slice(-3000)}\\n---\\n\\n` +\n `The agent is showing this blocking prompt:\\n` +\n `\"${promptText}\"\\n\\n` +\n `Decide how to respond. Your options:\\n\\n` +\n `1. \"respond\" — Send a response to unblock the agent. For text prompts (Y/n, questions), ` +\n `set \"response\" to the text to send. For TUI menus or interactive prompts that need ` +\n `special keys, set \"useKeys\": true and \"keys\" to the key sequence ` +\n `(e.g. [\"enter\"], [\"down\",\"enter\"], [\"y\",\"enter\"]).\\n\\n` +\n `2. \"complete\" — The original task has been fulfilled. The agent has finished its work ` +\n `(e.g. code written, PR created, tests passed) and is back at the idle prompt. ` +\n `Use this when the terminal output shows the task objectives have been met.\\n\\n` +\n `3. \"escalate\" — The prompt requires human judgment (e.g. design decisions, ` +\n `ambiguous requirements, security-sensitive actions). Do NOT respond yourself.\\n\\n` +\n `4. \"ignore\" — The prompt is not actually blocking or is already being handled.\\n\\n` +\n `Guidelines:\\n` +\n `- IMPORTANT: If the prompt asks to approve access to files or directories OUTSIDE the working ` +\n `directory (${taskCtx.workdir}), DECLINE the request and REDIRECT the agent. Do NOT approve ` +\n `access to paths like /etc, ~/.ssh, ~/, /tmp, or any path that doesn't start with the working ` +\n `directory. Instead, respond with \"n\" (or the decline option) and tell the agent: ` +\n `\"That path is outside your workspace. Use ${taskCtx.workdir} instead — ` +\n `create any files or directories you need there.\" This keeps the agent moving without ` +\n `granting out-of-scope access. The coordinator will also notify the human in case ` +\n `broader access was intended.\\n` +\n `- For tool approval prompts (file writes, shell commands, etc.), respond \"y\" or use keys:[\"enter\"] to approve.\\n` +\n `- For Y/n confirmations that align with the original task, respond \"y\".\\n` +\n `- For design questions or choices that could go either way, escalate.\\n` +\n `- For error recovery prompts, try to respond if the path forward is clear.\\n` +\n `- If the output shows a PR was just created (e.g. \"Created pull request #N\"), use \"complete\" — the task is done.\\n` +\n `- If the agent is asking for information that was NOT provided in the original task ` +\n `(e.g. which repository to use, project requirements, credentials), ESCALATE. ` +\n `The coordinator does not have this information — the human must provide it.\\n` +\n `- When in doubt, escalate — it's better to ask the human than to make a wrong choice.\\n` +\n `- If the agent's output reveals a significant decision that sibling agents should know about ` +\n `(e.g. chose a library, designed an API shape, picked a UI pattern, established a writing style, ` +\n `narrowed a research scope, made any choice that affects the shared project), ` +\n `include \"keyDecision\" with a brief one-line summary. Skip this for routine tool approvals.\\n` +\n `- Look for explicit \"DECISION:\" markers in the agent's output — these are the agent deliberately ` +\n `surfacing design choices. Always capture these as keyDecision.\\n\\n` +\n `Respond with JSON only:\\n` +\n `{\"action\":\"respond\",\"response\":\"y\",\"useKeys\":false,\"keys\":[],\"reasoning\":\"One short reason.\",\"keyDecision\":\"Optional one-line shared decision.\"}`\n );\n}\n\n/**\n * Build the LLM prompt for checking on an idle session that hasn't\n * produced any events for a while.\n */\nexport function buildIdleCheckPrompt(\n taskCtx: TaskContextSummary,\n recentOutput: string,\n idleMinutes: number,\n idleCheckNumber: number,\n maxIdleChecks: number,\n decisionHistory: DecisionHistoryEntry[],\n siblingTasks?: SiblingTaskSummary[],\n sharedDecisions?: SharedDecision[],\n swarmContext?: string,\n): string {\n const historySection =\n decisionHistory.length > 0\n ? `\\nPrevious decisions for this session:\\n${decisionHistory\n .slice(-5)\n .map(\n (d, i) =>\n ` ${i + 1}. [${d.event}] prompt=\"${d.promptText}\" → ${d.action}${d.response ? ` (\"${d.response}\")` : \"\"} — ${d.reasoning}`,\n )\n .join(\"\\n\")}\\n`\n : \"\";\n\n return (\n `You are Eliza, an AI orchestrator managing a swarm of task agents. ` +\n `A ${taskCtx.agentType} task agent (\"${taskCtx.label}\", session: ${taskCtx.sessionId}) ` +\n `has been idle for ${idleMinutes} minutes with no events or output changes.\\n\\n` +\n `Original task: \"${taskCtx.originalTask}\"\\n` +\n `Working directory: ${taskCtx.workdir}\\n` +\n `Repository: ${taskCtx.repo ?? \"none (scratch directory)\"}\\n` +\n `Idle check: ${idleCheckNumber} of ${maxIdleChecks} (session will be force-escalated after ${maxIdleChecks})\\n` +\n buildSwarmContextSection(swarmContext) +\n buildSiblingSection(siblingTasks) +\n buildSharedDecisionsSection(sharedDecisions) +\n historySection +\n `\\nRecent terminal output (last 50 lines):\\n` +\n `---\\n${recentOutput.slice(-3000)}\\n---\\n\\n` +\n `The session has gone silent. Analyze the terminal output and decide:\\n\\n` +\n `1. \"complete\" — The task is FULLY done. ALL objectives in the original task were met ` +\n `AND the final deliverable is visible in the output (e.g. a PR URL was printed, or the ` +\n `task explicitly did not require a PR). The agent is back at the idle prompt.\\n\\n` +\n `2. \"respond\" — The agent appears stuck or waiting for input that wasn't detected ` +\n `as a blocking prompt. Send a message to nudge it (e.g. \"continue\", or answer a question ` +\n `visible in the output). If code was committed but no PR was created yet, respond with ` +\n `\"please create a pull request with your changes\" or similar.\\n\\n` +\n `3. \"escalate\" — Something looks wrong or unclear. The human should review.\\n\\n` +\n `4. \"ignore\" — The agent is still actively working (e.g. compiling, running tests, ` +\n `pushing to remote, creating a PR). The idle period is expected and it will produce output soon.\\n\\n` +\n `Guidelines:\\n` +\n `- IMPORTANT: Do NOT mark \"complete\" if the original task involves creating a PR and no PR URL ` +\n `(e.g. github.com/...pull/...) appears in the output. Instead use \"respond\" to nudge the agent ` +\n `to create the PR.\\n` +\n `- Do NOT mark \"complete\" just because code was committed — commits alone don't finish a task ` +\n `that requires a PR.\\n` +\n `- Network operations (git push, gh pr create, API calls) can cause several minutes of silence — ` +\n `prefer \"ignore\" for early idle checks if the agent was mid-workflow.\\n` +\n `- If the output ends with a command prompt ($ or >) and ALL task objectives are confirmed met, use \"complete\".\\n` +\n `- If the output shows an error or the agent seems stuck in a loop, escalate.\\n` +\n `- If the agent is clearly mid-operation (build output, test runner, git operations), use \"ignore\".\\n` +\n `- On check ${idleCheckNumber} of ${maxIdleChecks} — if unsure, lean toward \"respond\" with a nudge rather than \"complete\".\\n` +\n `- If the agent's output reveals a significant creative or architectural decision, ` +\n `include \"keyDecision\" with a brief one-line summary.\\n` +\n `- Look for explicit \"DECISION:\" markers in the agent's output — always capture these as keyDecision.\\n\\n` +\n // CRITICAL constraint on the `response` field — fixes a real bug\n // where LLMs produced 3rd-person status reports that then got\n // piped verbatim into the agent's stdin as if the user typed them.\n `CRITICAL — \"response\" field format rules:\\n` +\n `- When action is \"respond\", the \"response\" string is sent VERBATIM into the agent's terminal as if the user typed it.\\n` +\n `- It MUST be a brief, second-person imperative addressed directly to the agent. Examples: \"continue\", \"please create the pull request\", \"answer the question above\", \"proceed with the next step\".\\n` +\n `- NEVER write a third-person status report about the agent. Do NOT write things like \"The agent is still setting up\" or \"The agent needs to continue its work\" — that text would be piped into the agent's stdin and confuse it into thinking a new user message arrived describing itself.\\n` +\n `- NEVER describe the situation in the response field. If you need to explain your reasoning, put it in the \"reasoning\" field instead.\\n` +\n `- Keep the response under 20 words when possible. Short nudges work best.\\n\\n` +\n `Respond with JSON only:\\n` +\n `{\"action\":\"respond\",\"response\":\"continue\",\"useKeys\":false,\"keys\":[],\"reasoning\":\"One short reason.\",\"keyDecision\":\"Optional one-line shared decision.\"}`\n );\n}\n\n/**\n * Build the LLM prompt for assessing whether a completed turn means the\n * overall task is done, or if the agent needs more turns.\n *\n * Called when the adapter detects \"task_complete\" (agent finished a turn and\n * returned to the idle prompt). The LLM decides whether to stop the session\n * or send a follow-up instruction.\n */\nexport function buildTurnCompletePrompt(\n taskCtx: TaskContextSummary,\n turnOutput: string,\n decisionHistory: DecisionHistoryEntry[],\n siblingTasks?: SiblingTaskSummary[],\n sharedDecisions?: SharedDecision[],\n swarmContext?: string,\n): string {\n const historySection =\n decisionHistory.length > 0\n ? `\\nPrevious decisions for this session:\\n${decisionHistory\n .slice(-5)\n .map(\n (d, i) =>\n ` ${i + 1}. [${d.event}] prompt=\"${d.promptText}\" → ${d.action}${d.response ? ` (\"${d.response}\")` : \"\"} — ${d.reasoning}`,\n )\n .join(\"\\n\")}\\n`\n : \"\";\n\n return (\n `You are Eliza, an AI orchestrator managing a swarm of task agents. ` +\n `A ${taskCtx.agentType} task agent (\"${taskCtx.label}\", session: ${taskCtx.sessionId}) ` +\n `just finished a turn and is back at the idle prompt waiting for input.\\n\\n` +\n `Original task: \"${taskCtx.originalTask}\"\\n` +\n `Working directory: ${taskCtx.workdir}\\n` +\n `Repository: ${taskCtx.repo ?? \"none (scratch directory)\"}\\n` +\n buildSwarmContextSection(swarmContext) +\n buildSiblingSection(siblingTasks) +\n buildSharedDecisionsSection(sharedDecisions) +\n historySection +\n `\\nOutput from this turn:\\n` +\n `---\\n${turnOutput.slice(-3000)}\\n---\\n\\n` +\n `The agent completed a turn. Decide if the task is done or needs more work.\\n\\n` +\n `Options:\\n` +\n `1. \"complete\" — The task objectives have been met.\\n` +\n ` - For repo tasks: ONLY when a PR creation signal appears (\"Created pull request #N\"). ` +\n `A generic \"done\" or \"finished\" statement is NOT sufficient for repo tasks — a PR must exist.\\n` +\n ` - For scratch/research tasks (no repo): when the agent has produced its deliverable.\\n` +\n `2. \"respond\" — The agent needs to do more work.\\n` +\n `3. \"escalate\" — Something is wrong. Let the human decide.\\n` +\n `4. \"ignore\" — The agent is still working (e.g., spinner text like \"Germinating...\", \"Frosting...\"). ` +\n `Wait for the next turn.\\n\\n` +\n `CRITICAL RULES:\\n` +\n `- For repo tasks: use \"complete\" ONLY when \"Created pull request #N\" appears in output.\\n` +\n `- For scratch/research tasks: use \"complete\" when the agent delivers its output.\\n` +\n `- Do NOT ask the agent to review, verify, or re-check work it already completed.\\n` +\n `- If output is only spinner text, use \"ignore\" and wait for the next turn.\\n` +\n `- Use \"respond\" when the agent hasn't started, or when code was written but not yet committed/pushed/PR'd.\\n\\n` +\n `If the agent's output reveals a significant decision, include \"keyDecision\" with a brief summary.\\n\\n` +\n `Respond with JSON only:\\n` +\n `{\"action\":\"complete\",\"response\":\"\",\"useKeys\":false,\"keys\":[],\"reasoning\":\"One short reason.\",\"keyDecision\":\"Optional one-line shared decision.\"}`\n );\n}\n\n// ─── Event Messages for Eliza Pipeline ───\n\n/**\n * Build a natural language event message describing a blocked agent, intended\n * to be processed by Eliza's full ElizaOS pipeline (with conversation memory,\n * personality, and actions). Unlike buildCoordinationPrompt(), this omits the\n * \"You are Eliza\" preamble (she already IS Eliza in the pipeline) and asks\n * for a JSON action object at the end of her response.\n */\nexport function buildBlockedEventMessage(\n taskCtx: TaskContextSummary,\n promptText: string,\n recentOutput: string,\n decisionHistory: DecisionHistoryEntry[],\n siblingTasks?: SiblingTaskSummary[],\n sharedDecisions?: SharedDecision[],\n swarmContext?: string,\n): string {\n const historySection =\n decisionHistory.length > 0\n ? `\\nPrevious decisions:\\n${decisionHistory\n .slice(-5)\n .map(\n (d, i) =>\n ` ${i + 1}. [${d.event}] \"${d.promptText}\" → ${d.action}${d.response ? ` (\"${d.response}\")` : \"\"} — ${d.reasoning}`,\n )\n .join(\"\\n\")}\\n`\n : \"\";\n\n return (\n `[Task Agent Event] A ${taskCtx.agentType} agent (\"${taskCtx.label}\") is blocked and waiting for input.\\n\\n` +\n `Task: \"${taskCtx.originalTask}\"\\n` +\n `Workdir: ${taskCtx.workdir}\\n` +\n `Repo: ${taskCtx.repo ?? \"none (scratch directory)\"}\\n` +\n buildSwarmContextSection(swarmContext) +\n buildSiblingSection(siblingTasks) +\n buildSharedDecisionsSection(sharedDecisions) +\n historySection +\n `\\nRecent terminal output:\\n---\\n${recentOutput.slice(-3000)}\\n---\\n\\n` +\n `Blocking prompt: \"${promptText}\"\\n\\n` +\n `Decide how to handle this. Options:\\n` +\n `- \"respond\" — send text or keys to unblock the agent\\n` +\n `- \"complete\" — the task is fully done\\n` +\n `- \"escalate\" — you need the user's input\\n` +\n `- \"ignore\" — not actually blocking\\n\\n` +\n `Guidelines:\\n` +\n `- For tool approvals / Y/n that align with the task, respond \"y\" or keys:[\"enter\"].\\n` +\n `- If the prompt asks for info NOT in the original task, escalate.\\n` +\n `- Decline access to paths outside ${taskCtx.workdir}.\\n` +\n `- If a PR was just created, the task is done — use \"complete\".\\n` +\n `- When in doubt, escalate.\\n\\n` +\n `If the agent's output reveals a significant decision that sibling agents should know about, include \"keyDecision\" with a brief summary.\\n` +\n `Look for explicit \"DECISION:\" markers in the agent's output — always capture these as keyDecision.\\n\\n` +\n `Include a JSON action object at the end of your response:\\n` +\n `{\"action\":\"respond\",\"response\":\"y\",\"useKeys\":false,\"keys\":[],\"reasoning\":\"One short reason.\",\"keyDecision\":\"Optional one-line shared decision.\"}`\n );\n}\n\n/**\n * Build a natural language event message describing a turn completion, intended\n * to be processed by Eliza's full ElizaOS pipeline.\n */\nexport function buildTurnCompleteEventMessage(\n taskCtx: TaskContextSummary,\n turnOutput: string,\n decisionHistory: DecisionHistoryEntry[],\n siblingTasks?: SiblingTaskSummary[],\n sharedDecisions?: SharedDecision[],\n swarmContext?: string,\n): string {\n const historySection =\n decisionHistory.length > 0\n ? `\\nPrevious decisions:\\n${decisionHistory\n .slice(-5)\n .map(\n (d, i) =>\n ` ${i + 1}. [${d.event}] \"${d.promptText}\" → ${d.action}${d.response ? ` (\"${d.response}\")` : \"\"} — ${d.reasoning}`,\n )\n .join(\"\\n\")}\\n`\n : \"\";\n\n return (\n `[Task Agent Event] A ${taskCtx.agentType} agent (\"${taskCtx.label}\") just finished a turn and is idle.\\n\\n` +\n `Task: \"${taskCtx.originalTask}\"\\n` +\n `Workdir: ${taskCtx.workdir}\\n` +\n `Repo: ${taskCtx.repo ?? \"none (scratch directory)\"}\\n` +\n buildSwarmContextSection(swarmContext) +\n buildSiblingSection(siblingTasks) +\n buildSharedDecisionsSection(sharedDecisions) +\n historySection +\n `\\nTurn output:\\n---\\n${turnOutput.slice(-3000)}\\n---\\n\\n` +\n `Decide if the overall task is done or if the agent needs more work.\\n\\n` +\n `Options:\\n` +\n `- \"respond\" — send a follow-up instruction (DEFAULT for intermediate steps)\\n` +\n `- \"complete\" — For repo tasks: ONLY when \"Created pull request #N\" appears. ` +\n `For scratch/research tasks: when the agent delivers its output.\\n` +\n `- \"escalate\" — something looks wrong, ask the user\\n` +\n `- \"ignore\" — spinner/loading output, agent still working\\n\\n` +\n `Guidelines:\\n` +\n `- For repo tasks, a generic \"done\" is NOT enough — require a PR creation signal.\\n` +\n `- If code was written but not committed/pushed/PR'd, respond with next step.\\n` +\n `- Do NOT ask the agent to re-verify work it already completed.\\n` +\n `- If the agent's output reveals a significant creative or architectural decision, include \"keyDecision\" with a brief summary.\\n` +\n `- Look for explicit \"DECISION:\" markers in the agent's output — always capture these as keyDecision.\\n\\n` +\n `Include a JSON action object at the end of your response:\\n` +\n `{\"action\":\"respond\",\"response\":\"please create the pull request\",\"useKeys\":false,\"keys\":[],\"reasoning\":\"One short reason.\",\"keyDecision\":\"Optional one-line shared decision.\"}`\n );\n}\n\n/**\n * Parse the LLM's coordination response from raw text output.\n * Returns null if the response is invalid or unparseable.\n */\nfunction normalizeCoordinationResponse(\n parsed: unknown,\n): CoordinationLLMResponse | null {\n if (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n return null;\n }\n const record = parsed as Record<string, unknown>;\n const validActions = [\"respond\", \"escalate\", \"ignore\", \"complete\"];\n if (!validActions.includes(String(record.action))) return null;\n\n const result: CoordinationLLMResponse = {\n action: String(record.action) as CoordinationLLMResponse[\"action\"],\n reasoning:\n typeof record.reasoning === \"string\" && record.reasoning.trim()\n ? record.reasoning.trim()\n : \"No reasoning provided\",\n };\n\n if (result.action === \"respond\") {\n const useKeys =\n record.useKeys === true ||\n (typeof record.useKeys === \"string\" &&\n record.useKeys.trim().toLowerCase() === \"true\");\n if (useKeys) {\n const keys = Array.isArray(record.keys)\n ? record.keys.map(String).filter(Boolean)\n : typeof record.keys === \"string\" && record.keys.trim()\n ? record.keys\n .split(\",\")\n .map((key) => key.trim())\n .filter(Boolean)\n : [];\n if (keys.length === 0) return null;\n result.useKeys = true;\n result.keys = keys;\n } else if (typeof record.response === \"string\" && record.response.trim()) {\n result.response = record.response;\n } else {\n return null;\n }\n }\n\n if (typeof record.keyDecision === \"string\" && record.keyDecision.trim()) {\n result.keyDecision = record.keyDecision.trim().slice(0, 240);\n }\n\n return result;\n}\n\nexport function parseCoordinationResponse(\n llmOutput: string,\n): CoordinationLLMResponse | null {\n const parsedJson =\n parseJsonObjectResponse<Record<string, unknown>>(llmOutput);\n const normalizedJson = normalizeCoordinationResponse(parsedJson);\n if (normalizedJson) return normalizedJson;\n\n return null;\n}\n",
|
|
26
|
+
"/**\n * Event Triage — classifies coordinator events as \"routine\" or \"creative\"\n * to route them to the fast small-LLM path or the full Eliza pipeline.\n *\n * Tier 1 (auto-response rules at PTY worker) already handled before we get here.\n * This module splits the remaining events into:\n * - \"routine\": simple approvals, permissions, config prompts → small LLM (~1-2s)\n * - \"creative\": error recovery, design questions, task evaluation → Eliza (~5-10s)\n *\n * Pure functions — no side effects, same pattern as stall-classifier.ts.\n *\n * @module services/swarm-event-triage\n */\n\nimport { type IAgentRuntime, ModelType } from \"@elizaos/core\";\nimport { parseJsonObjectResponse } from \"./json-model-output.js\";\nimport { withTrajectoryContext } from \"./trajectory-context.js\";\n\n// ─── Types ───\n\nexport type TriageTier = \"routine\" | \"creative\";\n\nexport interface TriageContext {\n /** \"blocked\" or \"turn_complete\" */\n eventType: \"blocked\" | \"turn_complete\";\n /** The blocking prompt text (empty for turn completions). */\n promptText: string;\n /** Adapter's promptInfo.type if available. */\n promptType?: string;\n /** Recent terminal output (for turn completions). */\n recentOutput?: string;\n /** The original task description. */\n originalTask: string;\n}\n\n// ─── Heuristic Sets ───\n\n/** Prompt types from coding-agent-adapters that are always routine. */\nconst ROUTINE_PROMPT_TYPES = new Set([\n \"permission\",\n \"config\",\n \"tos\",\n \"tool_wait\",\n]);\n\n/** Prompt types that always need creative/contextual handling. */\nconst CREATIVE_PROMPT_TYPES = new Set([\"project_select\", \"model_select\"]);\n\n/** Regex patterns that indicate routine approval prompts. */\nconst ROUTINE_PATTERNS: RegExp[] = [\n /\\bAllow\\s+tool\\b/i,\n /\\(Y\\/n\\)/,\n /\\(y\\/N\\)/,\n /\\bTrust\\s+(this\\s+)?directory\\b/i,\n /\\bProceed\\?/i,\n /\\boverwrite\\?/i,\n /\\bDo you trust\\b/i,\n /\\bAllow access\\b/i,\n /\\bGrant permission\\b/i,\n /\\bAccept\\?/i,\n /\\bContinue\\?/i,\n /\\bPermit\\b.*\\?/i,\n /\\bApprove\\b.*\\?/i,\n];\n\n/** Regex patterns that indicate creative / contextual decision needed. */\nconst CREATIVE_PATTERNS: RegExp[] = [\n /\\bWhich approach\\b/i,\n /\\bHow should\\b/i,\n /\\btests? failing\\b/i,\n /\\bchoose between\\b/i,\n /\\bpick (one|a|an)\\b/i,\n /\\bWhat do you (want|think)\\b/i,\n /\\berror recover/i,\n /\\bfailed with\\b/i,\n /\\bcompilation error/i,\n /\\bbuild failed\\b/i,\n /\\btype error/i,\n /\\bmerge conflict/i,\n];\n\n/** Turn-complete output patterns that are obviously terminal (routine). */\nconst TERMINAL_OUTPUT_PATTERNS: RegExp[] = [\n /All \\d+ tests? pass/i,\n /Tests?:\\s+\\d+ passed/i,\n /✓ All checks passed/i,\n /https:\\/\\/github\\.com\\/[^\\s]+\\/pull\\/\\d+/,\n /Successfully created PR/i,\n /Commit [a-f0-9]{7,40}/i,\n];\n\n/** Turn-complete output patterns that are obviously intermediate (routine → continue). */\nconst INTERMEDIATE_OUTPUT_PATTERNS: RegExp[] = [\n /^Running tests?\\.\\.\\./im,\n /^Building\\.\\.\\./im,\n /^Installing dependencies/im,\n];\n\n// ─── Heuristic Classifier ───\n\n/**\n * Classify an event tier using only heuristics (prompt type + regex).\n * Returns null if inconclusive.\n */\nexport function classifyByHeuristic(ctx: TriageContext): TriageTier | null {\n // 1. Check adapter-provided prompt type\n if (ctx.promptType) {\n if (ROUTINE_PROMPT_TYPES.has(ctx.promptType)) return \"routine\";\n if (CREATIVE_PROMPT_TYPES.has(ctx.promptType)) return \"creative\";\n }\n\n // 2. For blocked events, check prompt text patterns\n if (ctx.eventType === \"blocked\" && ctx.promptText) {\n const hasRoutine = ROUTINE_PATTERNS.some((r) => r.test(ctx.promptText));\n const hasCreative = CREATIVE_PATTERNS.some((r) => r.test(ctx.promptText));\n\n if (hasRoutine && !hasCreative) return \"routine\";\n if (hasCreative && !hasRoutine) return \"creative\";\n // Both or neither → inconclusive\n if (hasCreative) return \"creative\"; // creative wins ties\n }\n\n // 3. For turn completions, check output patterns\n if (ctx.eventType === \"turn_complete\" && ctx.recentOutput) {\n const recent = ctx.recentOutput;\n const isTerminal = TERMINAL_OUTPUT_PATTERNS.some((r) => r.test(recent));\n const isIntermediate = INTERMEDIATE_OUTPUT_PATTERNS.some((r) =>\n r.test(recent),\n );\n\n if (isTerminal || isIntermediate) return \"routine\";\n // For turn completions, bias toward creative — most benefit from task context\n }\n\n return null; // Inconclusive — needs LLM classifier\n}\n\n// ─── LLM Classifier ───\n\n/**\n * Build a short classifier prompt for ambiguous events.\n */\nexport function buildTriagePrompt(ctx: TriageContext): string {\n const eventDesc =\n ctx.eventType === \"blocked\"\n ? `BLOCKED prompt: \"${ctx.promptText.slice(0, 300)}\"`\n : `TURN COMPLETE. Recent output:\\n${(ctx.recentOutput ?? \"\").slice(-500)}`;\n\n return [\n \"task: classify_task_agent_event\",\n `originalTask: ${ctx.originalTask.slice(0, 200)}`,\n `eventType: ${ctx.eventType}`,\n \"event: |\",\n ...eventDesc.split(\"\\n\").map((line) => ` ${line}`),\n \"tiers:\",\n \" routine: simple approval, permission, config, yes/no, tool consent, obvious pass/fail\",\n \" creative: task context needed, error recovery, design choice, ambiguity, approach selection\",\n \"Return JSON only with this shape:\",\n '{\"tier\":\"routine\"}',\n ].join(\"\\n\");\n}\n\n/**\n * Parse the LLM's triage response. Returns null on failure.\n */\nexport function parseTriageResponse(llmOutput: string): TriageTier | null {\n const parsedJson =\n parseJsonObjectResponse<Record<string, unknown>>(llmOutput);\n if (parsedJson?.tier === \"routine\" || parsedJson?.tier === \"creative\") {\n return parsedJson.tier;\n }\n\n const matches = llmOutput.matchAll(/\\{[\\s\\S]*?\\}/g);\n for (const match of matches) {\n try {\n const parsed = JSON.parse(match[0]);\n if (parsed.tier === \"routine\" || parsed.tier === \"creative\") {\n return parsed.tier;\n }\n } catch {\n // Try next match\n }\n }\n return null;\n}\n\n/**\n * Main entry point: classify an event as routine or creative.\n *\n * 1. Heuristics (0ms)\n * 2. Small LLM classifier (~500ms-1s) if heuristics are inconclusive\n * 3. Default to \"creative\" if classifier fails (safe default)\n */\nexport async function classifyEventTier(\n runtime: IAgentRuntime,\n ctx: TriageContext,\n log: (msg: string) => void,\n): Promise<TriageTier> {\n // Step 1: Heuristic classification\n const heuristicResult = classifyByHeuristic(ctx);\n if (heuristicResult) {\n log(`Triage: heuristic → ${heuristicResult}`);\n return heuristicResult;\n }\n\n // Step 2: Small LLM classifier\n try {\n const prompt = buildTriagePrompt(ctx);\n const result = await withTrajectoryContext(\n runtime,\n { source: \"orchestrator\", decisionType: \"event-triage\" },\n () => runtime.useModel(ModelType.TEXT_SMALL, { prompt }),\n );\n const tier = parseTriageResponse(result);\n if (tier) {\n log(`Triage: LLM → ${tier}`);\n return tier;\n }\n log(`Triage: LLM returned unparseable response — defaulting to creative`);\n } catch (err) {\n log(`Triage: LLM classifier failed: ${err} — defaulting to creative`);\n }\n\n // Step 3: Safe default\n return \"creative\";\n}\n",
|
|
27
|
+
"import { execFile } from \"node:child_process\";\nimport { createHash } from \"node:crypto\";\nimport { mkdir, readdir, stat, writeFile } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport path from \"node:path\";\nimport { promisify } from \"node:util\";\n\nconst execFileAsync = promisify(execFile);\n\nimport { type IAgentRuntime, ModelType, resolveStateDir } from \"@elizaos/core\";\nimport { parseJsonObjectResponse } from \"./json-model-output.js\";\nimport type {\n SwarmCoordinatorContext,\n TaskContext,\n} from \"./swarm-coordinator.js\";\nimport type { TaskThreadDetail } from \"./task-registry.js\";\nimport { withTrajectoryContext } from \"./trajectory-context.js\";\n\ntype ValidationVerdict = \"pass\" | \"revise\" | \"escalate\";\n\ninterface TrajectoryListItem {\n id: string;\n status: string;\n llmCallCount: number;\n createdAt: string;\n metadata?: Record<string, unknown>;\n}\n\ninterface ValidationResponse {\n verdict: ValidationVerdict;\n summary: string;\n followUpPrompt?: string;\n checklist?: string[];\n}\n\nexport interface TaskValidationResult {\n verdict: ValidationVerdict;\n summary: string;\n followUpPrompt?: string;\n reportPath: string;\n artifacts: Array<{\n artifactType: string;\n title: string;\n path?: string | null;\n uri?: string | null;\n mimeType?: string | null;\n metadata?: Record<string, unknown>;\n }>;\n}\n\nexport interface ValidateTaskCompletionInput {\n sessionId: string;\n taskCtx: TaskContext;\n completionReasoning: string;\n completionSummary: string;\n turnOutput: string;\n}\n\ntype TrajectoryLoggerLike = {\n listTrajectories?: (options?: {\n limit?: number;\n offset?: number;\n search?: string;\n startDate?: string;\n }) => Promise<{ trajectories?: TrajectoryListItem[] } | null | undefined>;\n};\n\ntype ScreenshotSemanticResult = {\n contentVerified: boolean;\n contentSummary?: string;\n contentVerificationError?: string;\n};\n\nfunction normalizeValidationResponse(\n parsed: unknown,\n): ValidationResponse | null {\n if (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n return null;\n }\n const record = parsed as Record<string, unknown>;\n const verdict = record.verdict;\n const summary =\n typeof record.summary === \"string\" ? record.summary.trim() : \"\";\n if (\n (verdict !== \"pass\" && verdict !== \"revise\" && verdict !== \"escalate\") ||\n !summary\n ) {\n return null;\n }\n const followUpPrompt =\n typeof record.followUpPrompt === \"string\"\n ? record.followUpPrompt.trim()\n : \"\";\n const checklist = Array.isArray(record.checklist)\n ? record.checklist.filter(\n (item): item is string =>\n typeof item === \"string\" && item.trim().length > 0,\n )\n : undefined;\n return {\n verdict,\n summary,\n ...(followUpPrompt ? { followUpPrompt } : {}),\n ...(checklist && checklist.length > 0 ? { checklist } : {}),\n };\n}\n\nfunction parseValidationResponse(raw: string): ValidationResponse | null {\n return normalizeValidationResponse(parseJsonObjectResponse(raw));\n}\n\nfunction getValidationRootDir(): string {\n return path.join(resolveStateDir(), \"task-validation\");\n}\n\nfunction truncate(text: string, limit = 1200): string {\n const compact = text.replace(/\\s+/g, \" \").trim();\n if (compact.length <= limit) return compact;\n return `${compact.slice(0, limit)}...`;\n}\n\nfunction pngHeaderValid(buffer: Uint8Array): boolean {\n if (buffer.length < 8) return false;\n const signature = [137, 80, 78, 71, 13, 10, 26, 10];\n return signature.every((value, index) => buffer[index] === value);\n}\n\ntype ValidationScreenshotCapture =\n | {\n status: \"captured\";\n path: string;\n sizeBytes: number;\n fileIntegrityVerified: boolean;\n sha256: string;\n captureScope: \"desktop-fullscreen\";\n contentVerified: boolean;\n contentSummary?: string;\n contentVerificationError?: string;\n }\n | {\n status: \"unavailable\";\n reason: string;\n };\n\nfunction resolveLoopbackApiBase(): string {\n const port =\n process.env.ELIZA_API_PORT?.trim() ||\n process.env.ELIZA_PORT?.trim() ||\n \"31337\";\n return `http://127.0.0.1:${port}`;\n}\n\nasync function captureValidationScreenshot(\n runtime: IAgentRuntime,\n task: TaskContext,\n thread: TaskThreadDetail | null,\n sessionId: string,\n): Promise<ValidationScreenshotCapture> {\n try {\n const token =\n process.env.ELIZA_API_TOKEN?.trim() ||\n process.env.ELIZA_API_AUTH_TOKEN?.trim();\n const response = await fetch(\n `${resolveLoopbackApiBase()}/api/dev/cursor-screenshot`,\n {\n headers: token ? { Authorization: `Bearer ${token}` } : undefined,\n },\n );\n if (!response.ok) {\n return {\n status: \"unavailable\",\n reason: `HTTP ${response.status} from /api/dev/cursor-screenshot`,\n };\n }\n\n const bytes = new Uint8Array(await response.arrayBuffer());\n if (bytes.length === 0) {\n return {\n status: \"unavailable\",\n reason: \"Screenshot endpoint returned an empty PNG payload\",\n };\n }\n\n const dir = path.join(getValidationRootDir(), task.threadId);\n await mkdir(dir, { recursive: true });\n const screenshotPath = path.join(\n dir,\n `screenshot-${sessionId}-${Date.now()}.png`,\n );\n await writeFile(screenshotPath, bytes);\n\n const screenshotDescription = await describeScreenshotContent(\n runtime,\n task,\n thread,\n bytes,\n );\n\n return {\n status: \"captured\",\n path: screenshotPath,\n sizeBytes: bytes.length,\n fileIntegrityVerified: pngHeaderValid(bytes) && bytes.length > 1024,\n sha256: createHash(\"sha256\").update(bytes).digest(\"hex\"),\n captureScope: \"desktop-fullscreen\",\n contentVerified: screenshotDescription.contentVerified,\n ...(screenshotDescription.contentSummary\n ? { contentSummary: screenshotDescription.contentSummary }\n : {}),\n ...(screenshotDescription.contentVerificationError\n ? {\n contentVerificationError:\n screenshotDescription.contentVerificationError,\n }\n : {}),\n };\n } catch (error) {\n return {\n status: \"unavailable\",\n reason: error instanceof Error ? error.message : String(error),\n };\n }\n}\n\nasync function listRelevantTrajectories(\n runtime: IAgentRuntime,\n task: TaskContext,\n thread: TaskThreadDetail | null,\n): Promise<TrajectoryListItem[]> {\n const logger = runtime.getService(\"trajectories\") as\n | TrajectoryLoggerLike\n | null\n | undefined;\n if (!logger?.listTrajectories) {\n return [];\n }\n\n const searchTerms = [\n task.sessionId,\n task.threadId,\n task.label,\n task.originalTask,\n ]\n .map((value) => value?.trim())\n .filter((value): value is string => Boolean(value));\n\n const seen = new Set<string>();\n const trajectories: TrajectoryListItem[] = [];\n for (const search of searchTerms) {\n const result = await logger.listTrajectories({\n limit: 10,\n search,\n ...(thread?.createdAt ? { startDate: thread.createdAt } : {}),\n });\n for (const item of result?.trajectories ?? []) {\n if (seen.has(item.id)) continue;\n seen.add(item.id);\n const metadata = (item.metadata ?? {}) as Record<string, unknown>;\n const orchestrator = metadata.orchestrator as\n | Record<string, unknown>\n | undefined;\n const sessionMatches =\n orchestrator?.sessionId === task.sessionId ||\n metadata.sessionId === task.sessionId;\n const labelMatches =\n orchestrator?.taskLabel === task.label ||\n metadata.taskLabel === task.label;\n if (!sessionMatches && !labelMatches && search !== task.sessionId) {\n continue;\n }\n trajectories.push(item);\n if (trajectories.length >= 3) {\n return trajectories;\n }\n }\n }\n\n return trajectories;\n}\n\nfunction extractImageDescriptionText(raw: unknown): string | null {\n if (typeof raw === \"string\") {\n const trimmed = raw.trim();\n return trimmed.length > 0 ? trimmed : null;\n }\n if (raw && typeof raw === \"object\") {\n const description = (raw as { description?: unknown }).description;\n if (typeof description === \"string\" && description.trim().length > 0) {\n return description.trim();\n }\n }\n return null;\n}\n\nasync function describeScreenshotContent(\n runtime: IAgentRuntime,\n task: TaskContext,\n thread: TaskThreadDetail | null,\n bytes: Uint8Array,\n): Promise<ScreenshotSemanticResult> {\n try {\n const dataUri = `data:image/png;base64,${Buffer.from(bytes).toString(\"base64\")}`;\n const acceptanceCriteria = thread?.acceptanceCriteria?.length\n ? thread.acceptanceCriteria.map((item) => `- ${item}`).join(\"\\n\")\n : \"- none\";\n const raw = await runtime.useModel(ModelType.IMAGE_DESCRIPTION, {\n imageUrl: dataUri,\n prompt: [\n \"Describe this validation screenshot for an orchestrated task.\",\n \"Focus on visible terminal output, UI state, status banners, tests, errors, and other completion evidence.\",\n `Task: ${task.originalTask}`,\n \"Acceptance criteria:\",\n acceptanceCriteria,\n \"Return a concise factual description.\",\n ].join(\"\\n\"),\n });\n const contentSummary = extractImageDescriptionText(raw);\n if (!contentSummary) {\n return {\n contentVerified: false,\n contentVerificationError:\n \"Vision model returned no usable screenshot description.\",\n };\n }\n return {\n contentVerified: true,\n contentSummary: truncate(contentSummary, 800),\n };\n } catch (error) {\n return {\n contentVerified: false,\n contentVerificationError:\n error instanceof Error ? error.message : String(error),\n };\n }\n}\n\nfunction describeScreenshotEvidence(\n screenshot: ValidationScreenshotCapture,\n): string {\n if (screenshot.status !== \"captured\") {\n return `- status=unavailable reason=${screenshot.reason}`;\n }\n return `- status=captured scope=${screenshot.captureScope} fileIntegrityVerified=${screenshot.fileIntegrityVerified} contentVerified=${screenshot.contentVerified} sha256=${screenshot.sha256} path=${screenshot.path} sizeBytes=${screenshot.sizeBytes}${screenshot.contentSummary ? ` summary=${truncate(screenshot.contentSummary, 500)}` : \"\"}${screenshot.contentVerificationError ? ` contentVerificationError=${screenshot.contentVerificationError}` : \"\"}`;\n}\n\n/**\n * Objective filesystem snapshot of the workspace passed to the validator.\n *\n * Produced by `collectWorkspaceEvidence()`. Everything here is read from\n * disk and git — it does not depend on the agent's own turn output, so\n * the validator can see ground truth regardless of which CLI (Claude,\n * Codex, Gemini, Aider) produced the work. Codex in particular emits\n * `apply_patch` previews wrapped in TUI box-drawing that the validator\n * LLM can't reliably parse as evidence files actually exist.\n */\ninterface WorkspaceEvidence {\n workdir: string;\n /** Relative file paths (up to `fileLimit`), sorted for deterministic prompts. */\n files: string[];\n /** Total count of files found, including any truncated from `files`. */\n fileCount: number;\n /** True if `workdir` is inside a git working tree. */\n isGitRepo: boolean;\n /** `git status --short` output, trimmed. Empty string if not a git repo or clean. */\n gitStatus: string;\n /** `git diff --stat HEAD` output, trimmed. Empty if no diff or not a git repo. */\n gitDiffStat: string;\n /** Non-fatal collection errors we want to surface to the validator. */\n notes: string[];\n}\n\nexport const WORKSPACE_EVIDENCE_FILE_LIMIT = 200;\nexport const WORKSPACE_EVIDENCE_MAX_DEPTH = 5;\n// Hard ceiling on the total walk. We still report `fileCount` up to this\n// number, but stop walking once we cross it so an enormous tree (e.g.\n// someone passing `~` as workdir) can't wedge the validator.\nexport const WORKSPACE_EVIDENCE_MAX_WALK = 2_000;\nconst WORKSPACE_EVIDENCE_SKIP_DIRS = new Set([\n \".git\",\n \"node_modules\",\n \".next\",\n \"dist\",\n \"build\",\n \"out\",\n \"target\",\n \".turbo\",\n \"__pycache__\",\n \".venv\",\n \"venv\",\n \".DS_Store\",\n \".cache\",\n]);\n\n/**\n * Read the workspace filesystem to produce objective evidence for the\n * validator prompt.\n *\n * - Walks `workdir` up to `WORKSPACE_EVIDENCE_MAX_DEPTH` levels, skipping\n * common build/dep directories.\n * - Caps the file list at `WORKSPACE_EVIDENCE_FILE_LIMIT` entries; the\n * `fileCount` field still reflects the total discovered so the\n * validator can see truncation happened.\n * - If `workdir` is a git repository, captures `git status --short` and\n * `git diff --stat HEAD` so the validator can see uncommitted work.\n * - Never throws. All errors are captured in `notes` so the validator\n * can judge whether missing evidence should downgrade the verdict.\n */\nexport async function collectWorkspaceEvidence(\n workdir: string | undefined | null,\n): Promise<WorkspaceEvidence> {\n const evidence: WorkspaceEvidence = {\n workdir: workdir ?? \"\",\n files: [],\n fileCount: 0,\n isGitRepo: false,\n gitStatus: \"\",\n gitDiffStat: \"\",\n notes: [],\n };\n\n if (!workdir) {\n evidence.notes.push(\"no workdir supplied\");\n return evidence;\n }\n\n // Resolve ~ and confirm the directory exists.\n const resolved = workdir.startsWith(\"~\")\n ? path.join(homedir(), workdir.slice(1))\n : path.resolve(workdir);\n evidence.workdir = resolved;\n\n try {\n const rootStat = await stat(resolved);\n if (!rootStat.isDirectory()) {\n evidence.notes.push(`workdir is not a directory: ${resolved}`);\n return evidence;\n }\n } catch (err) {\n evidence.notes.push(\n `workdir not readable: ${err instanceof Error ? err.message : String(err)}`,\n );\n return evidence;\n }\n\n // Walk the tree breadth-first-ish and collect relative file paths.\n interface WalkEntry {\n name: string;\n isDirectory: () => boolean;\n isFile: () => boolean;\n }\n const collected: string[] = [];\n let totalCount = 0;\n let walkCeilingHit = false;\n const walk = async (dir: string, depth: number): Promise<void> => {\n if (depth > WORKSPACE_EVIDENCE_MAX_DEPTH) return;\n if (totalCount >= WORKSPACE_EVIDENCE_MAX_WALK) {\n walkCeilingHit = true;\n return;\n }\n let entries: WalkEntry[];\n try {\n entries = (await readdir(dir, { withFileTypes: true })) as WalkEntry[];\n } catch {\n return;\n }\n for (const entry of entries) {\n if (WORKSPACE_EVIDENCE_SKIP_DIRS.has(entry.name)) continue;\n if (totalCount >= WORKSPACE_EVIDENCE_MAX_WALK) {\n walkCeilingHit = true;\n break;\n }\n const full = path.join(dir, entry.name);\n if (entry.isDirectory()) {\n await walk(full, depth + 1);\n } else if (entry.isFile()) {\n totalCount++;\n if (collected.length < WORKSPACE_EVIDENCE_FILE_LIMIT) {\n collected.push(path.relative(resolved, full));\n }\n }\n }\n };\n\n try {\n await walk(resolved, 0);\n } catch (err) {\n evidence.notes.push(\n `walk failed: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n\n collected.sort();\n evidence.files = collected;\n evidence.fileCount = totalCount;\n if (walkCeilingHit) {\n evidence.notes.push(\n `workspace walk hit the ${WORKSPACE_EVIDENCE_MAX_WALK}-file ceiling; counts and listing are truncated`,\n );\n }\n\n // Git evidence — best-effort, silent on failure.\n try {\n await execFileAsync(\"git\", [\"rev-parse\", \"--is-inside-work-tree\"], {\n cwd: resolved,\n timeout: 3_000,\n });\n evidence.isGitRepo = true;\n try {\n const { stdout } = await execFileAsync(\n \"git\",\n [\"status\", \"--short\", \"--untracked-files=all\"],\n { cwd: resolved, timeout: 5_000, maxBuffer: 256 * 1024 },\n );\n evidence.gitStatus = stdout.trim();\n } catch {\n /* ignore */\n }\n try {\n const { stdout } = await execFileAsync(\n \"git\",\n [\"diff\", \"--stat\", \"HEAD\"],\n { cwd: resolved, timeout: 5_000, maxBuffer: 256 * 1024 },\n );\n evidence.gitDiffStat = stdout.trim();\n } catch {\n // No HEAD yet (empty repo) or other error — fall back to a\n // full diff against the empty tree.\n try {\n const { stdout } = await execFileAsync(\"git\", [\"diff\", \"--stat\"], {\n cwd: resolved,\n timeout: 5_000,\n maxBuffer: 256 * 1024,\n });\n evidence.gitDiffStat = stdout.trim();\n } catch {\n /* ignore */\n }\n }\n } catch {\n // Not a git repo, or git not installed. Both fine — filesystem\n // listing alone is still useful for scratch dirs.\n }\n\n return evidence;\n}\n\nfunction formatWorkspaceEvidence(evidence: WorkspaceEvidence): string {\n if (!evidence.workdir) return \"- no workdir supplied\";\n if (evidence.fileCount === 0 && evidence.notes.length > 0) {\n return `- workdir: ${evidence.workdir}\\n- ${evidence.notes.join(\"\\n- \")}`;\n }\n\n const lines: string[] = [];\n lines.push(`workdir: ${evidence.workdir}`);\n lines.push(\n `file count: ${evidence.fileCount}${\n evidence.files.length < evidence.fileCount\n ? ` (showing first ${evidence.files.length})`\n : \"\"\n }`,\n );\n if (evidence.files.length > 0) {\n lines.push(\"files:\");\n for (const file of evidence.files) {\n lines.push(` ${file}`);\n }\n } else {\n lines.push(\"files: (workspace is empty)\");\n }\n if (evidence.isGitRepo) {\n lines.push(\n evidence.gitStatus\n ? `git status:\\n${indent(evidence.gitStatus, \" \")}`\n : \"git status: (clean or no changes)\",\n );\n if (evidence.gitDiffStat) {\n lines.push(\n `git diff --stat HEAD:\\n${indent(evidence.gitDiffStat, \" \")}`,\n );\n }\n }\n if (evidence.notes.length > 0) {\n lines.push(`notes: ${evidence.notes.join(\"; \")}`);\n }\n return lines.join(\"\\n\");\n}\n\nfunction indent(text: string, prefix: string): string {\n return text\n .split(\"\\n\")\n .map((line) => `${prefix}${line}`)\n .join(\"\\n\");\n}\n\nfunction buildValidationPrompt(\n task: TaskContext,\n thread: TaskThreadDetail | null,\n completionReasoning: string,\n completionSummary: string,\n turnOutput: string,\n trajectories: TrajectoryListItem[],\n screenshot: ValidationScreenshotCapture,\n workspaceEvidence: WorkspaceEvidence,\n): string {\n const acceptanceCriteria = thread?.acceptanceCriteria?.length\n ? thread.acceptanceCriteria.map((item) => `- ${item}`).join(\"\\n\")\n : \"- Complete the user's request\\n- Verify the result with available evidence\\n- Do not claim success if important work is still missing\";\n const completionExcerpt =\n turnOutput || completionSummary || completionReasoning || \"none\";\n const trajectoryBlock =\n trajectories.length > 0\n ? trajectories\n .map(\n (item) =>\n `- ${item.id} | status=${item.status} | llmCalls=${item.llmCallCount} | createdAt=${item.createdAt}`,\n )\n .join(\"\\n\")\n : \"- none\";\n const transcriptPreview =\n thread?.transcripts\n ?.slice(-8)\n .map((entry) => {\n const content = truncate(entry.content, 220);\n return `- [${entry.direction}] ${content}`;\n })\n .join(\"\\n\") ?? \"- none\";\n const artifactBlock =\n thread?.artifacts\n ?.slice(-8)\n .map((artifact) => {\n const locator = artifact.path ?? artifact.uri ?? \"inline\";\n return `- ${artifact.artifactType}: ${artifact.title} (${locator})`;\n })\n .join(\"\\n\") ?? \"- none\";\n\n return [\n \"You are validating whether an orchestrated task is actually finished.\",\n \"Return JSON only with this shape:\",\n JSON.stringify(\n {\n verdict: \"pass\",\n summary: \"concise user-facing result\",\n followUpPrompt: \"only if verdict=revise\",\n checklist: [\"optional evidence note\", \"optional evidence note\"],\n },\n null,\n 2,\n ),\n \"\",\n `Task title: ${task.label}`,\n `Original request: ${task.originalTask}`,\n `Completion reasoning: ${completionReasoning || \"none\"}`,\n `Completion summary: ${completionSummary || \"none\"}`,\n \"\",\n \"Acceptance criteria:\",\n acceptanceCriteria,\n \"\",\n \"Latest turn output excerpt:\",\n truncate(completionExcerpt, 2400),\n \"\",\n \"Recent transcript excerpt:\",\n transcriptPreview,\n \"\",\n \"Existing task artifacts:\",\n artifactBlock,\n \"\",\n \"Related trajectories:\",\n trajectoryBlock,\n \"\",\n \"Screenshot evidence:\",\n describeScreenshotEvidence(screenshot),\n \"\",\n // Objective filesystem evidence. This is the ground truth — it does\n // NOT depend on the agent's own turn output, so it is reliable\n // regardless of which CLI produced the work. Use this as the\n // primary signal for \"did files actually get created / modified\".\n \"Workspace evidence (read from disk):\",\n formatWorkspaceEvidence(workspaceEvidence),\n \"\",\n \"Rules:\",\n \"- Pass only if the task appears complete and the available evidence supports that claim.\",\n \"- When passing, write summary as the final result that can be shown to the requester. Use concrete facts from the transcript, artifacts, workspace evidence, screenshots, and trajectories. Preserve exact URLs and source links from the evidence when they are part of the result. Include important limitations or uncertainty. Do not describe the validation process.\",\n \"- Revise if the agent should keep working. In that case, provide a direct follow-up prompt.\",\n \"- Escalate if the task cannot be validated from available evidence and needs human review.\",\n \"- For information / question-answering / research tasks (no repo, no files expected), the completion summary IS the deliverable. Pass if the summary directly answers the original request with concrete content. Empty workspace evidence is expected for these and is not a failure signal.\",\n \"- For code / build tasks (repo set, or the request asks to create/edit/test files), missing tests or missing verification should usually mean revise or escalate, not pass.\",\n \"- Treat screenshot capture as artifact evidence only. A desktop screenshot may prove the UI rendered, but it does not semantically prove the task without supporting transcript, test, or trajectory evidence.\",\n \"- Trust the 'Workspace evidence' block over agent commentary: if files are listed there, they exist on disk, regardless of how the agent described its work. If the task was to create files and the workspace evidence shows them, that is strong evidence for pass.\",\n \"- Conversely, if the agent CLAIMS to have created files but the workspace evidence shows an empty directory or missing files, treat that as revise (not pass) — the agent's claim is unverified. This rule applies only when files were actually expected.\",\n ].join(\"\\n\");\n}\n\nasync function persistValidationReport(\n threadId: string,\n sessionId: string,\n report: Record<string, unknown>,\n): Promise<string> {\n const dir = path.join(getValidationRootDir(), threadId);\n await mkdir(dir, { recursive: true });\n const reportPath = path.join(\n dir,\n `validation-${sessionId}-${Date.now()}.json`,\n );\n await writeFile(reportPath, JSON.stringify(report, null, 2), \"utf8\");\n return reportPath;\n}\n\nexport async function validateTaskCompletion(\n ctx: SwarmCoordinatorContext,\n input: ValidateTaskCompletionInput,\n): Promise<TaskValidationResult> {\n const {\n sessionId,\n taskCtx,\n completionReasoning,\n completionSummary,\n turnOutput,\n } = input;\n const thread = await ctx.taskRegistry.getThread(taskCtx.threadId);\n const trajectories = await listRelevantTrajectories(\n ctx.runtime,\n taskCtx,\n thread,\n );\n const [screenshot, workspaceEvidence] = await Promise.all([\n captureValidationScreenshot(ctx.runtime, taskCtx, thread, sessionId),\n collectWorkspaceEvidence(taskCtx.workdir),\n ]);\n\n const prompt = buildValidationPrompt(\n taskCtx,\n thread,\n completionReasoning,\n completionSummary,\n turnOutput,\n trajectories,\n screenshot,\n workspaceEvidence,\n );\n const rawValidation = await withTrajectoryContext(\n ctx.runtime,\n {\n source: \"orchestrator\",\n decisionType: \"task-validation\",\n sessionId,\n taskLabel: taskCtx.label,\n repo: taskCtx.repo,\n workdir: taskCtx.workdir,\n originalTask: taskCtx.originalTask,\n },\n () => ctx.runtime.useModel(ModelType.TEXT_SMALL, { prompt }),\n );\n\n const parsed = parseValidationResponse(rawValidation);\n const verdict: ValidationResponse = parsed ?? {\n verdict: \"escalate\",\n summary:\n \"Validation model returned an invalid response, so this task needs human review.\",\n };\n\n const report = {\n version: 1,\n createdAt: new Date().toISOString(),\n threadId: taskCtx.threadId,\n sessionId,\n label: taskCtx.label,\n originalTask: taskCtx.originalTask,\n completionReasoning,\n completionSummary,\n verdict: verdict.verdict,\n summary: verdict.summary,\n followUpPrompt: verdict.followUpPrompt ?? null,\n acceptanceCriteria: thread?.acceptanceCriteria ?? [],\n evidence: {\n transcriptCount: thread?.transcripts.length ?? 0,\n decisionCount: thread?.decisions.length ?? 0,\n eventCount: thread?.events.length ?? 0,\n artifactCount: thread?.artifacts.length ?? 0,\n screenshot,\n trajectories: trajectories.map((item) => ({\n id: item.id,\n status: item.status,\n llmCallCount: item.llmCallCount,\n createdAt: item.createdAt,\n })),\n checklist: verdict.checklist ?? [],\n turnOutputExcerpt: truncate(\n turnOutput || completionSummary || completionReasoning || \"\",\n ),\n },\n };\n const reportPath = await persistValidationReport(\n taskCtx.threadId,\n sessionId,\n report,\n );\n\n const artifacts: TaskValidationResult[\"artifacts\"] = [\n {\n artifactType: \"validation_report\",\n title: `Validation report for ${taskCtx.label}`,\n path: reportPath,\n mimeType: \"application/json\",\n metadata: {\n verdict: verdict.verdict,\n summary: verdict.summary,\n },\n },\n ...trajectories.map((item) => ({\n artifactType: \"trajectory_link\",\n title: `Trajectory ${item.id}`,\n uri: `/api/trajectories/${encodeURIComponent(item.id)}`,\n metadata: {\n trajectoryId: item.id,\n status: item.status,\n llmCallCount: item.llmCallCount,\n },\n })),\n ];\n\n if (screenshot.status === \"captured\") {\n artifacts.push({\n artifactType: \"screenshot\",\n title: `Validation screenshot for ${taskCtx.label}`,\n path: screenshot.path,\n mimeType: \"image/png\",\n metadata: {\n fileIntegrityVerified: screenshot.fileIntegrityVerified,\n sizeBytes: screenshot.sizeBytes,\n sha256: screenshot.sha256,\n captureScope: screenshot.captureScope,\n contentVerified: screenshot.contentVerified,\n ...(screenshot.contentSummary\n ? { contentSummary: screenshot.contentSummary }\n : {}),\n ...(screenshot.contentVerificationError\n ? {\n contentVerificationError: screenshot.contentVerificationError,\n }\n : {}),\n },\n });\n }\n\n return {\n verdict: verdict.verdict,\n summary: verdict.summary,\n ...(verdict.followUpPrompt\n ? { followUpPrompt: verdict.followUpPrompt }\n : {}),\n reportPath,\n artifacts,\n };\n}\n",
|
|
28
|
+
"import { createHash } from \"node:crypto\";\nimport { mkdir, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { type IAgentRuntime, ModelType, resolveStateDir } from \"@elizaos/core\";\nimport { parseJsonObjectResponse } from \"./json-model-output.js\";\nimport type {\n TaskNodeRecord,\n TaskRegistry,\n TaskThreadDetail,\n TaskVerifierJobRecord,\n} from \"./task-registry.js\";\nimport { withTrajectoryContext } from \"./trajectory-context.js\";\n\ntype AcceptanceVerdict = \"pass\" | \"fail\";\n\ninterface AcceptanceChecklistItem {\n criterion: string;\n status: \"pass\" | \"fail\" | \"partial\";\n evidence: string;\n}\n\ninterface AcceptanceEvaluation {\n verdict: AcceptanceVerdict;\n summary: string;\n checklist: AcceptanceChecklistItem[];\n}\n\nconst terminalNodeStates = new Set([\n \"completed\",\n \"failed\",\n \"canceled\",\n \"interrupted\",\n]);\nconst activeVerifierRuns = new Set<string>();\n\nfunction normalizeChecklistItem(\n entry: unknown,\n): AcceptanceChecklistItem | null {\n if (!entry || typeof entry !== \"object\") {\n return null;\n }\n const record = entry as Record<string, unknown>;\n const criterion =\n typeof record.criterion === \"string\" ? record.criterion.trim() : \"\";\n const rawStatus =\n typeof record.status === \"string\" ? record.status.trim() : \"\";\n const evidence =\n typeof record.evidence === \"string\" ? record.evidence.trim() : \"\";\n if (!criterion || !evidence) {\n return null;\n }\n return {\n criterion,\n status:\n rawStatus === \"pass\" || rawStatus === \"fail\" || rawStatus === \"partial\"\n ? rawStatus\n : \"partial\",\n evidence,\n };\n}\n\nfunction normalizeAcceptanceEvaluation(\n parsed: unknown,\n): AcceptanceEvaluation | null {\n if (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n return null;\n }\n const record = parsed as Record<string, unknown>;\n if (\n (record.verdict !== \"pass\" && record.verdict !== \"fail\") ||\n typeof record.summary !== \"string\" ||\n record.summary.trim().length === 0\n ) {\n return null;\n }\n const rawChecklist = record.checklist;\n const checklist = Array.isArray(rawChecklist)\n ? rawChecklist\n .map(normalizeChecklistItem)\n .filter((entry): entry is AcceptanceChecklistItem => Boolean(entry))\n : [];\n return {\n verdict: record.verdict,\n summary: record.summary.trim(),\n checklist,\n };\n}\n\nfunction parseAcceptanceEvaluation(raw: string): AcceptanceEvaluation | null {\n return normalizeAcceptanceEvaluation(parseJsonObjectResponse(raw));\n}\n\nfunction getVerifierRootDir(): string {\n return path.join(resolveStateDir(), \"task-verifiers\");\n}\n\nfunction truncate(text: string, limit = 1_200): string {\n const compact = text.replace(/\\s+/g, \" \").trim();\n return compact.length <= limit ? compact : `${compact.slice(0, limit)}...`;\n}\n\nfunction isVerifierReady(\n thread: TaskThreadDetail,\n job: TaskVerifierJobRecord,\n): boolean {\n if (job.status !== \"pending\") return false;\n if (job.verifierType !== \"acceptance_criteria\") return false;\n const executionNodes = thread.nodes.filter((node) => node.kind !== \"goal\");\n if (executionNodes.some((node) => !terminalNodeStates.has(node.status))) {\n return false;\n }\n if (!job.nodeId) return true;\n const node = thread.nodes.find((entry) => entry.id === job.nodeId);\n return node ? terminalNodeStates.has(node.status) : false;\n}\n\nfunction collectAcceptancePrerequisiteFailures(thread: TaskThreadDetail): {\n failedExecutionNodes: TaskNodeRecord[];\n completedWithoutEvidence: TaskNodeRecord[];\n} {\n const executionNodes = thread.nodes.filter(\n (node) => node.kind === \"execution\",\n );\n const passedCompletionVerifierNodeIds = new Set(\n thread.verifierJobs\n .filter(\n (job) =>\n job.verifierType === \"task_completion\" &&\n job.status === \"passed\" &&\n typeof job.nodeId === \"string\",\n )\n .map((job) => job.nodeId as string),\n );\n const evidenceBackedNodeIds = new Set(\n thread.evidence\n .filter(\n (entry) =>\n typeof entry.nodeId === \"string\" &&\n (entry.evidenceType === \"validation_summary\" ||\n entry.evidenceType === \"acceptance_report\"),\n )\n .map((entry) => entry.nodeId as string),\n );\n return {\n failedExecutionNodes: executionNodes.filter(\n (node) =>\n node.status === \"failed\" ||\n node.status === \"canceled\" ||\n node.status === \"interrupted\",\n ),\n completedWithoutEvidence: executionNodes.filter(\n (node) =>\n node.status === \"completed\" &&\n !passedCompletionVerifierNodeIds.has(node.id) &&\n !evidenceBackedNodeIds.has(node.id),\n ),\n };\n}\n\nfunction buildDeterministicFailureEvaluation(\n thread: TaskThreadDetail,\n failures: ReturnType<typeof collectAcceptancePrerequisiteFailures>,\n): AcceptanceEvaluation | null {\n if (failures.failedExecutionNodes.length > 0) {\n return {\n verdict: \"fail\",\n summary: `Acceptance cannot pass because execution nodes failed: ${failures.failedExecutionNodes.map((node) => node.title).join(\", \")}.`,\n checklist: thread.acceptanceCriteria.map((criterion) => ({\n criterion,\n status: \"fail\",\n evidence: `Execution nodes failed before acceptance verification completed: ${failures.failedExecutionNodes.map((node) => `${node.title}=${node.status}`).join(\", \")}.`,\n })),\n };\n }\n if (failures.completedWithoutEvidence.length > 0) {\n return {\n verdict: \"fail\",\n summary: `Acceptance cannot pass because completed execution nodes lack verification evidence: ${failures.completedWithoutEvidence.map((node) => node.title).join(\", \")}.`,\n checklist: thread.acceptanceCriteria.map((criterion) => ({\n criterion,\n status: \"partial\",\n evidence: `Missing task-completion evidence for: ${failures.completedWithoutEvidence.map((node) => node.title).join(\", \")}.`,\n })),\n };\n }\n return null;\n}\n\nfunction summarizeThreadEvidence(thread: TaskThreadDetail): string {\n const sessionSummaries = thread.sessions\n .map((session) =>\n [\n `${session.label} [${session.framework}] status=${session.status}`,\n session.completionSummary\n ? `summary=${truncate(session.completionSummary, 400)}`\n : \"\",\n ]\n .filter(Boolean)\n .join(\" | \"),\n )\n .filter(Boolean)\n .join(\"\\n\");\n const decisions = thread.decisions\n .slice(-8)\n .map(\n (decision) =>\n `${decision.decision}: ${truncate(decision.reasoning, 240)}`,\n )\n .join(\"\\n\");\n const artifacts = thread.artifacts\n .slice(-12)\n .map(\n (artifact) =>\n `${artifact.artifactType}: ${artifact.title}${artifact.path ? ` (${artifact.path})` : \"\"}`,\n )\n .join(\"\\n\");\n const evidence = thread.evidence\n .slice(-16)\n .map(\n (entry) =>\n `${entry.evidenceType}: ${entry.title}${entry.summary ? ` - ${truncate(entry.summary, 220)}` : \"\"}`,\n )\n .join(\"\\n\");\n const transcripts = thread.transcripts\n .slice(-8)\n .map((entry) => `${entry.direction}: ${truncate(entry.content, 240)}`)\n .join(\"\\n\");\n return [\n sessionSummaries ? `Sessions\\n${sessionSummaries}` : \"\",\n decisions ? `Decisions\\n${decisions}` : \"\",\n artifacts ? `Artifacts\\n${artifacts}` : \"\",\n evidence ? `Evidence\\n${evidence}` : \"\",\n transcripts ? `Recent transcripts\\n${transcripts}` : \"\",\n ]\n .filter(Boolean)\n .join(\"\\n\\n\");\n}\n\nasync function evaluateAcceptanceCriteria(\n runtime: IAgentRuntime,\n thread: TaskThreadDetail,\n job: TaskVerifierJobRecord,\n): Promise<AcceptanceEvaluation> {\n const prompt = [\n \"You are a strict task verifier for an agent coordinator.\",\n \"Decide whether the thread satisfies its acceptance criteria based only on the provided evidence.\",\n \"Return JSON only with keys: verdict, summary, checklist.\",\n 'Set verdict to \"pass\" only if every criterion is satisfied by concrete evidence.',\n 'Set verdict to \"fail\" if any criterion is missing, contradicted, or unsupported.',\n \"Each checklist entry must contain criterion, status (pass|fail|partial), and evidence.\",\n \"Use this JSON shape:\",\n JSON.stringify(\n {\n verdict: \"pass\",\n summary: \"One sentence explaining the decision.\",\n checklist: [\n {\n criterion: \"Acceptance criterion one\",\n status: \"pass\",\n evidence: \"Concrete evidence for criterion one\",\n },\n {\n criterion: \"Acceptance criterion two\",\n status: \"fail\",\n evidence: \"What evidence is missing or contradictory\",\n },\n ],\n },\n null,\n 2,\n ),\n \"\",\n `Thread title: ${thread.title}`,\n `Original request: ${thread.originalRequest}`,\n `Verifier job: ${job.title}`,\n `Acceptance criteria:\\n${thread.acceptanceCriteria.map((criterion, index) => `${index + 1}. ${criterion}`).join(\"\\n\")}`,\n \"\",\n `Thread evidence:\\n${summarizeThreadEvidence(thread) || \"No evidence recorded.\"}`,\n ].join(\"\\n\");\n\n const raw = await withTrajectoryContext(\n runtime,\n {\n source: \"orchestrator\",\n decisionType: \"acceptance-verifier\",\n threadId: thread.id,\n verifierJobId: job.id,\n },\n () =>\n runtime.useModel(ModelType.TEXT_SMALL, {\n prompt,\n temperature: 0,\n stream: false,\n }),\n );\n const parsed = parseAcceptanceEvaluation(raw);\n if (parsed) {\n return parsed;\n }\n return {\n verdict: \"fail\",\n summary:\n \"Acceptance verifier returned an invalid response, so the thread could not be proven complete.\",\n checklist: thread.acceptanceCriteria.map((criterion) => ({\n criterion,\n status: \"partial\",\n evidence: \"Verifier response was invalid JSON.\",\n })),\n };\n}\n\nasync function writeAcceptanceReport(\n thread: TaskThreadDetail,\n job: TaskVerifierJobRecord,\n evaluation: AcceptanceEvaluation,\n): Promise<{ reportPath: string; sha256: string }> {\n const dir = path.join(getVerifierRootDir(), thread.id);\n await mkdir(dir, { recursive: true });\n const reportPath = path.join(dir, `${job.id}.json`);\n const report = {\n threadId: thread.id,\n verifierJobId: job.id,\n title: job.title,\n originalRequest: thread.originalRequest,\n acceptanceCriteria: thread.acceptanceCriteria,\n evaluation,\n generatedAt: new Date().toISOString(),\n };\n const serialized = JSON.stringify(report, null, 2);\n await writeFile(reportPath, serialized, \"utf8\");\n return {\n reportPath,\n sha256: createHash(\"sha256\").update(serialized).digest(\"hex\"),\n };\n}\n\nasync function finalizeAcceptanceJob(\n taskRegistry: TaskRegistry,\n thread: TaskThreadDetail,\n job: TaskVerifierJobRecord,\n evaluation: AcceptanceEvaluation,\n reportPath: string,\n sha256: string,\n): Promise<void> {\n await taskRegistry.updateTaskVerifierJob(job.id, {\n status: evaluation.verdict === \"pass\" ? \"passed\" : \"failed\",\n completedAt: new Date().toISOString(),\n metadata: {\n verdict: evaluation.verdict,\n summary: evaluation.summary,\n reportPath,\n sha256,\n checklist: evaluation.checklist,\n },\n });\n await taskRegistry.recordArtifact({\n threadId: thread.id,\n sessionId: thread.latestSessionId ?? null,\n artifactType: \"acceptance_report\",\n title: `${job.title} report`,\n path: reportPath,\n mimeType: \"application/json\",\n metadata: {\n verifierJobId: job.id,\n verdict: evaluation.verdict,\n sha256,\n },\n });\n await taskRegistry.recordTaskEvidence({\n threadId: thread.id,\n nodeId: job.nodeId,\n sessionId: thread.latestSessionId ?? null,\n verifierJobId: job.id,\n evidenceType: \"acceptance_report\",\n title: job.title,\n summary: evaluation.summary,\n path: reportPath,\n content: {\n checklist: evaluation.checklist,\n verdict: evaluation.verdict,\n },\n metadata: {\n sha256,\n },\n });\n await taskRegistry.appendEvent({\n threadId: thread.id,\n sessionId: thread.latestSessionId ?? null,\n eventType: \"verifier_job_completed\",\n summary: `${job.title} ${evaluation.verdict}`,\n data: {\n verifierJobId: job.id,\n verdict: evaluation.verdict,\n reportPath,\n },\n });\n if (job.nodeId) {\n const node = thread.nodes.find((entry) => entry.id === job.nodeId);\n const patch =\n evaluation.verdict === \"pass\"\n ? {\n metadata: {\n acceptanceVerifierJobId: job.id,\n acceptanceSummary: evaluation.summary,\n },\n }\n : {\n status: \"failed\" as const,\n metadata: {\n acceptanceVerifierJobId: job.id,\n acceptanceSummary: evaluation.summary,\n },\n };\n if (node) {\n await taskRegistry.updateTaskNode(node.id, patch);\n }\n }\n}\n\nexport async function runReadyTaskVerifiers(\n runtime: IAgentRuntime,\n taskRegistry: TaskRegistry,\n threadId: string,\n): Promise<void> {\n let thread = await taskRegistry.getThread(threadId);\n if (!thread) {\n return;\n }\n const readyJobs = thread.verifierJobs.filter((job) =>\n isVerifierReady(thread as TaskThreadDetail, job),\n );\n for (const job of readyJobs) {\n if (activeVerifierRuns.has(job.id)) {\n continue;\n }\n activeVerifierRuns.add(job.id);\n try {\n await taskRegistry.updateTaskVerifierJob(job.id, {\n status: \"running\",\n startedAt: new Date().toISOString(),\n metadata: {\n source: \"acceptance-runner\",\n },\n });\n await taskRegistry.appendEvent({\n threadId,\n sessionId: thread.latestSessionId ?? null,\n eventType: \"verifier_job_started\",\n summary: `Running ${job.title}`,\n data: {\n verifierJobId: job.id,\n verifierType: job.verifierType,\n },\n });\n thread = (await taskRegistry.getThread(threadId)) ?? thread;\n const deterministicFailure = buildDeterministicFailureEvaluation(\n thread,\n collectAcceptancePrerequisiteFailures(thread),\n );\n const evaluation =\n deterministicFailure ??\n (await evaluateAcceptanceCriteria(runtime, thread, job));\n const report = await writeAcceptanceReport(thread, job, evaluation);\n await finalizeAcceptanceJob(\n taskRegistry,\n thread,\n job,\n evaluation,\n report.reportPath,\n report.sha256,\n );\n thread = (await taskRegistry.getThread(threadId)) ?? thread;\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n await taskRegistry.updateTaskVerifierJob(job.id, {\n status: \"failed\",\n completedAt: new Date().toISOString(),\n metadata: {\n source: \"acceptance-runner\",\n error: message,\n },\n });\n await taskRegistry.appendEvent({\n threadId,\n sessionId: thread.latestSessionId ?? null,\n eventType: \"verifier_job_failed\",\n summary: `${job.title} failed`,\n data: {\n verifierJobId: job.id,\n error: message,\n },\n });\n if (job.nodeId) {\n await taskRegistry.updateTaskNode(job.nodeId, {\n status: \"failed\",\n metadata: {\n acceptanceVerifierJobId: job.id,\n acceptanceSummary: message,\n },\n });\n }\n } finally {\n activeVerifierRuns.delete(job.id);\n }\n }\n}\n\nexport function isTerminalTaskNodeStatus(\n status: TaskNodeRecord[\"status\"],\n): boolean {\n return terminalNodeStates.has(status);\n}\n",
|
|
29
|
+
"/**\n * Swarm Coordinator: decision loop and blocked/turn-complete handlers.\n *\n * Extracted from swarm-coordinator.ts for modularity.\n * All functions are pure async helpers that receive a SwarmCoordinatorContext\n * to access shared state and services.\n *\n * @module services/swarm-decision-loop\n */\n\nimport * as path from \"node:path\";\nimport { ModelType } from \"@elizaos/core\";\nimport {\n cleanForChat,\n closeUnbalancedMarkdownFences,\n extractCompletionSummary,\n formatMarkdownTablesForChat,\n summarizeUserFacingTurnOutput,\n} from \"./ansi-utils.js\";\nimport {\n type CustomValidatorResult,\n type CustomValidatorSpec,\n getMaxRetries,\n runCustomValidator,\n} from \"./custom-validator-runner.js\";\nimport type {\n PendingDecision,\n SwarmCoordinatorContext,\n TaskContext,\n} from \"./swarm-coordinator.js\";\nimport {\n buildBlockedEventMessage,\n buildCoordinationPrompt,\n buildTurnCompletePrompt,\n type CoordinationLLMResponse,\n type DecisionHistoryEntry,\n parseCoordinationResponse,\n type SiblingTaskSummary,\n type TaskContextSummary,\n} from \"./swarm-coordinator-prompts.js\";\nimport { classifyEventTier, type TriageContext } from \"./swarm-event-triage.js\";\nimport { validateTaskCompletion } from \"./task-validation.js\";\nimport { runReadyTaskVerifiers } from \"./task-verifier-runner.js\";\nimport { withTrajectoryContext } from \"./trajectory-context.js\";\n\n/**\n * Per-session metadata key holding the running retry counter for the custom\n * validator path. Stored on `orchestrator_task_sessions.metadata_json` so\n * it survives restarts. Sibling key: `validator`, `maxRetries`,\n * `onVerificationFail`, and the `structuredProof` claim recorded by the\n * structured-proof bridge.\n */\nconst VERIFICATION_RETRY_COUNT_KEY = \"verificationRetryCount\";\n\ninterface VerificationMetadata {\n validator: CustomValidatorSpec | null;\n maxRetries: number | undefined;\n onVerificationFail: \"retry\" | \"escalate\";\n retryCount: number;\n structuredProof: unknown;\n /**\n * Room where the verification verdict should be posted back. Carried\n * from START_CODING_TASK metadata into session metadata. Consumers (e.g.\n * plugin-app-control's verification-room-bridge) read this off the\n * task_complete / escalation broadcast payloads to close the chat loop.\n */\n originRoomId: string | undefined;\n}\n\nfunction readVerificationMetadata(\n metadata: Record<string, unknown> | null | undefined,\n): VerificationMetadata {\n const validatorRaw = metadata?.validator;\n let validator: CustomValidatorSpec | null = null;\n if (\n validatorRaw &&\n typeof validatorRaw === \"object\" &&\n !Array.isArray(validatorRaw)\n ) {\n const v = validatorRaw as Record<string, unknown>;\n if (\n typeof v.service === \"string\" &&\n v.service.trim().length > 0 &&\n typeof v.method === \"string\" &&\n v.method.trim().length > 0\n ) {\n validator = {\n service: v.service,\n method: v.method,\n params:\n v.params && typeof v.params === \"object\" && !Array.isArray(v.params)\n ? (v.params as Record<string, unknown>)\n : {},\n };\n }\n }\n const maxRetries =\n typeof metadata?.maxRetries === \"number\" &&\n metadata.maxRetries >= 0 &&\n Number.isFinite(metadata.maxRetries)\n ? Math.floor(metadata.maxRetries)\n : undefined;\n const onVerificationFail =\n metadata?.onVerificationFail === \"escalate\" ? \"escalate\" : \"retry\";\n const retryCount =\n typeof metadata?.[VERIFICATION_RETRY_COUNT_KEY] === \"number\" &&\n Number.isFinite(metadata[VERIFICATION_RETRY_COUNT_KEY] as number)\n ? Math.max(\n 0,\n Math.floor(metadata[VERIFICATION_RETRY_COUNT_KEY] as number),\n )\n : 0;\n const structuredProof = metadata?.structuredProof;\n const originRoomIdRaw = metadata?.originRoomId;\n const originRoomId =\n typeof originRoomIdRaw === \"string\" && originRoomIdRaw.trim().length > 0\n ? originRoomIdRaw\n : undefined;\n return {\n validator,\n maxRetries,\n onVerificationFail,\n retryCount,\n structuredProof,\n originRoomId,\n };\n}\n\nfunction summarizeValidatorFailure(result: CustomValidatorResult): string {\n const detailsObj =\n result.details && typeof result.details === \"object\" && result.details\n ? (result.details as Record<string, unknown>)\n : null;\n const summary =\n detailsObj && typeof detailsObj.summary === \"string\"\n ? detailsObj.summary\n : null;\n return summary ?? result.retryablePromptForChild;\n}\n\n// ─── Constants ───\n\n/** Timeout for agent decision pipeline callback (ms). */\nconst DECISION_CB_TIMEOUT_MS = 30_000;\nconst LOGIN_REQUIRED_PROMPT_RE =\n /\\b(?:requires authentication|needs (?:a )?provider login|run\\s+\"?claude login\"?|claude code requires authentication|login required|authenticate|sign in)\\b/i;\n\n/** Wrap a promise with a timeout. Rejects with an error if not resolved in time. */\nfunction withTimeout<T>(\n promise: Promise<T>,\n ms: number,\n label: string,\n): Promise<T> {\n return new Promise<T>((resolve, reject) => {\n const timer = setTimeout(\n () => reject(new Error(`${label} timed out after ${ms}ms`)),\n ms,\n );\n promise.then(\n (val) => {\n clearTimeout(timer);\n resolve(val);\n },\n (err) => {\n clearTimeout(timer);\n reject(err);\n },\n );\n });\n}\n\n/** Maximum consecutive auto-responses before escalating to a human. */\nconst MAX_AUTO_RESPONSES = 10;\n\n/**\n * Grace period after the coordinator sends input to an agent (ms).\n * During this window, stall and turn-complete events are suppressed\n * to give the agent time to process the input before re-assessment.\n */\nexport const POST_SEND_COOLDOWN_MS = 15_000;\nconst deferredTurnCompleteTimers = new Map<\n string,\n ReturnType<typeof setTimeout>\n>();\n\n/** Clear all deferred turn-complete timers (used during coordinator shutdown). */\nexport function clearDeferredTurnCompleteTimers(): void {\n for (const timer of deferredTurnCompleteTimers.values()) {\n clearTimeout(timer);\n }\n deferredTurnCompleteTimers.clear();\n}\n\n// ─── Helpers ───\n\n/**\n * Detect status-indicator patterns (spinners, progress animations) that\n * the PTY manager surfaces as \"blocking prompts\" but are not real user-facing\n * prompts. These fire repeatedly during long CLI operations (e.g. Claude Code\n * \"Orchestrating…\") and must be filtered before they flood the decision loop.\n */\nconst STATUS_PATTERNS = [\n /^orchestrating/i,\n /^thinking/i,\n /^planning/i,\n /^processing/i,\n /^loading/i,\n /^analyzing/i,\n /^searching/i,\n /^compiling/i,\n /^building/i,\n /^bundling/i,\n /^installing/i,\n /^resolving/i,\n];\n// biome-ignore lint/suspicious/noControlCharactersInRegex: this intentionally strips ANSI escape sequences.\nconst ANSI_ESCAPE_PATTERN = /\\u001B\\[[0-9;]*[a-zA-Z]/g;\n\nfunction isStatusAnimation(text: string): boolean {\n // Strip ANSI escapes, whitespace, ellipsis, and spinner glyphs so\n // \"⠋ Orchestrating…\" normalizes to \"Orchestrating\".\n const stripped = text\n .replace(ANSI_ESCAPE_PATTERN, \"\")\n .replace(/[\\s\\u2026\\u00b7\\u2022\\u25cf\\u25cb⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏|/\\-\\\\]/g, \"\")\n .trim();\n if (stripped.length === 0) return true;\n return STATUS_PATTERNS.some((p) => p.test(stripped));\n}\n\n/**\n * Detect when the agent's text is a request for the human user (not new\n * instructions for the agent itself). The turn-assessment LLM sometimes\n * misclassifies these as `respond` (= feed back to the agent), which causes\n * a feedback loop where the agent's own clarification request gets sent back\n * to it as input. When matched, the decision should be converted to `escalate`\n * and the agent's question surfaced to chat.\n */\nconst ASK_USER_PATTERNS = [\n /\\bi need (?:you|the user) to\\b/i,\n /\\bplease (?:pick|choose|select|provide|paste|share|tell me|let me know)\\b/i,\n /\\bcan you (?:provide|share|paste|tell me|let me know|confirm|clarify)\\b/i,\n /\\bwhich (?:would you|do you|of these)\\b/i,\n /\\bpick one of\\b/i,\n /\\bchoose one of\\b/i,\n /\\boption\\s*[([]?[123abc][)\\]]?\\b/i,\n /^\\s*[123abc]\\.\\s/m,\n];\n\nfunction isAskingUserForInput(text: string | undefined): boolean {\n if (!text) return false;\n return ASK_USER_PATTERNS.some((p) => p.test(text));\n}\n\n/** Build a TaskContextSummary from a TaskContext. */\nfunction toContextSummary(taskCtx: TaskContext): TaskContextSummary {\n return {\n sessionId: taskCtx.sessionId,\n agentType: taskCtx.agentType,\n label: taskCtx.label,\n originalTask: taskCtx.originalTask,\n workdir: taskCtx.workdir,\n repo: taskCtx.repo,\n };\n}\n\n/** Extract recent non-auto-resolved decisions as history entries. */\nfunction toDecisionHistory(taskCtx: TaskContext): DecisionHistoryEntry[] {\n return taskCtx.decisions\n .filter((d) => d.decision !== \"auto_resolved\")\n .slice(-5)\n .map((d) => ({\n event: d.event,\n promptText: d.promptText,\n action: d.decision,\n response: d.response,\n reasoning: d.reasoning,\n }));\n}\n\n/** Collect sibling task summaries for cross-task context (excludes the current session). */\nfunction collectSiblings(\n ctx: SwarmCoordinatorContext,\n currentSessionId: string,\n): SiblingTaskSummary[] {\n const siblings: SiblingTaskSummary[] = [];\n for (const [sid, task] of ctx.tasks) {\n if (sid === currentSessionId) continue;\n\n // Find the most recent keyDecision from this sibling's decisions\n let lastKeyDecision: string | undefined;\n for (let i = task.decisions.length - 1; i >= 0; i--) {\n const d = task.decisions[i];\n if (d.reasoning && d.decision !== \"auto_resolved\") {\n lastKeyDecision = d.reasoning;\n break;\n }\n }\n\n // Also check shared decisions for this sibling's key decisions\n for (let i = ctx.sharedDecisions.length - 1; i >= 0; i--) {\n const sd = ctx.sharedDecisions[i];\n if (sd.agentLabel === task.label) {\n lastKeyDecision = sd.summary;\n break;\n }\n }\n\n siblings.push({\n label: task.label,\n agentType: task.agentType,\n originalTask: task.originalTask,\n status: task.status,\n lastKeyDecision,\n completionSummary: task.completionSummary,\n });\n }\n return siblings;\n}\n\n/**\n * Enrich a text response with any shared decisions the agent hasn't seen yet.\n * Returns the enriched response and the snapshot index to commit after send.\n * Short responses (like \"y\", \"n\", single-word approvals) are left untouched\n * to avoid confusing TUI prompts.\n */\nfunction enrichWithSharedDecisions(\n ctx: SwarmCoordinatorContext,\n sessionId: string,\n response: string,\n): { response: string; snapshotIndex?: number } {\n const taskCtx = ctx.tasks.get(sessionId);\n if (!taskCtx) return { response };\n\n const allDecisions = ctx.sharedDecisions;\n const lastSeen = taskCtx.lastSeenDecisionIndex;\n // Snapshot the current length so we don't skip decisions appended during send.\n const snapshotEnd = allDecisions.length;\n if (lastSeen >= snapshotEnd) return { response };\n\n // Don't inject context into short responses (approvals, single words)\n if (response.length < 20) {\n return { response };\n }\n\n const unseen = allDecisions.slice(lastSeen, snapshotEnd);\n\n const contextBlock = unseen\n .map((d) => `[${d.agentLabel}] ${d.summary}`)\n .join(\"; \");\n\n return {\n response: `${response}\\n\\n(Context from other agents: ${contextBlock})`,\n snapshotIndex: snapshotEnd,\n };\n}\n\n/** Advance the shared-decisions high-water mark for a session after a successful send. */\nfunction commitSharedDecisionIndex(\n ctx: SwarmCoordinatorContext,\n sessionId: string,\n snapshotIndex: number,\n): void {\n const taskCtx = ctx.tasks.get(sessionId);\n if (taskCtx) {\n taskCtx.lastSeenDecisionIndex = snapshotIndex;\n }\n}\n\n/** Record a key decision from an LLM response into the shared decisions list. */\nfunction recordKeyDecision(\n ctx: SwarmCoordinatorContext,\n agentLabel: string,\n decision: CoordinationLLMResponse,\n): void {\n if (!decision.keyDecision) return;\n ctx.sharedDecisions.push({\n agentLabel,\n summary: decision.keyDecision,\n timestamp: Date.now(),\n });\n ctx.log(`Shared decision from \"${agentLabel}\": ${decision.keyDecision}`);\n}\n\n/**\n * Drain a buffered task_complete event for a session after an in-flight\n * decision finishes. Prevents task_complete from being silently dropped\n * when it arrives during a slow handleBlocked/handleAutonomous LLM call.\n */\nasync function drainPendingTurnComplete(\n ctx: SwarmCoordinatorContext,\n sessionId: string,\n): Promise<void> {\n if (!ctx.pendingTurnComplete.has(sessionId)) return;\n const pendingData = ctx.pendingTurnComplete.get(sessionId);\n ctx.pendingTurnComplete.delete(sessionId);\n\n const taskCtx = ctx.tasks.get(sessionId);\n if (\n !taskCtx ||\n (taskCtx.status !== \"active\" && taskCtx.status !== \"tool_running\")\n ) {\n return;\n }\n\n ctx.log(`Draining buffered turn-complete for \"${taskCtx.label}\"`);\n await handleTurnComplete(ctx, sessionId, taskCtx, pendingData);\n}\n\n/**\n * Drain a buffered blocked event for a session after an in-flight\n * decision finishes. Prevents a distinct blocked prompt from being\n * silently dropped when it arrives during a slow LLM call.\n */\nasync function drainPendingBlocked(\n ctx: SwarmCoordinatorContext,\n sessionId: string,\n): Promise<void> {\n if (!ctx.pendingBlocked.has(sessionId)) return;\n const pendingData = ctx.pendingBlocked.get(sessionId);\n ctx.pendingBlocked.delete(sessionId);\n\n const taskCtx = ctx.tasks.get(sessionId);\n // Mirror drainPendingTurnComplete: a buffered blocked event should still\n // drain if the task is in tool_running state (subagents using tools sit\n // there continuously). Without this, a blocked prompt that arrived during\n // an in-flight decision gets dropped silently when the lock releases.\n if (\n !taskCtx ||\n (taskCtx.status !== \"active\" && taskCtx.status !== \"tool_running\")\n ) {\n return;\n }\n\n ctx.log(`Draining buffered blocked event for \"${taskCtx.label}\"`);\n await handleBlocked(ctx, sessionId, taskCtx, pendingData);\n}\n\n/** Format a decision's response for recording. */\nfunction formatDecisionResponse(\n decision: CoordinationLLMResponse,\n): string | undefined {\n if (decision.action !== \"respond\") return undefined;\n return decision.useKeys\n ? `keys:${decision.keys?.join(\",\")}`\n : decision.response;\n}\n\nfunction truncateForUser(text: string, max = 140): string {\n const trimmed = text.trim();\n if (trimmed.length <= max) {\n return trimmed;\n }\n return `${trimmed.slice(0, max)}...`;\n}\n\nexport function completionReasoningFromTurnOutput(turnOutput: string): string {\n const cleaned = summarizeUserFacingTurnOutput(turnOutput);\n\n return cleaned\n ? truncateForUser(cleaned, 2000)\n : \"Subagent completed and produced output.\";\n}\n\nexport function taskAgentFailureReasonFromTurnOutput(\n turnOutput: string,\n): string | null {\n const cleaned = cleanForChat(turnOutput);\n if (!cleaned.trim()) return null;\n\n if (\n /\\b(?:401\\s+Unauthorized|authentication required|Invalid API key|API key is invalid|OPENAI_API_KEY|Set OPENAI_API_KEY)\\b/i.test(\n cleaned,\n )\n ) {\n return \"Task agent failed to authenticate before completing.\";\n }\n\n return null;\n}\n\nexport function completeDecisionWithTurnOutput(\n decision: CoordinationLLMResponse,\n turnOutput: string,\n): CoordinationLLMResponse {\n if (decision.action !== \"complete\") {\n return decision;\n }\n\n if (!cleanForChat(turnOutput).trim()) {\n return decision;\n }\n\n const finalOutput = completionReasoningFromTurnOutput(turnOutput);\n return {\n ...decision,\n reasoning: finalOutput,\n keyDecision: finalOutput,\n };\n}\n\nexport function isCompletingWithCapturedOutput(task: {\n status: string;\n completionSummary?: string;\n}): boolean {\n return (\n task.status === \"tool_running\" &&\n typeof task.completionSummary === \"string\" &&\n task.completionSummary.trim().length > 0\n );\n}\n\nexport function shouldIgnoreStoppedEventDuringCompletion(options: {\n task: { status: string; completionSummary?: string };\n hasInFlightDecision: boolean;\n hasPendingTurnComplete: boolean;\n}): boolean {\n if (options.task.status === \"completed\" || options.task.status === \"error\") {\n return true;\n }\n\n if (isCompletingWithCapturedOutput(options.task)) {\n return true;\n }\n\n return (\n (options.task.status === \"active\" ||\n options.task.status === \"tool_running\") &&\n (options.hasInFlightDecision || options.hasPendingTurnComplete)\n );\n}\n\nexport function isMissingPtySessionError(error: unknown): boolean {\n return (\n error instanceof Error && /^Session\\s+.+\\s+not found$/u.test(error.message)\n );\n}\n\nexport function uniqueSummaryParts(parts: string[]): string[] {\n const entries: Array<{ key: string; value: string }> = [];\n for (const part of parts) {\n const trimmed = formatMarkdownTablesForChat(\n closeUnbalancedMarkdownFences(part),\n );\n if (!trimmed) continue;\n const key = normalizeSummaryPartForDedupe(trimmed);\n const overlappingIndex = entries.findIndex((entry) =>\n areDuplicateSummaryParts(entry.key, key),\n );\n if (overlappingIndex >= 0) {\n if (\n key !== entries[overlappingIndex].key &&\n trimmed.length > entries[overlappingIndex].value.length\n ) {\n entries[overlappingIndex] = { key, value: trimmed };\n }\n continue;\n }\n entries.push({ key, value: trimmed });\n }\n return entries.map((entry) => entry.value);\n}\n\nfunction normalizeSummaryPartForDedupe(text: string): string {\n return text\n .replace(/^```[a-z0-9_-]*$/gim, \"\")\n .replace(/^\\s*\\|(?:\\s*:?-{3,}:?\\s*\\|)+\\s*$/gim, \"\")\n .replace(/\\s+/g, \" \")\n .trim();\n}\n\nfunction areDuplicateSummaryParts(a: string, b: string): boolean {\n if (!a || !b) return false;\n if (a === b) return true;\n const minMeaningfulLength = 80;\n return (\n a.length >= minMeaningfulLength &&\n b.length >= minMeaningfulLength &&\n (a.includes(b) || b.includes(a))\n );\n}\n\nfunction stringMetadataValue(value: unknown): string | undefined {\n return typeof value === \"string\" && value.trim().length > 0\n ? value.trim()\n : undefined;\n}\n\nfunction readReplyToExternalMessageId(task: {\n originMetadata?: Record<string, unknown>;\n}): string | undefined {\n const metadata = task.originMetadata;\n if (!metadata) return undefined;\n const discord =\n metadata.discord && typeof metadata.discord === \"object\"\n ? (metadata.discord as Record<string, unknown>)\n : null;\n return (\n stringMetadataValue(metadata.replyToExternalMessageId) ??\n stringMetadataValue(metadata.discordMessageId) ??\n stringMetadataValue(metadata.messageIdFull) ??\n stringMetadataValue(discord?.messageId)\n );\n}\n\nfunction extractLoginInstructions(eventData: {\n promptInfo?: {\n instructions?: string;\n prompt?: string;\n };\n}): string {\n const instructions =\n typeof eventData.promptInfo?.instructions === \"string\"\n ? eventData.promptInfo.instructions.trim()\n : \"\";\n if (instructions) {\n return instructions;\n }\n return typeof eventData.promptInfo?.prompt === \"string\"\n ? eventData.promptInfo.prompt.trim()\n : \"\";\n}\n\nfunction isLoginRequiredPrompt(\n promptText: string,\n promptType?: string,\n): boolean {\n if (promptType === \"login\") {\n return true;\n }\n return LOGIN_REQUIRED_PROMPT_RE.test(promptText);\n}\n\nfunction formatSuggestedAction(\n decision: CoordinationLLMResponse | null,\n): string {\n if (!decision) {\n return \"Needs human review with no automatic suggestion.\";\n }\n if (decision.action === \"respond\") {\n if (decision.useKeys && decision.keys?.length) {\n return `Suggested action: send keys ${decision.keys.join(\", \")}.`;\n }\n if (decision.response?.trim()) {\n return `Suggested action: reply \"${truncateForUser(decision.response, 80)}\".`;\n }\n }\n return `Suggested action: ${decision.action}.`;\n}\n\nfunction decisionFromSuggestedResponse(\n suggestedResponse: string,\n reasoning = \"Used adapter-provided auto-response for a routine blocking prompt.\",\n): CoordinationLLMResponse {\n if (suggestedResponse.startsWith(\"keys:\")) {\n return {\n action: \"respond\",\n useKeys: true,\n keys: suggestedResponse\n .slice(\"keys:\".length)\n .split(\",\")\n .map((part) => part.trim())\n .filter(Boolean),\n reasoning,\n };\n }\n return {\n action: \"respond\",\n response: suggestedResponse,\n reasoning,\n };\n}\n\nfunction inferRoutinePromptResponse(\n promptText: string,\n promptType?: string,\n): { suggestedResponse: string; reasoning: string } | null {\n if (\n promptType === \"project_select\" &&\n /project|workspace/i.test(promptText)\n ) {\n return {\n suggestedResponse: \"keys:enter\",\n reasoning:\n \"Accepted the current workspace so a routine project-selection prompt does not stall the task.\",\n };\n }\n\n if (\n promptType === \"config\" &&\n /claude (?:dialog awaiting navigation|menu navigation required)/i.test(\n promptText,\n )\n ) {\n return {\n suggestedResponse: \"keys:enter\",\n reasoning:\n \"Accepted Claude's default dialog action so the replacement session can continue without exiting the CLI.\",\n };\n }\n\n if (promptType && promptType !== \"unknown\") {\n return null;\n }\n\n if (\n /should i open (?:the )?(?:page|link|url).*(?:new tab|browser tab).*instead\\??/i.test(\n promptText,\n )\n ) {\n return {\n suggestedResponse: \"yes\",\n reasoning:\n \"Accepted routine browser follow-up so the agent can keep using its web tool without human intervention.\",\n };\n }\n\n const isCodexModelSwitchPrompt =\n /keep\\s+current\\s+model/i.test(promptText) &&\n /cheaper,\\s*faster,\\s*but less capable|efficient\\s+model|less\\s+capable|faster|rate\\s+limit|switching\\s+models/i.test(\n promptText,\n );\n if (isCodexModelSwitchPrompt) {\n const shouldHideFuturePrompts =\n /never\\s+show\\s+again|hide\\s+future\\s+rate\\s+limit\\s+reminders/i.test(\n promptText,\n );\n return {\n suggestedResponse: shouldHideFuturePrompts ? \"3\" : \"2\",\n reasoning:\n \"Kept the current Codex model so a routine model-selection prompt does not stall the task.\",\n };\n }\n\n return null;\n}\n\n/** Check if a permission prompt references paths outside the workspace. */\nexport function isOutOfScopeAccess(\n promptText: string,\n workdir: string,\n): boolean {\n // Strip URLs so we don't false-positive on https://example.com/foo/bar\n const stripped = promptText.replace(/https?:\\/\\/\\S+/g, \"\");\n\n // Match absolute paths: multi-segment (/dir/file) or well-known single-segment\n // roots that agents should never touch (/etc, /tmp, /var, /usr, /opt, /sys, /proc).\n const multiSegment = /\\/[\\w.-]+(?:\\/[\\w.-]+)+/g;\n const sensitiveRoots = /\\b\\/(etc|tmp|var|usr|opt|sys|proc|root)\\b/g;\n const homeTilde = /~\\/[\\w.-]+/g;\n\n const matches = [\n ...(stripped.match(multiSegment) ?? []),\n ...(stripped.match(sensitiveRoots) ?? []).map((m) => m.trimStart()),\n ...(stripped.match(homeTilde) ?? []).map((m) =>\n m.replace(\"~\", process.env.HOME ?? \"/home/user\"),\n ),\n ];\n if (matches.length === 0) return false;\n\n const resolvedWorkdir = path.resolve(workdir);\n return matches.some((p) => {\n const resolved = path.resolve(p);\n return (\n !resolved.startsWith(resolvedWorkdir + path.sep) &&\n resolved !== resolvedWorkdir\n );\n });\n}\n\n/**\n * Check if all registered tasks have reached a terminal state.\n * If so, send a swarm-wide summary message to the chat.\n */\nexport function checkAllTasksComplete(ctx: SwarmCoordinatorContext): void {\n void checkAllTasksCompleteAsync(ctx);\n}\n\nasync function checkAllTasksCompleteAsync(\n ctx: SwarmCoordinatorContext,\n): Promise<void> {\n const tasks = Array.from(ctx.tasks.values());\n if (tasks.length === 0) return;\n\n const terminalStates = new Set([\"completed\", \"stopped\", \"error\"]);\n const allDone = tasks.every((t) => terminalStates.has(t.status));\n\n if (!allDone) {\n const statuses = tasks.map((t) => `${t.label}=${t.status}`).join(\", \");\n ctx.log(`checkAllTasksComplete: not all done yet: ${statuses}`);\n return;\n }\n\n const threadIds = [...new Set(tasks.map((task) => task.threadId))];\n const failingThreads: Array<{\n threadId: string;\n failedGoals: string[];\n failedVerifiers: string[];\n }> = [];\n for (const threadId of threadIds) {\n await runReadyTaskVerifiers(ctx.runtime, ctx.taskRegistry, threadId);\n const thread = await ctx.taskRegistry.getThread(threadId);\n if (!thread || thread.nodes.length === 0) {\n continue;\n }\n const goalNodes = thread.nodes.filter((node) => node.kind === \"goal\");\n const failedGoals = goalNodes\n .filter(\n (node) =>\n node.status === \"failed\" ||\n node.status === \"canceled\" ||\n node.status === \"interrupted\",\n )\n .map((node) => `${node.title}=${node.status}`);\n const incompleteGoals = goalNodes\n .filter(\n (node) =>\n node.status !== \"completed\" &&\n node.status !== \"failed\" &&\n node.status !== \"canceled\" &&\n node.status !== \"interrupted\",\n )\n .map((node) => `${node.title}=${node.status}`);\n if (incompleteGoals.length > 0) {\n const pendingGoals = goalNodes\n .filter((node) => node.status !== \"completed\")\n .map((node) => `${node.title}=${node.status}`)\n .join(\", \");\n ctx.log(\n `checkAllTasksComplete: thread ${threadId} still has non-terminal goal nodes: ${pendingGoals}`,\n );\n return;\n }\n const runningVerifiers = thread.verifierJobs.filter(\n (job) => job.status === \"running\",\n );\n if (runningVerifiers.length > 0) {\n ctx.log(\n `checkAllTasksComplete: thread ${threadId} still has running verifier jobs`,\n );\n return;\n }\n const pendingVerifiers = thread.verifierJobs.filter(\n (job) => job.status === \"pending\",\n );\n if (pendingVerifiers.length > 0) {\n ctx.log(\n `checkAllTasksComplete: thread ${threadId} still has pending verifier jobs`,\n );\n return;\n }\n const failedVerifiers = thread.verifierJobs\n .filter((job) => job.status === \"failed\")\n .map((job) => `${job.title}=failed`);\n if (failedGoals.length > 0 || failedVerifiers.length > 0) {\n failingThreads.push({\n threadId,\n failedGoals,\n failedVerifiers,\n });\n }\n }\n\n if (failingThreads.length > 0) {\n const summary = failingThreads\n .map((thread) =>\n [\n `thread ${thread.threadId}`,\n thread.failedGoals.length > 0\n ? `failed goals: ${thread.failedGoals.join(\", \")}`\n : \"\",\n thread.failedVerifiers.length > 0\n ? `failed verifiers: ${thread.failedVerifiers.join(\", \")}`\n : \"\",\n ]\n .filter(Boolean)\n .join(\" | \"),\n )\n .join(\"; \");\n ctx.log(\n `checkAllTasksComplete: sessions are terminal but acceptance failed: ${summary}`,\n );\n ctx.broadcast({\n type: \"swarm_attention_required\",\n sessionId: \"\",\n timestamp: Date.now(),\n data: {\n summary,\n threads: failingThreads,\n },\n });\n // If any subagent produced a Shared decision the real work landed.\n // A failing verifier or a task swept to \"stopped\" by the idle watchdog\n // after PTY session exit must not swallow the final chat reply. The\n // broadcast above is enough for operators to see the validator\n // disagreement in the web UI; fall through to normal synthesis so the\n // user still gets the agent's actual text (buildTaskLine reads the\n // jsonl end_turn regardless of the coordinator's validator verdict).\n //\n // Only short-circuit when no subagent reached a meaningful end: the\n // genuine unrecoverable-failure case where synthesis has nothing\n // meaningful to say beyond the coordinator's signal.\n const labelsWithDecisions = new Set(\n ctx.sharedDecisions.map((decision) => decision.agentLabel),\n );\n const anyMeaningful = tasks.some(\n (task) =>\n task.status === \"completed\" || labelsWithDecisions.has(task.label),\n );\n if (!anyMeaningful) {\n if (ctx.swarmCompleteNotified) return;\n ctx.swarmCompleteNotified = true;\n return;\n }\n }\n if (failingThreads.length > 0) {\n ctx.log(\n `checkAllTasksComplete: ${failingThreads.length} thread(s) failed acceptance but at least one task produced deliverable output — falling through to synthesis`,\n );\n }\n\n // Guard: only fire once per swarm (reset by coordinator on stop/new swarm)\n if (ctx.swarmCompleteNotified) {\n ctx.log(\"checkAllTasksComplete: already notified, skipping\");\n return;\n }\n ctx.swarmCompleteNotified = true;\n\n const completed = tasks.filter((t) => t.status === \"completed\");\n const stopped = tasks.filter((t) => t.status === \"stopped\");\n const errored = tasks.filter((t) => t.status === \"error\");\n\n const parts: string[] = [];\n if (completed.length > 0) {\n parts.push(`${completed.length} completed`);\n }\n if (stopped.length > 0) {\n parts.push(`${stopped.length} stopped`);\n }\n if (errored.length > 0) {\n parts.push(`${errored.length} errored`);\n }\n\n ctx.log(\n `checkAllTasksComplete: all ${tasks.length} tasks terminal (${parts.join(\", \")}): firing swarm_complete`,\n );\n\n ctx.broadcast({\n type: \"swarm_complete\",\n sessionId: \"\",\n timestamp: Date.now(),\n data: {\n total: tasks.length,\n completed: completed.length,\n stopped: stopped.length,\n errored: errored.length,\n },\n });\n\n // Fire swarm complete callback for synthesis. If wired, the host\n // (eliza) will use this to generate a synthesized overview.\n const swarmCompleteCb = ctx.getSwarmCompleteCallback();\n // When no callback is wired (first-coordinator race during plugin init)\n // or the callback throws, post the subagent's actual output if we have\n // it instead of a generic \"all done\" status. The SharedDecision ledger\n // is the coordinator's own record of per-turn assessor findings: the\n // best proxy for \"what did the subagent actually produce\" without going\n // through the full synthesis LLM. Falling back to a generic status\n // string drops real subagent output from chat.\n const sendFallbackSummary = () => {\n const taskLines = tasks.map((t) => {\n const decisions = ctx.sharedDecisions\n .filter((sd) => sd.agentLabel === t.label)\n .map((sd) => sd.summary)\n .join(\"; \");\n const body =\n t.validationSummary ||\n decisions ||\n t.completionSummary ||\n \"no output captured\";\n return tasks.length === 1 ? body : `• ${t.label}: ${body}`;\n });\n const text =\n tasks.length === 1\n ? taskLines[0]\n : `done: ${tasks.length} tasks:\\n${taskLines.join(\"\\n\")}`;\n ctx.sendChatMessage(text, \"task-agent\");\n };\n\n if (swarmCompleteCb) {\n ctx.log(\n \"checkAllTasksComplete: swarm complete callback is wired, calling synthesis\",\n );\n // Pull thread roomIds up-front so synthesis knows where to deliver\n // (TaskContext itself doesn't carry roomId; the taskThread does).\n const threadRoomIds = new Map<string, string>();\n for (const tid of [...new Set(tasks.map((task) => task.threadId))]) {\n const thread = await ctx.taskRegistry.getThread(tid);\n if (thread?.roomId) threadRoomIds.set(tid, thread.roomId);\n }\n const taskSummaries = tasks.map((t) => {\n // Fold in shared decisions relevant to this task so the synthesis\n // prompt includes the agent's actual findings, not just PR URLs.\n const decisions = ctx.sharedDecisions\n .filter((sd) => sd.agentLabel === t.label)\n .map((sd) => sd.summary);\n const summaryParts: string[] = [];\n if (decisions.length > 0) summaryParts.push(decisions.join(\"; \"));\n if (t.completionSummary) summaryParts.push(t.completionSummary);\n return {\n sessionId: t.sessionId,\n label: t.label,\n agentType: t.agentType,\n originalTask: t.originalTask,\n status: t.status,\n completionSummary: uniqueSummaryParts(summaryParts).join(\"\\n\") || \"\",\n validationSummary: t.validationSummary,\n // Forward the task's workdir so buildTaskLine in synthesis can\n // read the agent's end_turn jsonl directly. Without this, the\n // session is already killed by the time synthesis runs and\n // resolveSessionWorkdir returns null → fallback to the honest\n // placeholder even though the jsonl has the real answer.\n workdir: t.workdir,\n roomId: threadRoomIds.get(t.threadId),\n replyToExternalMessageId: readReplyToExternalMessageId(t),\n };\n });\n // Wrap in Promise.resolve().then() to catch sync throws, and race against\n // a timeout to guard against callbacks that never settle.\n void withTimeout(\n Promise.resolve().then(() =>\n swarmCompleteCb({\n tasks: taskSummaries,\n total: tasks.length,\n completed: completed.length,\n stopped: stopped.length,\n errored: errored.length,\n }),\n ),\n DECISION_CB_TIMEOUT_MS,\n \"swarmCompleteCb\",\n ).catch((err) => {\n ctx.log(\n `Swarm complete callback failed: ${err}; falling back to generic summary`,\n );\n sendFallbackSummary();\n });\n } else {\n ctx.log(\n \"checkAllTasksComplete: no synthesis callback, sending generic message\",\n );\n sendFallbackSummary();\n }\n}\n\n/** Fetch recent PTY output, returning empty string on failure. */\nasync function fetchRecentOutput(\n ctx: SwarmCoordinatorContext,\n sessionId: string,\n lines = 50,\n): Promise<string> {\n if (!ctx.ptyService) return \"\";\n try {\n return await ctx.ptyService.getSessionOutput(sessionId, lines);\n } catch {\n return \"\";\n }\n}\n\n// ─── LLM Decision ───\n\n/**\n * Ask the LLM to make a coordination decision about a blocked agent.\n */\nexport async function makeCoordinationDecision(\n ctx: SwarmCoordinatorContext,\n taskCtx: TaskContext,\n promptText: string,\n recentOutput: string,\n): Promise<CoordinationLLMResponse | null> {\n const prompt = buildCoordinationPrompt(\n toContextSummary(taskCtx),\n promptText,\n recentOutput,\n toDecisionHistory(taskCtx),\n collectSiblings(ctx, taskCtx.sessionId),\n ctx.sharedDecisions,\n ctx.getSwarmContext(),\n );\n\n try {\n const result = await withTrajectoryContext(\n ctx.runtime,\n {\n source: \"orchestrator\",\n decisionType: \"coordination\",\n sessionId: taskCtx.sessionId,\n taskLabel: taskCtx.label,\n repo: taskCtx.repo,\n workdir: taskCtx.workdir,\n originalTask: taskCtx.originalTask,\n },\n () => ctx.runtime.useModel(ModelType.TEXT_SMALL, { prompt }),\n );\n return parseCoordinationResponse(result);\n } catch (err) {\n ctx.log(`LLM coordination call failed: ${err}`);\n return null;\n }\n}\n\n/**\n * Run the custom validator branch for a `complete` decision. Returns `true`\n * when the branch fully handled the completion (pass, retry-with-feedback,\n * or escalate after retry exhaustion) so the caller skips the generic\n * `validateTaskCompletion` flow. Returns `false` only when the validator\n * succeeded so completion can proceed through the original code path —\n * but in practice we handle pass internally too, so this helper never\n * returns `false` once it's invoked.\n *\n * Backward compatibility: this helper is only invoked when the task's\n * session metadata carries a `validator` spec. Pre-existing callers (and\n * any START_CODING_TASK invocation that does not pass `validator`) bypass this\n * branch entirely and continue through `validateTaskCompletion`.\n */\nasync function runCustomValidatorBranch(\n ctx: SwarmCoordinatorContext,\n sessionId: string,\n input: {\n taskCtx: TaskContext;\n decision: CoordinationLLMResponse;\n completionSummary: string;\n verificationMeta: VerificationMetadata;\n structuredProof: unknown;\n },\n): Promise<boolean> {\n const { taskCtx, decision, verificationMeta, structuredProof } = input;\n const validator = verificationMeta.validator;\n if (!validator || !ctx.ptyService) return false;\n\n const result = await runCustomValidator(\n ctx.runtime,\n validator,\n structuredProof,\n );\n\n if (result.verdict === \"pass\") {\n taskCtx.status = \"completed\";\n await Promise.all([\n ctx.syncTaskContext(taskCtx),\n ctx.taskRegistry.updateThreadSummary(\n taskCtx.threadId,\n taskCtx.completionSummary ?? \"\",\n ),\n ctx.taskRegistry.appendEvent({\n threadId: taskCtx.threadId,\n sessionId,\n eventType: \"task_status_changed\",\n summary: `Task \"${taskCtx.label}\" completed (custom validator pass)`,\n data: {\n status: \"completed\",\n completionSummary: taskCtx.completionSummary,\n validator: { service: validator.service, method: validator.method },\n },\n }),\n ]);\n ctx.broadcast({\n type: \"task_complete\",\n sessionId,\n timestamp: Date.now(),\n data: {\n reasoning: decision.reasoning,\n verification: {\n source: \"custom-validator\",\n verdict: \"pass\",\n validator: { service: validator.service, method: validator.method },\n params: validator.params,\n },\n originRoomId: verificationMeta.originRoomId,\n label: taskCtx.label,\n workdir: taskCtx.workdir,\n },\n });\n ctx.ptyService.stopSession(sessionId, /* force */ true).catch((err) => {\n ctx.log(`Failed to stop session after custom-validator pass: ${err}`);\n });\n checkAllTasksComplete(ctx);\n return true;\n }\n\n // verdict === \"fail\"\n const cap = getMaxRetries(verificationMeta.maxRetries);\n const nextCount = verificationMeta.retryCount + 1;\n const onFail = verificationMeta.onVerificationFail;\n const shouldRetry = onFail === \"retry\" && nextCount <= cap;\n const summary = summarizeValidatorFailure(result);\n\n await ctx.taskRegistry.appendEvent({\n threadId: taskCtx.threadId,\n sessionId,\n eventType: \"validation_failed\",\n summary: `Custom validator (${validator.service}.${validator.method}) verdict=fail`,\n data: {\n verdict: \"fail\",\n summary,\n retryCount: verificationMeta.retryCount,\n attempt: nextCount,\n maxRetries: cap,\n details: result.details ?? null,\n },\n });\n\n if (shouldRetry) {\n // Replay the validator's retry prompt back to the live PTY session and\n // bump the persisted retry counter. The session stays running; the\n // child agent will receive the prompt as its next turn input.\n taskCtx.status = \"active\";\n await ctx.ptyService.sendToSession(\n sessionId,\n result.retryablePromptForChild,\n );\n taskCtx.lastInputSentAt = Date.now();\n await ctx.syncTaskContext(taskCtx);\n await ctx.taskRegistry.updateSession(sessionId, {\n lastInputSentAt: taskCtx.lastInputSentAt,\n metadata: { [VERIFICATION_RETRY_COUNT_KEY]: nextCount },\n });\n ctx.log(\n `[CustomValidator] retry ${nextCount}/${cap} sent to session ${sessionId}`,\n );\n return true;\n }\n\n // Retry budget exhausted (or onVerificationFail=escalate).\n taskCtx.status = \"error\";\n await Promise.all([\n ctx.syncTaskContext(taskCtx),\n ctx.taskRegistry.updateSession(sessionId, {\n status: \"error\",\n metadata: { [VERIFICATION_RETRY_COUNT_KEY]: verificationMeta.retryCount },\n }),\n ctx.taskRegistry.appendEvent({\n threadId: taskCtx.threadId,\n sessionId,\n eventType: \"task_status_changed\",\n summary:\n onFail === \"escalate\"\n ? `Task \"${taskCtx.label}\" escalated (custom validator failed; onVerificationFail=escalate)`\n : `Task \"${taskCtx.label}\" escalated after ${verificationMeta.retryCount} verification retries`,\n data: {\n status: \"error\",\n verdict: \"fail\",\n retryCount: verificationMeta.retryCount,\n maxRetries: cap,\n summary,\n },\n }),\n ]);\n ctx.broadcast({\n type: \"escalation\",\n sessionId,\n timestamp: Date.now(),\n data: {\n reason: \"verification_failed\",\n summary:\n onFail === \"escalate\"\n ? `Verification failed: ${summary}`\n : `Verification failed after ${verificationMeta.retryCount} retries: ${summary}`,\n verifier: {\n service: validator.service,\n method: validator.method,\n },\n verification: {\n source: \"custom-validator\",\n verdict: \"fail\",\n validator: { service: validator.service, method: validator.method },\n params: validator.params,\n },\n details: result.details ?? null,\n retryCount: verificationMeta.retryCount,\n maxRetries: cap,\n originRoomId: verificationMeta.originRoomId,\n label: taskCtx.label,\n workdir: taskCtx.workdir,\n },\n });\n ctx.ptyService.stopSession(sessionId, /* force */ true).catch((err) => {\n ctx.log(`Failed to stop session after verification escalation: ${err}`);\n });\n checkAllTasksComplete(ctx);\n return true;\n}\n\n/**\n * Execute a coordination decision: send response, complete session, escalate, or ignore.\n */\nexport async function executeDecision(\n ctx: SwarmCoordinatorContext,\n sessionId: string,\n decision: CoordinationLLMResponse,\n): Promise<void> {\n if (!ctx.ptyService) return;\n\n switch (decision.action) {\n case \"respond\": {\n const taskCtx = ctx.tasks.get(sessionId);\n if (taskCtx) {\n taskCtx.status = \"active\";\n }\n if (decision.useKeys && decision.keys) {\n await ctx.ptyService.sendKeysToSession(sessionId, decision.keys);\n } else if (decision.response !== undefined) {\n // Proactive injection: append unseen shared decisions to text responses\n const { response: enriched, snapshotIndex } = enrichWithSharedDecisions(\n ctx,\n sessionId,\n decision.response,\n );\n await ctx.ptyService.sendToSession(sessionId, enriched);\n // Only advance the high-water mark after send succeeds: if the send\n // fails, the decisions will be retried on the next enrichment.\n if (snapshotIndex !== undefined) {\n commitSharedDecisionIndex(ctx, sessionId, snapshotIndex);\n }\n }\n // Mark the send time so stall/turn-complete events are suppressed\n // during the grace period while the agent processes this input.\n if (taskCtx) {\n taskCtx.lastInputSentAt = Date.now();\n await ctx.syncTaskContext(taskCtx);\n }\n break;\n }\n\n case \"complete\": {\n const taskCtx = ctx.tasks.get(sessionId);\n\n // Extract meaningful artifacts and summaries instead of\n // dumping raw terminal output which is full of TUI noise.\n let summary = \"\";\n try {\n const rawOutput = await ctx.ptyService.getSessionOutput(sessionId, 240);\n summary = extractCompletionSummary(rawOutput);\n } catch {\n /* ignore */\n }\n\n if (!taskCtx) {\n ctx.broadcast({\n type: \"task_complete\",\n sessionId,\n timestamp: Date.now(),\n data: { reasoning: decision.reasoning },\n });\n ctx.ptyService.stopSession(sessionId, /* force */ true).catch((err) => {\n ctx.log(\n `Failed to stop session after LLM-detected completion: ${err}`,\n );\n });\n break;\n }\n\n taskCtx.completionSummary = summary || decision.reasoning || \"\";\n taskCtx.status = \"tool_running\";\n await Promise.all([\n ctx.syncTaskContext(taskCtx),\n ctx.taskRegistry.appendEvent({\n threadId: taskCtx.threadId,\n sessionId,\n eventType: \"validation_started\",\n summary: `Validation started for \"${taskCtx.label}\"`,\n data: {\n completionReasoning: decision.reasoning,\n completionSummary: taskCtx.completionSummary,\n },\n }),\n ]);\n ctx.broadcast({\n type: \"tool_running\",\n sessionId,\n timestamp: Date.now(),\n data: {\n description: \"validation\",\n },\n });\n\n // ─── Custom validator branch ───\n //\n // When the task was registered with a `validator` spec on its\n // session metadata (APP.create / PLUGIN.create / etc. pass one\n // through START_CODING_TASK), defer to that disk-aware verifier instead\n // of the generic LLM `validateTaskCompletion` flow below. This is a\n // sibling code path: when no validator is set, behavior is\n // unchanged and the existing escalation path runs.\n const sessionRecord = await ctx.taskRegistry\n .getSession(sessionId)\n .catch(() => null);\n const verificationMeta = readVerificationMetadata(\n sessionRecord?.metadata ?? null,\n );\n if (verificationMeta.validator) {\n const handled = await runCustomValidatorBranch(ctx, sessionId, {\n taskCtx,\n decision,\n completionSummary: taskCtx.completionSummary ?? \"\",\n verificationMeta,\n structuredProof: verificationMeta.structuredProof,\n });\n if (handled) break;\n }\n\n // Only spin up the acceptance verifier when the task is actually a\n // code/build task against a real repo. The verifier is an LLM pass\n // that judges whether file/test evidence matches acceptance criteria,\n // which is only meaningful for tasks that produce artifacts on disk.\n // For scratch tasks (no repo) and info/question-answering tasks, the\n // subagent's own response IS the deliverable and there is no\n // workspace evidence to grade; running the verifier there produces\n // false \"acceptance failed\" signals that block synthesis from\n // delivering the actual answer.\n const verifierJob =\n taskCtx.taskNodeId && taskCtx.repo\n ? await ctx.taskRegistry.createTaskVerifierJob({\n threadId: taskCtx.threadId,\n nodeId: taskCtx.taskNodeId,\n status: \"running\",\n verifierType: \"task_completion\",\n title: `Validate ${taskCtx.label}`,\n instructions: [\n `Task: ${taskCtx.originalTask}`,\n taskCtx.completionSummary\n ? `Completion summary: ${taskCtx.completionSummary}`\n : \"\",\n decision.reasoning ? `Reasoning: ${decision.reasoning}` : \"\",\n ]\n .filter(Boolean)\n .join(\"\\n\"),\n config: {\n sessionId,\n agentType: taskCtx.agentType,\n },\n metadata: {\n source: \"swarm-decision-loop\",\n },\n startedAt: new Date().toISOString(),\n })\n : null;\n\n const validation = await validateTaskCompletion(ctx, {\n sessionId,\n taskCtx,\n completionReasoning: decision.reasoning,\n completionSummary: taskCtx.completionSummary,\n turnOutput: taskCtx.completionSummary,\n }).catch(\n (err) =>\n ({\n verdict: \"escalate\" as const,\n summary:\n err instanceof Error\n ? `Validation failed: ${err.message}`\n : `Validation failed: ${String(err)}`,\n followUpPrompt: undefined,\n reportPath: \"\",\n artifacts: [],\n }) satisfies Awaited<ReturnType<typeof validateTaskCompletion>>,\n );\n\n for (const artifact of validation.artifacts) {\n await ctx.taskRegistry.recordArtifact({\n threadId: taskCtx.threadId,\n sessionId,\n artifactType: artifact.artifactType,\n title: artifact.title,\n path: artifact.path ?? null,\n uri: artifact.uri ?? null,\n mimeType: artifact.mimeType ?? null,\n metadata: artifact.metadata ?? {},\n });\n if (taskCtx.taskNodeId && verifierJob) {\n await ctx.taskRegistry.recordTaskEvidence({\n threadId: taskCtx.threadId,\n nodeId: taskCtx.taskNodeId,\n sessionId,\n verifierJobId: verifierJob.id,\n evidenceType: artifact.artifactType,\n title: artifact.title,\n summary: validation.summary,\n path: artifact.path ?? null,\n uri: artifact.uri ?? null,\n content:\n artifact.metadata &&\n typeof artifact.metadata === \"object\" &&\n !Array.isArray(artifact.metadata)\n ? (artifact.metadata as Record<string, unknown>)\n : {},\n metadata: {\n mimeType: artifact.mimeType ?? null,\n },\n });\n }\n }\n\n if (validation.verdict !== \"pass\") {\n const followUpPrompt =\n validation.followUpPrompt?.trim() ||\n `Validation found the task incomplete. Continue working until this is resolved:\\n\\n${validation.summary}`;\n const nextStatus =\n validation.verdict === \"escalate\" ? \"blocked\" : \"active\";\n taskCtx.status = nextStatus;\n await Promise.all([\n ctx.syncTaskContext(taskCtx),\n verifierJob\n ? ctx.taskRegistry.updateTaskVerifierJob(verifierJob.id, {\n status: \"failed\",\n completedAt: new Date().toISOString(),\n metadata: {\n verdict: validation.verdict,\n summary: validation.summary,\n },\n })\n : Promise.resolve(),\n taskCtx.taskNodeId && verifierJob\n ? ctx.taskRegistry.recordTaskEvidence({\n threadId: taskCtx.threadId,\n nodeId: taskCtx.taskNodeId,\n sessionId,\n verifierJobId: verifierJob.id,\n evidenceType: \"validation_summary\",\n title: `Validation ${validation.verdict} for ${taskCtx.label}`,\n summary: validation.summary,\n content: {\n followUpPrompt:\n validation.verdict === \"revise\" ? followUpPrompt : null,\n reportPath: validation.reportPath || null,\n verdict: validation.verdict,\n },\n metadata: {\n source: \"task-validation\",\n },\n })\n : Promise.resolve(),\n ctx.taskRegistry.appendEvent({\n threadId: taskCtx.threadId,\n sessionId,\n eventType: \"validation_failed\",\n summary: `Validation did not approve \"${taskCtx.label}\"`,\n data: {\n verdict: validation.verdict,\n summary: validation.summary,\n followUpPrompt:\n validation.verdict === \"revise\" ? followUpPrompt : null,\n reportPath: validation.reportPath || null,\n },\n }),\n ]);\n\n if (validation.verdict === \"revise\") {\n await ctx.ptyService.sendToSession(sessionId, followUpPrompt);\n taskCtx.lastInputSentAt = Date.now();\n await ctx.syncTaskContext(taskCtx);\n // Validator-driven continuation is coordinator-internal;\n // synthesis reports the final outcome.\n return;\n }\n\n // verdict === \"escalate\": the subagent finished with an answer but\n // the validator LLM could not prove acceptance from available\n // evidence. The answer itself is still in the session jsonl — mark\n // the task completed so the normal swarm_complete synthesis path\n // delivers the subagent's real response (see buildTaskResultLine).\n // The escalation broadcast still goes out for UI observability; we\n // just skip the \"needs human review\" chat noise because the user\n // gets the actual answer via synthesis.\n ctx.broadcast({\n type: \"escalation\",\n sessionId,\n timestamp: Date.now(),\n data: {\n reason: \"validation_escalation\",\n summary: validation.summary,\n },\n });\n }\n\n const validationSummary =\n validation.verdict === \"pass\"\n ? summarizeUserFacingTurnOutput(validation.summary) ||\n validation.summary.trim()\n : \"\";\n if (validationSummary) {\n taskCtx.validationSummary = validationSummary;\n }\n\n taskCtx.status = \"completed\";\n await Promise.all([\n ctx.syncTaskContext(taskCtx),\n verifierJob\n ? ctx.taskRegistry.updateTaskVerifierJob(verifierJob.id, {\n status: \"passed\",\n completedAt: new Date().toISOString(),\n metadata: {\n summary: validation.summary,\n reportPath: validation.reportPath || null,\n },\n })\n : Promise.resolve(),\n taskCtx.taskNodeId && verifierJob\n ? ctx.taskRegistry.recordTaskEvidence({\n threadId: taskCtx.threadId,\n nodeId: taskCtx.taskNodeId,\n sessionId,\n verifierJobId: verifierJob.id,\n evidenceType: \"validation_summary\",\n title: `Validation passed for ${taskCtx.label}`,\n summary: validation.summary,\n content: {\n completionSummary: taskCtx.completionSummary,\n reportPath: validation.reportPath || null,\n },\n metadata: {\n source: \"task-validation\",\n },\n })\n : Promise.resolve(),\n ctx.taskRegistry.updateThreadSummary(\n taskCtx.threadId,\n taskCtx.completionSummary,\n ),\n ctx.taskRegistry.appendEvent({\n threadId: taskCtx.threadId,\n sessionId,\n eventType: \"validation_passed\",\n summary: `Validation passed for \"${taskCtx.label}\"`,\n data: {\n summary: validation.summary,\n reportPath: validation.reportPath || null,\n },\n }),\n ctx.taskRegistry.appendEvent({\n threadId: taskCtx.threadId,\n sessionId,\n eventType: \"task_status_changed\",\n summary: `Task \"${taskCtx.label}\" completed`,\n data: {\n status: \"completed\",\n completionSummary: taskCtx.completionSummary,\n validationSummary: taskCtx.validationSummary ?? validation.summary,\n },\n }),\n ]);\n\n // Log to persistent history (non-blocking but observed)\n (ctx as { history?: { append: (e: unknown) => Promise<void> } }).history\n ?.append({\n timestamp: Date.now(),\n type: \"task_completed\",\n sessionId,\n label: taskCtx.label,\n agentType: taskCtx.agentType,\n repo: taskCtx.repo,\n workdir: taskCtx.workdir,\n completionSummary: taskCtx.completionSummary,\n validationSummary: taskCtx.validationSummary ?? validation.summary,\n })\n .catch((err) => {\n ctx.log(\n `Failed to persist task completion for \"${taskCtx.label}\" (${sessionId}): ${err}`,\n );\n });\n\n ctx.broadcast({\n type: \"task_complete\",\n sessionId,\n timestamp: Date.now(),\n data: {\n reasoning: decision.reasoning,\n validationSummary: taskCtx.validationSummary ?? validation.summary,\n },\n });\n\n // Per-task completion message is runtime-internal. The validator's\n // `completionSummary` is an analysis paragraph (\"The agent wrote the\n // files, verified ..., reported the URL\"): NOT the subagent's\n // actual last message, so pasting it to chat hides the real URL /\n // result. The synthesis callback (handleSwarmSynthesis) reads the\n // subagent's jsonl end_turn text and delivers the actual answer;\n // this chat write would just land first with a stale narrative.\n\n if (taskCtx.keepAliveAfterComplete) {\n ctx.log(\n `Keeping session ${sessionId} alive after completion for explicit reuse`,\n );\n } else {\n // Force-kill the session: task is done, nothing to save.\n // SIGKILL ensures the PTY and all child processes exit immediately,\n // preventing orphaned workspace processes.\n ctx.ptyService.stopSession(sessionId, /* force */ true).catch((err) => {\n ctx.log(\n `Failed to stop session after LLM-detected completion: ${err}`,\n );\n });\n }\n\n // Check if all tasks are now done, send a swarm-wide summary if so\n checkAllTasksComplete(ctx);\n break;\n }\n\n case \"escalate\":\n ctx.broadcast({\n type: \"escalation\",\n sessionId,\n timestamp: Date.now(),\n data: {\n reasoning: decision.reasoning,\n },\n });\n break;\n\n case \"ignore\":\n // No action needed\n break;\n }\n}\n\n// ─── Event Handlers ───\n\n/**\n * Handle a \"blocked\" session event: auto-resolved, escalated, or routed to decision loop.\n */\nexport async function handleBlocked(\n ctx: SwarmCoordinatorContext,\n sessionId: string,\n taskCtx: TaskContext,\n data: unknown,\n): Promise<void> {\n // Event data from pty-init: { promptInfo: BlockingPromptInfo, autoResponded: boolean }\n const eventData = data as {\n promptInfo?: {\n type?: string;\n prompt?: string;\n canAutoRespond?: boolean;\n suggestedResponse?: string;\n instructions?: string;\n url?: string;\n };\n autoResponded?: boolean;\n };\n\n // Extract prompt text from promptInfo (the actual blocking prompt info object)\n const promptText =\n eventData.promptInfo?.prompt ?? eventData.promptInfo?.instructions ?? \"\";\n\n if (isLoginRequiredPrompt(promptText, eventData.promptInfo?.type)) {\n const instructions = extractLoginInstructions(eventData);\n const url =\n typeof eventData.promptInfo?.url === \"string\" &&\n eventData.promptInfo.url.trim().length > 0\n ? eventData.promptInfo.url.trim()\n : null;\n\n taskCtx.status = \"blocked\";\n await ctx.syncTaskContext(taskCtx);\n await ctx.recordDecision(taskCtx, {\n timestamp: Date.now(),\n event: \"blocked\",\n promptText,\n decision: \"escalate\",\n reasoning:\n \"Provider login is required before the task agent can continue.\",\n });\n await ctx.taskRegistry.appendEvent({\n threadId: taskCtx.threadId,\n sessionId,\n eventType: \"task_status_changed\",\n summary: `Task \"${taskCtx.label}\" is waiting for login`,\n data: {\n status: \"blocked\",\n reason: \"login_required\",\n instructions: instructions || null,\n url,\n promptType: eventData.promptInfo?.type ?? null,\n },\n });\n ctx.broadcast({\n type: \"login_required\",\n sessionId,\n timestamp: Date.now(),\n data: {\n instructions: instructions || null,\n url,\n prompt: promptText,\n promptType: eventData.promptInfo?.type,\n },\n });\n const loginParts = [\n `\"${taskCtx.label}\" needs a provider login before it can continue.`,\n instructions || \"\",\n url ? `Login link: ${url}` : \"\",\n ].filter(Boolean);\n ctx.sendChatMessage(loginParts.join(\" \"), \"coding-agent\");\n return;\n }\n\n // Skip status-indicator patterns (spinners, animations, progress text) that\n // are not real prompts. These come from TUI re-renders during long operations\n // like \"Orchestrating…\" in Claude Code. Without this filter the coordinator\n // floods the decision loop with false \"blocked\" events and eventually\n // escalates to the user with a verbose debug dump.\n if (isStatusAnimation(promptText)) {\n ctx.log(\n `Ignoring status animation for ${taskCtx.label}: ${promptText.slice(0, 60).replace(/\\n/g, \" \")}`,\n );\n return;\n }\n\n // Auto-responded by rules: log and broadcast, no LLM needed\n if (eventData.autoResponded) {\n // Safety: check if the auto-approved prompt accessed out-of-scope paths.\n // The approval already happened in pty-manager, but we can stop the session\n // and alert the user to prevent further damage.\n if (isOutOfScopeAccess(promptText, taskCtx.workdir)) {\n taskCtx.status = \"error\";\n await ctx.recordDecision(taskCtx, {\n timestamp: Date.now(),\n event: \"blocked\",\n promptText,\n decision: \"escalate\",\n reasoning: `SECURITY: Auto-response approved access outside workspace (${taskCtx.workdir}). Session stopped.`,\n });\n\n ctx.broadcast({\n type: \"escalation\",\n sessionId,\n timestamp: Date.now(),\n data: {\n prompt: promptText,\n reason: \"out_of_scope_auto_approved\",\n workdir: taskCtx.workdir,\n },\n });\n\n ctx.sendChatMessage(\n `[${taskCtx.label}] WARNING: Auto-approved access to path outside workspace (${taskCtx.workdir}). ` +\n `Prompt: \"${promptText.slice(0, 150)}\". Stopping session for safety.`,\n \"coding-agent\",\n );\n\n // Force-kill the session to prevent further out-of-scope access\n ctx.ptyService?.stopSession(sessionId, /* force */ true).catch((err) => {\n ctx.log(\n `Failed to stop session after out-of-scope auto-approval: ${err}`,\n );\n });\n return;\n }\n\n taskCtx.autoResolvedCount++;\n await ctx.recordDecision(taskCtx, {\n timestamp: Date.now(),\n event: \"blocked\",\n promptText,\n decision: \"auto_resolved\",\n reasoning: \"Handled by auto-response rules\",\n });\n\n ctx.broadcast({\n type: \"blocked_auto_resolved\",\n sessionId,\n timestamp: Date.now(),\n data: {\n prompt: promptText,\n promptType: eventData.promptInfo?.type,\n autoResolvedCount: taskCtx.autoResolvedCount,\n },\n });\n\n // Log auto-approvals server-side only, don't persist to chat.\n const count = taskCtx.autoResolvedCount;\n if (count <= 2 || count % 5 === 0) {\n const excerpt =\n promptText.length > 120 ? `${promptText.slice(0, 120)}...` : promptText;\n ctx.log(`[${taskCtx.label}] Approved: ${excerpt}`);\n }\n return;\n }\n\n // Known-safe prompts the fast-path can handle without an LLM hop even when\n // the worker doesn't forward canAutoRespond (the pty-manager strips it from\n // promptInfo when `skipAdapterAutoResponse` is set). Bypass Permissions is\n // the motivating case: without this the dialog falls through to LLM\n // supervision and defaults to Enter (\"No, exit\"), killing claude before work\n // starts. Used both to pick the \"2\" suggested-response override below and\n // to admit the prompt into the autonomous fast-path below the\n // inferredPromptResponse check.\n //\n // Covers failure mode: layer-1 (seedClaudeTrustForWorkdir) failed AND the\n // session is coordinator-managed in subscription mode (adapter auto-\n // response is skipped, so the layer-2 session rule never fires).\n const knownRoutinePermissionPrompt =\n eventData.promptInfo?.type === \"permission\" &&\n /bypass\\s+permissions/i.test(promptText);\n\n const adapterSuggestedResponse =\n typeof eventData.promptInfo?.suggestedResponse === \"string\" &&\n eventData.promptInfo.suggestedResponse.trim().length > 0\n ? eventData.promptInfo.suggestedResponse.trim()\n : // The Claude Bypass Permissions dialog (\"WARNING: ... Bypass Permissions\n // mode accept all responsibility\") exposes options 1 (No, exit) and 2\n // (Yes, I accept). The raw permission-fallback below presses Enter,\n // which resolves to option 1 and kills claude with exit code 1 before\n // any work starts. Detect the prompt by text and send option 2 plus\n // Enter through the key path so it behaves like the PTY auto-response\n // rule instead of depending on send() newline semantics.\n knownRoutinePermissionPrompt\n ? \"keys:2,enter\"\n : eventData.promptInfo?.canAutoRespond &&\n eventData.promptInfo?.type === \"permission\"\n ? \"keys:enter\"\n : undefined;\n const inferredPromptResponse = inferRoutinePromptResponse(\n promptText,\n eventData.promptInfo?.type,\n );\n const routineSuggestedResponse =\n adapterSuggestedResponse ?? inferredPromptResponse?.suggestedResponse;\n\n if (\n ctx.getSupervisionLevel() === \"autonomous\" &&\n (eventData.promptInfo?.canAutoRespond ||\n inferredPromptResponse ||\n knownRoutinePermissionPrompt) &&\n routineSuggestedResponse\n ) {\n const fastDecision = decisionFromSuggestedResponse(\n routineSuggestedResponse,\n inferredPromptResponse?.reasoning,\n );\n\n taskCtx.autoResolvedCount++;\n await ctx.recordDecision(taskCtx, {\n timestamp: Date.now(),\n event: \"blocked\",\n promptText,\n decision: \"auto_resolved\",\n response: formatDecisionResponse(fastDecision),\n reasoning: fastDecision.reasoning,\n });\n\n ctx.broadcast({\n type: \"blocked_auto_resolved\",\n sessionId,\n timestamp: Date.now(),\n data: {\n prompt: promptText,\n promptType: eventData.promptInfo?.type,\n autoResolvedCount: taskCtx.autoResolvedCount,\n strategy: \"adapter_suggested_response\",\n },\n });\n\n await executeDecision(ctx, sessionId, fastDecision);\n return;\n }\n\n // Deduplicate: if an LLM decision is already in-flight for this session\n // AND the prompt text matches the one already being handled, skip.\n // TUI re-renders fire the same prompt many times; a *different* prompt\n // (theoretically possible if the agent resolves one prompt and immediately\n // hits another) should not be dropped.\n const promptFingerprint = promptText.slice(0, 200);\n if (ctx.inFlightDecisions.has(sessionId)) {\n if (ctx.lastBlockedPromptFingerprint.get(sessionId) === promptFingerprint) {\n ctx.log(\n `Skipping duplicate blocked event for ${taskCtx.label} (decision in-flight, same prompt)`,\n );\n return;\n }\n // Different prompt: buffer it so it's replayed after the current decision completes.\n ctx.log(\n `New blocked prompt for ${taskCtx.label} while decision in-flight: buffering`,\n );\n ctx.pendingBlocked.set(sessionId, data);\n ctx.lastBlockedPromptFingerprint.set(sessionId, promptFingerprint);\n return;\n }\n ctx.lastBlockedPromptFingerprint.set(sessionId, promptFingerprint);\n taskCtx.status = \"blocked\";\n await ctx.syncTaskContext(taskCtx);\n\n // Broadcast that the agent is blocked (for all supervision levels)\n ctx.broadcast({\n type: \"blocked\",\n sessionId,\n timestamp: Date.now(),\n data: {\n prompt: promptText,\n promptType: eventData.promptInfo?.type,\n supervisionLevel: ctx.getSupervisionLevel(),\n },\n });\n\n // Safety check: escalate after too many consecutive auto-responses\n if (taskCtx.autoResolvedCount >= MAX_AUTO_RESPONSES) {\n await ctx.recordDecision(taskCtx, {\n timestamp: Date.now(),\n event: \"blocked\",\n promptText,\n decision: \"escalate\",\n reasoning: `Escalating after ${MAX_AUTO_RESPONSES} consecutive auto-responses`,\n });\n ctx.broadcast({\n type: \"escalation\",\n sessionId,\n timestamp: Date.now(),\n data: {\n prompt: promptText,\n reason: \"max_auto_responses_exceeded\",\n },\n });\n ctx.sendChatMessage(\n `[${taskCtx.label}] Paused for your attention after ${MAX_AUTO_RESPONSES} consecutive automatic approvals. Prompt: ${truncateForUser(promptText, 180)}`,\n \"coding-agent\",\n );\n return;\n }\n\n // Route based on supervision level\n switch (ctx.getSupervisionLevel()) {\n case \"autonomous\":\n await handleAutonomousDecision(\n ctx,\n sessionId,\n taskCtx,\n promptText,\n \"\",\n eventData.promptInfo?.type,\n );\n break;\n\n case \"confirm\":\n await handleConfirmDecision(\n ctx,\n sessionId,\n taskCtx,\n promptText,\n \"\",\n eventData.promptInfo?.type,\n );\n break;\n\n case \"notify\":\n // Notify mode: broadcast only, no action\n await ctx.recordDecision(taskCtx, {\n timestamp: Date.now(),\n event: \"blocked\",\n promptText,\n decision: \"escalate\",\n reasoning: \"Supervision level is notify, broadcasting only\",\n });\n ctx.sendChatMessage(\n `[${taskCtx.label}] Waiting on a blocked prompt: ${truncateForUser(promptText, 180)}`,\n \"coding-agent\",\n );\n break;\n }\n}\n\n// ─── Turn Completion Assessment ───\n\n/**\n * Handle a turn completion event. Instead of immediately stopping the session,\n * ask the LLM whether the overall task is done or the agent needs more turns.\n */\nexport async function handleTurnComplete(\n ctx: SwarmCoordinatorContext,\n sessionId: string,\n taskCtx: TaskContext,\n data: unknown,\n): Promise<void> {\n // Accept both \"active\" and \"tool_running\": subagents using tools sit in\n // tool_running almost continuously, and we still want to run validation\n // when they hit task_complete. Only bail on truly terminal/blocked states.\n if (taskCtx.status !== \"active\" && taskCtx.status !== \"tool_running\") {\n return;\n }\n\n // If another decision (e.g. handleBlocked) is running for this session,\n // buffer the task_complete event so it's processed when the lock releases.\n // Without this, task_complete events are silently lost and sessions hang.\n if (ctx.inFlightDecisions.has(sessionId)) {\n ctx.log(\n `Buffering turn-complete for ${sessionId} (in-flight decision running)`,\n );\n ctx.pendingTurnComplete.set(sessionId, data);\n return;\n }\n\n // Suppress turn-complete events during the post-send cooldown period.\n // After the coordinator sends input, the agent needs time to process it.\n // Without this, stall-classified \"task_complete\" events from stale output\n // trigger cascading follow-ups before the agent starts responding.\n if (taskCtx.lastInputSentAt) {\n const elapsed = Date.now() - taskCtx.lastInputSentAt;\n if (elapsed < POST_SEND_COOLDOWN_MS) {\n ctx.pendingTurnComplete.set(sessionId, data);\n if (!deferredTurnCompleteTimers.has(sessionId)) {\n const delayMs = POST_SEND_COOLDOWN_MS - elapsed + 50;\n const timer = setTimeout(() => {\n deferredTurnCompleteTimers.delete(sessionId);\n const pendingData = ctx.pendingTurnComplete.get(sessionId);\n if (!pendingData) return;\n const currentTask = ctx.tasks.get(sessionId);\n if (\n !currentTask ||\n (currentTask.status !== \"active\" &&\n currentTask.status !== \"tool_running\")\n ) {\n ctx.pendingTurnComplete.delete(sessionId);\n return;\n }\n void handleTurnComplete(\n ctx,\n sessionId,\n currentTask,\n pendingData,\n ).catch((err) => {\n ctx.log(\n `Deferred turn-complete replay failed for ${sessionId}: ${err}`,\n );\n });\n }, delayMs);\n deferredTurnCompleteTimers.set(sessionId, timer);\n }\n ctx.log(\n `Suppressing turn-complete for \"${taskCtx.label}\": ` +\n `${Math.round(elapsed / 1000)}s since last input (cooldown ${POST_SEND_COOLDOWN_MS / 1000}s)`,\n );\n return;\n }\n }\n\n const deferredTimer = deferredTurnCompleteTimers.get(sessionId);\n if (deferredTimer) {\n clearTimeout(deferredTimer);\n deferredTurnCompleteTimers.delete(sessionId);\n }\n ctx.pendingTurnComplete.delete(sessionId);\n\n ctx.inFlightDecisions.add(sessionId);\n try {\n ctx.log(\n `Turn complete for \"${taskCtx.label}\": assessing whether task is done`,\n );\n\n // Get the turn output: prefer the captured response, fall back to PTY output\n const rawResponse = (data as { response?: string }).response ?? \"\";\n let turnOutput = cleanForChat(rawResponse);\n if (!turnOutput) {\n const raw = await fetchRecentOutput(ctx, sessionId);\n turnOutput = cleanForChat(raw);\n }\n\n // Fast-path: if the turn output contains a PR URL or \"Created pull request\",\n // the task is done: skip the LLM assessment entirely. The LLM (especially\n // Gemini Flash) tends to ignore \"do not verify\" instructions and sends\n // unnecessary verification follow-ups, adding 2-5 extra rounds per agent.\n // Only match explicit PR creation signals, not references to existing PRs.\n const PR_CREATED_RE =\n /(?:Created|Opened)\\s+pull\\s+request\\s+#?\\d+|gh\\s+pr\\s+create/i;\n // `gh pr create` in the output matches even when the command actually\n // errored with \"a pull request already exists for branch ...\". That\n // false positive was fast-path-marking the task complete and echoing\n // the pre-existing PR URL as if the subagent had just created it.\n // Skip the fast-path when the output contains the gh-cli error.\n const PR_ALREADY_EXISTS_RE =\n /a pull request (?:for branch)?.*already exists|pull request already exists/i;\n if (\n PR_CREATED_RE.test(turnOutput) &&\n !PR_ALREADY_EXISTS_RE.test(turnOutput)\n ) {\n // Set `keyDecision` so recordKeyDecision pushes this into\n // ctx.sharedDecisions. That ledger is what\n // checkAllTasksComplete uses to decide whether to fall through\n // to synthesis when a task's validator verifier fails. Without\n // this, a fast-path-completed task whose validator happens to\n // fail gets its real output (the PR URL) swallowed because the\n // fallthrough predicate sees neither status=completed (idle\n // watchdog may have downgraded it to `stopped`) nor a recorded\n // shared decision.\n const fastDecision: CoordinationLLMResponse = {\n action: \"complete\",\n reasoning: \"PR detected in turn output - task complete.\",\n keyDecision: \"PR created and pushed; task complete.\",\n };\n ctx.log(\n `Turn assessment for \"${taskCtx.label}\": complete (fast-path: PR detected in output)`,\n );\n await ctx.recordDecision(taskCtx, {\n timestamp: Date.now(),\n event: \"turn_complete\",\n promptText: \"Agent finished a turn\",\n decision: \"complete\",\n response: \"\",\n reasoning: fastDecision.reasoning,\n });\n recordKeyDecision(ctx, taskCtx.label, fastDecision);\n ctx.broadcast({\n type: \"turn_assessment\",\n sessionId,\n timestamp: Date.now(),\n data: { action: \"complete\", reasoning: fastDecision.reasoning },\n });\n await executeDecision(ctx, sessionId, fastDecision);\n return;\n }\n\n // Turn completions always use the fast small-LLM path.\n // The assessment is a structured complete/continue/escalate decision\n // that doesn't benefit from the full Eliza pipeline, and routing\n // through it risks hangs that block the inFlightDecisions lock.\n let decision: CoordinationLLMResponse | null = null;\n const decisionFromPipeline = false;\n\n const prompt = buildTurnCompletePrompt(\n toContextSummary(taskCtx),\n turnOutput,\n toDecisionHistory(taskCtx),\n collectSiblings(ctx, sessionId),\n ctx.sharedDecisions,\n ctx.getSwarmContext(),\n );\n try {\n const result = await withTrajectoryContext(\n ctx.runtime,\n {\n source: \"orchestrator\",\n decisionType: \"turn-complete\",\n sessionId,\n taskLabel: taskCtx.label,\n repo: taskCtx.repo,\n workdir: taskCtx.workdir,\n originalTask: taskCtx.originalTask,\n },\n () => ctx.runtime.useModel(ModelType.TEXT_SMALL, { prompt }),\n );\n decision = parseCoordinationResponse(result);\n } catch (err) {\n ctx.log(`Turn-complete LLM call failed: ${err}`);\n }\n\n if (!decision) {\n // The small LLM's response didn't parse into a valid decision. Before\n // defaulting to \"escalate\" (which surfaces \"needs your attention\" in\n // chat even when the agent actually finished cleanly), trust the\n // subagent's own terminal signal: this handler only runs on\n // `task_complete` events, and `turnOutput` above is the subagent's\n // captured response text. When turnOutput has content, treating the\n // task as complete lets synthesis deliver the real answer. A\n // transient assessor-LLM misfire shouldn't shadow output the agent\n // actually produced. Escalate only when we genuinely have nothing.\n if (turnOutput.trim().length > 0) {\n const failureReason = taskAgentFailureReasonFromTurnOutput(turnOutput);\n if (failureReason) {\n ctx.log(\n `Turn-complete for \"${taskCtx.label}\": assessor LLM failed and output is a task-agent failure, escalating`,\n );\n decision = {\n action: \"escalate\",\n reasoning: failureReason,\n };\n } else {\n ctx.log(\n `Turn-complete for \"${taskCtx.label}\": assessor LLM failed but turn output is non-empty, treating as complete`,\n );\n decision = {\n action: \"complete\",\n reasoning: completionReasoningFromTurnOutput(turnOutput),\n };\n }\n } else {\n ctx.log(\n `Turn-complete for \"${taskCtx.label}\": all decision paths failed, escalating`,\n );\n decision = {\n action: \"escalate\",\n reasoning:\n \"Assessor LLM returned an invalid response and the subagent produced no captured output. Escalating for human review.\",\n };\n }\n }\n\n // Guardrail: if the assessment LLM said \"respond\" but the response is\n // actually the agent asking the user for input (clarification, choice,\n // missing context), convert to escalate. Otherwise we feed the agent's\n // own question back to itself as new input — infinite-loop bait.\n if (\n decision.action === \"respond\" &&\n isAskingUserForInput(decision.response)\n ) {\n const agentQuestion = decision.response ?? \"\";\n ctx.log(\n `Converting \"respond\" → \"escalate\" for \"${taskCtx.label}\": agent is asking user for input`,\n );\n decision = {\n action: \"escalate\",\n reasoning: agentQuestion,\n };\n }\n\n decision = completeDecisionWithTurnOutput(decision, turnOutput);\n\n // Log the decision\n ctx.log(\n `Turn assessment for \"${taskCtx.label}\": ${decision.action}${\n decision.action === \"respond\"\n ? ` → \"${(decision.response ?? \"\").slice(0, 80)}\"`\n : \"\"\n }: ${decision.reasoning.slice(0, 120)}`,\n );\n\n // Record\n await ctx.recordDecision(taskCtx, {\n timestamp: Date.now(),\n event: \"turn_complete\",\n promptText: \"Agent finished a turn\",\n decision: decision.action,\n response: formatDecisionResponse(decision),\n reasoning: decision.reasoning,\n });\n\n // Layer 2: capture significant decisions for cross-agent sharing\n recordKeyDecision(ctx, taskCtx.label, decision);\n\n ctx.broadcast({\n type: \"turn_assessment\",\n sessionId,\n timestamp: Date.now(),\n data: {\n action: decision.action,\n reasoning: decision.reasoning,\n },\n });\n\n if (\n ctx.pendingBlocked.has(sessionId) &&\n decision.action === \"complete\" &&\n turnOutput.trim().length > 0\n ) {\n ctx.pendingBlocked.delete(sessionId);\n ctx.lastBlockedPromptFingerprint.delete(sessionId);\n ctx.log(\n `Ignoring buffered blocked prompt for \"${taskCtx.label}\" because task_complete produced final output`,\n );\n } else if (ctx.pendingBlocked.has(sessionId)) {\n ctx.log(\n `Deferring turn assessment execution for \"${taskCtx.label}\" because a newer blocked prompt arrived during assessment`,\n );\n ctx.pendingTurnComplete.set(sessionId, data);\n return;\n }\n\n // \"respond\" continuations and \"complete\" chat messages reach the user\n // through the synthesis path; only real \"escalate\" decisions surface\n // directly in chat. Log \"respond\" internally for traceability.\n if (!decisionFromPipeline) {\n if (decision.action === \"respond\") {\n const instruction = decision.response ?? \"\";\n const preview =\n instruction.length > 120\n ? `${instruction.slice(0, 120)}...`\n : instruction;\n ctx.log(`[${taskCtx.label}] Turn done, continuing: ${preview}`);\n // Mid-task continuation is coordinator-internal; the synthesis\n // callback delivers the final answer once the thread completes.\n }\n // \"escalate\" no longer posts its own chat message here. The swarm\n // synthesis callback delivers the same reasoning in its final wrap-up\n // once the task reaches terminal state, so announcing it twice (once\n // as \"[label] needs your attention: ...\" and again inside the\n // synthesis output) produces duplicated, noisy messages. Let the\n // synthesis path own the user-facing notification.\n }\n\n try {\n await executeDecision(ctx, sessionId, decision);\n } catch (err) {\n if (\n decision.action === \"complete\" &&\n isMissingPtySessionError(err) &&\n taskCtx.completionSummary?.trim()\n ) {\n ctx.log(\n `Completing \"${taskCtx.label}\" from captured output after PTY session disappeared`,\n );\n taskCtx.status = \"completed\";\n await ctx.syncTaskContext(taskCtx);\n checkAllTasksComplete(ctx);\n return;\n }\n throw err;\n }\n\n // executeDecision only stops the session on \"complete\" / \"respond\".\n // Escalate and ignore need an explicit stop to release the PTY that\n // would otherwise be held open by cancelTaskCompleteAutoStop.\n if (decision.action === \"escalate\" || decision.action === \"ignore\") {\n ctx.ptyService?.stopSession(sessionId, /* force */ false).catch((err) => {\n ctx.log(\n `Failed to stop session after ${decision.action}: ${err instanceof Error ? err.message : String(err)}`,\n );\n });\n }\n } finally {\n ctx.inFlightDecisions.delete(sessionId);\n await drainPendingBlocked(ctx, sessionId);\n await drainPendingTurnComplete(ctx, sessionId);\n }\n}\n\n// ─── Autonomous / Confirm Decision Flows ───\n\n/**\n * Handle an autonomous decision for a blocked session: call the LLM and execute immediately.\n */\nexport async function handleAutonomousDecision(\n ctx: SwarmCoordinatorContext,\n sessionId: string,\n taskCtx: TaskContext,\n promptText: string,\n recentOutput: string,\n promptType?: string,\n): Promise<void> {\n // Debounce: skip if decision already in-flight for this session\n if (ctx.inFlightDecisions.has(sessionId)) {\n ctx.log(`Skipping duplicate decision for ${sessionId} (in-flight)`);\n return;\n }\n\n ctx.inFlightDecisions.add(sessionId);\n try {\n // Get recent output from PTY if not provided\n let output = recentOutput;\n if (!output) {\n output = await fetchRecentOutput(ctx, sessionId);\n }\n\n // Triage: route to small LLM (routine) or Eliza pipeline (creative).\n // Track source so we skip duplicate chat messages when Eliza already spoke.\n const agentDecisionCb = ctx.getAgentDecisionCallback();\n let decision: CoordinationLLMResponse | null = null;\n let decisionFromPipeline = false;\n\n const triageCtx: TriageContext = {\n eventType: \"blocked\",\n promptText,\n promptType,\n recentOutput: output,\n originalTask: taskCtx.originalTask,\n };\n const tier = agentDecisionCb\n ? await classifyEventTier(ctx.runtime, triageCtx, ctx.log)\n : \"routine\"; // No pipeline → always small LLM\n\n if (tier === \"routine\") {\n decision = await makeCoordinationDecision(\n ctx,\n taskCtx,\n promptText,\n output,\n );\n } else {\n // Creative: try Eliza pipeline, fall back to small LLM\n if (agentDecisionCb) {\n const eventMessage = buildBlockedEventMessage(\n toContextSummary(taskCtx),\n promptText,\n output,\n toDecisionHistory(taskCtx),\n collectSiblings(ctx, sessionId),\n ctx.sharedDecisions,\n ctx.getSwarmContext(),\n );\n try {\n decision = await withTimeout(\n agentDecisionCb(eventMessage, sessionId, taskCtx),\n DECISION_CB_TIMEOUT_MS,\n \"agentDecisionCb\",\n );\n if (decision) decisionFromPipeline = true;\n } catch (err) {\n ctx.log(\n `Agent decision callback failed: ${err}; falling back to small LLM`,\n );\n }\n }\n\n if (!decision) {\n decision = await makeCoordinationDecision(\n ctx,\n taskCtx,\n promptText,\n output,\n );\n }\n }\n\n if (!decision) {\n // All decision paths returned invalid response, escalate\n await ctx.recordDecision(taskCtx, {\n timestamp: Date.now(),\n event: \"blocked\",\n promptText,\n decision: \"escalate\",\n reasoning: \"All decision paths returned invalid coordination response\",\n });\n ctx.broadcast({\n type: \"escalation\",\n sessionId,\n timestamp: Date.now(),\n data: {\n prompt: promptText,\n reason: \"invalid_llm_response\",\n },\n });\n ctx.sendChatMessage(\n `[${taskCtx.label}] Needs your attention: the coordinator could not decide how to handle \"${truncateForUser(promptText, 160)}\".`,\n \"coding-agent\",\n );\n return;\n }\n\n // Guard: decline + redirect if the prompt references out-of-scope paths.\n // Instead of stalling via escalate, tell the agent \"no\" and point it to the\n // workspace. Also notify the human in case broader access was intended.\n if (\n decision.action === \"respond\" &&\n isOutOfScopeAccess(promptText, taskCtx.workdir)\n ) {\n decision = {\n action: \"respond\",\n response: `No, that path is outside your workspace. Use ${taskCtx.workdir} instead. Create any files or directories you need there.`,\n reasoning: `Declined out-of-scope access (outside ${taskCtx.workdir}) and redirected agent to workspace.`,\n };\n // Surface to human so they can grant broader access if intended\n ctx.sendChatMessage(\n `[${taskCtx.label}] Declined out-of-scope access and redirected to workspace (${taskCtx.workdir}). If you intended broader access, send the agent an override.`,\n \"coding-agent\",\n );\n }\n\n // Record the decision\n taskCtx.autoResolvedCount = 0;\n await ctx.recordDecision(taskCtx, {\n timestamp: Date.now(),\n event: \"blocked\",\n promptText,\n decision: decision.action,\n response: formatDecisionResponse(decision),\n reasoning: decision.reasoning,\n });\n\n // Layer 2: capture significant decisions for cross-agent sharing\n recordKeyDecision(ctx, taskCtx.label, decision);\n\n // Broadcast the decision\n ctx.broadcast({\n type: \"coordination_decision\",\n sessionId,\n timestamp: Date.now(),\n data: {\n action: decision.action,\n response: decision.response,\n useKeys: decision.useKeys,\n keys: decision.keys,\n reasoning: decision.reasoning,\n },\n });\n\n // Send chat message for small-LLM decisions only.\n // When Eliza's pipeline handled it, she already spoke via WS broadcast.\n if (!decisionFromPipeline) {\n if (decision.action === \"respond\") {\n const actionDesc = decision.useKeys\n ? `Sent keys: ${decision.keys?.join(\", \")}`\n : decision.response\n ? `Responded: ${decision.response.length > 100 ? `${decision.response.slice(0, 100)}...` : decision.response}`\n : \"Responded\";\n const reasonExcerpt =\n decision.reasoning.length > 150\n ? `${decision.reasoning.slice(0, 150)}...`\n : decision.reasoning;\n ctx.log(`[${taskCtx.label}] ${actionDesc}: ${reasonExcerpt}`);\n } else if (decision.action === \"escalate\") {\n // Cap escalation messages to avoid dumping debug-level text into chat.\n const reason =\n decision.reasoning.length > 120\n ? `${decision.reasoning.slice(0, 120)}…`\n : decision.reasoning;\n ctx.sendChatMessage(\n `[${taskCtx.label}] Needs your attention: ${reason}`,\n \"coding-agent\",\n );\n }\n }\n\n // Execute\n await executeDecision(ctx, sessionId, decision);\n } finally {\n ctx.inFlightDecisions.delete(sessionId);\n await drainPendingBlocked(ctx, sessionId);\n await drainPendingTurnComplete(ctx, sessionId);\n }\n}\n\n/**\n * Handle a confirm-mode decision: call LLM, then queue for human approval.\n */\nexport async function handleConfirmDecision(\n ctx: SwarmCoordinatorContext,\n sessionId: string,\n taskCtx: TaskContext,\n promptText: string,\n recentOutput: string,\n promptType?: string,\n): Promise<void> {\n // Debounce\n if (ctx.inFlightDecisions.has(sessionId)) return;\n\n ctx.inFlightDecisions.add(sessionId);\n try {\n let output = recentOutput;\n if (!output) {\n output = await fetchRecentOutput(ctx, sessionId);\n }\n\n // Triage: route to small LLM (routine) or Eliza pipeline (creative)\n const agentDecisionCb = ctx.getAgentDecisionCallback();\n let decision: CoordinationLLMResponse | null = null;\n let decisionFromPipeline = false;\n\n const triageCtx: TriageContext = {\n eventType: \"blocked\",\n promptText,\n promptType,\n recentOutput: output,\n originalTask: taskCtx.originalTask,\n };\n const tier = agentDecisionCb\n ? await classifyEventTier(ctx.runtime, triageCtx, ctx.log)\n : \"routine\"; // No pipeline → always small LLM\n\n if (tier === \"routine\") {\n decision = await makeCoordinationDecision(\n ctx,\n taskCtx,\n promptText,\n output,\n );\n } else {\n // Creative: try Eliza pipeline, fall back to small LLM\n if (agentDecisionCb) {\n const eventMessage = buildBlockedEventMessage(\n toContextSummary(taskCtx),\n promptText,\n output,\n toDecisionHistory(taskCtx),\n collectSiblings(ctx, sessionId),\n ctx.sharedDecisions,\n ctx.getSwarmContext(),\n );\n try {\n decision = await withTimeout(\n agentDecisionCb(eventMessage, sessionId, taskCtx),\n DECISION_CB_TIMEOUT_MS,\n \"agentDecisionCb\",\n );\n if (decision) decisionFromPipeline = true;\n } catch (err) {\n ctx.log(\n `Agent decision callback failed (confirm): ${err}; falling back to small LLM`,\n );\n }\n }\n\n if (!decision) {\n decision = await makeCoordinationDecision(\n ctx,\n taskCtx,\n promptText,\n output,\n );\n }\n }\n\n if (!decision) {\n // Queue for human with no suggestion\n taskCtx.status = \"blocked\";\n await ctx.syncTaskContext(taskCtx);\n const pendingDecision: PendingDecision = {\n sessionId,\n promptText,\n recentOutput: output,\n llmDecision: {\n action: \"escalate\",\n reasoning:\n \"All decision paths returned invalid response, needs human review\",\n },\n taskContext: taskCtx,\n createdAt: Date.now(),\n };\n ctx.pendingDecisions.set(sessionId, pendingDecision);\n await ctx.taskRegistry.upsertPendingDecision({\n sessionId,\n threadId: taskCtx.threadId,\n promptText,\n recentOutput: output,\n llmDecision: { ...pendingDecision.llmDecision },\n taskContext: { ...taskCtx },\n createdAt: pendingDecision.createdAt,\n });\n } else {\n // Queue the LLM's suggestion for human approval\n taskCtx.status = \"blocked\";\n await ctx.syncTaskContext(taskCtx);\n const pendingDecision: PendingDecision = {\n sessionId,\n promptText,\n recentOutput: output,\n llmDecision: decision,\n taskContext: taskCtx,\n createdAt: Date.now(),\n };\n ctx.pendingDecisions.set(sessionId, pendingDecision);\n await ctx.taskRegistry.upsertPendingDecision({\n sessionId,\n threadId: taskCtx.threadId,\n promptText,\n recentOutput: output,\n llmDecision: { ...decision },\n taskContext: { ...taskCtx },\n createdAt: pendingDecision.createdAt,\n });\n }\n\n await ctx.taskRegistry.appendEvent({\n threadId: taskCtx.threadId,\n sessionId,\n eventType: \"pending_confirmation\",\n summary: `Queued human confirmation for \"${taskCtx.label}\"`,\n data: {\n promptText,\n suggestedAction: decision?.action ?? \"escalate\",\n },\n });\n\n // When Eliza's pipeline made the suggestion, she already spoke via WS broadcast.\n // Only broadcast the pending_confirmation event for small-LLM suggestions or\n // always broadcast it (the UI needs it regardless) but skip any chat messages.\n ctx.broadcast({\n type: \"pending_confirmation\",\n sessionId,\n timestamp: Date.now(),\n data: {\n prompt: promptText,\n suggestedAction: decision?.action,\n suggestedResponse: decision?.response,\n reasoning: decision?.reasoning,\n fromPipeline: decisionFromPipeline,\n },\n });\n ctx.sendChatMessage(\n [\n `[${taskCtx.label}] Waiting for your approval: ${truncateForUser(promptText, 180)}`,\n formatSuggestedAction(decision),\n decision?.reasoning\n ? `Reason: ${truncateForUser(decision.reasoning, 180)}`\n : \"\",\n ]\n .filter(Boolean)\n .join(\" \"),\n \"coding-agent\",\n );\n } finally {\n ctx.inFlightDecisions.delete(sessionId);\n await drainPendingTurnComplete(ctx, sessionId);\n await drainPendingBlocked(ctx, sessionId);\n }\n}\n",
|
|
30
|
+
"import * as fs from \"node:fs/promises\";\nimport * as path from \"node:path\";\nimport { resolveStateDir } from \"@elizaos/core\";\n\nexport type HistoryEntryType =\n | \"task_registered\"\n | \"task_completed\"\n | \"task_stopped\"\n | \"task_error\"\n | \"key_decision\";\n\nexport interface HistoryEntry {\n timestamp: number;\n type: HistoryEntryType;\n sessionId: string;\n label: string;\n agentType: string;\n repo?: string;\n workdir: string;\n originalTask?: string;\n completionSummary?: string;\n reasoning?: string;\n}\n\nconst MAX_ENTRIES = 150;\nconst TRUNCATE_TO = 100;\n/** Maximum file size in bytes before forced truncation (1 MB). */\nconst MAX_FILE_SIZE_BYTES = 1_048_576;\n\n/**\n * Simple async mutex — serializes all file mutations so concurrent\n * append() and truncate() calls don't interleave reads and writes.\n */\nclass WriteMutex {\n private queue: Array<() => void> = [];\n private locked = false;\n\n async acquire(): Promise<void> {\n if (!this.locked) {\n this.locked = true;\n return;\n }\n return new Promise<void>((resolve) => {\n this.queue.push(resolve);\n });\n }\n\n release(): void {\n const next = this.queue.shift();\n if (next) {\n next();\n } else {\n this.locked = false;\n }\n }\n}\n\nexport class SwarmHistory {\n private filePath: string;\n /** In-memory counter to avoid reading the file on every append. */\n private appendCount = 0;\n /** Serializes all file mutations. */\n private mutex = new WriteMutex();\n\n constructor(stateDir?: string) {\n const dir = stateDir || resolveStateDir();\n this.filePath = path.join(dir, \"swarm-history.jsonl\");\n }\n\n async append(entry: HistoryEntry): Promise<void> {\n await this.mutex.acquire();\n try {\n const dir = path.dirname(this.filePath);\n await fs.mkdir(dir, { recursive: true });\n await fs.appendFile(this.filePath, `${JSON.stringify(entry)}\\n`, \"utf-8\");\n this.appendCount++;\n\n // Size-based rotation: truncate if file exceeds 1 MB regardless of line count\n try {\n const stat = await fs.stat(this.filePath);\n if (stat.size > MAX_FILE_SIZE_BYTES) {\n await this.truncateInner(TRUNCATE_TO);\n return;\n }\n } catch {\n // stat failed — skip size check, fall through to line-count check\n }\n\n // Line-count check after enough appends to potentially exceed MAX_ENTRIES\n if (this.appendCount >= MAX_ENTRIES - TRUNCATE_TO) {\n const content = await fs.readFile(this.filePath, \"utf-8\");\n const lineCount = content\n .split(\"\\n\")\n .filter((l) => l.trim() !== \"\").length;\n if (lineCount > MAX_ENTRIES) {\n await this.truncateInner(TRUNCATE_TO);\n }\n }\n } catch (err) {\n console.error(\"[swarm-history] append failed:\", err);\n throw err;\n } finally {\n this.mutex.release();\n }\n }\n\n async readAll(): Promise<HistoryEntry[]> {\n try {\n const content = await fs.readFile(this.filePath, \"utf-8\");\n const entries: HistoryEntry[] = [];\n const lines = content.split(\"\\n\");\n for (let i = 0; i < lines.length; i++) {\n if (lines[i].trim() === \"\") continue;\n try {\n entries.push(JSON.parse(lines[i]) as HistoryEntry);\n } catch {\n console.warn(\n `[swarm-history] skipping corrupted line at index ${i} (length=${lines[i].length})`,\n );\n }\n }\n return entries;\n } catch (err: unknown) {\n if (\n err instanceof Error &&\n \"code\" in err &&\n (err as NodeJS.ErrnoException).code === \"ENOENT\"\n ) {\n return [];\n }\n console.error(\"[swarm-history] readAll failed:\", err);\n return [];\n }\n }\n\n async getLastUsedRepo(): Promise<string | undefined> {\n const entries = await this.readAll();\n for (let i = entries.length - 1; i >= 0; i--) {\n if (entries[i].repo) {\n return entries[i].repo;\n }\n }\n return undefined;\n }\n\n /** Called while holding the mutex — no external callers. */\n private async truncateInner(maxEntries: number): Promise<void> {\n const entries = await this.readAll();\n // If readAll returned empty but the file exists, a read error occurred —\n // don't overwrite the file or we'd erase valid history.\n if (entries.length === 0) {\n try {\n await fs.stat(this.filePath);\n console.error(\n \"[swarm-history] truncate aborted: file exists but readAll returned empty\",\n );\n return;\n } catch {\n return;\n }\n }\n // First enforce entry count, then enforce byte budget.\n // This ensures the file is both under MAX_ENTRIES and MAX_FILE_SIZE_BYTES.\n let kept = entries.slice(-maxEntries);\n let content = `${kept.map((e) => JSON.stringify(e)).join(\"\\n\")}\\n`;\n\n // If still over size budget, drop oldest entries until it fits\n while (\n Buffer.byteLength(content, \"utf-8\") > MAX_FILE_SIZE_BYTES &&\n kept.length > 1\n ) {\n kept = kept.slice(Math.max(1, Math.floor(kept.length * 0.2)));\n content = `${kept.map((e) => JSON.stringify(e)).join(\"\\n\")}\\n`;\n }\n\n await fs.writeFile(this.filePath, content, \"utf-8\");\n this.appendCount = 0;\n }\n}\n",
|
|
31
|
+
"/**\n * Swarm Coordinator — Idle Watchdog\n *\n * Extracted from swarm-coordinator.ts for modularity.\n * Scans active sessions for idle ones and asks the LLM to assess their state.\n *\n * @module services/swarm-idle-watchdog\n */\n\nimport { ModelType } from \"@elizaos/core\";\nimport { cleanForChat, stripAnsi } from \"./ansi-utils.js\";\nimport type {\n SwarmCoordinatorContext,\n TaskContext,\n} from \"./swarm-coordinator.js\";\nimport {\n buildIdleCheckPrompt,\n type CoordinationLLMResponse,\n type DecisionHistoryEntry,\n parseCoordinationResponse,\n type SiblingTaskSummary,\n type TaskContextSummary,\n} from \"./swarm-coordinator-prompts.js\";\nimport {\n checkAllTasksComplete,\n executeDecision,\n} from \"./swarm-decision-loop.js\";\nimport { withTrajectoryContext } from \"./trajectory-context.js\";\n\n// ─── Constants ───\n\n/** How long a session can be idle before the watchdog checks on it (ms). */\nexport const IDLE_THRESHOLD_MS = 5 * 60 * 1000; // 5 minutes\n\n/** Max idle checks before force-escalating a session. */\nexport const MAX_IDLE_CHECKS = 4;\n\n// ─── Idle Watchdog ───\n\n/**\n * Scan all active sessions for idle ones. Called periodically by the watchdog timer.\n */\nexport async function scanIdleSessions(\n ctx: SwarmCoordinatorContext,\n): Promise<void> {\n const now = Date.now();\n for (const taskCtx of ctx.tasks.values()) {\n // Always run the liveness check — a task stuck at \"blocked\"\n // (login_required, pending_approval, ...) whose PTY has actually\n // exited would otherwise remain blocked forever and prevent the\n // swarm from reaching a terminal state, so synthesis never fires.\n // The status-based skip only applies to the idle-timer path below.\n if (ctx.ptyService) {\n const session = ctx.ptyService.getSession(taskCtx.sessionId);\n if (\n !session &&\n taskCtx.status !== \"completed\" &&\n taskCtx.status !== \"stopped\" &&\n taskCtx.status !== \"error\"\n ) {\n const completionSummary = taskCtx.completionSummary?.trim();\n if (completionSummary) {\n ctx.log(\n `Idle watchdog: \"${taskCtx.label}\" — PTY session is gone after captured completion, marking completed`,\n );\n taskCtx.status = \"completed\";\n await ctx.syncTaskContext(taskCtx);\n checkAllTasksComplete(ctx);\n continue;\n }\n\n ctx.log(\n `Idle watchdog: \"${taskCtx.label}\" — PTY session no longer exists, marking as stopped`,\n );\n taskCtx.status = \"stopped\";\n taskCtx.stoppedAt = now;\n await ctx.recordDecision(taskCtx, {\n timestamp: now,\n event: \"idle_watchdog\",\n promptText: \"PTY session no longer exists\",\n decision: \"stopped\",\n reasoning:\n \"Underlying PTY process is gone (likely killed during restart)\",\n });\n ctx.broadcast({\n type: \"stopped\",\n sessionId: taskCtx.sessionId,\n timestamp: now,\n data: { reason: \"pty_session_gone\" },\n });\n ctx.sendChatMessage(\n `[${taskCtx.label}] Session lost — the agent process is no longer running (likely killed during a restart).`,\n \"coding-agent\",\n );\n checkAllTasksComplete(ctx);\n continue;\n }\n }\n\n // Idle-timer path below only applies to live, running sessions — skip\n // anything already in a non-running state.\n if (taskCtx.status !== \"active\" && taskCtx.status !== \"tool_running\") {\n continue;\n }\n\n const idleMs = now - taskCtx.lastActivityAt;\n if (idleMs < IDLE_THRESHOLD_MS) continue;\n\n // Skip if already checking this session\n if (ctx.inFlightDecisions.has(taskCtx.sessionId)) continue;\n\n // Check if PTY output has changed since last scan — if data is flowing,\n // the session is active even without named events (e.g. loading spinners).\n // Compare stripped output to ignore TUI cursor movements and redraws\n // that would otherwise fool the watchdog into thinking the session is active.\n if (ctx.ptyService) {\n try {\n const rawOutput = await ctx.ptyService.getSessionOutput(\n taskCtx.sessionId,\n 20,\n );\n const currentOutput = stripAnsi(rawOutput).trim();\n const lastSeen = ctx.lastSeenOutput.get(taskCtx.sessionId) ?? \"\";\n ctx.lastSeenOutput.set(taskCtx.sessionId, currentOutput);\n if (currentOutput !== lastSeen) {\n // Output changed — session is producing data, reset idle state\n taskCtx.lastActivityAt = now;\n taskCtx.idleCheckCount = 0;\n ctx.log(\n `Idle watchdog: \"${taskCtx.label}\" has fresh PTY output — not idle`,\n );\n continue;\n }\n } catch {\n // Can't read output — proceed with idle check\n }\n\n // Even if the visible 20-line tail didn't change, trust the adapter's\n // own \"I am busy\" signal. TUIs like Codex redraw their status row\n // (\"Working (Xs • esc to interrupt)\") in place via cursor positioning,\n // so consecutive ANSI-stripped tails can collapse to identical text\n // even while the model is actively reasoning for minutes. The adapter's\n // detectLoading() runs against the full buffer and is the source of\n // truth for \"is the agent processing right now\".\n try {\n const isLoading = await ctx.ptyService.isSessionLoading(\n taskCtx.sessionId,\n );\n if (isLoading) {\n taskCtx.lastActivityAt = now;\n taskCtx.idleCheckCount = 0;\n ctx.log(\n `Idle watchdog: \"${taskCtx.label}\" adapter reports loading — not idle`,\n );\n continue;\n }\n } catch {\n // Fall through to the LLM idle check if we can't query the adapter.\n }\n }\n\n taskCtx.idleCheckCount++;\n const idleMinutes = Math.round(idleMs / 60_000);\n ctx.log(\n `Idle watchdog: \"${taskCtx.label}\" idle for ${idleMinutes}m (check ${taskCtx.idleCheckCount}/${MAX_IDLE_CHECKS})`,\n );\n\n if (taskCtx.idleCheckCount >= MAX_IDLE_CHECKS) {\n // Force-stop — too many idle checks with no resolution\n ctx.log(\n `Idle watchdog: force-stopping \"${taskCtx.label}\" after ${MAX_IDLE_CHECKS} checks`,\n );\n taskCtx.status = \"stopped\";\n taskCtx.stoppedAt = now;\n await ctx.recordDecision(taskCtx, {\n timestamp: now,\n event: \"idle_watchdog\",\n promptText: `Session idle for ${idleMinutes} minutes`,\n decision: \"stopped\",\n reasoning: `Force-stopped after ${MAX_IDLE_CHECKS} idle checks with no activity`,\n });\n ctx.broadcast({\n type: \"stopped\",\n sessionId: taskCtx.sessionId,\n timestamp: now,\n data: {\n reason: \"idle_watchdog_max_checks\",\n idleMinutes,\n idleCheckCount: taskCtx.idleCheckCount,\n },\n });\n ctx.sendChatMessage(\n `[${taskCtx.label}] Session stopped — idle for ${idleMinutes} minutes with no progress.`,\n \"coding-agent\",\n );\n // Force-kill the PTY session — idle timeout means nothing to save.\n if (ctx.ptyService) {\n try {\n await ctx.ptyService.stopSession(taskCtx.sessionId, /* force */ true);\n } catch (err) {\n ctx.log(\n `Idle watchdog: failed to stop session ${taskCtx.sessionId}: ${err}`,\n );\n taskCtx.status = \"error\";\n await ctx.syncTaskContext(taskCtx);\n ctx.broadcast({\n type: \"error\",\n sessionId: taskCtx.sessionId,\n timestamp: now,\n data: { message: `Failed to stop idle session: ${err}` },\n });\n }\n }\n // Check if all tasks are now done\n checkAllTasksComplete(ctx);\n continue;\n }\n\n // Ask the LLM what's going on\n await handleIdleCheck(ctx, taskCtx, idleMinutes);\n }\n}\n\n/**\n * Handle an idle session by asking the LLM to assess its state.\n */\nexport async function handleIdleCheck(\n ctx: SwarmCoordinatorContext,\n taskCtx: TaskContext,\n idleMinutes: number,\n): Promise<void> {\n const sessionId = taskCtx.sessionId;\n ctx.inFlightDecisions.add(sessionId);\n try {\n let recentOutput = \"\";\n if (ctx.ptyService) {\n try {\n const raw = await ctx.ptyService.getSessionOutput(sessionId, 50);\n recentOutput = cleanForChat(raw);\n } catch {\n recentOutput = \"\";\n }\n }\n\n const contextSummary: TaskContextSummary = {\n sessionId,\n agentType: taskCtx.agentType,\n label: taskCtx.label,\n originalTask: taskCtx.originalTask,\n workdir: taskCtx.workdir,\n };\n\n const decisionHistory: DecisionHistoryEntry[] = taskCtx.decisions\n .filter((d) => d.decision !== \"auto_resolved\")\n .slice(-5)\n .map((d) => ({\n event: d.event,\n promptText: d.promptText,\n action: d.decision,\n response: d.response,\n reasoning: d.reasoning,\n }));\n\n const siblings: SiblingTaskSummary[] = [];\n for (const [sid, task] of ctx.tasks) {\n if (sid === sessionId) continue;\n siblings.push({\n label: task.label,\n agentType: task.agentType,\n originalTask: task.originalTask,\n status: task.status,\n });\n }\n\n const prompt = buildIdleCheckPrompt(\n contextSummary,\n recentOutput,\n idleMinutes,\n taskCtx.idleCheckCount,\n MAX_IDLE_CHECKS,\n decisionHistory,\n siblings,\n ctx.sharedDecisions,\n ctx.getSwarmContext(),\n );\n\n let decision: CoordinationLLMResponse | null = null;\n try {\n const result = await withTrajectoryContext(\n ctx.runtime,\n {\n source: \"orchestrator\",\n decisionType: \"idle-check\",\n sessionId,\n taskLabel: taskCtx.label,\n repo: taskCtx.repo,\n workdir: taskCtx.workdir,\n originalTask: taskCtx.originalTask,\n },\n () => ctx.runtime.useModel(ModelType.TEXT_SMALL, { prompt }),\n );\n decision = parseCoordinationResponse(result);\n } catch (err) {\n ctx.log(`Idle check LLM call failed: ${err}`);\n }\n\n if (!decision) {\n ctx.log(\n `Idle check for \"${taskCtx.label}\": LLM returned invalid response — escalating`,\n );\n ctx.sendChatMessage(\n `[${taskCtx.label}] Session idle for ${idleMinutes}m — couldn't determine status. Needs your attention.`,\n \"coding-agent\",\n );\n return;\n }\n\n // Record the decision\n await ctx.recordDecision(taskCtx, {\n timestamp: Date.now(),\n event: \"idle_watchdog\",\n promptText: `Session idle for ${idleMinutes} minutes`,\n decision: decision.action,\n response:\n decision.action === \"respond\"\n ? decision.useKeys\n ? `keys:${decision.keys?.join(\",\")}`\n : decision.response\n : undefined,\n reasoning: decision.reasoning,\n });\n\n ctx.broadcast({\n type: \"idle_check_decision\",\n sessionId,\n timestamp: Date.now(),\n data: {\n action: decision.action,\n idleMinutes,\n idleCheckNumber: taskCtx.idleCheckCount,\n reasoning: decision.reasoning,\n },\n });\n\n // Send chat message\n if (decision.action === \"complete\") {\n // executeDecision handles chat + stop for \"complete\"\n } else if (decision.action === \"respond\") {\n const actionDesc = decision.useKeys\n ? `Sent keys: ${decision.keys?.join(\", \")}`\n : `Nudged: ${decision.response ?? \"\"}`;\n ctx.log(`[${taskCtx.label}] Idle for ${idleMinutes}m — ${actionDesc}`);\n } else if (decision.action === \"escalate\") {\n ctx.sendChatMessage(\n `[${taskCtx.label}] Idle for ${idleMinutes}m — needs your attention: ${decision.reasoning}`,\n \"coding-agent\",\n );\n } else if (decision.action === \"ignore\") {\n ctx.log(\n `Idle check for \"${taskCtx.label}\": LLM says still working — ${decision.reasoning}`,\n );\n }\n\n await executeDecision(ctx, sessionId, decision);\n } finally {\n ctx.inFlightDecisions.delete(sessionId);\n }\n}\n",
|
|
32
|
+
"import { type IAgentRuntime, ModelType } from \"@elizaos/core\";\nimport { parseJsonObjectResponse } from \"./json-model-output.js\";\nimport type { CreateTaskThreadInput } from \"./task-registry.js\";\n\nexport interface TaskAcceptanceCriteriaResult {\n criteria: string[];\n source: \"provided\" | \"model\" | \"baseline\";\n}\n\nconst MAX_CRITERIA = 7;\n\nfunction trimCriterion(value: string): string {\n return value\n .replace(/^[\\s*-]+/, \"\")\n .replace(/\\s+/g, \" \")\n .trim();\n}\n\nfunction uniqueCriteria(values: string[]): string[] {\n const seen = new Set<string>();\n const result: string[] = [];\n for (const value of values.map(trimCriterion)) {\n if (!value) continue;\n const key = value.toLowerCase();\n if (seen.has(key)) continue;\n seen.add(key);\n result.push(value);\n if (result.length >= MAX_CRITERIA) break;\n }\n return result;\n}\n\nfunction parseCriteriaResponse(raw: string): string[] {\n const parsedJson = parseJsonObjectResponse<Record<string, unknown>>(raw);\n const rawCriteria = parsedJson?.criteria;\n if (Array.isArray(rawCriteria)) {\n return uniqueCriteria(\n rawCriteria.filter((entry): entry is string => typeof entry === \"string\"),\n );\n }\n if (typeof rawCriteria === \"string\") {\n return uniqueCriteria(rawCriteria.split(/\\r?\\n|,/));\n }\n\n const trimmed = raw.trim();\n const fenced = trimmed.match(/```(?:json)?\\s*([\\s\\S]*?)\\s*```/i);\n const candidate = (fenced?.[1] ?? trimmed).trim();\n const parsed = JSON.parse(candidate) as unknown;\n if (!Array.isArray(parsed)) return [];\n return uniqueCriteria(\n parsed.filter((entry): entry is string => typeof entry === \"string\"),\n );\n}\n\nfunction plannedSubtasks(input: CreateTaskThreadInput): string[] {\n const subtasks = (input.currentPlan as { subtasks?: unknown } | undefined)\n ?.subtasks;\n if (!Array.isArray(subtasks)) return [];\n return uniqueCriteria(\n subtasks.filter((entry): entry is string => typeof entry === \"string\"),\n );\n}\n\nfunction getRepo(input: CreateTaskThreadInput): string | null {\n const repo = input.metadata?.repo;\n if (typeof repo !== \"string\") return null;\n const trimmed = repo.trim();\n return trimmed.length > 0 ? trimmed : null;\n}\n\nfunction buildBaselineAcceptanceCriteria(\n input: CreateTaskThreadInput,\n): string[] {\n const criteria: string[] = [];\n const subtasks = plannedSubtasks(input);\n\n criteria.push(`Address the full request: ${input.originalRequest}`);\n for (const subtask of subtasks.slice(0, 3)) {\n criteria.push(`Complete this planned subtask: ${subtask}`);\n }\n if (input.kind === \"coding\" || getRepo(input)) {\n criteria.push(\n \"Run the relevant checks for the changed code, or record the exact blocker.\",\n );\n }\n criteria.push(\"Capture concrete completion evidence in the task record.\");\n criteria.push(\n \"Do not claim completion while any blocker or missing verification remains.\",\n );\n return uniqueCriteria(criteria).slice(0, MAX_CRITERIA);\n}\n\nfunction buildAcceptancePrompt(input: CreateTaskThreadInput): string {\n const subtasks = plannedSubtasks(input);\n const planBlock =\n subtasks.length > 0\n ? subtasks.map((task) => `- ${task}`).join(\"\\n\")\n : \"- none\";\n return [\n \"Generate task completion criteria for an orchestrated agent task.\",\n \"Return JSON only with a criteria array of 3 to 7 measurable strings.\",\n \"Each criterion must be observable and suitable for completion validation.\",\n \"Avoid generic wording like 'do a good job'.\",\n \"Use this JSON shape:\",\n JSON.stringify(\n {\n criteria: [\n \"Complete the requested implementation.\",\n \"Run relevant checks or record exact blockers.\",\n \"Capture concrete completion evidence.\",\n ],\n },\n null,\n 2,\n ),\n \"\",\n `Title: ${input.title}`,\n `Kind: ${input.kind ?? \"coding\"}`,\n `Original request: ${input.originalRequest}`,\n `Repository: ${getRepo(input) ?? \"none\"}`,\n \"Planned subtasks:\",\n planBlock,\n \"\",\n \"Prefer criteria about completed work, verification, evidence, and unresolved blockers.\",\n ].join(\"\\n\");\n}\n\nexport async function deriveTaskAcceptanceCriteria(\n runtime: IAgentRuntime,\n input: CreateTaskThreadInput,\n): Promise<TaskAcceptanceCriteriaResult> {\n const provided = uniqueCriteria(input.acceptanceCriteria ?? []);\n if (provided.length > 0) {\n return {\n criteria: provided,\n source: \"provided\",\n };\n }\n\n try {\n const raw = await runtime.useModel(ModelType.TEXT_SMALL, {\n prompt: buildAcceptancePrompt(input),\n temperature: 0.1,\n stream: false,\n });\n if (typeof raw === \"string\") {\n const parsed = parseCriteriaResponse(raw);\n if (parsed.length >= 3) {\n return {\n criteria: parsed,\n source: \"model\",\n };\n }\n }\n } catch {\n // Fall back to baseline criteria when the model is unavailable or invalid.\n }\n\n return {\n criteria: buildBaselineAcceptanceCriteria(input),\n source: \"baseline\",\n };\n}\n",
|
|
33
|
+
"import type { CreateTaskThreadInput, TaskThreadKind } from \"./task-registry.js\";\n\nconst CODING_RE =\n /\\b(code|coding|implement|fix|debug|refactor|write|build|patch|repo|repository|branch|commit|pull request|pr|test|tests|typescript|javascript|react|server|api)\\b/i;\nconst RESEARCH_RE =\n /\\b(research|investigate|analyze|analysis|compare|evaluate|review|study|summarize|summary|deep research|report|find out|look into|explore)\\b/i;\nconst PLANNING_RE =\n /\\b(plan|planning|roadmap|strategy|spec|prd|design|architecture|scope|milestone|breakdown|sequence|timeline)\\b/i;\nconst OPS_RE =\n /\\b(deploy|release|ship|rollback|monitor|incident|ops|operations|runbook|infra|infrastructure|configure|setup|provision|container|docker|kubernetes|ci|cd)\\b/i;\n\nfunction collectTaskText(input: CreateTaskThreadInput): string {\n const subtasks = Array.isArray(\n (input.currentPlan as { subtasks?: unknown } | undefined)?.subtasks,\n )\n ? (\n ((input.currentPlan as { subtasks?: unknown }).subtasks as unknown[]) ??\n []\n )\n .filter((entry): entry is string => typeof entry === \"string\")\n .join(\"\\n\")\n : \"\";\n const repo =\n typeof input.metadata?.repo === \"string\" ? input.metadata.repo : \"\";\n return [input.title, input.originalRequest, subtasks, repo]\n .filter((value) => typeof value === \"string\" && value.trim().length > 0)\n .join(\"\\n\");\n}\n\nexport function inferTaskThreadKind(\n input: CreateTaskThreadInput,\n): TaskThreadKind {\n if (input.kind) return input.kind;\n\n const text = collectTaskText(input);\n const matches: TaskThreadKind[] = [];\n\n if (CODING_RE.test(text) || typeof input.metadata?.repo === \"string\") {\n matches.push(\"coding\");\n }\n if (RESEARCH_RE.test(text)) {\n matches.push(\"research\");\n }\n if (PLANNING_RE.test(text)) {\n matches.push(\"planning\");\n }\n if (OPS_RE.test(text)) {\n matches.push(\"ops\");\n }\n\n const unique = Array.from(new Set(matches));\n if (unique.length === 0) return \"coding\";\n if (unique.length === 1) return unique[0] ?? \"coding\";\n return \"mixed\";\n}\n",
|
|
34
|
+
"import crypto from \"node:crypto\";\nimport type { IAgentRuntime } from \"@elizaos/core\";\nimport type { CodingAgentType } from \"./pty-types.js\";\n\ntype RawSqlQuery = {\n queryChunks: Array<{ value?: unknown }>;\n};\n\ntype RuntimeDb = {\n execute: (query: RawSqlQuery) => Promise<unknown>;\n};\n\ntype Row = Record<string, unknown>;\n\nlet cachedSqlRaw: ((query: string) => RawSqlQuery) | null = null;\nconst schemaReady = new WeakSet<object>();\n\nexport type TaskThreadKind =\n | \"coding\"\n | \"research\"\n | \"planning\"\n | \"ops\"\n | \"mixed\";\n\nexport type TaskThreadStatus =\n | \"open\"\n | \"active\"\n | \"waiting_on_user\"\n | \"blocked\"\n | \"validating\"\n | \"done\"\n | \"failed\"\n | \"archived\"\n | \"interrupted\";\n\nexport type TaskSessionStatus =\n | \"active\"\n | \"blocked\"\n | \"waiting_on_user\"\n | \"completed\"\n | \"stopped\"\n | \"error\"\n | \"tool_running\"\n | \"interrupted\";\n\nexport type TaskThreadEventType =\n | \"task_created\"\n | \"task_registered\"\n | \"task_status_changed\"\n | \"task_paused\"\n | \"task_resumed\"\n | \"task_stopped\"\n | \"task_archived\"\n | \"task_reopened\"\n | \"session_registered\"\n | \"session_updated\"\n | \"session_interrupted\"\n | \"decision_recorded\"\n | \"artifact_recorded\"\n | \"summary_updated\"\n | \"share_discovered\";\n\nexport interface TaskThreadRecord {\n id: string;\n agentId: string;\n roomId: string | null;\n worldId: string | null;\n ownerUserId: string | null;\n scenarioId: string | null;\n batchId: string | null;\n title: string;\n kind: TaskThreadKind;\n status: TaskThreadStatus;\n originalRequest: string;\n summary: string;\n acceptanceCriteria: string[];\n currentPlan: Record<string, unknown>;\n searchText: string;\n createdAt: string;\n updatedAt: string;\n closedAt: string | null;\n archivedAt: string | null;\n lastUserTurnAt: string | null;\n lastCoordinatorTurnAt: string | null;\n metadata: Record<string, unknown>;\n}\n\nexport interface TaskSessionRecord {\n id: string;\n threadId: string;\n agentId: string;\n sessionId: string;\n framework: CodingAgentType;\n providerSource: string | null;\n label: string;\n originalTask: string;\n workdir: string;\n repo: string | null;\n status: TaskSessionStatus;\n decisionCount: number;\n autoResolvedCount: number;\n registeredAt: number;\n lastActivityAt: number;\n idleCheckCount: number;\n taskDelivered: boolean;\n completionSummary: string | null;\n lastSeenDecisionIndex: number;\n lastInputSentAt: number | null;\n stoppedAt: number | null;\n createdAt: string;\n updatedAt: string;\n metadata: Record<string, unknown>;\n}\n\nexport interface TaskDecisionRecord {\n id: string;\n threadId: string;\n sessionId: string;\n timestamp: number;\n event: string;\n promptText: string;\n decision: string;\n response: string | null;\n reasoning: string;\n metadata: Record<string, unknown>;\n}\n\nexport interface TaskEventRecord {\n id: string;\n threadId: string;\n sessionId: string | null;\n eventType: TaskThreadEventType | string;\n timestamp: number;\n summary: string;\n data: Record<string, unknown>;\n createdAt: string;\n}\n\nexport interface TaskArtifactRecord {\n id: string;\n threadId: string;\n sessionId: string | null;\n artifactType: string;\n title: string;\n path: string | null;\n uri: string | null;\n mimeType: string | null;\n metadata: Record<string, unknown>;\n createdAt: string;\n}\n\nexport interface TaskTranscriptRecord {\n id: string;\n threadId: string;\n sessionId: string;\n timestamp: number;\n direction: \"stdout\" | \"stderr\" | \"stdin\" | \"keys\" | \"system\";\n content: string;\n metadata: Record<string, unknown>;\n createdAt: string;\n}\n\nexport interface TaskPendingDecisionRecord {\n sessionId: string;\n threadId: string;\n promptText: string;\n recentOutput: string;\n llmDecision: Record<string, unknown>;\n taskContext: Record<string, unknown>;\n createdAt: number;\n updatedAt: string;\n}\n\nexport type TaskNodeKind =\n | \"goal\"\n | \"execution\"\n | \"research\"\n | \"planning\"\n | \"verification\"\n | \"handoff\";\n\nexport type TaskNodeStatus =\n | \"planned\"\n | \"ready\"\n | \"claimed\"\n | \"running\"\n | \"blocked\"\n | \"waiting_on_user\"\n | \"verifying\"\n | \"completed\"\n | \"failed\"\n | \"canceled\"\n | \"interrupted\";\n\nexport interface TaskNodeRecord {\n id: string;\n threadId: string;\n parentNodeId: string | null;\n kind: TaskNodeKind;\n status: TaskNodeStatus;\n title: string;\n instructions: string;\n acceptanceCriteria: string[];\n requiredCapabilities: string[];\n expectedArtifacts: string[];\n assignedSessionId: string | null;\n assignedLabel: string | null;\n agentType: CodingAgentType | null;\n workdir: string | null;\n repo: string | null;\n priority: number;\n depth: number;\n sequence: number;\n createdFrom: string | null;\n metadata: Record<string, unknown>;\n createdAt: string;\n updatedAt: string;\n startedAt: string | null;\n completedAt: string | null;\n}\n\nexport type TaskDependencyKind =\n | \"blocks\"\n | \"parent_child\"\n | \"artifact\"\n | \"handoff\";\n\nexport interface TaskDependencyRecord {\n id: string;\n threadId: string;\n fromNodeId: string;\n toNodeId: string;\n dependencyKind: TaskDependencyKind;\n requiredStatus: TaskNodeStatus;\n metadata: Record<string, unknown>;\n createdAt: string;\n}\n\nexport type TaskClaimType = \"execution\" | \"verification\" | \"ownership\";\nexport type TaskClaimStatus =\n | \"active\"\n | \"released\"\n | \"completed\"\n | \"failed\"\n | \"interrupted\";\n\nexport interface TaskClaimRecord {\n id: string;\n threadId: string;\n nodeId: string;\n sessionId: string;\n claimType: TaskClaimType;\n status: TaskClaimStatus;\n claimedAt: string;\n releasedAt: string | null;\n metadata: Record<string, unknown>;\n}\n\nexport type TaskMailboxDeliveryState = \"pending\" | \"delivered\" | \"consumed\";\n\nexport interface TaskMailboxMessageRecord {\n id: string;\n threadId: string;\n nodeId: string | null;\n sessionId: string | null;\n sender: string;\n recipient: string;\n subject: string;\n body: string;\n deliveryState: TaskMailboxDeliveryState;\n metadata: Record<string, unknown>;\n createdAt: string;\n deliveredAt: string | null;\n}\n\nexport type TaskVerifierJobStatus =\n | \"pending\"\n | \"running\"\n | \"passed\"\n | \"failed\"\n | \"canceled\";\n\nexport interface TaskVerifierJobRecord {\n id: string;\n threadId: string;\n nodeId: string;\n status: TaskVerifierJobStatus;\n verifierType: string;\n title: string;\n instructions: string;\n config: Record<string, unknown>;\n metadata: Record<string, unknown>;\n createdAt: string;\n startedAt: string | null;\n completedAt: string | null;\n}\n\nexport interface TaskEvidenceRecord {\n id: string;\n threadId: string;\n nodeId: string | null;\n sessionId: string | null;\n verifierJobId: string | null;\n evidenceType: string;\n title: string;\n summary: string;\n path: string | null;\n uri: string | null;\n content: Record<string, unknown>;\n metadata: Record<string, unknown>;\n createdAt: string;\n}\n\nexport interface TaskThreadSummary extends TaskThreadRecord {\n sessionCount: number;\n activeSessionCount: number;\n latestSessionId: string | null;\n latestSessionLabel: string | null;\n latestWorkdir: string | null;\n latestRepo: string | null;\n latestActivityAt: number | null;\n decisionCount: number;\n nodeCount: number;\n readyNodeCount: number;\n completedNodeCount: number;\n verifierJobCount: number;\n evidenceCount: number;\n}\n\nexport interface TaskThreadDetail extends TaskThreadSummary {\n sessions: TaskSessionRecord[];\n decisions: TaskDecisionRecord[];\n events: TaskEventRecord[];\n artifacts: TaskArtifactRecord[];\n transcripts: TaskTranscriptRecord[];\n pendingDecisions: TaskPendingDecisionRecord[];\n nodes: TaskNodeRecord[];\n dependencies: TaskDependencyRecord[];\n claims: TaskClaimRecord[];\n mailbox: TaskMailboxMessageRecord[];\n verifierJobs: TaskVerifierJobRecord[];\n evidence: TaskEvidenceRecord[];\n}\n\nexport interface CreateTaskThreadInput {\n id?: string;\n title: string;\n originalRequest: string;\n kind?: TaskThreadKind;\n roomId?: string | null;\n worldId?: string | null;\n ownerUserId?: string | null;\n scenarioId?: string | null;\n batchId?: string | null;\n summary?: string;\n acceptanceCriteria?: string[];\n currentPlan?: Record<string, unknown>;\n lastUserTurnAt?: string | null;\n metadata?: Record<string, unknown>;\n}\n\nexport interface RegisterTaskSessionInput {\n threadId: string;\n sessionId: string;\n framework: CodingAgentType;\n label: string;\n originalTask: string;\n workdir: string;\n repo?: string;\n providerSource?: string | null;\n status?: TaskSessionStatus;\n decisionCount?: number;\n autoResolvedCount?: number;\n registeredAt?: number;\n lastActivityAt?: number;\n idleCheckCount?: number;\n taskDelivered?: boolean;\n completionSummary?: string | null;\n lastSeenDecisionIndex?: number;\n lastInputSentAt?: number | null;\n stoppedAt?: number | null;\n metadata?: Record<string, unknown>;\n}\n\nexport interface UpdateTaskSessionInput {\n status?: TaskSessionStatus;\n decisionCount?: number;\n autoResolvedCount?: number;\n lastActivityAt?: number;\n idleCheckCount?: number;\n taskDelivered?: boolean;\n completionSummary?: string | null;\n lastSeenDecisionIndex?: number;\n lastInputSentAt?: number | null;\n stoppedAt?: number | null;\n metadata?: Record<string, unknown>;\n}\n\nexport interface UpdateTaskThreadInput {\n status?: TaskThreadStatus;\n summary?: string;\n currentPlan?: Record<string, unknown>;\n lastUserTurnAt?: string | null;\n lastCoordinatorTurnAt?: string | null;\n closedAt?: string | null;\n archivedAt?: string | null;\n metadata?: Record<string, unknown>;\n}\n\nexport interface RecordTaskDecisionInput {\n threadId: string;\n sessionId: string;\n timestamp: number;\n event: string;\n promptText: string;\n decision: string;\n response?: string;\n reasoning: string;\n metadata?: Record<string, unknown>;\n}\n\nexport interface RecordTaskEventInput {\n threadId: string;\n sessionId?: string | null;\n eventType: TaskThreadEventType | string;\n timestamp?: number;\n summary?: string;\n data?: Record<string, unknown>;\n}\n\nexport interface RecordTaskArtifactInput {\n threadId: string;\n sessionId?: string | null;\n artifactType: string;\n title: string;\n path?: string | null;\n uri?: string | null;\n mimeType?: string | null;\n metadata?: Record<string, unknown>;\n}\n\nexport interface RecordTaskTranscriptInput {\n threadId: string;\n sessionId: string;\n timestamp?: number;\n direction: TaskTranscriptRecord[\"direction\"];\n content: string;\n metadata?: Record<string, unknown>;\n}\n\nexport interface UpsertPendingDecisionInput {\n sessionId: string;\n threadId: string;\n promptText: string;\n recentOutput: string;\n llmDecision: Record<string, unknown>;\n taskContext: Record<string, unknown>;\n createdAt?: number;\n}\n\nexport interface CreateTaskNodeInput {\n id?: string;\n threadId: string;\n parentNodeId?: string | null;\n kind?: TaskNodeKind;\n status?: TaskNodeStatus;\n title: string;\n instructions?: string;\n acceptanceCriteria?: string[];\n requiredCapabilities?: string[];\n expectedArtifacts?: string[];\n assignedSessionId?: string | null;\n assignedLabel?: string | null;\n agentType?: CodingAgentType | null;\n workdir?: string | null;\n repo?: string | null;\n priority?: number;\n depth?: number;\n sequence?: number;\n createdFrom?: string | null;\n metadata?: Record<string, unknown>;\n startedAt?: string | null;\n completedAt?: string | null;\n}\n\nexport interface UpdateTaskNodeInput {\n parentNodeId?: string | null;\n kind?: TaskNodeKind;\n status?: TaskNodeStatus;\n title?: string;\n instructions?: string;\n acceptanceCriteria?: string[];\n requiredCapabilities?: string[];\n expectedArtifacts?: string[];\n assignedSessionId?: string | null;\n assignedLabel?: string | null;\n agentType?: CodingAgentType | null;\n workdir?: string | null;\n repo?: string | null;\n priority?: number;\n depth?: number;\n sequence?: number;\n createdFrom?: string | null;\n metadata?: Record<string, unknown>;\n startedAt?: string | null;\n completedAt?: string | null;\n}\n\nexport interface CreateTaskDependencyInput {\n id?: string;\n threadId: string;\n fromNodeId: string;\n toNodeId: string;\n dependencyKind?: TaskDependencyKind;\n requiredStatus?: TaskNodeStatus;\n metadata?: Record<string, unknown>;\n}\n\nexport interface CreateTaskClaimInput {\n id?: string;\n threadId: string;\n nodeId: string;\n sessionId: string;\n claimType?: TaskClaimType;\n status?: TaskClaimStatus;\n metadata?: Record<string, unknown>;\n claimedAt?: string;\n releasedAt?: string | null;\n}\n\nexport interface UpdateTaskClaimInput {\n status?: TaskClaimStatus;\n metadata?: Record<string, unknown>;\n releasedAt?: string | null;\n}\n\nexport interface AppendTaskMailboxMessageInput {\n id?: string;\n threadId: string;\n nodeId?: string | null;\n sessionId?: string | null;\n sender: string;\n recipient: string;\n subject?: string;\n body: string;\n deliveryState?: TaskMailboxDeliveryState;\n metadata?: Record<string, unknown>;\n createdAt?: string;\n deliveredAt?: string | null;\n}\n\nexport interface CreateTaskVerifierJobInput {\n id?: string;\n threadId: string;\n nodeId: string;\n status?: TaskVerifierJobStatus;\n verifierType: string;\n title: string;\n instructions?: string;\n config?: Record<string, unknown>;\n metadata?: Record<string, unknown>;\n createdAt?: string;\n startedAt?: string | null;\n completedAt?: string | null;\n}\n\nexport interface UpdateTaskVerifierJobInput {\n status?: TaskVerifierJobStatus;\n title?: string;\n instructions?: string;\n config?: Record<string, unknown>;\n metadata?: Record<string, unknown>;\n startedAt?: string | null;\n completedAt?: string | null;\n}\n\nexport interface RecordTaskEvidenceInput {\n id?: string;\n threadId: string;\n nodeId?: string | null;\n sessionId?: string | null;\n verifierJobId?: string | null;\n evidenceType: string;\n title: string;\n summary?: string;\n path?: string | null;\n uri?: string | null;\n content?: Record<string, unknown>;\n metadata?: Record<string, unknown>;\n}\n\nexport interface ListTaskThreadsOptions {\n includeArchived?: boolean;\n threadId?: string;\n status?: TaskThreadStatus;\n statuses?: TaskThreadStatus[];\n kind?: TaskThreadKind;\n roomId?: string;\n worldId?: string;\n ownerUserId?: string;\n scenarioId?: string;\n batchId?: string;\n createdAfter?: string;\n createdBefore?: string;\n updatedAfter?: string;\n updatedBefore?: string;\n latestActivityAfter?: number;\n latestActivityBefore?: number;\n hasActiveSession?: boolean;\n search?: string;\n limit?: number;\n}\n\nfunction asObject(value: unknown): Row | null {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) return null;\n return value as Row;\n}\n\nfunction toText(value: unknown, fallback = \"\"): string {\n if (typeof value === \"string\") return value;\n if (value === null || value === undefined) return fallback;\n return String(value);\n}\n\nfunction toNumber(value: unknown, fallback = 0): number {\n if (typeof value === \"number\" && Number.isFinite(value)) return value;\n if (typeof value === \"string\") {\n const parsed = Number(value);\n if (Number.isFinite(parsed)) return parsed;\n }\n return fallback;\n}\n\nfunction toNullableText(value: unknown): string | null {\n if (value === null || value === undefined || value === \"\") return null;\n return toText(value);\n}\n\nfunction toNullableNumber(value: unknown): number | null {\n if (value === null || value === undefined || value === \"\") return null;\n const parsed = toNumber(value, Number.NaN);\n return Number.isFinite(parsed) ? parsed : null;\n}\n\nfunction toBoolean(value: unknown, fallback = false): boolean {\n if (typeof value === \"boolean\") return value;\n if (typeof value === \"number\") return value !== 0;\n if (typeof value === \"string\") {\n const normalized = value.trim().toLowerCase();\n if ([\"1\", \"true\", \"yes\", \"on\"].includes(normalized)) return true;\n if ([\"0\", \"false\", \"no\", \"off\"].includes(normalized)) return false;\n }\n return fallback;\n}\n\nfunction parseJsonRecord(value: unknown): Record<string, unknown> {\n if (value === null || value === undefined || value === \"\") return {};\n if (typeof value !== \"string\") return asObject(value) ?? {};\n try {\n return asObject(JSON.parse(value)) ?? {};\n } catch {\n return {};\n }\n}\n\nfunction parseJsonArray(value: unknown): string[] {\n if (value === null || value === undefined || value === \"\") return [];\n if (Array.isArray(value)) {\n return value.filter((entry): entry is string => typeof entry === \"string\");\n }\n if (typeof value !== \"string\") return [];\n try {\n const parsed = JSON.parse(value);\n return Array.isArray(parsed)\n ? parsed.filter((entry): entry is string => typeof entry === \"string\")\n : [];\n } catch {\n return [];\n }\n}\n\nfunction isoNow(): string {\n return new Date().toISOString();\n}\n\nfunction sqlQuote(value: string): string {\n return `'${value.replace(/'/g, \"''\")}'`;\n}\n\nfunction sqlText(value: string | null | undefined): string {\n if (value === null || value === undefined) return \"NULL\";\n return sqlQuote(value);\n}\n\nfunction sqlInteger(value: number | null | undefined): string {\n if (value === null || value === undefined) return \"NULL\";\n if (!Number.isFinite(value)) {\n throw new Error(\"invalid numeric SQL literal\");\n }\n return String(Math.trunc(value));\n}\n\nfunction sqlBoolean(value: boolean): string {\n return value ? \"TRUE\" : \"FALSE\";\n}\n\nfunction sqlJson(value: unknown): string {\n return sqlQuote(JSON.stringify(value ?? null));\n}\n\nfunction sqlStringList(values: string[]): string {\n return values.map((value) => sqlQuote(value)).join(\", \");\n}\n\nfunction normalizeThreadStatus(value: unknown): TaskThreadStatus {\n switch (toText(value).toLowerCase()) {\n case \"active\":\n case \"waiting_on_user\":\n case \"blocked\":\n case \"validating\":\n case \"done\":\n case \"failed\":\n case \"archived\":\n case \"interrupted\":\n return toText(value).toLowerCase() as TaskThreadStatus;\n default:\n return \"open\";\n }\n}\n\nfunction normalizeSessionStatus(value: unknown): TaskSessionStatus {\n switch (toText(value).toLowerCase()) {\n case \"blocked\":\n case \"waiting_on_user\":\n case \"completed\":\n case \"stopped\":\n case \"error\":\n case \"tool_running\":\n case \"interrupted\":\n return toText(value).toLowerCase() as TaskSessionStatus;\n default:\n return \"active\";\n }\n}\n\nfunction normalizeTaskNodeKind(value: unknown): TaskNodeKind {\n switch (toText(value).toLowerCase()) {\n case \"goal\":\n case \"execution\":\n case \"research\":\n case \"planning\":\n case \"verification\":\n case \"handoff\":\n return toText(value).toLowerCase() as TaskNodeKind;\n default:\n return \"execution\";\n }\n}\n\nfunction normalizeTaskNodeStatus(value: unknown): TaskNodeStatus {\n switch (toText(value).toLowerCase()) {\n case \"ready\":\n case \"claimed\":\n case \"running\":\n case \"blocked\":\n case \"waiting_on_user\":\n case \"verifying\":\n case \"completed\":\n case \"failed\":\n case \"canceled\":\n case \"interrupted\":\n return toText(value).toLowerCase() as TaskNodeStatus;\n default:\n return \"planned\";\n }\n}\n\nfunction normalizeTaskDependencyKind(value: unknown): TaskDependencyKind {\n switch (toText(value).toLowerCase()) {\n case \"parent_child\":\n case \"artifact\":\n case \"handoff\":\n return toText(value).toLowerCase() as TaskDependencyKind;\n default:\n return \"blocks\";\n }\n}\n\nfunction normalizeTaskClaimType(value: unknown): TaskClaimType {\n switch (toText(value).toLowerCase()) {\n case \"verification\":\n case \"ownership\":\n return toText(value).toLowerCase() as TaskClaimType;\n default:\n return \"execution\";\n }\n}\n\nfunction normalizeTaskClaimStatus(value: unknown): TaskClaimStatus {\n switch (toText(value).toLowerCase()) {\n case \"released\":\n case \"completed\":\n case \"failed\":\n case \"interrupted\":\n return toText(value).toLowerCase() as TaskClaimStatus;\n default:\n return \"active\";\n }\n}\n\nfunction normalizeMailboxDeliveryState(\n value: unknown,\n): TaskMailboxDeliveryState {\n switch (toText(value).toLowerCase()) {\n case \"delivered\":\n case \"consumed\":\n return toText(value).toLowerCase() as TaskMailboxDeliveryState;\n default:\n return \"pending\";\n }\n}\n\nfunction normalizeVerifierJobStatus(value: unknown): TaskVerifierJobStatus {\n switch (toText(value).toLowerCase()) {\n case \"running\":\n case \"passed\":\n case \"failed\":\n case \"canceled\":\n return toText(value).toLowerCase() as TaskVerifierJobStatus;\n default:\n return \"pending\";\n }\n}\n\nfunction extractRows(result: unknown): Row[] {\n if (Array.isArray(result)) {\n return result\n .map((row) => asObject(row))\n .filter((row): row is Row => row !== null);\n }\n const obj = asObject(result);\n if (!obj || !Array.isArray(obj.rows)) return [];\n return obj.rows\n .map((row) => asObject(row))\n .filter((row): row is Row => row !== null);\n}\n\nasync function getSqlRaw(): Promise<(query: string) => RawSqlQuery> {\n if (cachedSqlRaw) return cachedSqlRaw;\n const drizzle = (await import(\"drizzle-orm\")) as {\n sql: { raw: (query: string) => RawSqlQuery };\n };\n cachedSqlRaw = drizzle.sql.raw;\n return cachedSqlRaw;\n}\n\nfunction getRuntimeDb(runtime: IAgentRuntime): RuntimeDb {\n const runtimeLike = runtime as IAgentRuntime & {\n adapter?: { db?: RuntimeDb };\n databaseAdapter?: { db?: RuntimeDb };\n };\n const db = runtimeLike.adapter?.db ?? runtimeLike.databaseAdapter?.db;\n if (!db || typeof db.execute !== \"function\") {\n throw new Error(\"runtime database adapter unavailable\");\n }\n return db;\n}\n\nasync function executeRawSql(\n runtime: IAgentRuntime,\n sqlTextValue: string,\n): Promise<Row[]> {\n const raw = await getSqlRaw();\n const result = await getRuntimeDb(runtime).execute(raw(sqlTextValue));\n return extractRows(result);\n}\n\nfunction parseThreadRow(row: Row): TaskThreadRecord {\n return {\n id: toText(row.id),\n agentId: toText(row.agent_id),\n roomId: toNullableText(row.room_id),\n worldId: toNullableText(row.world_id),\n ownerUserId: toNullableText(row.owner_user_id),\n scenarioId: toNullableText(row.scenario_id),\n batchId: toNullableText(row.batch_id),\n title: toText(row.title),\n kind: toText(row.kind, \"coding\") as TaskThreadKind,\n status: normalizeThreadStatus(row.status),\n originalRequest: toText(row.original_request),\n summary: toText(row.summary),\n acceptanceCriteria: parseJsonArray(row.acceptance_criteria_json),\n currentPlan: parseJsonRecord(row.current_plan_json),\n searchText: toText(row.search_text),\n createdAt: toText(row.created_at),\n updatedAt: toText(row.updated_at),\n closedAt: toNullableText(row.closed_at),\n archivedAt: toNullableText(row.archived_at),\n lastUserTurnAt: toNullableText(row.last_user_turn_at),\n lastCoordinatorTurnAt: toNullableText(row.last_coordinator_turn_at),\n metadata: parseJsonRecord(row.metadata_json),\n };\n}\n\nfunction parseThreadSummaryRow(row: Row): TaskThreadSummary {\n return {\n ...parseThreadRow(row),\n sessionCount: toNumber(row.session_count, 0),\n activeSessionCount: toNumber(row.active_session_count, 0),\n latestSessionId: toNullableText(row.latest_session_id),\n latestSessionLabel: toNullableText(row.latest_session_label),\n latestWorkdir: toNullableText(row.latest_workdir),\n latestRepo: toNullableText(row.latest_repo),\n latestActivityAt: toNullableNumber(row.latest_activity_at),\n decisionCount: toNumber(row.decision_count, 0),\n nodeCount: toNumber(row.node_count, 0),\n readyNodeCount: toNumber(row.ready_node_count, 0),\n completedNodeCount: toNumber(row.completed_node_count, 0),\n verifierJobCount: toNumber(row.verifier_job_count, 0),\n evidenceCount: toNumber(row.evidence_count, 0),\n };\n}\n\nfunction parseSessionRow(row: Row): TaskSessionRecord {\n return {\n id: toText(row.id),\n threadId: toText(row.thread_id),\n agentId: toText(row.agent_id),\n sessionId: toText(row.session_id),\n framework: toText(row.framework, \"claude\") as CodingAgentType,\n providerSource: toNullableText(row.provider_source),\n label: toText(row.label),\n originalTask: toText(row.original_task),\n workdir: toText(row.workdir),\n repo: toNullableText(row.repo),\n status: normalizeSessionStatus(row.status),\n decisionCount: toNumber(row.decision_count, 0),\n autoResolvedCount: toNumber(row.auto_resolved_count, 0),\n registeredAt: toNumber(row.registered_at, 0),\n lastActivityAt: toNumber(row.last_activity_at, 0),\n idleCheckCount: toNumber(row.idle_check_count, 0),\n taskDelivered: toBoolean(row.task_delivered),\n completionSummary: toNullableText(row.completion_summary),\n lastSeenDecisionIndex: toNumber(row.last_seen_decision_index, 0),\n lastInputSentAt: toNullableNumber(row.last_input_sent_at),\n stoppedAt: toNullableNumber(row.stopped_at),\n createdAt: toText(row.created_at),\n updatedAt: toText(row.updated_at),\n metadata: parseJsonRecord(row.metadata_json),\n };\n}\n\nfunction parseDecisionRow(row: Row): TaskDecisionRecord {\n return {\n id: toText(row.id),\n threadId: toText(row.thread_id),\n sessionId: toText(row.session_id),\n timestamp: toNumber(row.timestamp, 0),\n event: toText(row.event_type),\n promptText: toText(row.prompt_text),\n decision: toText(row.decision),\n response: toNullableText(row.response),\n reasoning: toText(row.reasoning),\n metadata: parseJsonRecord(row.metadata_json),\n };\n}\n\nfunction parseEventRow(row: Row): TaskEventRecord {\n return {\n id: toText(row.id),\n threadId: toText(row.thread_id),\n sessionId: toNullableText(row.session_id),\n eventType: toText(row.event_type),\n timestamp: toNumber(row.timestamp, 0),\n summary: toText(row.summary),\n data: parseJsonRecord(row.data_json),\n createdAt: toText(row.created_at),\n };\n}\n\nfunction parseArtifactRow(row: Row): TaskArtifactRecord {\n return {\n id: toText(row.id),\n threadId: toText(row.thread_id),\n sessionId: toNullableText(row.session_id),\n artifactType: toText(row.artifact_type),\n title: toText(row.title),\n path: toNullableText(row.path),\n uri: toNullableText(row.uri),\n mimeType: toNullableText(row.mime_type),\n metadata: parseJsonRecord(row.metadata_json),\n createdAt: toText(row.created_at),\n };\n}\n\nfunction parseTranscriptRow(row: Row): TaskTranscriptRecord {\n return {\n id: toText(row.id),\n threadId: toText(row.thread_id),\n sessionId: toText(row.session_id),\n timestamp: toNumber(row.timestamp, 0),\n direction: toText(row.direction) as TaskTranscriptRecord[\"direction\"],\n content: toText(row.content),\n metadata: parseJsonRecord(row.metadata_json),\n createdAt: toText(row.created_at),\n };\n}\n\nfunction parsePendingDecisionRow(row: Row): TaskPendingDecisionRecord {\n return {\n sessionId: toText(row.session_id),\n threadId: toText(row.thread_id),\n promptText: toText(row.prompt_text),\n recentOutput: toText(row.recent_output),\n llmDecision: parseJsonRecord(row.llm_decision_json),\n taskContext: parseJsonRecord(row.task_context_json),\n createdAt: toNumber(row.created_at, 0),\n updatedAt: toText(row.updated_at),\n };\n}\n\nfunction parseTaskNodeRow(row: Row): TaskNodeRecord {\n return {\n id: toText(row.id),\n threadId: toText(row.thread_id),\n parentNodeId: toNullableText(row.parent_node_id),\n kind: normalizeTaskNodeKind(row.kind),\n status: normalizeTaskNodeStatus(row.status),\n title: toText(row.title),\n instructions: toText(row.instructions),\n acceptanceCriteria: parseJsonArray(row.acceptance_criteria_json),\n requiredCapabilities: parseJsonArray(row.required_capabilities_json),\n expectedArtifacts: parseJsonArray(row.expected_artifacts_json),\n assignedSessionId: toNullableText(row.assigned_session_id),\n assignedLabel: toNullableText(row.assigned_label),\n agentType: toNullableText(row.agent_type) as CodingAgentType | null,\n workdir: toNullableText(row.workdir),\n repo: toNullableText(row.repo),\n priority: toNumber(row.priority, 0),\n depth: toNumber(row.depth, 0),\n sequence: toNumber(row.sequence, 0),\n createdFrom: toNullableText(row.created_from),\n metadata: parseJsonRecord(row.metadata_json),\n createdAt: toText(row.created_at),\n updatedAt: toText(row.updated_at),\n startedAt: toNullableText(row.started_at),\n completedAt: toNullableText(row.completed_at),\n };\n}\n\nfunction parseTaskDependencyRow(row: Row): TaskDependencyRecord {\n return {\n id: toText(row.id),\n threadId: toText(row.thread_id),\n fromNodeId: toText(row.from_node_id),\n toNodeId: toText(row.to_node_id),\n dependencyKind: normalizeTaskDependencyKind(row.dependency_kind),\n requiredStatus: normalizeTaskNodeStatus(row.required_status),\n metadata: parseJsonRecord(row.metadata_json),\n createdAt: toText(row.created_at),\n };\n}\n\nfunction parseTaskClaimRow(row: Row): TaskClaimRecord {\n return {\n id: toText(row.id),\n threadId: toText(row.thread_id),\n nodeId: toText(row.node_id),\n sessionId: toText(row.session_id),\n claimType: normalizeTaskClaimType(row.claim_type),\n status: normalizeTaskClaimStatus(row.status),\n claimedAt: toText(row.claimed_at),\n releasedAt: toNullableText(row.released_at),\n metadata: parseJsonRecord(row.metadata_json),\n };\n}\n\nfunction parseTaskMailboxMessageRow(row: Row): TaskMailboxMessageRecord {\n return {\n id: toText(row.id),\n threadId: toText(row.thread_id),\n nodeId: toNullableText(row.node_id),\n sessionId: toNullableText(row.session_id),\n sender: toText(row.sender),\n recipient: toText(row.recipient),\n subject: toText(row.subject),\n body: toText(row.body),\n deliveryState: normalizeMailboxDeliveryState(row.delivery_state),\n metadata: parseJsonRecord(row.metadata_json),\n createdAt: toText(row.created_at),\n deliveredAt: toNullableText(row.delivered_at),\n };\n}\n\nfunction parseTaskVerifierJobRow(row: Row): TaskVerifierJobRecord {\n return {\n id: toText(row.id),\n threadId: toText(row.thread_id),\n nodeId: toText(row.node_id),\n status: normalizeVerifierJobStatus(row.status),\n verifierType: toText(row.verifier_type),\n title: toText(row.title),\n instructions: toText(row.instructions),\n config: parseJsonRecord(row.config_json),\n metadata: parseJsonRecord(row.metadata_json),\n createdAt: toText(row.created_at),\n startedAt: toNullableText(row.started_at),\n completedAt: toNullableText(row.completed_at),\n };\n}\n\nfunction parseTaskEvidenceRow(row: Row): TaskEvidenceRecord {\n return {\n id: toText(row.id),\n threadId: toText(row.thread_id),\n nodeId: toNullableText(row.node_id),\n sessionId: toNullableText(row.session_id),\n verifierJobId: toNullableText(row.verifier_job_id),\n evidenceType: toText(row.evidence_type),\n title: toText(row.title),\n summary: toText(row.summary),\n path: toNullableText(row.path),\n uri: toNullableText(row.uri),\n content: parseJsonRecord(row.content_json),\n metadata: parseJsonRecord(row.metadata_json),\n createdAt: toText(row.created_at),\n };\n}\n\nfunction buildSearchText(parts: Array<string | null | undefined>): string {\n return parts\n .map((part) => (part ?? \"\").trim().toLowerCase())\n .filter(Boolean)\n .join(\" \");\n}\n\nfunction isTerminalTaskNodeStatus(status: TaskNodeStatus): boolean {\n return (\n status === \"completed\" ||\n status === \"failed\" ||\n status === \"canceled\" ||\n status === \"interrupted\"\n );\n}\n\nfunction dependencyStatusSatisfied(\n actual: TaskNodeStatus,\n required: TaskNodeStatus,\n): boolean {\n if (actual === required) return true;\n return false;\n}\n\nfunction buildThreadListWhereClauses(\n options: ListTaskThreadsOptions,\n): string[] {\n const clauses: string[] = [];\n if (options.threadId) {\n clauses.push(`thread.id = ${sqlQuote(options.threadId)}`);\n }\n if (!options.includeArchived) {\n clauses.push(\"thread.archived_at IS NULL\");\n }\n if (options.status) {\n clauses.push(`thread.status = ${sqlQuote(options.status)}`);\n }\n if (Array.isArray(options.statuses) && options.statuses.length > 0) {\n const normalizedStatuses = options.statuses\n .map((status) => normalizeThreadStatus(status))\n .filter(Boolean);\n if (normalizedStatuses.length > 0) {\n clauses.push(`thread.status IN (${sqlStringList(normalizedStatuses)})`);\n }\n }\n if (options.kind) {\n clauses.push(`thread.kind = ${sqlQuote(options.kind)}`);\n }\n if (options.roomId) {\n clauses.push(`thread.room_id = ${sqlQuote(options.roomId)}`);\n }\n if (options.worldId) {\n clauses.push(`thread.world_id = ${sqlQuote(options.worldId)}`);\n }\n if (options.ownerUserId) {\n clauses.push(`thread.owner_user_id = ${sqlQuote(options.ownerUserId)}`);\n }\n if (options.scenarioId) {\n clauses.push(`thread.scenario_id = ${sqlQuote(options.scenarioId)}`);\n }\n if (options.batchId) {\n clauses.push(`thread.batch_id = ${sqlQuote(options.batchId)}`);\n }\n if (options.createdAfter) {\n clauses.push(`thread.created_at >= ${sqlQuote(options.createdAfter)}`);\n }\n if (options.createdBefore) {\n clauses.push(`thread.created_at <= ${sqlQuote(options.createdBefore)}`);\n }\n if (options.updatedAfter) {\n clauses.push(`thread.updated_at >= ${sqlQuote(options.updatedAfter)}`);\n }\n if (options.updatedBefore) {\n clauses.push(`thread.updated_at <= ${sqlQuote(options.updatedBefore)}`);\n }\n if (typeof options.latestActivityAfter === \"number\") {\n clauses.push(\n `COALESCE(latest.last_activity_at, 0) >= ${sqlInteger(options.latestActivityAfter)}`,\n );\n }\n if (typeof options.latestActivityBefore === \"number\") {\n clauses.push(\n `COALESCE(latest.last_activity_at, 0) <= ${sqlInteger(options.latestActivityBefore)}`,\n );\n }\n if (typeof options.hasActiveSession === \"boolean\") {\n clauses.push(\n options.hasActiveSession\n ? \"COALESCE(session_counts.active_session_count, 0) > 0\"\n : \"COALESCE(session_counts.active_session_count, 0) = 0\",\n );\n }\n if (options.search?.trim()) {\n const q = options.search.trim().toLowerCase().replace(/[%_]/g, \"\\\\$&\");\n clauses.push(`thread.search_text LIKE ${sqlQuote(`%${q}%`)}`);\n }\n\n return clauses;\n}\n\nexport class TaskRegistry {\n constructor(private readonly runtime: IAgentRuntime) {}\n\n private schemaKey(): object {\n const runtimeLike = this.runtime as IAgentRuntime & {\n adapter?: object;\n databaseAdapter?: object;\n };\n return (\n runtimeLike.adapter ??\n runtimeLike.databaseAdapter ??\n (this.runtime as object)\n );\n }\n\n async ensureSchema(): Promise<void> {\n const key = this.schemaKey();\n if (schemaReady.has(key)) return;\n\n await executeRawSql(\n this.runtime,\n `CREATE TABLE IF NOT EXISTS orchestrator_task_threads (\n id TEXT PRIMARY KEY,\n agent_id TEXT NOT NULL,\n room_id TEXT,\n world_id TEXT,\n owner_user_id TEXT,\n scenario_id TEXT,\n batch_id TEXT,\n title TEXT NOT NULL,\n kind TEXT NOT NULL DEFAULT 'coding',\n status TEXT NOT NULL DEFAULT 'open',\n original_request TEXT NOT NULL,\n summary TEXT NOT NULL DEFAULT '',\n acceptance_criteria_json TEXT NOT NULL DEFAULT '[]',\n current_plan_json TEXT NOT NULL DEFAULT '{}',\n search_text TEXT NOT NULL DEFAULT '',\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n closed_at TEXT,\n archived_at TEXT,\n last_user_turn_at TEXT,\n last_coordinator_turn_at TEXT,\n metadata_json TEXT NOT NULL DEFAULT '{}'\n )`,\n );\n\n await executeRawSql(\n this.runtime,\n `CREATE TABLE IF NOT EXISTS orchestrator_task_sessions (\n id TEXT PRIMARY KEY,\n thread_id TEXT NOT NULL,\n agent_id TEXT NOT NULL,\n session_id TEXT NOT NULL UNIQUE,\n framework TEXT NOT NULL,\n provider_source TEXT,\n label TEXT NOT NULL,\n original_task TEXT NOT NULL,\n workdir TEXT NOT NULL,\n repo TEXT,\n status TEXT NOT NULL DEFAULT 'active',\n decision_count INTEGER NOT NULL DEFAULT 0,\n auto_resolved_count INTEGER NOT NULL DEFAULT 0,\n registered_at BIGINT NOT NULL,\n last_activity_at BIGINT NOT NULL,\n idle_check_count INTEGER NOT NULL DEFAULT 0,\n task_delivered BOOLEAN NOT NULL DEFAULT FALSE,\n completion_summary TEXT,\n last_seen_decision_index INTEGER NOT NULL DEFAULT 0,\n last_input_sent_at BIGINT,\n stopped_at BIGINT,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n metadata_json TEXT NOT NULL DEFAULT '{}'\n )`,\n );\n\n await executeRawSql(\n this.runtime,\n `CREATE TABLE IF NOT EXISTS orchestrator_task_decisions (\n id TEXT PRIMARY KEY,\n thread_id TEXT NOT NULL,\n session_id TEXT NOT NULL,\n timestamp BIGINT NOT NULL,\n event_type TEXT NOT NULL,\n prompt_text TEXT NOT NULL DEFAULT '',\n decision TEXT NOT NULL,\n response TEXT,\n reasoning TEXT NOT NULL,\n metadata_json TEXT NOT NULL DEFAULT '{}',\n created_at TEXT NOT NULL\n )`,\n );\n\n await executeRawSql(\n this.runtime,\n `CREATE TABLE IF NOT EXISTS orchestrator_task_events (\n id TEXT PRIMARY KEY,\n thread_id TEXT NOT NULL,\n session_id TEXT,\n event_type TEXT NOT NULL,\n timestamp BIGINT NOT NULL,\n summary TEXT NOT NULL DEFAULT '',\n data_json TEXT NOT NULL DEFAULT '{}',\n created_at TEXT NOT NULL\n )`,\n );\n\n await executeRawSql(\n this.runtime,\n `CREATE TABLE IF NOT EXISTS orchestrator_task_artifacts (\n id TEXT PRIMARY KEY,\n thread_id TEXT NOT NULL,\n session_id TEXT,\n artifact_type TEXT NOT NULL,\n title TEXT NOT NULL,\n path TEXT,\n uri TEXT,\n mime_type TEXT,\n metadata_json TEXT NOT NULL DEFAULT '{}',\n created_at TEXT NOT NULL\n )`,\n );\n\n await executeRawSql(\n this.runtime,\n `CREATE TABLE IF NOT EXISTS orchestrator_task_transcripts (\n id TEXT PRIMARY KEY,\n thread_id TEXT NOT NULL,\n session_id TEXT NOT NULL,\n timestamp BIGINT NOT NULL,\n direction TEXT NOT NULL,\n content TEXT NOT NULL,\n metadata_json TEXT NOT NULL DEFAULT '{}',\n created_at TEXT NOT NULL\n )`,\n );\n\n await executeRawSql(\n this.runtime,\n `CREATE TABLE IF NOT EXISTS orchestrator_task_pending_decisions (\n session_id TEXT PRIMARY KEY,\n thread_id TEXT NOT NULL,\n prompt_text TEXT NOT NULL,\n recent_output TEXT NOT NULL DEFAULT '',\n llm_decision_json TEXT NOT NULL DEFAULT '{}',\n task_context_json TEXT NOT NULL DEFAULT '{}',\n created_at BIGINT NOT NULL,\n updated_at TEXT NOT NULL\n )`,\n );\n\n await executeRawSql(\n this.runtime,\n `CREATE TABLE IF NOT EXISTS orchestrator_task_nodes (\n id TEXT PRIMARY KEY,\n thread_id TEXT NOT NULL,\n parent_node_id TEXT,\n kind TEXT NOT NULL DEFAULT 'execution',\n status TEXT NOT NULL DEFAULT 'planned',\n title TEXT NOT NULL,\n instructions TEXT NOT NULL DEFAULT '',\n acceptance_criteria_json TEXT NOT NULL DEFAULT '[]',\n required_capabilities_json TEXT NOT NULL DEFAULT '[]',\n expected_artifacts_json TEXT NOT NULL DEFAULT '[]',\n assigned_session_id TEXT,\n assigned_label TEXT,\n agent_type TEXT,\n workdir TEXT,\n repo TEXT,\n priority INTEGER NOT NULL DEFAULT 0,\n depth INTEGER NOT NULL DEFAULT 0,\n sequence INTEGER NOT NULL DEFAULT 0,\n created_from TEXT,\n metadata_json TEXT NOT NULL DEFAULT '{}',\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n started_at TEXT,\n completed_at TEXT\n )`,\n );\n\n await executeRawSql(\n this.runtime,\n `CREATE TABLE IF NOT EXISTS orchestrator_task_dependencies (\n id TEXT PRIMARY KEY,\n thread_id TEXT NOT NULL,\n from_node_id TEXT NOT NULL,\n to_node_id TEXT NOT NULL,\n dependency_kind TEXT NOT NULL DEFAULT 'blocks',\n required_status TEXT NOT NULL DEFAULT 'completed',\n metadata_json TEXT NOT NULL DEFAULT '{}',\n created_at TEXT NOT NULL\n )`,\n );\n\n await executeRawSql(\n this.runtime,\n `CREATE TABLE IF NOT EXISTS orchestrator_task_claims (\n id TEXT PRIMARY KEY,\n thread_id TEXT NOT NULL,\n node_id TEXT NOT NULL,\n session_id TEXT NOT NULL,\n claim_type TEXT NOT NULL DEFAULT 'execution',\n status TEXT NOT NULL DEFAULT 'active',\n claimed_at TEXT NOT NULL,\n released_at TEXT,\n metadata_json TEXT NOT NULL DEFAULT '{}'\n )`,\n );\n\n await executeRawSql(\n this.runtime,\n `CREATE TABLE IF NOT EXISTS orchestrator_task_mailbox (\n id TEXT PRIMARY KEY,\n thread_id TEXT NOT NULL,\n node_id TEXT,\n session_id TEXT,\n sender TEXT NOT NULL,\n recipient TEXT NOT NULL,\n subject TEXT NOT NULL DEFAULT '',\n body TEXT NOT NULL,\n delivery_state TEXT NOT NULL DEFAULT 'pending',\n metadata_json TEXT NOT NULL DEFAULT '{}',\n created_at TEXT NOT NULL,\n delivered_at TEXT\n )`,\n );\n\n await executeRawSql(\n this.runtime,\n `CREATE TABLE IF NOT EXISTS orchestrator_task_verifier_jobs (\n id TEXT PRIMARY KEY,\n thread_id TEXT NOT NULL,\n node_id TEXT NOT NULL,\n status TEXT NOT NULL DEFAULT 'pending',\n verifier_type TEXT NOT NULL,\n title TEXT NOT NULL,\n instructions TEXT NOT NULL DEFAULT '',\n config_json TEXT NOT NULL DEFAULT '{}',\n metadata_json TEXT NOT NULL DEFAULT '{}',\n created_at TEXT NOT NULL,\n started_at TEXT,\n completed_at TEXT\n )`,\n );\n\n await executeRawSql(\n this.runtime,\n `CREATE TABLE IF NOT EXISTS orchestrator_task_evidence (\n id TEXT PRIMARY KEY,\n thread_id TEXT NOT NULL,\n node_id TEXT,\n session_id TEXT,\n verifier_job_id TEXT,\n evidence_type TEXT NOT NULL,\n title TEXT NOT NULL,\n summary TEXT NOT NULL DEFAULT '',\n path TEXT,\n uri TEXT,\n content_json TEXT NOT NULL DEFAULT '{}',\n metadata_json TEXT NOT NULL DEFAULT '{}',\n created_at TEXT NOT NULL\n )`,\n );\n\n await executeRawSql(\n this.runtime,\n `ALTER TABLE orchestrator_task_threads ADD COLUMN scenario_id TEXT`,\n ).catch(() => undefined);\n await executeRawSql(\n this.runtime,\n `ALTER TABLE orchestrator_task_threads ADD COLUMN batch_id TEXT`,\n ).catch(() => undefined);\n await executeRawSql(\n this.runtime,\n `CREATE INDEX IF NOT EXISTS idx_orchestrator_task_threads_status\n ON orchestrator_task_threads(status)`,\n );\n await executeRawSql(\n this.runtime,\n `CREATE INDEX IF NOT EXISTS idx_orchestrator_task_threads_scenario_id\n ON orchestrator_task_threads(scenario_id)`,\n );\n await executeRawSql(\n this.runtime,\n `CREATE INDEX IF NOT EXISTS idx_orchestrator_task_threads_batch_id\n ON orchestrator_task_threads(batch_id)`,\n );\n await executeRawSql(\n this.runtime,\n `CREATE INDEX IF NOT EXISTS idx_orchestrator_task_threads_updated_at\n ON orchestrator_task_threads(updated_at)`,\n );\n await executeRawSql(\n this.runtime,\n `CREATE INDEX IF NOT EXISTS idx_orchestrator_task_threads_archived_at\n ON orchestrator_task_threads(archived_at)`,\n );\n await executeRawSql(\n this.runtime,\n `CREATE INDEX IF NOT EXISTS idx_orchestrator_task_sessions_thread_id\n ON orchestrator_task_sessions(thread_id)`,\n );\n await executeRawSql(\n this.runtime,\n `CREATE INDEX IF NOT EXISTS idx_orchestrator_task_sessions_status\n ON orchestrator_task_sessions(status)`,\n );\n await executeRawSql(\n this.runtime,\n `CREATE INDEX IF NOT EXISTS idx_orchestrator_task_decisions_thread_id\n ON orchestrator_task_decisions(thread_id, timestamp DESC)`,\n );\n await executeRawSql(\n this.runtime,\n `CREATE INDEX IF NOT EXISTS idx_orchestrator_task_events_thread_id\n ON orchestrator_task_events(thread_id, timestamp DESC)`,\n );\n await executeRawSql(\n this.runtime,\n `CREATE INDEX IF NOT EXISTS idx_orchestrator_task_transcripts_thread_id\n ON orchestrator_task_transcripts(thread_id, timestamp DESC)`,\n );\n await executeRawSql(\n this.runtime,\n `CREATE INDEX IF NOT EXISTS idx_orchestrator_task_pending_decisions_thread_id\n ON orchestrator_task_pending_decisions(thread_id)`,\n );\n await executeRawSql(\n this.runtime,\n `CREATE INDEX IF NOT EXISTS idx_orchestrator_task_pending_decisions_created_at\n ON orchestrator_task_pending_decisions(created_at DESC)`,\n );\n await executeRawSql(\n this.runtime,\n `CREATE INDEX IF NOT EXISTS idx_orchestrator_task_nodes_thread_id\n ON orchestrator_task_nodes(thread_id, sequence ASC, created_at ASC)`,\n );\n await executeRawSql(\n this.runtime,\n `CREATE INDEX IF NOT EXISTS idx_orchestrator_task_nodes_status\n ON orchestrator_task_nodes(thread_id, status)`,\n );\n await executeRawSql(\n this.runtime,\n `CREATE INDEX IF NOT EXISTS idx_orchestrator_task_dependencies_thread_id\n ON orchestrator_task_dependencies(thread_id)`,\n );\n await executeRawSql(\n this.runtime,\n `CREATE INDEX IF NOT EXISTS idx_orchestrator_task_dependencies_to_node_id\n ON orchestrator_task_dependencies(to_node_id)`,\n );\n await executeRawSql(\n this.runtime,\n `CREATE INDEX IF NOT EXISTS idx_orchestrator_task_claims_thread_id\n ON orchestrator_task_claims(thread_id, status, claimed_at DESC)`,\n );\n await executeRawSql(\n this.runtime,\n `CREATE INDEX IF NOT EXISTS idx_orchestrator_task_claims_node_id\n ON orchestrator_task_claims(node_id, status)`,\n );\n await executeRawSql(\n this.runtime,\n `CREATE INDEX IF NOT EXISTS idx_orchestrator_task_mailbox_thread_id\n ON orchestrator_task_mailbox(thread_id, created_at ASC)`,\n );\n await executeRawSql(\n this.runtime,\n `CREATE INDEX IF NOT EXISTS idx_orchestrator_task_verifier_jobs_thread_id\n ON orchestrator_task_verifier_jobs(thread_id, status, created_at ASC)`,\n );\n await executeRawSql(\n this.runtime,\n `CREATE INDEX IF NOT EXISTS idx_orchestrator_task_evidence_thread_id\n ON orchestrator_task_evidence(thread_id, created_at ASC)`,\n );\n await executeRawSql(\n this.runtime,\n `CREATE INDEX IF NOT EXISTS idx_orchestrator_task_threads_search_text\n ON orchestrator_task_threads(search_text)`,\n );\n\n schemaReady.add(key);\n }\n\n async recoverInterruptedTasks(): Promise<void> {\n await this.ensureSchema();\n const impactedSessions = await executeRawSql(\n this.runtime,\n `SELECT session_id, thread_id\n FROM orchestrator_task_sessions\n WHERE status IN ('active', 'blocked', 'tool_running')`,\n );\n if (impactedSessions.length === 0) return;\n\n const nowIso = isoNow();\n const now = Date.now();\n await executeRawSql(\n this.runtime,\n `UPDATE orchestrator_task_sessions\n SET status = 'interrupted',\n updated_at = ${sqlQuote(nowIso)},\n stopped_at = COALESCE(stopped_at, ${sqlInteger(now)})\n WHERE status IN ('active', 'blocked', 'tool_running')`,\n );\n\n const affectedThreadIds = new Set<string>();\n for (const row of impactedSessions) {\n const sessionId = toText(row.session_id);\n const threadId = toText(row.thread_id);\n if (!threadId) continue;\n affectedThreadIds.add(threadId);\n await this.appendEvent({\n threadId,\n sessionId,\n eventType: \"session_interrupted\",\n timestamp: now,\n summary: \"Session interrupted by runtime restart or shutdown\",\n data: { reason: \"runtime_restart\" },\n });\n }\n\n for (const threadId of affectedThreadIds) {\n await this.recomputeThreadStatus(threadId);\n }\n }\n\n async createThread(input: CreateTaskThreadInput): Promise<TaskThreadRecord> {\n await this.ensureSchema();\n const id = input.id?.trim() || `task-${crypto.randomUUID()}`;\n const createdAt = isoNow();\n const acceptanceCriteria = input.acceptanceCriteria ?? [];\n const currentPlan = input.currentPlan ?? {};\n const summary = input.summary?.trim() ?? \"\";\n const scenarioId =\n input.scenarioId ??\n (typeof input.metadata?.scenarioId === \"string\"\n ? input.metadata.scenarioId\n : typeof input.metadata?.scenario_id === \"string\"\n ? input.metadata.scenario_id\n : null);\n const batchId =\n input.batchId ??\n (typeof input.metadata?.batchId === \"string\"\n ? input.metadata.batchId\n : typeof input.metadata?.batch_id === \"string\"\n ? input.metadata.batch_id\n : null);\n const searchText = buildSearchText([\n input.title,\n input.originalRequest,\n summary,\n scenarioId,\n batchId,\n input.metadata ? JSON.stringify(input.metadata) : \"\",\n ]);\n\n await executeRawSql(\n this.runtime,\n `INSERT INTO orchestrator_task_threads (\n id, agent_id, room_id, world_id, owner_user_id, scenario_id, batch_id, title, kind, status,\n original_request, summary, acceptance_criteria_json, current_plan_json,\n search_text, created_at, updated_at, closed_at, archived_at,\n last_user_turn_at, last_coordinator_turn_at, metadata_json\n ) VALUES (\n ${sqlQuote(id)},\n ${sqlQuote(this.runtime.agentId)},\n ${sqlText(input.roomId ?? null)},\n ${sqlText(input.worldId ?? null)},\n ${sqlText(input.ownerUserId ?? null)},\n ${sqlText(scenarioId ?? null)},\n ${sqlText(batchId ?? null)},\n ${sqlQuote(input.title.trim())},\n ${sqlQuote(input.kind ?? \"coding\")},\n 'open',\n ${sqlQuote(input.originalRequest)},\n ${sqlQuote(summary)},\n ${sqlJson(acceptanceCriteria)},\n ${sqlJson(currentPlan)},\n ${sqlQuote(searchText)},\n ${sqlQuote(createdAt)},\n ${sqlQuote(createdAt)},\n NULL,\n NULL,\n ${sqlText(input.lastUserTurnAt ?? createdAt)},\n NULL,\n ${sqlJson(input.metadata ?? {})}\n )`,\n );\n\n await this.appendEvent({\n threadId: id,\n eventType: \"task_created\",\n timestamp: Date.now(),\n summary: `Created task thread \"${input.title.trim()}\"`,\n data: {\n kind: input.kind ?? \"coding\",\n roomId: input.roomId ?? null,\n worldId: input.worldId ?? null,\n },\n });\n\n const created = await this.getThreadRecord(id);\n if (!created) {\n throw new Error(`Failed to create task thread ${id}`);\n }\n return created;\n }\n\n async getThreadRecord(threadId: string): Promise<TaskThreadRecord | null> {\n await this.ensureSchema();\n const rows = await executeRawSql(\n this.runtime,\n `SELECT *\n FROM orchestrator_task_threads\n WHERE id = ${sqlQuote(threadId)}\n LIMIT 1`,\n );\n return rows[0] ? parseThreadRow(rows[0]) : null;\n }\n\n async getThread(threadId: string): Promise<TaskThreadDetail | null> {\n await this.ensureSchema();\n const summary = await this.getThreadSummary(threadId);\n if (!summary) return null;\n\n const [\n sessions,\n decisions,\n events,\n artifacts,\n transcripts,\n pendingDecisions,\n nodes,\n dependencies,\n claims,\n mailbox,\n verifierJobs,\n evidence,\n ] = await Promise.all([\n this.listSessionsForThread(threadId),\n this.listDecisionsForThread(threadId),\n this.listEventsForThread(threadId),\n this.listArtifactsForThread(threadId),\n this.listTranscriptsForThread(threadId),\n this.listPendingDecisionsForThread(threadId),\n this.listTaskNodesForThread(threadId),\n this.listTaskDependenciesForThread(threadId),\n this.listTaskClaimsForThread(threadId),\n this.listTaskMailboxMessagesForThread(threadId),\n this.listTaskVerifierJobsForThread(threadId),\n this.listTaskEvidenceForThread(threadId),\n ]);\n\n return {\n ...summary,\n sessions,\n decisions,\n events,\n artifacts,\n transcripts,\n pendingDecisions,\n nodes,\n dependencies,\n claims,\n mailbox,\n verifierJobs,\n evidence,\n };\n }\n\n async listThreads(\n options: ListTaskThreadsOptions = {},\n ): Promise<TaskThreadSummary[]> {\n await this.ensureSchema();\n const clauses = buildThreadListWhereClauses(options);\n const whereClause =\n clauses.length > 0 ? `WHERE ${clauses.join(\" AND \")}` : \"\";\n const limitClause =\n typeof options.limit === \"number\" && options.limit > 0\n ? `LIMIT ${Math.trunc(options.limit)}`\n : \"\";\n\n const rows = await executeRawSql(\n this.runtime,\n `SELECT\n thread.*,\n COALESCE(session_counts.session_count, 0) AS session_count,\n COALESCE(session_counts.active_session_count, 0) AS active_session_count,\n latest.session_id AS latest_session_id,\n latest.label AS latest_session_label,\n latest.workdir AS latest_workdir,\n latest.repo AS latest_repo,\n latest.last_activity_at AS latest_activity_at,\n COALESCE(decision_counts.decision_count, 0) AS decision_count,\n COALESCE(node_counts.node_count, 0) AS node_count,\n COALESCE(node_counts.ready_node_count, 0) AS ready_node_count,\n COALESCE(node_counts.completed_node_count, 0) AS completed_node_count,\n COALESCE(verifier_counts.verifier_job_count, 0) AS verifier_job_count,\n COALESCE(evidence_counts.evidence_count, 0) AS evidence_count\n FROM orchestrator_task_threads AS thread\n LEFT JOIN (\n SELECT\n thread_id,\n COUNT(*) AS session_count,\n SUM(CASE WHEN status IN ('active', 'blocked', 'tool_running') THEN 1 ELSE 0 END) AS active_session_count\n FROM orchestrator_task_sessions\n GROUP BY thread_id\n ) AS session_counts\n ON session_counts.thread_id = thread.id\n LEFT JOIN (\n SELECT latest_session.thread_id,\n latest_session.session_id,\n latest_session.label,\n latest_session.workdir,\n latest_session.repo,\n latest_session.last_activity_at\n FROM orchestrator_task_sessions AS latest_session\n INNER JOIN (\n SELECT thread_id, MAX(last_activity_at) AS max_last_activity_at\n FROM orchestrator_task_sessions\n GROUP BY thread_id\n ) AS grouped\n ON grouped.thread_id = latest_session.thread_id\n AND grouped.max_last_activity_at = latest_session.last_activity_at\n ) AS latest\n ON latest.thread_id = thread.id\n LEFT JOIN (\n SELECT thread_id, COUNT(*) AS decision_count\n FROM orchestrator_task_decisions\n GROUP BY thread_id\n ) AS decision_counts\n ON decision_counts.thread_id = thread.id\n LEFT JOIN (\n SELECT\n thread_id,\n COUNT(*) AS node_count,\n SUM(CASE WHEN status = 'ready' THEN 1 ELSE 0 END) AS ready_node_count,\n SUM(CASE WHEN status = 'completed' THEN 1 ELSE 0 END) AS completed_node_count\n FROM orchestrator_task_nodes\n GROUP BY thread_id\n ) AS node_counts\n ON node_counts.thread_id = thread.id\n LEFT JOIN (\n SELECT thread_id, COUNT(*) AS verifier_job_count\n FROM orchestrator_task_verifier_jobs\n GROUP BY thread_id\n ) AS verifier_counts\n ON verifier_counts.thread_id = thread.id\n LEFT JOIN (\n SELECT thread_id, COUNT(*) AS evidence_count\n FROM orchestrator_task_evidence\n GROUP BY thread_id\n ) AS evidence_counts\n ON evidence_counts.thread_id = thread.id\n ${whereClause}\n ORDER BY thread.updated_at DESC\n ${limitClause}`,\n );\n\n return rows.map(parseThreadSummaryRow);\n }\n\n async countThreads(options: ListTaskThreadsOptions = {}): Promise<number> {\n await this.ensureSchema();\n const clauses = buildThreadListWhereClauses(options);\n const whereClause =\n clauses.length > 0 ? `WHERE ${clauses.join(\" AND \")}` : \"\";\n\n const rows = await executeRawSql(\n this.runtime,\n `SELECT COUNT(*) AS total\n FROM orchestrator_task_threads AS thread\n LEFT JOIN (\n SELECT\n thread_id,\n COUNT(*) AS session_count,\n SUM(CASE WHEN status IN ('active', 'blocked', 'tool_running') THEN 1 ELSE 0 END) AS active_session_count\n FROM orchestrator_task_sessions\n GROUP BY thread_id\n ) AS session_counts\n ON session_counts.thread_id = thread.id\n LEFT JOIN (\n SELECT latest_session.thread_id,\n latest_session.session_id,\n latest_session.label,\n latest_session.workdir,\n latest_session.repo,\n latest_session.last_activity_at\n FROM orchestrator_task_sessions AS latest_session\n INNER JOIN (\n SELECT thread_id, MAX(last_activity_at) AS max_last_activity_at\n FROM orchestrator_task_sessions\n GROUP BY thread_id\n ) AS grouped\n ON grouped.thread_id = latest_session.thread_id\n AND grouped.max_last_activity_at = latest_session.last_activity_at\n ) AS latest\n ON latest.thread_id = thread.id\n LEFT JOIN (\n SELECT\n thread_id,\n COUNT(*) AS node_count,\n SUM(CASE WHEN status = 'ready' THEN 1 ELSE 0 END) AS ready_node_count,\n SUM(CASE WHEN status = 'completed' THEN 1 ELSE 0 END) AS completed_node_count\n FROM orchestrator_task_nodes\n GROUP BY thread_id\n ) AS node_counts\n ON node_counts.thread_id = thread.id\n LEFT JOIN (\n SELECT thread_id, COUNT(*) AS verifier_job_count\n FROM orchestrator_task_verifier_jobs\n GROUP BY thread_id\n ) AS verifier_counts\n ON verifier_counts.thread_id = thread.id\n LEFT JOIN (\n SELECT thread_id, COUNT(*) AS evidence_count\n FROM orchestrator_task_evidence\n GROUP BY thread_id\n ) AS evidence_counts\n ON evidence_counts.thread_id = thread.id\n ${whereClause}`,\n );\n\n return toNumber(rows[0]?.total, 0);\n }\n\n async getThreadSummary(threadId: string): Promise<TaskThreadSummary | null> {\n const rows = await this.listThreads({\n threadId,\n includeArchived: true,\n });\n return rows[0] ?? null;\n }\n\n async findThreadIdBySessionId(sessionId: string): Promise<string | null> {\n await this.ensureSchema();\n const rows = await executeRawSql(\n this.runtime,\n `SELECT thread_id\n FROM orchestrator_task_sessions\n WHERE session_id = ${sqlQuote(sessionId)}\n LIMIT 1`,\n );\n return rows[0] ? toText(rows[0].thread_id) : null;\n }\n\n async getSession(sessionId: string): Promise<TaskSessionRecord | null> {\n await this.ensureSchema();\n const rows = await executeRawSql(\n this.runtime,\n `SELECT *\n FROM orchestrator_task_sessions\n WHERE session_id = ${sqlQuote(sessionId)}\n LIMIT 1`,\n );\n return rows[0] ? parseSessionRow(rows[0]) : null;\n }\n\n async registerSession(input: RegisterTaskSessionInput): Promise<void> {\n await this.ensureSchema();\n const nowIso = isoNow();\n const registeredAt = input.registeredAt ?? Date.now();\n const lastActivityAt = input.lastActivityAt ?? registeredAt;\n const existingThread = await this.getThreadRecord(input.threadId);\n if (!existingThread) {\n throw new Error(`Task thread ${input.threadId} not found`);\n }\n\n await executeRawSql(\n this.runtime,\n `INSERT INTO orchestrator_task_sessions (\n id, thread_id, agent_id, session_id, framework, provider_source, label,\n original_task, workdir, repo, status, decision_count, auto_resolved_count,\n registered_at, last_activity_at, idle_check_count, task_delivered,\n completion_summary, last_seen_decision_index, last_input_sent_at, stopped_at,\n created_at, updated_at, metadata_json\n ) VALUES (\n ${sqlQuote(input.sessionId)},\n ${sqlQuote(input.threadId)},\n ${sqlQuote(this.runtime.agentId)},\n ${sqlQuote(input.sessionId)},\n ${sqlQuote(input.framework)},\n ${sqlText(input.providerSource ?? null)},\n ${sqlQuote(input.label)},\n ${sqlQuote(input.originalTask)},\n ${sqlQuote(input.workdir)},\n ${sqlText(input.repo ?? null)},\n ${sqlQuote(input.status ?? \"active\")},\n ${sqlInteger(input.decisionCount ?? 0)},\n ${sqlInteger(input.autoResolvedCount ?? 0)},\n ${sqlInteger(registeredAt)},\n ${sqlInteger(lastActivityAt)},\n ${sqlInteger(input.idleCheckCount ?? 0)},\n ${sqlBoolean(input.taskDelivered ?? false)},\n ${sqlText(input.completionSummary ?? null)},\n ${sqlInteger(input.lastSeenDecisionIndex ?? 0)},\n ${sqlInteger(input.lastInputSentAt ?? null)},\n ${sqlInteger(input.stoppedAt ?? null)},\n ${sqlQuote(nowIso)},\n ${sqlQuote(nowIso)},\n ${sqlJson(input.metadata ?? {})}\n )\n ON CONFLICT(id) DO UPDATE SET\n thread_id = EXCLUDED.thread_id,\n framework = EXCLUDED.framework,\n provider_source = EXCLUDED.provider_source,\n label = EXCLUDED.label,\n original_task = EXCLUDED.original_task,\n workdir = EXCLUDED.workdir,\n repo = EXCLUDED.repo,\n status = EXCLUDED.status,\n decision_count = EXCLUDED.decision_count,\n auto_resolved_count = EXCLUDED.auto_resolved_count,\n registered_at = EXCLUDED.registered_at,\n last_activity_at = EXCLUDED.last_activity_at,\n idle_check_count = EXCLUDED.idle_check_count,\n task_delivered = EXCLUDED.task_delivered,\n completion_summary = EXCLUDED.completion_summary,\n last_seen_decision_index = EXCLUDED.last_seen_decision_index,\n last_input_sent_at = EXCLUDED.last_input_sent_at,\n stopped_at = EXCLUDED.stopped_at,\n updated_at = EXCLUDED.updated_at,\n metadata_json = EXCLUDED.metadata_json`,\n );\n\n await this.appendEvent({\n threadId: input.threadId,\n sessionId: input.sessionId,\n eventType: \"session_registered\",\n timestamp: registeredAt,\n summary: `Registered session \"${input.label}\"`,\n data: {\n framework: input.framework,\n repo: input.repo ?? null,\n workdir: input.workdir,\n },\n });\n\n await this.recomputeThreadStatus(input.threadId);\n }\n\n async updateSession(\n sessionId: string,\n patch: UpdateTaskSessionInput,\n ): Promise<void> {\n await this.ensureSchema();\n const threadId = await this.findThreadIdBySessionId(sessionId);\n if (!threadId) return;\n const existingRows = await executeRawSql(\n this.runtime,\n `SELECT *\n FROM orchestrator_task_sessions\n WHERE session_id = ${sqlQuote(sessionId)}\n LIMIT 1`,\n );\n if (!existingRows[0]) return;\n const existing = parseSessionRow(existingRows[0]);\n const nextMeta = patch.metadata\n ? { ...existing.metadata, ...patch.metadata }\n : existing.metadata;\n const nowIso = isoNow();\n\n await executeRawSql(\n this.runtime,\n `UPDATE orchestrator_task_sessions\n SET status = ${sqlQuote(patch.status ?? existing.status)},\n decision_count = ${sqlInteger(\n patch.decisionCount ?? existing.decisionCount,\n )},\n auto_resolved_count = ${sqlInteger(\n patch.autoResolvedCount ?? existing.autoResolvedCount,\n )},\n last_activity_at = ${sqlInteger(\n patch.lastActivityAt ?? existing.lastActivityAt,\n )},\n idle_check_count = ${sqlInteger(\n patch.idleCheckCount ?? existing.idleCheckCount,\n )},\n task_delivered = ${sqlBoolean(\n patch.taskDelivered ?? existing.taskDelivered,\n )},\n completion_summary = ${sqlText(\n patch.completionSummary ?? existing.completionSummary,\n )},\n last_seen_decision_index = ${sqlInteger(\n patch.lastSeenDecisionIndex ?? existing.lastSeenDecisionIndex,\n )},\n last_input_sent_at = ${sqlInteger(\n patch.lastInputSentAt ?? existing.lastInputSentAt,\n )},\n stopped_at = ${sqlInteger(patch.stoppedAt ?? existing.stoppedAt)},\n updated_at = ${sqlQuote(nowIso)},\n metadata_json = ${sqlJson(nextMeta)}\n WHERE session_id = ${sqlQuote(sessionId)}`,\n );\n\n await this.appendEvent({\n threadId,\n sessionId,\n eventType: \"session_updated\",\n timestamp: patch.lastActivityAt ?? Date.now(),\n summary: `Updated session \"${existing.label}\"`,\n data: {\n status: patch.status ?? existing.status,\n decisionCount: patch.decisionCount ?? existing.decisionCount,\n autoResolvedCount:\n patch.autoResolvedCount ?? existing.autoResolvedCount,\n },\n });\n\n await this.recomputeThreadStatus(threadId);\n }\n\n async recordDecision(input: RecordTaskDecisionInput): Promise<void> {\n await this.ensureSchema();\n const createdAt = isoNow();\n await executeRawSql(\n this.runtime,\n `INSERT INTO orchestrator_task_decisions (\n id, thread_id, session_id, timestamp, event_type, prompt_text, decision,\n response, reasoning, metadata_json, created_at\n ) VALUES (\n ${sqlQuote(`decision-${crypto.randomUUID()}`)},\n ${sqlQuote(input.threadId)},\n ${sqlQuote(input.sessionId)},\n ${sqlInteger(input.timestamp)},\n ${sqlQuote(input.event)},\n ${sqlQuote(input.promptText)},\n ${sqlQuote(input.decision)},\n ${sqlText(input.response ?? null)},\n ${sqlQuote(input.reasoning)},\n ${sqlJson(input.metadata ?? {})},\n ${sqlQuote(createdAt)}\n )`,\n );\n\n await this.appendEvent({\n threadId: input.threadId,\n sessionId: input.sessionId,\n eventType: \"decision_recorded\",\n timestamp: input.timestamp,\n summary: `${input.decision} decision recorded`,\n data: {\n event: input.event,\n promptText: input.promptText,\n response: input.response ?? null,\n },\n });\n }\n\n async appendEvent(input: RecordTaskEventInput): Promise<void> {\n await this.ensureSchema();\n const createdAt = isoNow();\n const timestamp = input.timestamp ?? Date.now();\n await executeRawSql(\n this.runtime,\n `INSERT INTO orchestrator_task_events (\n id, thread_id, session_id, event_type, timestamp, summary, data_json, created_at\n ) VALUES (\n ${sqlQuote(`event-${crypto.randomUUID()}`)},\n ${sqlQuote(input.threadId)},\n ${sqlText(input.sessionId ?? null)},\n ${sqlQuote(input.eventType)},\n ${sqlInteger(timestamp)},\n ${sqlQuote(input.summary ?? \"\")},\n ${sqlJson(input.data ?? {})},\n ${sqlQuote(createdAt)}\n )`,\n );\n\n await executeRawSql(\n this.runtime,\n `UPDATE orchestrator_task_threads\n SET updated_at = ${sqlQuote(createdAt)}\n WHERE id = ${sqlQuote(input.threadId)}`,\n );\n }\n\n async recordArtifact(input: RecordTaskArtifactInput): Promise<void> {\n await this.ensureSchema();\n const createdAt = isoNow();\n await executeRawSql(\n this.runtime,\n `INSERT INTO orchestrator_task_artifacts (\n id, thread_id, session_id, artifact_type, title, path, uri, mime_type, metadata_json, created_at\n ) VALUES (\n ${sqlQuote(`artifact-${crypto.randomUUID()}`)},\n ${sqlQuote(input.threadId)},\n ${sqlText(input.sessionId ?? null)},\n ${sqlQuote(input.artifactType)},\n ${sqlQuote(input.title)},\n ${sqlText(input.path ?? null)},\n ${sqlText(input.uri ?? null)},\n ${sqlText(input.mimeType ?? null)},\n ${sqlJson(input.metadata ?? {})},\n ${sqlQuote(createdAt)}\n )`,\n );\n\n await this.appendEvent({\n threadId: input.threadId,\n sessionId: input.sessionId ?? null,\n eventType: \"artifact_recorded\",\n summary: `Recorded ${input.artifactType} artifact`,\n data: {\n artifactType: input.artifactType,\n title: input.title,\n path: input.path ?? null,\n uri: input.uri ?? null,\n },\n });\n }\n\n async recordTranscript(input: RecordTaskTranscriptInput): Promise<void> {\n await this.ensureSchema();\n const createdAt = isoNow();\n const timestamp = input.timestamp ?? Date.now();\n await executeRawSql(\n this.runtime,\n `INSERT INTO orchestrator_task_transcripts (\n id, thread_id, session_id, timestamp, direction, content, metadata_json, created_at\n ) VALUES (\n ${sqlQuote(`transcript-${crypto.randomUUID()}`)},\n ${sqlQuote(input.threadId)},\n ${sqlQuote(input.sessionId)},\n ${sqlInteger(timestamp)},\n ${sqlQuote(input.direction)},\n ${sqlQuote(input.content)},\n ${sqlJson(input.metadata ?? {})},\n ${sqlQuote(createdAt)}\n )`,\n );\n await executeRawSql(\n this.runtime,\n `UPDATE orchestrator_task_threads\n SET updated_at = ${sqlQuote(createdAt)}\n WHERE id = ${sqlQuote(input.threadId)}`,\n );\n }\n\n async updateThreadSummary(threadId: string, summary: string): Promise<void> {\n await this.ensureSchema();\n const thread = await this.getThreadRecord(threadId);\n if (!thread) return;\n const nextSearchText = buildSearchText([\n thread.title,\n thread.originalRequest,\n summary,\n thread.searchText,\n ]);\n const nowIso = isoNow();\n await executeRawSql(\n this.runtime,\n `UPDATE orchestrator_task_threads\n SET summary = ${sqlQuote(summary)},\n search_text = ${sqlQuote(nextSearchText)},\n updated_at = ${sqlQuote(nowIso)}\n WHERE id = ${sqlQuote(threadId)}`,\n );\n await this.appendEvent({\n threadId,\n eventType: \"summary_updated\",\n summary: \"Updated task summary\",\n data: { summary },\n });\n }\n\n async updateThread(\n threadId: string,\n patch: UpdateTaskThreadInput,\n ): Promise<void> {\n await this.ensureSchema();\n const existing = await this.getThreadRecord(threadId);\n if (!existing) return;\n\n const nextMetadata = patch.metadata\n ? { ...existing.metadata, ...patch.metadata }\n : existing.metadata;\n const nextSummary = patch.summary ?? existing.summary;\n const nextSearchText = buildSearchText([\n existing.title,\n existing.originalRequest,\n nextSummary,\n patch.status ?? existing.status,\n existing.scenarioId,\n existing.batchId,\n JSON.stringify(nextMetadata),\n ]);\n const nowIso = isoNow();\n\n await executeRawSql(\n this.runtime,\n `UPDATE orchestrator_task_threads\n SET status = ${sqlQuote(patch.status ?? existing.status)},\n summary = ${sqlQuote(nextSummary)},\n current_plan_json = ${sqlJson(\n patch.currentPlan ?? existing.currentPlan,\n )},\n search_text = ${sqlQuote(nextSearchText)},\n closed_at = ${sqlText(\n patch.closedAt !== undefined\n ? patch.closedAt\n : existing.closedAt,\n )},\n archived_at = ${sqlText(\n patch.archivedAt !== undefined\n ? patch.archivedAt\n : existing.archivedAt,\n )},\n last_user_turn_at = ${sqlText(\n patch.lastUserTurnAt !== undefined\n ? patch.lastUserTurnAt\n : existing.lastUserTurnAt,\n )},\n last_coordinator_turn_at = ${sqlText(\n patch.lastCoordinatorTurnAt !== undefined\n ? patch.lastCoordinatorTurnAt\n : existing.lastCoordinatorTurnAt,\n )},\n updated_at = ${sqlQuote(nowIso)},\n metadata_json = ${sqlJson(nextMetadata)}\n WHERE id = ${sqlQuote(threadId)}`,\n );\n }\n\n async archiveThread(threadId: string): Promise<void> {\n await this.ensureSchema();\n const nowIso = isoNow();\n await executeRawSql(\n this.runtime,\n `UPDATE orchestrator_task_threads\n SET status = 'archived',\n archived_at = ${sqlQuote(nowIso)},\n closed_at = COALESCE(closed_at, ${sqlQuote(nowIso)}),\n updated_at = ${sqlQuote(nowIso)}\n WHERE id = ${sqlQuote(threadId)}`,\n );\n await this.appendEvent({\n threadId,\n eventType: \"task_archived\",\n summary: \"Archived task thread\",\n data: {},\n });\n }\n\n async reopenThread(threadId: string): Promise<void> {\n await this.ensureSchema();\n const nowIso = isoNow();\n await executeRawSql(\n this.runtime,\n `UPDATE orchestrator_task_threads\n SET status = 'open',\n archived_at = NULL,\n closed_at = NULL,\n updated_at = ${sqlQuote(nowIso)}\n WHERE id = ${sqlQuote(threadId)}`,\n );\n await this.appendEvent({\n threadId,\n eventType: \"task_reopened\",\n summary: \"Reopened task thread\",\n data: {},\n });\n await this.recomputeThreadStatus(threadId);\n }\n\n async upsertPendingDecision(\n input: UpsertPendingDecisionInput,\n ): Promise<void> {\n await this.ensureSchema();\n const createdAt = input.createdAt ?? Date.now();\n const nowIso = isoNow();\n await executeRawSql(\n this.runtime,\n `INSERT INTO orchestrator_task_pending_decisions (\n session_id,\n thread_id,\n prompt_text,\n recent_output,\n llm_decision_json,\n task_context_json,\n created_at,\n updated_at\n ) VALUES (\n ${sqlQuote(input.sessionId)},\n ${sqlQuote(input.threadId)},\n ${sqlQuote(input.promptText)},\n ${sqlQuote(input.recentOutput)},\n ${sqlJson(input.llmDecision)},\n ${sqlJson(input.taskContext)},\n ${sqlInteger(createdAt)},\n ${sqlQuote(nowIso)}\n )\n ON CONFLICT(session_id) DO UPDATE SET\n thread_id = EXCLUDED.thread_id,\n prompt_text = EXCLUDED.prompt_text,\n recent_output = EXCLUDED.recent_output,\n llm_decision_json = EXCLUDED.llm_decision_json,\n task_context_json = EXCLUDED.task_context_json,\n created_at = EXCLUDED.created_at,\n updated_at = EXCLUDED.updated_at`,\n );\n await executeRawSql(\n this.runtime,\n `UPDATE orchestrator_task_threads\n SET updated_at = ${sqlQuote(nowIso)}\n WHERE id = ${sqlQuote(input.threadId)}`,\n );\n }\n\n async deletePendingDecision(sessionId: string): Promise<void> {\n await this.ensureSchema();\n const rows = await executeRawSql(\n this.runtime,\n `SELECT thread_id\n FROM orchestrator_task_pending_decisions\n WHERE session_id = ${sqlQuote(sessionId)}\n LIMIT 1`,\n );\n if (rows.length === 0) return;\n const threadId = toText(rows[0]?.thread_id);\n await executeRawSql(\n this.runtime,\n `DELETE FROM orchestrator_task_pending_decisions\n WHERE session_id = ${sqlQuote(sessionId)}`,\n );\n if (threadId) {\n await executeRawSql(\n this.runtime,\n `UPDATE orchestrator_task_threads\n SET updated_at = ${sqlQuote(isoNow())}\n WHERE id = ${sqlQuote(threadId)}`,\n );\n }\n }\n\n async listPendingDecisions(): Promise<TaskPendingDecisionRecord[]> {\n await this.ensureSchema();\n const rows = await executeRawSql(\n this.runtime,\n `SELECT *\n FROM orchestrator_task_pending_decisions\n ORDER BY created_at ASC`,\n );\n return rows.map(parsePendingDecisionRow);\n }\n\n async listPendingDecisionsForThread(\n threadId: string,\n ): Promise<TaskPendingDecisionRecord[]> {\n await this.ensureSchema();\n const rows = await executeRawSql(\n this.runtime,\n `SELECT *\n FROM orchestrator_task_pending_decisions\n WHERE thread_id = ${sqlQuote(threadId)}\n ORDER BY created_at ASC`,\n );\n return rows.map(parsePendingDecisionRow);\n }\n\n async createTaskNode(input: CreateTaskNodeInput): Promise<TaskNodeRecord> {\n await this.ensureSchema();\n const nowIso = isoNow();\n const id = input.id?.trim() || `node-${crypto.randomUUID()}`;\n await executeRawSql(\n this.runtime,\n `INSERT INTO orchestrator_task_nodes (\n id, thread_id, parent_node_id, kind, status, title, instructions,\n acceptance_criteria_json, required_capabilities_json, expected_artifacts_json,\n assigned_session_id, assigned_label, agent_type, workdir, repo, priority,\n depth, sequence, created_from, metadata_json, created_at, updated_at,\n started_at, completed_at\n ) VALUES (\n ${sqlQuote(id)},\n ${sqlQuote(input.threadId)},\n ${sqlText(input.parentNodeId ?? null)},\n ${sqlQuote(input.kind ?? \"execution\")},\n ${sqlQuote(input.status ?? \"planned\")},\n ${sqlQuote(input.title)},\n ${sqlQuote(input.instructions ?? \"\")},\n ${sqlJson(input.acceptanceCriteria ?? [])},\n ${sqlJson(input.requiredCapabilities ?? [])},\n ${sqlJson(input.expectedArtifacts ?? [])},\n ${sqlText(input.assignedSessionId ?? null)},\n ${sqlText(input.assignedLabel ?? null)},\n ${sqlText(input.agentType ?? null)},\n ${sqlText(input.workdir ?? null)},\n ${sqlText(input.repo ?? null)},\n ${sqlInteger(input.priority ?? 0)},\n ${sqlInteger(input.depth ?? 0)},\n ${sqlInteger(input.sequence ?? 0)},\n ${sqlText(input.createdFrom ?? null)},\n ${sqlJson(input.metadata ?? {})},\n ${sqlQuote(nowIso)},\n ${sqlQuote(nowIso)},\n ${sqlText(input.startedAt ?? null)},\n ${sqlText(input.completedAt ?? null)}\n )`,\n );\n await this.appendEvent({\n threadId: input.threadId,\n sessionId: input.assignedSessionId ?? null,\n eventType: \"task_node_created\",\n summary: `Created task node \"${input.title}\"`,\n data: {\n nodeId: id,\n kind: input.kind ?? \"execution\",\n status: input.status ?? \"planned\",\n parentNodeId: input.parentNodeId ?? null,\n },\n });\n const node = await this.getTaskNode(id);\n if (!node) {\n throw new Error(`Failed to create task node ${id}`);\n }\n await this.recomputeTaskGraphState(input.threadId);\n return node;\n }\n\n async getTaskNode(nodeId: string): Promise<TaskNodeRecord | null> {\n await this.ensureSchema();\n const rows = await executeRawSql(\n this.runtime,\n `SELECT *\n FROM orchestrator_task_nodes\n WHERE id = ${sqlQuote(nodeId)}\n LIMIT 1`,\n );\n return rows[0] ? parseTaskNodeRow(rows[0]) : null;\n }\n\n async updateTaskNode(\n nodeId: string,\n patch: UpdateTaskNodeInput,\n ): Promise<void> {\n await this.ensureSchema();\n const existing = await this.getTaskNode(nodeId);\n if (!existing) return;\n const nextMetadata = patch.metadata\n ? { ...existing.metadata, ...patch.metadata }\n : existing.metadata;\n const nextStatus = patch.status ?? existing.status;\n const nextStartedAt =\n patch.startedAt !== undefined\n ? patch.startedAt\n : nextStatus === \"running\" || nextStatus === \"verifying\"\n ? (existing.startedAt ?? isoNow())\n : existing.startedAt;\n const nextCompletedAt =\n patch.completedAt !== undefined\n ? patch.completedAt\n : [\"completed\", \"failed\", \"canceled\", \"interrupted\"].includes(\n nextStatus,\n )\n ? (existing.completedAt ?? isoNow())\n : null;\n const nowIso = isoNow();\n\n await executeRawSql(\n this.runtime,\n `UPDATE orchestrator_task_nodes\n SET parent_node_id = ${sqlText(\n patch.parentNodeId !== undefined\n ? patch.parentNodeId\n : existing.parentNodeId,\n )},\n kind = ${sqlQuote(patch.kind ?? existing.kind)},\n status = ${sqlQuote(nextStatus)},\n title = ${sqlQuote(patch.title ?? existing.title)},\n instructions = ${sqlQuote(\n patch.instructions ?? existing.instructions,\n )},\n acceptance_criteria_json = ${sqlJson(\n patch.acceptanceCriteria ?? existing.acceptanceCriteria,\n )},\n required_capabilities_json = ${sqlJson(\n patch.requiredCapabilities ?? existing.requiredCapabilities,\n )},\n expected_artifacts_json = ${sqlJson(\n patch.expectedArtifacts ?? existing.expectedArtifacts,\n )},\n assigned_session_id = ${sqlText(\n patch.assignedSessionId !== undefined\n ? patch.assignedSessionId\n : existing.assignedSessionId,\n )},\n assigned_label = ${sqlText(\n patch.assignedLabel !== undefined\n ? patch.assignedLabel\n : existing.assignedLabel,\n )},\n agent_type = ${sqlText(\n patch.agentType !== undefined\n ? patch.agentType\n : existing.agentType,\n )},\n workdir = ${sqlText(\n patch.workdir !== undefined ? patch.workdir : existing.workdir,\n )},\n repo = ${sqlText(\n patch.repo !== undefined ? patch.repo : existing.repo,\n )},\n priority = ${sqlInteger(patch.priority ?? existing.priority)},\n depth = ${sqlInteger(patch.depth ?? existing.depth)},\n sequence = ${sqlInteger(patch.sequence ?? existing.sequence)},\n created_from = ${sqlText(\n patch.createdFrom !== undefined\n ? patch.createdFrom\n : existing.createdFrom,\n )},\n metadata_json = ${sqlJson(nextMetadata)},\n updated_at = ${sqlQuote(nowIso)},\n started_at = ${sqlText(nextStartedAt)},\n completed_at = ${sqlText(nextCompletedAt)}\n WHERE id = ${sqlQuote(nodeId)}`,\n );\n await this.appendEvent({\n threadId: existing.threadId,\n sessionId:\n patch.assignedSessionId !== undefined\n ? patch.assignedSessionId\n : existing.assignedSessionId,\n eventType: \"task_node_updated\",\n summary: `Updated task node \"${patch.title ?? existing.title}\"`,\n data: {\n nodeId,\n status: nextStatus,\n },\n });\n await this.recomputeTaskGraphState(existing.threadId);\n }\n\n async listTaskNodesForThread(threadId: string): Promise<TaskNodeRecord[]> {\n await this.ensureSchema();\n const rows = await executeRawSql(\n this.runtime,\n `SELECT *\n FROM orchestrator_task_nodes\n WHERE thread_id = ${sqlQuote(threadId)}\n ORDER BY depth ASC, sequence ASC, created_at ASC`,\n );\n return rows.map(parseTaskNodeRow);\n }\n\n async listReadyTaskNodesForThread(\n threadId: string,\n ): Promise<TaskNodeRecord[]> {\n await this.ensureSchema();\n const rows = await executeRawSql(\n this.runtime,\n `SELECT *\n FROM orchestrator_task_nodes\n WHERE thread_id = ${sqlQuote(threadId)}\n AND status = 'ready'\n ORDER BY priority DESC, depth ASC, sequence ASC, created_at ASC`,\n );\n return rows.map(parseTaskNodeRow);\n }\n\n async createTaskDependency(\n input: CreateTaskDependencyInput,\n ): Promise<TaskDependencyRecord> {\n await this.ensureSchema();\n const createdAt = isoNow();\n const id = input.id?.trim() || `dep-${crypto.randomUUID()}`;\n await executeRawSql(\n this.runtime,\n `INSERT INTO orchestrator_task_dependencies (\n id, thread_id, from_node_id, to_node_id, dependency_kind, required_status,\n metadata_json, created_at\n ) VALUES (\n ${sqlQuote(id)},\n ${sqlQuote(input.threadId)},\n ${sqlQuote(input.fromNodeId)},\n ${sqlQuote(input.toNodeId)},\n ${sqlQuote(input.dependencyKind ?? \"blocks\")},\n ${sqlQuote(input.requiredStatus ?? \"completed\")},\n ${sqlJson(input.metadata ?? {})},\n ${sqlQuote(createdAt)}\n )`,\n );\n await this.appendEvent({\n threadId: input.threadId,\n eventType: \"task_dependency_created\",\n summary: `Created dependency ${input.fromNodeId} -> ${input.toNodeId}`,\n data: {\n dependencyId: id,\n fromNodeId: input.fromNodeId,\n toNodeId: input.toNodeId,\n dependencyKind: input.dependencyKind ?? \"blocks\",\n requiredStatus: input.requiredStatus ?? \"completed\",\n },\n });\n const dependency = await this.getTaskDependency(id);\n if (!dependency) {\n throw new Error(`Failed to create task dependency ${id}`);\n }\n await this.recomputeTaskGraphState(input.threadId);\n return dependency;\n }\n\n async getTaskDependency(\n dependencyId: string,\n ): Promise<TaskDependencyRecord | null> {\n await this.ensureSchema();\n const rows = await executeRawSql(\n this.runtime,\n `SELECT *\n FROM orchestrator_task_dependencies\n WHERE id = ${sqlQuote(dependencyId)}\n LIMIT 1`,\n );\n return rows[0] ? parseTaskDependencyRow(rows[0]) : null;\n }\n\n async listTaskDependenciesForThread(\n threadId: string,\n ): Promise<TaskDependencyRecord[]> {\n await this.ensureSchema();\n const rows = await executeRawSql(\n this.runtime,\n `SELECT *\n FROM orchestrator_task_dependencies\n WHERE thread_id = ${sqlQuote(threadId)}\n ORDER BY created_at ASC`,\n );\n return rows.map(parseTaskDependencyRow);\n }\n\n async createTaskClaim(input: CreateTaskClaimInput): Promise<TaskClaimRecord> {\n await this.ensureSchema();\n const claimedAt = input.claimedAt ?? isoNow();\n const id = input.id?.trim() || `claim-${crypto.randomUUID()}`;\n await executeRawSql(\n this.runtime,\n `INSERT INTO orchestrator_task_claims (\n id, thread_id, node_id, session_id, claim_type, status, claimed_at,\n released_at, metadata_json\n ) VALUES (\n ${sqlQuote(id)},\n ${sqlQuote(input.threadId)},\n ${sqlQuote(input.nodeId)},\n ${sqlQuote(input.sessionId)},\n ${sqlQuote(input.claimType ?? \"execution\")},\n ${sqlQuote(input.status ?? \"active\")},\n ${sqlQuote(claimedAt)},\n ${sqlText(input.releasedAt ?? null)},\n ${sqlJson(input.metadata ?? {})}\n )`,\n );\n await this.appendEvent({\n threadId: input.threadId,\n sessionId: input.sessionId,\n eventType: \"task_claim_created\",\n summary: `Claimed task node ${input.nodeId}`,\n data: {\n claimId: id,\n nodeId: input.nodeId,\n sessionId: input.sessionId,\n claimType: input.claimType ?? \"execution\",\n status: input.status ?? \"active\",\n },\n });\n const claim = await this.getTaskClaim(id);\n if (!claim) {\n throw new Error(`Failed to create task claim ${id}`);\n }\n return claim;\n }\n\n async getTaskClaim(claimId: string): Promise<TaskClaimRecord | null> {\n await this.ensureSchema();\n const rows = await executeRawSql(\n this.runtime,\n `SELECT *\n FROM orchestrator_task_claims\n WHERE id = ${sqlQuote(claimId)}\n LIMIT 1`,\n );\n return rows[0] ? parseTaskClaimRow(rows[0]) : null;\n }\n\n async findActiveTaskClaim(\n nodeId: string,\n sessionId: string,\n ): Promise<TaskClaimRecord | null> {\n await this.ensureSchema();\n const rows = await executeRawSql(\n this.runtime,\n `SELECT *\n FROM orchestrator_task_claims\n WHERE node_id = ${sqlQuote(nodeId)}\n AND session_id = ${sqlQuote(sessionId)}\n AND status = 'active'\n ORDER BY claimed_at DESC\n LIMIT 1`,\n );\n return rows[0] ? parseTaskClaimRow(rows[0]) : null;\n }\n\n async updateTaskClaim(\n claimId: string,\n patch: UpdateTaskClaimInput,\n ): Promise<void> {\n await this.ensureSchema();\n const existing = await this.getTaskClaim(claimId);\n if (!existing) return;\n const nextMetadata = patch.metadata\n ? { ...existing.metadata, ...patch.metadata }\n : existing.metadata;\n await executeRawSql(\n this.runtime,\n `UPDATE orchestrator_task_claims\n SET status = ${sqlQuote(patch.status ?? existing.status)},\n released_at = ${sqlText(\n patch.releasedAt !== undefined\n ? patch.releasedAt\n : existing.releasedAt,\n )},\n metadata_json = ${sqlJson(nextMetadata)}\n WHERE id = ${sqlQuote(claimId)}`,\n );\n }\n\n async listTaskClaimsForThread(threadId: string): Promise<TaskClaimRecord[]> {\n await this.ensureSchema();\n const rows = await executeRawSql(\n this.runtime,\n `SELECT *\n FROM orchestrator_task_claims\n WHERE thread_id = ${sqlQuote(threadId)}\n ORDER BY claimed_at ASC`,\n );\n return rows.map(parseTaskClaimRow);\n }\n\n async appendTaskMailboxMessage(\n input: AppendTaskMailboxMessageInput,\n ): Promise<TaskMailboxMessageRecord> {\n await this.ensureSchema();\n const id = input.id?.trim() || `mail-${crypto.randomUUID()}`;\n const createdAt = input.createdAt ?? isoNow();\n await executeRawSql(\n this.runtime,\n `INSERT INTO orchestrator_task_mailbox (\n id, thread_id, node_id, session_id, sender, recipient, subject, body,\n delivery_state, metadata_json, created_at, delivered_at\n ) VALUES (\n ${sqlQuote(id)},\n ${sqlQuote(input.threadId)},\n ${sqlText(input.nodeId ?? null)},\n ${sqlText(input.sessionId ?? null)},\n ${sqlQuote(input.sender)},\n ${sqlQuote(input.recipient)},\n ${sqlQuote(input.subject ?? \"\")},\n ${sqlQuote(input.body)},\n ${sqlQuote(input.deliveryState ?? \"pending\")},\n ${sqlJson(input.metadata ?? {})},\n ${sqlQuote(createdAt)},\n ${sqlText(input.deliveredAt ?? null)}\n )`,\n );\n await this.appendEvent({\n threadId: input.threadId,\n sessionId: input.sessionId ?? null,\n eventType: \"task_mailbox_message\",\n summary: `Mailbox message \"${input.subject ?? \"\"}\" queued for ${input.recipient}`,\n data: {\n messageId: id,\n nodeId: input.nodeId ?? null,\n sender: input.sender,\n recipient: input.recipient,\n deliveryState: input.deliveryState ?? \"pending\",\n },\n });\n const message = await this.getTaskMailboxMessage(id);\n if (!message) {\n throw new Error(`Failed to create mailbox message ${id}`);\n }\n return message;\n }\n\n async getTaskMailboxMessage(\n messageId: string,\n ): Promise<TaskMailboxMessageRecord | null> {\n await this.ensureSchema();\n const rows = await executeRawSql(\n this.runtime,\n `SELECT *\n FROM orchestrator_task_mailbox\n WHERE id = ${sqlQuote(messageId)}\n LIMIT 1`,\n );\n return rows[0] ? parseTaskMailboxMessageRow(rows[0]) : null;\n }\n\n async markTaskMailboxMessageDelivered(messageId: string): Promise<void> {\n await this.ensureSchema();\n await executeRawSql(\n this.runtime,\n `UPDATE orchestrator_task_mailbox\n SET delivery_state = 'delivered',\n delivered_at = ${sqlQuote(isoNow())}\n WHERE id = ${sqlQuote(messageId)}`,\n );\n }\n\n async listTaskMailboxMessagesForThread(\n threadId: string,\n ): Promise<TaskMailboxMessageRecord[]> {\n await this.ensureSchema();\n const rows = await executeRawSql(\n this.runtime,\n `SELECT *\n FROM orchestrator_task_mailbox\n WHERE thread_id = ${sqlQuote(threadId)}\n ORDER BY created_at ASC`,\n );\n return rows.map(parseTaskMailboxMessageRow);\n }\n\n async createTaskVerifierJob(\n input: CreateTaskVerifierJobInput,\n ): Promise<TaskVerifierJobRecord> {\n await this.ensureSchema();\n const id = input.id?.trim() || `verify-${crypto.randomUUID()}`;\n const createdAt = input.createdAt ?? isoNow();\n await executeRawSql(\n this.runtime,\n `INSERT INTO orchestrator_task_verifier_jobs (\n id, thread_id, node_id, status, verifier_type, title, instructions,\n config_json, metadata_json, created_at, started_at, completed_at\n ) VALUES (\n ${sqlQuote(id)},\n ${sqlQuote(input.threadId)},\n ${sqlQuote(input.nodeId)},\n ${sqlQuote(input.status ?? \"pending\")},\n ${sqlQuote(input.verifierType)},\n ${sqlQuote(input.title)},\n ${sqlQuote(input.instructions ?? \"\")},\n ${sqlJson(input.config ?? {})},\n ${sqlJson(input.metadata ?? {})},\n ${sqlQuote(createdAt)},\n ${sqlText(input.startedAt ?? null)},\n ${sqlText(input.completedAt ?? null)}\n )`,\n );\n await this.appendEvent({\n threadId: input.threadId,\n eventType: \"verifier_job_created\",\n summary: `Created verifier job \"${input.title}\"`,\n data: {\n verifierJobId: id,\n nodeId: input.nodeId,\n verifierType: input.verifierType,\n status: input.status ?? \"pending\",\n },\n });\n const job = await this.getTaskVerifierJob(id);\n if (!job) {\n throw new Error(`Failed to create verifier job ${id}`);\n }\n return job;\n }\n\n async getTaskVerifierJob(\n verifierJobId: string,\n ): Promise<TaskVerifierJobRecord | null> {\n await this.ensureSchema();\n const rows = await executeRawSql(\n this.runtime,\n `SELECT *\n FROM orchestrator_task_verifier_jobs\n WHERE id = ${sqlQuote(verifierJobId)}\n LIMIT 1`,\n );\n return rows[0] ? parseTaskVerifierJobRow(rows[0]) : null;\n }\n\n async updateTaskVerifierJob(\n verifierJobId: string,\n patch: UpdateTaskVerifierJobInput,\n ): Promise<void> {\n await this.ensureSchema();\n const existing = await this.getTaskVerifierJob(verifierJobId);\n if (!existing) return;\n const nextMetadata = patch.metadata\n ? { ...existing.metadata, ...patch.metadata }\n : existing.metadata;\n await executeRawSql(\n this.runtime,\n `UPDATE orchestrator_task_verifier_jobs\n SET status = ${sqlQuote(patch.status ?? existing.status)},\n title = ${sqlQuote(patch.title ?? existing.title)},\n instructions = ${sqlQuote(\n patch.instructions ?? existing.instructions,\n )},\n config_json = ${sqlJson(patch.config ?? existing.config)},\n metadata_json = ${sqlJson(nextMetadata)},\n started_at = ${sqlText(\n patch.startedAt !== undefined\n ? patch.startedAt\n : existing.startedAt,\n )},\n completed_at = ${sqlText(\n patch.completedAt !== undefined\n ? patch.completedAt\n : existing.completedAt,\n )}\n WHERE id = ${sqlQuote(verifierJobId)}`,\n );\n }\n\n async listTaskVerifierJobsForThread(\n threadId: string,\n ): Promise<TaskVerifierJobRecord[]> {\n await this.ensureSchema();\n const rows = await executeRawSql(\n this.runtime,\n `SELECT *\n FROM orchestrator_task_verifier_jobs\n WHERE thread_id = ${sqlQuote(threadId)}\n ORDER BY created_at ASC`,\n );\n return rows.map(parseTaskVerifierJobRow);\n }\n\n async recordTaskEvidence(\n input: RecordTaskEvidenceInput,\n ): Promise<TaskEvidenceRecord> {\n await this.ensureSchema();\n const id = input.id?.trim() || `evidence-${crypto.randomUUID()}`;\n const createdAt = isoNow();\n await executeRawSql(\n this.runtime,\n `INSERT INTO orchestrator_task_evidence (\n id, thread_id, node_id, session_id, verifier_job_id, evidence_type, title,\n summary, path, uri, content_json, metadata_json, created_at\n ) VALUES (\n ${sqlQuote(id)},\n ${sqlQuote(input.threadId)},\n ${sqlText(input.nodeId ?? null)},\n ${sqlText(input.sessionId ?? null)},\n ${sqlText(input.verifierJobId ?? null)},\n ${sqlQuote(input.evidenceType)},\n ${sqlQuote(input.title)},\n ${sqlQuote(input.summary ?? \"\")},\n ${sqlText(input.path ?? null)},\n ${sqlText(input.uri ?? null)},\n ${sqlJson(input.content ?? {})},\n ${sqlJson(input.metadata ?? {})},\n ${sqlQuote(createdAt)}\n )`,\n );\n await this.appendEvent({\n threadId: input.threadId,\n sessionId: input.sessionId ?? null,\n eventType: \"task_evidence_recorded\",\n summary: `Recorded ${input.evidenceType} evidence`,\n data: {\n evidenceId: id,\n nodeId: input.nodeId ?? null,\n verifierJobId: input.verifierJobId ?? null,\n title: input.title,\n },\n });\n const evidence = await this.getTaskEvidence(id);\n if (!evidence) {\n throw new Error(`Failed to create task evidence ${id}`);\n }\n return evidence;\n }\n\n async getTaskEvidence(\n evidenceId: string,\n ): Promise<TaskEvidenceRecord | null> {\n await this.ensureSchema();\n const rows = await executeRawSql(\n this.runtime,\n `SELECT *\n FROM orchestrator_task_evidence\n WHERE id = ${sqlQuote(evidenceId)}\n LIMIT 1`,\n );\n return rows[0] ? parseTaskEvidenceRow(rows[0]) : null;\n }\n\n async listTaskEvidenceForThread(\n threadId: string,\n ): Promise<TaskEvidenceRecord[]> {\n await this.ensureSchema();\n const rows = await executeRawSql(\n this.runtime,\n `SELECT *\n FROM orchestrator_task_evidence\n WHERE thread_id = ${sqlQuote(threadId)}\n ORDER BY created_at ASC`,\n );\n return rows.map(parseTaskEvidenceRow);\n }\n\n private deriveDependentNodeStatus(\n node: TaskNodeRecord,\n incomingDependencies: TaskDependencyRecord[],\n nodesById: Map<string, TaskNodeRecord>,\n ): TaskNodeStatus {\n if (isTerminalTaskNodeStatus(node.status)) {\n return node.status;\n }\n if (\n node.status === \"running\" ||\n node.status === \"blocked\" ||\n node.status === \"waiting_on_user\" ||\n node.status === \"verifying\" ||\n node.status === \"claimed\"\n ) {\n return node.status;\n }\n\n const prerequisiteStatuses = incomingDependencies\n .map((dependency) => nodesById.get(dependency.fromNodeId))\n .filter((entry): entry is TaskNodeRecord => Boolean(entry))\n .map((entry) => entry.status);\n const allSatisfied =\n incomingDependencies.length === 0 ||\n incomingDependencies.every((dependency) => {\n const source = nodesById.get(dependency.fromNodeId);\n return (\n source !== undefined &&\n dependencyStatusSatisfied(source.status, dependency.requiredStatus)\n );\n });\n const hasFailedPrerequisite = prerequisiteStatuses.some(\n (status) =>\n status === \"failed\" ||\n status === \"canceled\" ||\n status === \"interrupted\",\n );\n\n if (node.kind === \"goal\" && incomingDependencies.length > 0) {\n if (allSatisfied) {\n return \"completed\";\n }\n return hasFailedPrerequisite ? \"failed\" : \"planned\";\n }\n\n if (node.assignedSessionId) {\n return node.status;\n }\n if (allSatisfied) {\n return \"ready\";\n }\n return hasFailedPrerequisite ? \"blocked\" : \"planned\";\n }\n\n private async recomputeTaskGraphState(threadId: string): Promise<void> {\n const [nodes, dependencies] = await Promise.all([\n this.listTaskNodesForThread(threadId),\n this.listTaskDependenciesForThread(threadId),\n ]);\n if (nodes.length === 0) {\n return;\n }\n\n const nodesById = new Map(nodes.map((node) => [node.id, node]));\n const incomingDependencies = new Map<string, TaskDependencyRecord[]>();\n for (const dependency of dependencies) {\n const bucket = incomingDependencies.get(dependency.toNodeId) ?? [];\n bucket.push(dependency);\n incomingDependencies.set(dependency.toNodeId, bucket);\n }\n\n const nowIso = isoNow();\n for (const node of nodes) {\n const nextStatus = this.deriveDependentNodeStatus(\n node,\n incomingDependencies.get(node.id) ?? [],\n nodesById,\n );\n if (nextStatus === node.status) {\n continue;\n }\n const nextCompletedAt =\n nextStatus === \"completed\" || nextStatus === \"failed\"\n ? (node.completedAt ?? nowIso)\n : null;\n await executeRawSql(\n this.runtime,\n `UPDATE orchestrator_task_nodes\n SET status = ${sqlQuote(nextStatus)},\n updated_at = ${sqlQuote(nowIso)},\n completed_at = ${sqlText(nextCompletedAt)}\n WHERE id = ${sqlQuote(node.id)}`,\n );\n }\n }\n\n async getLastUsedRepo(): Promise<string | undefined> {\n await this.ensureSchema();\n const rows = await executeRawSql(\n this.runtime,\n `SELECT repo\n FROM orchestrator_task_sessions\n WHERE repo IS NOT NULL AND repo <> ''\n ORDER BY last_activity_at DESC\n LIMIT 1`,\n );\n return rows[0] ? toText(rows[0].repo) : undefined;\n }\n\n async listSessionsForThread(threadId: string): Promise<TaskSessionRecord[]> {\n const rows = await executeRawSql(\n this.runtime,\n `SELECT *\n FROM orchestrator_task_sessions\n WHERE thread_id = ${sqlQuote(threadId)}\n ORDER BY registered_at ASC`,\n );\n return rows.map(parseSessionRow);\n }\n\n async listDecisionsForThread(\n threadId: string,\n ): Promise<TaskDecisionRecord[]> {\n const rows = await executeRawSql(\n this.runtime,\n `SELECT *\n FROM orchestrator_task_decisions\n WHERE thread_id = ${sqlQuote(threadId)}\n ORDER BY timestamp ASC`,\n );\n return rows.map(parseDecisionRow);\n }\n\n async listDecisionsForSession(\n sessionId: string,\n ): Promise<TaskDecisionRecord[]> {\n const rows = await executeRawSql(\n this.runtime,\n `SELECT *\n FROM orchestrator_task_decisions\n WHERE session_id = ${sqlQuote(sessionId)}\n ORDER BY timestamp ASC`,\n );\n return rows.map(parseDecisionRow);\n }\n\n async listEventsForThread(threadId: string): Promise<TaskEventRecord[]> {\n const rows = await executeRawSql(\n this.runtime,\n `SELECT *\n FROM orchestrator_task_events\n WHERE thread_id = ${sqlQuote(threadId)}\n ORDER BY timestamp ASC`,\n );\n return rows.map(parseEventRow);\n }\n\n async listArtifactsForThread(\n threadId: string,\n ): Promise<TaskArtifactRecord[]> {\n const rows = await executeRawSql(\n this.runtime,\n `SELECT *\n FROM orchestrator_task_artifacts\n WHERE thread_id = ${sqlQuote(threadId)}\n ORDER BY created_at ASC`,\n );\n return rows.map(parseArtifactRow);\n }\n\n async listTranscriptsForThread(\n threadId: string,\n ): Promise<TaskTranscriptRecord[]> {\n const rows = await executeRawSql(\n this.runtime,\n `SELECT *\n FROM orchestrator_task_transcripts\n WHERE thread_id = ${sqlQuote(threadId)}\n ORDER BY timestamp ASC`,\n );\n return rows.map(parseTranscriptRow);\n }\n\n private async recomputeThreadStatus(threadId: string): Promise<void> {\n await this.ensureSchema();\n const thread = await this.getThreadRecord(threadId);\n if (!thread) return;\n if (thread.archivedAt) return;\n const controlState = toText(thread.metadata.controlState)\n .trim()\n .toLowerCase();\n\n const sessions = await this.listSessionsForThread(threadId);\n const nowIso = isoNow();\n let nextStatus: TaskThreadStatus = \"open\";\n let closedAt: string | null = null;\n\n const activeCount = sessions.filter((session) =>\n [\"active\", \"tool_running\"].includes(session.status),\n ).length;\n const waitingOnUserCount = sessions.filter(\n (session) => session.status === \"waiting_on_user\",\n ).length;\n const blockedCount = sessions.filter(\n (session) => session.status === \"blocked\",\n ).length;\n const interruptedCount = sessions.filter((session) =>\n [\"interrupted\", \"stopped\"].includes(session.status),\n ).length;\n const errorCount = sessions.filter(\n (session) => session.status === \"error\",\n ).length;\n const completedCount = sessions.filter(\n (session) => session.status === \"completed\",\n ).length;\n\n if (controlState === \"paused\" && activeCount === 0 && blockedCount === 0) {\n nextStatus = \"waiting_on_user\";\n } else if (\n controlState === \"stopped\" &&\n activeCount === 0 &&\n blockedCount === 0 &&\n waitingOnUserCount === 0\n ) {\n nextStatus = \"interrupted\";\n closedAt = nowIso;\n } else if (sessions.length === 0) {\n nextStatus = \"open\";\n } else if (activeCount > 0) {\n nextStatus = \"active\";\n } else if (waitingOnUserCount > 0) {\n nextStatus = \"waiting_on_user\";\n } else if (blockedCount > 0) {\n nextStatus = \"blocked\";\n } else if (interruptedCount > 0) {\n nextStatus = \"interrupted\";\n closedAt = nowIso;\n } else if (completedCount === sessions.length) {\n nextStatus = \"done\";\n closedAt = nowIso;\n } else if (errorCount > 0) {\n nextStatus = \"failed\";\n closedAt = nowIso;\n }\n\n await executeRawSql(\n this.runtime,\n `UPDATE orchestrator_task_threads\n SET status = ${sqlQuote(nextStatus)},\n closed_at = ${sqlText(closedAt)},\n updated_at = ${sqlQuote(nowIso)}\n WHERE id = ${sqlQuote(threadId)}`,\n );\n }\n}\n",
|
|
35
|
+
"/**\n * Swarm Coordinator: autonomous coordination loop bound to PTYService.\n *\n * Subscribes to PTY session events and routes unhandled blocking prompts\n * through an autonomous LLM decision pipeline. Heavy logic is extracted into\n * swarm-decision-loop.ts (blocked / turn-complete / LLM decisions) and\n * swarm-idle-watchdog.ts (idle session scanning).\n *\n * It is bound only to PTYService and is dormant for sessions spawned via\n * AcpService. The ACP flow is:\n * AcpService session events → SubAgentRouter\n * → synthetic Memory posted to runtime.messageService.handleMessage\n * → main agent's planner decides REPLY / SEND_TO_AGENT / both.\n *\n * See `docs/sub-agent-routing.md`.\n *\n * @module services/swarm-coordinator\n */\n\nimport { promises as fs } from \"node:fs\";\nimport type { ServerResponse } from \"node:http\";\nimport type { IAgentRuntime } from \"@elizaos/core\";\nimport { logger } from \"@elizaos/core\";\n\n/**\n * True when the workspace contains files the subagent produced. Filters\n * out our injected bookkeeping (CLAUDE.md memory file) and Claude Code's\n * own dot-prefixed scaffolding (`.claude/`, `.gitignore`, `.git/`). Query\n * tasks — \"what's the price of btc\", \"explain X\" — leave the workspace\n * with only those bookkeeping entries, so `false` lets callers skip the\n * noisy \"task finished, code is at …\" prompt for ephemeral lookups.\n */\nasync function _hasSubagentArtifacts(workspacePath: string): Promise<boolean> {\n try {\n const entries = await fs.readdir(workspacePath);\n return entries.some(\n (name) => name !== \"CLAUDE.md\" && !name.startsWith(\".\"),\n );\n } catch {\n // Workspace already cleaned up or never existed — treat as no artifacts\n // so the caller defaults to the quiet path.\n return false;\n }\n}\n\nimport { buildAgentCredentials } from \"./agent-credentials.js\";\nimport { cleanForFailoverContext, extractDevServerUrl } from \"./ansi-utils.js\";\nimport {\n type CoordinatorBlockedEvent,\n type CoordinatorLoginRequiredEvent,\n type CoordinatorNormalizedEvent,\n normalizeCoordinatorEvent,\n} from \"./coordinator-event-normalizer.js\";\nimport type { PTYService } from \"./pty-service.js\";\nimport type { CodingAgentType } from \"./pty-types.js\";\nimport { normalizeAgentType } from \"./pty-types.js\";\nimport type {\n CoordinationLLMResponse,\n SharedDecision,\n} from \"./swarm-coordinator-prompts.js\";\nimport {\n checkAllTasksComplete,\n clearDeferredTurnCompleteTimers,\n executeDecision as execDecision,\n handleBlocked,\n handleTurnComplete,\n shouldIgnoreStoppedEventDuringCompletion,\n} from \"./swarm-decision-loop.js\";\nimport { SwarmHistory } from \"./swarm-history.js\";\nimport { scanIdleSessions } from \"./swarm-idle-watchdog.js\";\nimport { deriveTaskAcceptanceCriteria } from \"./task-acceptance.js\";\nimport type { TaskAgentAuthLaunchResult } from \"./task-agent-auth.js\";\nimport {\n isUsageExhaustedTaskAgentError,\n markTaskAgentFrameworkHealthy,\n markTaskAgentFrameworkUnavailable,\n type SupportedTaskAgentAdapter,\n type TaskAgentFrameworkAvailability,\n type TaskAgentFrameworkId,\n} from \"./task-agent-frameworks.js\";\nimport { inferTaskThreadKind } from \"./task-kind.js\";\nimport {\n type CreateTaskThreadInput,\n type TaskDecisionRecord,\n type TaskNodeRecord,\n type TaskNodeStatus,\n type TaskPendingDecisionRecord,\n TaskRegistry,\n type TaskSessionRecord,\n type TaskThreadDetail,\n type TaskThreadStatus,\n type TaskThreadSummary,\n} from \"./task-registry.js\";\n\n// ─── Types ───\n\n/** Callback injected by server.ts to route chat messages to the user's conversation. */\nexport type ChatMessageCallback = (\n text: string,\n source?: string,\n) => Promise<void>;\n\n/** Callback injected by server.ts to relay coordinator events to WebSocket clients. */\nexport type WsBroadcastCallback = (event: SwarmEvent) => void;\n\n/**\n * Listener for in-process consumers of the same event stream that the\n * `wsBroadcast` callback receives (e.g. the verification-room-bridge in\n * plugin-app-control). Returned from `subscribe()`; call to unsubscribe.\n */\nexport type SwarmEventListener = (event: SwarmEvent) => void;\n\n/**\n * Callback injected by server.ts to route coordinator events through\n * Eliza's full ElizaOS pipeline (conversation memory, personality, actions).\n * Returns a CoordinationLLMResponse parsed from Eliza's natural language\n * response, or null if no actionable JSON block was found.\n */\nexport type AgentDecisionCallback = (\n eventDescription: string,\n sessionId: string,\n taskContext: TaskContext,\n) => Promise<CoordinationLLMResponse | null>;\n\n/** Per-task summary included in the swarm complete payload. */\nexport interface TaskCompletionSummary {\n sessionId: string;\n label: string;\n agentType: string;\n originalTask: string;\n status: string;\n completionSummary: string;\n /** Validator-accepted user-facing summary, when a completion validator ran. */\n validationSummary?: string;\n /** Subagent's working directory — used by synthesis to read the final\n * assistant response from the Claude Code session jsonl after the PTY\n * session has been cleaned up. */\n workdir?: string;\n /** Room the task was spawned from (captured from the originating user\n * message). Used by synthesis to route the final answer back to the\n * same chat channel. */\n roomId?: string;\n}\n\n/** Callback fired when all tasks in a swarm reach terminal state. */\nexport type SwarmCompleteCallback = (payload: {\n tasks: TaskCompletionSummary[];\n total: number;\n completed: number;\n stopped: number;\n errored: number;\n}) => Promise<void>;\n\nexport type SupervisionLevel = \"autonomous\" | \"confirm\" | \"notify\";\n\nexport interface TaskContext {\n threadId: string;\n taskNodeId?: string;\n sessionId: string;\n agentType: CodingAgentType;\n label: string;\n originalTask: string;\n workdir: string;\n /** Repository URL if provided, undefined for scratch directory tasks. */\n repo?: string;\n /** Original parent room for this spawned task, when available. */\n originRoomId?: string;\n /** Read-only parent metadata captured at spawn time. */\n originMetadata?: Record<string, unknown>;\n status:\n | \"active\"\n | \"blocked\"\n | \"tool_running\"\n | \"completed\"\n | \"error\"\n | \"stopped\";\n decisions: CoordinationDecision[];\n autoResolvedCount: number;\n registeredAt: number;\n /** Timestamp of the last session event (any type). Used by idle watchdog. */\n lastActivityAt: number;\n /** How many idle checks have been performed on this session. */\n idleCheckCount: number;\n /** True once the initial task has been delivered to the agent. */\n taskDelivered: boolean;\n /** Summary of what the agent accomplished, populated on completion. */\n completionSummary?: string;\n /** Validator-accepted summary to use as final-answer evidence. */\n validationSummary?: string;\n /** Index into sharedDecisions[]: tracks which decisions this agent has already seen. */\n lastSeenDecisionIndex: number;\n /** Timestamp of last coordinator-sent input. Used to suppress stall/turn-complete\n * events for a grace period so the agent has time to process the input. */\n lastInputSentAt?: number;\n /** Timestamp when the task was last transitioned to `stopped`. */\n stoppedAt?: number;\n /** Suppress the generic stop notice when the session is intentionally replaced. */\n suppressStopNotice?: boolean;\n /** Keep the PTY session open after this task completes so callers can reuse it. */\n keepAliveAfterComplete?: boolean;\n}\n\nexport interface CoordinationDecision {\n timestamp: number;\n event: string;\n promptText: string;\n decision:\n | \"respond\"\n | \"escalate\"\n | \"ignore\"\n | \"complete\"\n | \"auto_resolved\"\n | \"stopped\";\n response?: string;\n reasoning: string;\n}\n\nexport interface SwarmEvent {\n type: string;\n sessionId: string;\n timestamp: number;\n data: unknown;\n}\n\nexport interface PendingDecision {\n sessionId: string;\n promptText: string;\n recentOutput: string;\n llmDecision: CoordinationLLMResponse;\n taskContext: TaskContext;\n createdAt: number;\n}\n\n/**\n * Context interface exposing internal state and helpers to extracted modules.\n * Implemented by SwarmCoordinator. Passed as `this` to module-level functions.\n */\nexport interface SwarmCoordinatorContext {\n readonly runtime: IAgentRuntime;\n readonly ptyService: PTYService | null;\n readonly taskRegistry: TaskRegistry;\n readonly tasks: Map<string, TaskContext>;\n readonly inFlightDecisions: Set<string>;\n readonly pendingDecisions: Map<string, PendingDecision>;\n /** Buffered task_complete events that arrived while an in-flight decision was running. */\n readonly pendingTurnComplete: Map<string, unknown>;\n /** Fingerprint of the last blocked prompt per session, for re-render dedup. */\n readonly lastBlockedPromptFingerprint: Map<string, string>;\n /** Buffered blocked events that arrived while an in-flight decision was running. */\n readonly pendingBlocked: Map<string, unknown>;\n /** Last-seen output snapshot per session, used by idle watchdog. */\n readonly lastSeenOutput: Map<string, string>;\n /** Timestamp of last tool_running chat notification per session, for throttling. */\n readonly lastToolNotification: Map<string, number>;\n\n /** Whether LLM decisions are paused (user sent a chat message). */\n readonly isPaused: boolean;\n\n /** Significant decisions shared across the swarm. */\n readonly sharedDecisions: SharedDecision[];\n\n /** Get the shared context brief from the planning phase. */\n getSwarmContext(): string;\n\n /**\n * Guard flag: whether the swarm_complete event has already been fired\n * for the current swarm lifecycle. Set to `true` by `checkAllTasksComplete()`\n * when all tasks reach terminal state. Reset to `false` by:\n * - `stop()`: full coordinator teardown\n * - `registerTask()`: when detecting a new swarm (all previous tasks terminal)\n */\n swarmCompleteNotified: boolean;\n\n broadcast(event: SwarmEvent): void;\n /**\n * Register an in-process listener that receives every broadcast event.\n * Returns an unsubscribe function. Listeners run synchronously after the\n * SSE/WS fan-out and must not throw — the coordinator catches and logs\n * any thrown error so a misbehaving listener cannot poison the event\n * stream for other consumers.\n */\n subscribe(listener: SwarmEventListener): () => void;\n sendChatMessage(text: string, source?: string): boolean;\n log(message: string): void;\n getSupervisionLevel(): SupervisionLevel;\n getAgentDecisionCallback(): AgentDecisionCallback | null;\n getSwarmCompleteCallback(): SwarmCompleteCallback | null;\n recordDecision(\n taskCtx: TaskContext,\n decision: CoordinationDecision,\n ): Promise<void>;\n syncTaskContext(taskCtx: TaskContext): Promise<void>;\n}\n\n// ─── Constants ───\n\n/** Time to buffer events for unregistered sessions (ms). */\n/** Exponential backoff delays for unregistered session buffer retries. */\nconst UNREGISTERED_RETRY_DELAYS = [2000, 4000, 8000, 16000];\n/** Absolute maximum wait time before discarding unregistered events. */\nconst UNREGISTERED_MAX_TOTAL_MS = 30_000;\n\n/** Coalesce rapid turn-complete events within this window (ms). */\nconst TURN_COMPLETE_COALESCE_MS = 500;\n\n/** How often the idle watchdog scans for idle sessions (ms). */\nconst IDLE_SCAN_INTERVAL_MS = 60 * 1000; // 1 minute\n\n/** How long to wait before auto-resuming a paused coordinator (ms). */\nconst PAUSE_TIMEOUT_MS = 30_000;\n/** Max events to buffer before WS bridge is wired. */\nconst MAX_PRE_BRIDGE_BUFFER = 100;\n/** Grace window where a late task_complete can recover a recently-stopped task. */\nconst STOPPED_RECOVERY_WINDOW_MS = 90_000;\nconst FAILOVER_OUTPUT_MAX_CHARS = 4_000;\nconst MAX_AUTOMATIC_ERROR_RECOVERIES = 2;\nconst ALTERNATE_FRAMEWORK_ERROR_RE =\n /\\b(auth|login|credential|401|403|unauthorized|forbidden|token|api key|not found|enoent|missing executable|command not found)\\b/i;\n\nfunction inferProviderSource(\n framework: TaskAgentFrameworkAvailability,\n): string | null {\n if (framework.subscriptionReady) {\n return \"subscription\";\n }\n if (framework.id === \"pi\") {\n return framework.installed ? \"local-cli\" : null;\n }\n if (framework.id === \"opencode\") {\n return framework.installed ? \"local-cli\" : null;\n }\n return framework.authReady ? \"credentials\" : null;\n}\n\n// ─── Service ───\n\nexport class SwarmCoordinator implements SwarmCoordinatorContext {\n static serviceType = \"SWARM_COORDINATOR\";\n\n readonly runtime: IAgentRuntime;\n readonly taskRegistry: TaskRegistry;\n ptyService: PTYService | null = null;\n private unsubscribeEvents: (() => void) | null = null;\n\n /** Per-session task context. */\n readonly tasks: Map<string, TaskContext> = new Map();\n\n /** SSE clients receiving live events. */\n private sseClients: Set<ServerResponse> = new Set();\n\n /** Supervision level (default: autonomous). */\n private supervisionLevel: SupervisionLevel = \"autonomous\";\n\n /** Pending confirmations for \"confirm\" mode. */\n readonly pendingDecisions: Map<string, PendingDecision> = new Map();\n\n /** In-flight decision lock: prevents parallel LLM calls for same session. */\n readonly inFlightDecisions: Set<string> = new Set();\n\n /** Buffered task_complete events that arrived while an in-flight decision was running. */\n readonly pendingTurnComplete: Map<string, unknown> = new Map();\n\n /** Fingerprint of the last blocked prompt per session, for re-render dedup. */\n readonly lastBlockedPromptFingerprint: Map<string, string> = new Map();\n\n /** Buffered blocked events that arrived while an in-flight decision was running. */\n readonly pendingBlocked: Map<string, unknown> = new Map();\n\n /** Callback to send chat messages to the user's conversation UI. */\n private chatCallback: ChatMessageCallback | null = null;\n\n /** Callback to relay coordinator events to WebSocket clients. */\n private wsBroadcast: WsBroadcastCallback | null = null;\n\n /** Callback to route coordinator events through Eliza's full pipeline. */\n private agentDecisionCb: AgentDecisionCallback | null = null;\n\n /** Callback fired when all swarm tasks complete, for synthesis. */\n private swarmCompleteCb: SwarmCompleteCallback | null = null;\n\n /** Buffer for events arriving before task registration. */\n private unregisteredBuffer: Map<\n string,\n Array<{ normalized: CoordinatorNormalizedEvent; receivedAt: number }>\n > = new Map();\n\n /** Idle watchdog timer handle. */\n private idleWatchdogTimer: ReturnType<typeof setInterval> | null = null;\n\n /** Last-seen output snapshot per session, used by idle watchdog to detect data flow. */\n readonly lastSeenOutput: Map<string, string> = new Map();\n\n /** Timestamp of last tool_running chat notification per session, for throttling. */\n readonly lastToolNotification: Map<string, number> = new Map();\n\n /** Whether LLM decisions are paused (user sent a chat message). */\n private _paused = false;\n\n /** Significant decisions shared across the swarm (Layer 2). */\n readonly sharedDecisions: SharedDecision[] = [];\n\n /** Shared context brief generated during swarm planning phase. */\n private _swarmContext = \"\";\n\n /** @see SwarmCoordinatorContext.swarmCompleteNotified */\n swarmCompleteNotified = false;\n\n /** Buffered events during pause, replayed on resume. */\n private pauseBuffer: CoordinatorNormalizedEvent[] = [];\n\n /** Buffered broadcasts waiting for wsBroadcast to be wired. */\n private preBridgeBroadcastBuffer: SwarmEvent[] = [];\n\n /** In-process listeners subscribed via `subscribe()`. */\n private eventListeners: Set<SwarmEventListener> = new Set();\n\n /** Auto-resume timeout handle. */\n private pauseTimeout: ReturnType<typeof setTimeout> | null = null;\n\n /** Coordinator startup timestamp: ignore events from sessions created before this. */\n private readonly startedAt = Date.now();\n\n /** Active retry timers for unregistered session buffers. */\n private unregisteredRetryTimers: Map<string, ReturnType<typeof setTimeout>> =\n new Map();\n\n /** Turn-complete coalescing timers: debounces rapid events per session. */\n private turnCompleteCoalesceTimers: Map<\n string,\n ReturnType<typeof setTimeout>\n > = new Map();\n\n /** Persistent swarm history: JSONL log that survives restarts. */\n readonly history = new SwarmHistory();\n\n constructor(runtime: IAgentRuntime) {\n this.runtime = runtime;\n this.taskRegistry = new TaskRegistry(runtime);\n }\n\n // ─── Chat Callback ───\n\n /** Inject a callback (from server.ts) to route messages to the user's chat UI. */\n /** Track whether we've already wired the scratch decision callback. */\n private scratchDecisionWired = false;\n\n setChatCallback(cb: ChatMessageCallback): void {\n this.chatCallback = cb;\n this.log(\"Chat callback wired\");\n // Try wiring scratch decision callback now, retry lazily if service not ready\n this.wireScratchDecisionCallback();\n }\n\n /**\n * Wire the scratch workspace save prompt callback.\n * Called eagerly from setChatCallback and lazily from handleSessionEvent\n * in case the workspace service wasn't ready at chat-callback time.\n */\n private wireScratchDecisionCallback(): void {\n if (this.scratchDecisionWired || !this.chatCallback) return;\n const wsService = this.runtime.getService(\"CODING_WORKSPACE_SERVICE\") as\n | {\n setScratchDecisionCallback?: (\n cb: (record: {\n label: string;\n path: string;\n expiresAt?: number;\n }) => Promise<void>,\n ) => void;\n }\n | undefined;\n if (wsService?.setScratchDecisionCallback) {\n wsService.setScratchDecisionCallback(async (_record) => {\n // Scratch workspace TTL notices are runtime-internal; the real\n // task output is delivered by the synthesis path. Keeping this\n // callback registered (so the coordinator wiring is complete)\n // but silent in chat to avoid \"Code is at …\" leaks to Discord.\n });\n this.scratchDecisionWired = true;\n this.log(\"Scratch decision callback wired\");\n }\n }\n\n /** Inject a callback (from server.ts) to relay events to WebSocket clients. */\n setWsBroadcast(cb: WsBroadcastCallback): void {\n this.wsBroadcast = cb;\n // Replay any events that were broadcast before the bridge was wired\n if (this.preBridgeBroadcastBuffer.length > 0) {\n this.log(\n `WS broadcast callback wired: replaying ${this.preBridgeBroadcastBuffer.length} buffered event(s)`,\n );\n for (const event of this.preBridgeBroadcastBuffer) {\n cb(event);\n }\n this.preBridgeBroadcastBuffer.length = 0;\n } else {\n this.log(\"WS broadcast callback wired\");\n }\n }\n\n /** Inject a callback fired when all swarm tasks reach terminal state. */\n setSwarmCompleteCallback(cb: SwarmCompleteCallback): void {\n this.swarmCompleteCb = cb;\n this.log(\"Swarm complete callback wired\");\n }\n\n /** Return the swarm complete callback (if wired). */\n getSwarmCompleteCallback(): SwarmCompleteCallback | null {\n return this.swarmCompleteCb;\n }\n\n /** Set the shared context brief for this swarm. */\n setSwarmContext(context: string): void {\n this._swarmContext = context;\n this.log(`Swarm context set (${context.length} chars)`);\n }\n\n /** Return the swarm planning context (if set). */\n getSwarmContext(): string {\n return this._swarmContext;\n }\n\n /** Inject a callback (from server.ts) to route events through Eliza's pipeline. */\n setAgentDecisionCallback(cb: AgentDecisionCallback): void {\n this.agentDecisionCb = cb;\n this.log(\"Agent decision callback wired, events will route through Eliza\");\n }\n\n /** Return the agent decision callback (if wired). */\n getAgentDecisionCallback(): AgentDecisionCallback | null {\n return this.agentDecisionCb;\n }\n\n /**\n * Null-safe chat dispatcher.\n *\n * CALLING POLICY. Keep this consistent or you'll either spam users or\n * hide important signals:\n *\n * POST to chat: user must act (auth prompts, \"needs your attention\"\n * escalations, security violations, unrecoverable\n * errors), or the final result of the swarm (delivered\n * via the synthesis callback, not this method).\n *\n * STAY SILENT: coordinator-internal state transitions (auto-\n * recovery, token refresh, scratch-decision TTL,\n * tool_running progress, mid-task continuation\n * decisions, PTY session-lost on restart). Web UI\n * still sees these via `broadcast()`; chat should\n * not duplicate them, because synthesis will deliver\n * the final outcome once a terminal state is reached.\n */\n sendChatMessage(text: string, source?: string): boolean {\n if (!this.chatCallback) return false;\n this.chatCallback(text, source).catch((err) => {\n this.log(`Failed to send chat message: ${err}`);\n });\n return true;\n }\n\n // ─── Lifecycle ───\n\n /**\n * Initialize the coordinator by subscribing to PTY session events.\n * Called from plugin init after services are ready.\n */\n async start(ptyService: PTYService): Promise<void> {\n await this.taskRegistry.ensureSchema();\n await this.taskRegistry.recoverInterruptedTasks();\n await this.rehydratePendingDecisions();\n this.ptyService = ptyService;\n this.unsubscribeEvents = ptyService.onNormalizedSessionEvent(\n (normalized) => {\n this.handleNormalizedSessionEvent(normalized).catch((err) => {\n this.log(`Error handling event: ${err}`);\n });\n },\n );\n\n // Start idle watchdog\n this.idleWatchdogTimer = setInterval(() => {\n scanIdleSessions(this).catch((err) => {\n this.log(`Idle watchdog error: ${err}`);\n });\n }, IDLE_SCAN_INTERVAL_MS);\n\n this.log(\"SwarmCoordinator started\");\n }\n\n private restorePendingTaskContext(\n record: TaskPendingDecisionRecord,\n ): TaskContext {\n const raw = record.taskContext;\n const status = (() => {\n switch (typeof raw.status === \"string\" ? raw.status : \"\") {\n case \"active\":\n case \"blocked\":\n case \"tool_running\":\n case \"completed\":\n case \"error\":\n case \"stopped\":\n return raw.status as TaskContext[\"status\"];\n default:\n return \"blocked\";\n }\n })();\n return {\n threadId:\n typeof raw.threadId === \"string\" && raw.threadId.trim().length > 0\n ? raw.threadId\n : record.threadId,\n ...(typeof raw.taskNodeId === \"string\" && raw.taskNodeId.trim().length > 0\n ? { taskNodeId: raw.taskNodeId }\n : {}),\n sessionId: record.sessionId,\n agentType:\n typeof raw.agentType === \"string\" && raw.agentType.trim().length > 0\n ? (raw.agentType as CodingAgentType)\n : \"claude\",\n label:\n typeof raw.label === \"string\" && raw.label.trim().length > 0\n ? raw.label\n : `agent-${record.sessionId.slice(-8)}`,\n originalTask:\n typeof raw.originalTask === \"string\"\n ? raw.originalTask\n : record.promptText,\n workdir: typeof raw.workdir === \"string\" ? raw.workdir : \"\",\n ...(typeof raw.repo === \"string\" && raw.repo.trim().length > 0\n ? { repo: raw.repo }\n : {}),\n ...(typeof raw.originRoomId === \"string\" &&\n raw.originRoomId.trim().length > 0\n ? { originRoomId: raw.originRoomId }\n : {}),\n ...(raw.originMetadata &&\n typeof raw.originMetadata === \"object\" &&\n !Array.isArray(raw.originMetadata)\n ? { originMetadata: raw.originMetadata as Record<string, unknown> }\n : {}),\n status,\n decisions: Array.isArray(raw.decisions)\n ? (raw.decisions.filter((entry) =>\n Boolean(entry && typeof entry === \"object\"),\n ) as CoordinationDecision[])\n : [],\n autoResolvedCount:\n typeof raw.autoResolvedCount === \"number\" ? raw.autoResolvedCount : 0,\n registeredAt:\n typeof raw.registeredAt === \"number\"\n ? raw.registeredAt\n : record.createdAt,\n lastActivityAt:\n typeof raw.lastActivityAt === \"number\"\n ? raw.lastActivityAt\n : record.createdAt,\n idleCheckCount:\n typeof raw.idleCheckCount === \"number\" ? raw.idleCheckCount : 0,\n taskDelivered: raw.taskDelivered === true,\n ...(typeof raw.completionSummary === \"string\"\n ? { completionSummary: raw.completionSummary }\n : {}),\n ...(typeof raw.validationSummary === \"string\"\n ? { validationSummary: raw.validationSummary }\n : {}),\n lastSeenDecisionIndex:\n typeof raw.lastSeenDecisionIndex === \"number\"\n ? raw.lastSeenDecisionIndex\n : 0,\n ...(typeof raw.lastInputSentAt === \"number\"\n ? { lastInputSentAt: raw.lastInputSentAt }\n : {}),\n ...(typeof raw.stoppedAt === \"number\"\n ? { stoppedAt: raw.stoppedAt }\n : {}),\n };\n }\n\n private restorePendingLlmDecision(\n record: TaskPendingDecisionRecord,\n ): CoordinationLLMResponse {\n const raw = record.llmDecision;\n const action =\n typeof raw.action === \"string\" &&\n [\"respond\", \"escalate\", \"ignore\", \"complete\"].includes(raw.action)\n ? (raw.action as CoordinationLLMResponse[\"action\"])\n : \"escalate\";\n return {\n action,\n ...(typeof raw.response === \"string\" ? { response: raw.response } : {}),\n ...(raw.useKeys === true ? { useKeys: true } : {}),\n ...(Array.isArray(raw.keys)\n ? {\n keys: raw.keys.filter(\n (entry): entry is string => typeof entry === \"string\",\n ),\n }\n : {}),\n reasoning:\n typeof raw.reasoning === \"string\" && raw.reasoning.trim().length > 0\n ? raw.reasoning\n : \"Recovered pending confirmation from persisted coordinator state.\",\n };\n }\n\n private async rehydratePendingDecisions(): Promise<void> {\n const records = await this.taskRegistry.listPendingDecisions();\n for (const record of records) {\n const taskContext = this.restorePendingTaskContext(record);\n this.tasks.set(record.sessionId, taskContext);\n this.pendingDecisions.set(record.sessionId, {\n sessionId: record.sessionId,\n promptText: record.promptText,\n recentOutput: record.recentOutput,\n llmDecision: this.restorePendingLlmDecision(record),\n taskContext,\n createdAt: record.createdAt,\n });\n }\n }\n\n async stop(): Promise<void> {\n const persistOnShutdown = Array.from(this.tasks.values())\n .filter(\n (task) =>\n task.status === \"active\" ||\n task.status === \"blocked\" ||\n task.status === \"tool_running\",\n )\n .map(async (task) => {\n task.status = \"stopped\";\n task.stoppedAt = Date.now();\n await this.taskRegistry.updateSession(task.sessionId, {\n status: \"interrupted\",\n lastActivityAt: task.lastActivityAt,\n idleCheckCount: task.idleCheckCount,\n taskDelivered: task.taskDelivered,\n autoResolvedCount: task.autoResolvedCount,\n decisionCount: task.decisions.length,\n completionSummary: task.completionSummary ?? null,\n lastSeenDecisionIndex: task.lastSeenDecisionIndex,\n lastInputSentAt: task.lastInputSentAt,\n stoppedAt: task.stoppedAt,\n });\n await this.taskRegistry.appendEvent({\n threadId: task.threadId,\n sessionId: task.sessionId,\n eventType: \"session_interrupted\",\n summary: \"Session interrupted during coordinator shutdown\",\n data: { reason: \"coordinator_shutdown\" },\n });\n });\n await Promise.allSettled(persistOnShutdown);\n if (this.idleWatchdogTimer) {\n clearInterval(this.idleWatchdogTimer);\n this.idleWatchdogTimer = null;\n }\n if (this.unsubscribeEvents) {\n this.unsubscribeEvents();\n this.unsubscribeEvents = null;\n }\n // Close all SSE connections\n for (const client of this.sseClients) {\n if (!client.writableEnded) {\n client.end();\n }\n }\n this.sseClients.clear();\n this.tasks.clear();\n this.pendingDecisions.clear();\n this.inFlightDecisions.clear();\n this.pendingTurnComplete.clear();\n clearDeferredTurnCompleteTimers();\n this.lastBlockedPromptFingerprint.clear();\n this.pendingBlocked.clear();\n this.unregisteredBuffer.clear();\n for (const timer of this.unregisteredRetryTimers.values()) {\n clearTimeout(timer);\n }\n this.unregisteredRetryTimers.clear();\n for (const timer of this.turnCompleteCoalesceTimers.values()) {\n clearTimeout(timer);\n }\n this.turnCompleteCoalesceTimers.clear();\n this.lastSeenOutput.clear();\n this.lastToolNotification.clear();\n this.agentDecisionCb = null;\n this.sharedDecisions.length = 0;\n this._swarmContext = \"\";\n this.swarmCompleteNotified = false;\n // Clear pause state\n this._paused = false;\n if (this.pauseTimeout) {\n clearTimeout(this.pauseTimeout);\n this.pauseTimeout = null;\n }\n this.pauseBuffer = [];\n this.preBridgeBroadcastBuffer.length = 0;\n this.log(\"SwarmCoordinator stopped\");\n }\n\n // ─── Pause / Resume ───\n\n /** Whether the coordinator is currently paused. */\n get isPaused(): boolean {\n return this._paused;\n }\n\n /** Pause LLM-based decisions. Auto-responses and broadcasts continue. */\n pause(): void {\n if (this._paused) return;\n this._paused = true;\n this.log(\n \"Coordinator paused: buffering LLM decisions until user message is processed\",\n );\n this.broadcast({\n type: \"coordinator_paused\",\n sessionId: \"\",\n timestamp: Date.now(),\n data: {},\n });\n\n // Safety: auto-resume after timeout\n this.pauseTimeout = setTimeout(() => {\n if (this._paused) {\n this.log(\"Coordinator auto-resuming after timeout\");\n this.resume();\n }\n }, PAUSE_TIMEOUT_MS);\n }\n\n /** Resume LLM-based decisions and replay buffered events. */\n resume(): void {\n if (!this._paused) return;\n this._paused = false;\n if (this.pauseTimeout) {\n clearTimeout(this.pauseTimeout);\n this.pauseTimeout = null;\n }\n\n this.log(\n `Coordinator resumed: replaying ${this.pauseBuffer.length} buffered events`,\n );\n this.broadcast({\n type: \"coordinator_resumed\",\n sessionId: \"\",\n timestamp: Date.now(),\n data: {},\n });\n\n // Replay buffered events\n const buffered = [...this.pauseBuffer];\n this.pauseBuffer = [];\n for (const entry of buffered) {\n this.handleNormalizedSessionEvent(entry).catch((err) => {\n this.log(`Error replaying buffered event: ${err}`);\n });\n }\n }\n\n // ─── Task Registration ───\n\n async registerTask(\n sessionId: string,\n context: {\n threadId?: string;\n taskNodeId?: string;\n agentType: CodingAgentType;\n label: string;\n originalTask: string;\n workdir: string;\n repo?: string;\n providerSource?: string | null;\n metadata?: Record<string, unknown>;\n },\n ): Promise<void> {\n const threadId = context.threadId?.trim() || sessionId;\n // Reset swarm state when the first task of a new swarm is registered.\n // Check for terminal-only tasks (all previous tasks in completed/stopped/error)\n // rather than empty map, so reuse without stop() works.\n const allPreviousTerminal =\n this.tasks.size === 0 ||\n Array.from(this.tasks.values()).every(\n (t) =>\n t.status === \"completed\" ||\n t.status === \"stopped\" ||\n t.status === \"error\",\n );\n if (allPreviousTerminal) {\n this.swarmCompleteNotified = false;\n // Clear stale tasks and shared context from previous swarm\n if (this.tasks.size > 0) {\n this.tasks.clear();\n this.sharedDecisions.length = 0;\n this._swarmContext = \"\";\n this.log(\"Cleared stale swarm state for new swarm\");\n }\n }\n\n const taskNodeId = context.taskNodeId?.trim() || `node-${sessionId}`;\n const originRoomId =\n typeof context.metadata?.originRoomId === \"string\" &&\n context.metadata.originRoomId.trim().length > 0\n ? context.metadata.originRoomId.trim()\n : typeof context.metadata?.roomId === \"string\" &&\n context.metadata.roomId.trim().length > 0\n ? context.metadata.roomId.trim()\n : undefined;\n const keepAliveAfterComplete =\n context.metadata?.keepAliveAfterComplete === true;\n\n this.tasks.set(sessionId, {\n threadId,\n taskNodeId,\n sessionId,\n agentType: context.agentType,\n label: context.label,\n originalTask: context.originalTask,\n workdir: context.workdir,\n repo: context.repo,\n ...(originRoomId ? { originRoomId } : {}),\n ...(context.metadata ? { originMetadata: context.metadata } : {}),\n status: \"active\",\n decisions: [],\n autoResolvedCount: 0,\n registeredAt: Date.now(),\n lastActivityAt: Date.now(),\n idleCheckCount: 0,\n taskDelivered: false,\n lastSeenDecisionIndex: 0,\n ...(keepAliveAfterComplete ? { keepAliveAfterComplete: true } : {}),\n });\n\n // Persist last used repo so it survives task cleanup\n if (context.repo) {\n this._lastUsedRepo = context.repo;\n }\n\n // Log to persistent history (fire-and-forget)\n this.history\n .append({\n timestamp: Date.now(),\n type: \"task_registered\",\n sessionId,\n label: context.label,\n agentType: context.agentType,\n repo: context.repo,\n workdir: context.workdir,\n originalTask: context.originalTask,\n })\n .catch((err) => {\n this.log(\n `Failed to append task registration history for ${sessionId}: ${err}`,\n );\n });\n\n const taskCtx = this.tasks.get(sessionId);\n const persistPromise = taskCtx\n ? (async () => {\n const existingThread =\n await this.taskRegistry.getThreadRecord(threadId);\n if (!existingThread) {\n await this.createTaskThread({\n id: threadId,\n title: context.label,\n originalRequest: context.originalTask,\n metadata: {\n repo: context.repo ?? null,\n source: \"register-task-fallback\",\n },\n });\n }\n const existingNode = await this.taskRegistry.getTaskNode(taskNodeId);\n if (!existingNode) {\n await this.taskRegistry.createTaskNode({\n id: taskNodeId,\n threadId: taskCtx.threadId,\n kind: \"execution\",\n status: \"running\",\n title: context.label,\n instructions: context.originalTask,\n requiredCapabilities: [context.agentType],\n assignedSessionId: sessionId,\n assignedLabel: context.label,\n agentType: context.agentType,\n workdir: context.workdir,\n repo: context.repo,\n createdFrom: context.taskNodeId\n ? \"register-task-existing-node\"\n : \"register-task-fallback\",\n metadata: {\n providerSource: context.providerSource ?? null,\n },\n });\n } else if (existingNode.threadId !== taskCtx.threadId) {\n throw new Error(\n `Task node ${taskNodeId} belongs to ${existingNode.threadId}, expected ${taskCtx.threadId}`,\n );\n }\n await Promise.all([\n this.taskRegistry.registerSession({\n threadId: taskCtx.threadId,\n sessionId,\n framework: context.agentType,\n providerSource: context.providerSource,\n label: context.label,\n originalTask: context.originalTask,\n workdir: context.workdir,\n repo: context.repo,\n status: \"active\",\n decisionCount: 0,\n autoResolvedCount: 0,\n registeredAt: taskCtx.registeredAt,\n lastActivityAt: taskCtx.lastActivityAt,\n idleCheckCount: taskCtx.idleCheckCount,\n taskDelivered: false,\n lastSeenDecisionIndex: 0,\n metadata: {\n ...(context.metadata ?? {}),\n taskNodeId,\n },\n }),\n this.taskRegistry.updateTaskNode(taskNodeId, {\n status: \"running\",\n title: context.label,\n instructions: context.originalTask,\n assignedSessionId: sessionId,\n assignedLabel: context.label,\n agentType: context.agentType,\n workdir: context.workdir,\n repo: context.repo,\n metadata: {\n providerSource: context.providerSource ?? null,\n },\n }),\n this.taskRegistry.createTaskClaim({\n threadId,\n nodeId: taskNodeId,\n sessionId,\n claimType: \"execution\",\n status: \"active\",\n metadata: {\n label: context.label,\n },\n }),\n this.taskRegistry.appendEvent({\n threadId,\n sessionId,\n eventType: \"task_registered\",\n timestamp: Date.now(),\n summary: `Registered task \"${context.label}\"`,\n data: {\n label: context.label,\n originalTask: context.originalTask,\n repo: context.repo ?? null,\n taskNodeId,\n },\n }),\n ]);\n })()\n : Promise.resolve();\n void persistPromise.catch((err) => {\n this.log(`Failed to persist task registration for ${sessionId}: ${err}`);\n });\n\n this.broadcast({\n type: \"task_registered\",\n sessionId,\n timestamp: Date.now(),\n data: {\n agentType: context.agentType,\n label: context.label,\n originalTask: context.originalTask,\n },\n });\n\n // Cancel any pending retry timer and flush buffered events\n const retryTimer = this.unregisteredRetryTimers.get(sessionId);\n if (retryTimer) {\n clearTimeout(retryTimer);\n this.unregisteredRetryTimers.delete(sessionId);\n }\n const buffered = this.unregisteredBuffer.get(sessionId);\n if (buffered) {\n this.unregisteredBuffer.delete(sessionId);\n for (const entry of buffered) {\n this.handleNormalizedSessionEvent(entry.normalized).catch((err) => {\n this.log(`Error replaying buffered event: ${err}`);\n });\n }\n }\n await persistPromise;\n }\n\n /**\n * Return the repo URL from the most recently registered task that had one.\n * Useful as a fallback when the user says \"in the same repo\" without a URL.\n */\n /**\n * Persisted separately from tasks so it survives task cleanup.\n * Updated whenever a task with a repo is registered.\n */\n private _lastUsedRepo: string | undefined;\n\n getLastUsedRepo(): string | undefined {\n // Check active tasks first (freshest), fall back to in-memory persisted value\n let latest: TaskContext | undefined;\n for (const task of this.tasks.values()) {\n if (task.repo && (!latest || task.registeredAt > latest.registeredAt)) {\n latest = task;\n }\n }\n return latest?.repo ?? this._lastUsedRepo;\n }\n\n /**\n * Async version that also checks disk history, survives process restarts.\n * Callers that can await should prefer this over the sync version.\n */\n async getLastUsedRepoAsync(): Promise<string | undefined> {\n const memoryRepo = this.getLastUsedRepo();\n if (memoryRepo) return memoryRepo;\n try {\n return (\n (await this.taskRegistry.getLastUsedRepo()) ??\n (await this.history.getLastUsedRepo())\n );\n } catch {\n return undefined;\n }\n }\n\n getTaskContext(sessionId: string): TaskContext | undefined {\n return this.tasks.get(sessionId);\n }\n\n private mapDecisionRecord(record: TaskDecisionRecord): CoordinationDecision {\n return {\n timestamp: record.timestamp,\n event: record.event,\n promptText: record.promptText,\n decision: record.decision as CoordinationDecision[\"decision\"],\n ...(record.response ? { response: record.response } : {}),\n reasoning: record.reasoning,\n };\n }\n\n private mapSessionStatus(\n status: TaskSessionRecord[\"status\"],\n ): TaskContext[\"status\"] {\n switch (status) {\n case \"blocked\":\n case \"waiting_on_user\":\n return \"blocked\";\n case \"tool_running\":\n return \"tool_running\";\n case \"completed\":\n return \"completed\";\n case \"error\":\n return \"error\";\n case \"stopped\":\n case \"interrupted\":\n return \"stopped\";\n default:\n return \"active\";\n }\n }\n\n private mapTaskContextStatusToNodeStatus(\n status: TaskContext[\"status\"],\n ): TaskNodeStatus {\n switch (status) {\n case \"blocked\":\n return \"blocked\";\n case \"completed\":\n return \"completed\";\n case \"error\":\n return \"failed\";\n case \"stopped\":\n return \"interrupted\";\n case \"tool_running\":\n return \"running\";\n default:\n return \"running\";\n }\n }\n\n private buildTaskContextFromSession(\n session: TaskSessionRecord,\n decisions: TaskDecisionRecord[],\n ): TaskContext {\n return {\n threadId: session.threadId,\n ...(typeof session.metadata.taskNodeId === \"string\" &&\n session.metadata.taskNodeId.trim().length > 0\n ? { taskNodeId: session.metadata.taskNodeId }\n : {}),\n sessionId: session.sessionId,\n agentType: session.framework,\n label: session.label,\n originalTask: session.originalTask,\n workdir: session.workdir,\n ...(session.repo ? { repo: session.repo } : {}),\n status: this.mapSessionStatus(session.status),\n decisions: decisions.map((decision) => this.mapDecisionRecord(decision)),\n autoResolvedCount: session.autoResolvedCount,\n registeredAt: session.registeredAt,\n lastActivityAt: session.lastActivityAt,\n idleCheckCount: session.idleCheckCount,\n taskDelivered: session.taskDelivered,\n ...(session.completionSummary\n ? { completionSummary: session.completionSummary }\n : {}),\n lastSeenDecisionIndex: session.lastSeenDecisionIndex,\n ...(session.lastInputSentAt !== null\n ? { lastInputSentAt: session.lastInputSentAt }\n : {}),\n ...(session.stoppedAt !== null ? { stoppedAt: session.stoppedAt } : {}),\n };\n }\n\n async getTaskContextSnapshot(sessionId: string): Promise<TaskContext | null> {\n const live = this.tasks.get(sessionId);\n if (live) return live;\n const session = await this.taskRegistry.getSession(sessionId);\n if (!session) return null;\n const decisions =\n await this.taskRegistry.listDecisionsForSession(sessionId);\n return this.buildTaskContextFromSession(session, decisions);\n }\n\n getAllTaskContexts(): TaskContext[] {\n return Array.from(this.tasks.values());\n }\n\n async createTaskThread(\n input: CreateTaskThreadInput,\n ): Promise<TaskThreadSummary> {\n const normalizedInput: CreateTaskThreadInput = {\n ...input,\n kind: inferTaskThreadKind(input),\n };\n const acceptance = await deriveTaskAcceptanceCriteria(\n this.runtime,\n normalizedInput,\n );\n const thread = await this.taskRegistry.createThread({\n ...normalizedInput,\n acceptanceCriteria: acceptance.criteria,\n metadata: {\n ...(normalizedInput.metadata ?? {}),\n acceptanceCriteriaSource: acceptance.source,\n },\n });\n const summary = await this.taskRegistry.getThreadSummary(thread.id);\n if (!summary) {\n throw new Error(`Failed to load task thread ${thread.id}`);\n }\n return summary;\n }\n\n async planTaskThreadGraph(input: {\n threadId: string;\n title: string;\n originalRequest: string;\n sharedContext?: string;\n subtasks: Array<{\n label: string;\n originalTask: string;\n agentType: CodingAgentType;\n repo?: string;\n }>;\n }): Promise<{\n rootNode: TaskNodeRecord;\n workerNodes: TaskNodeRecord[];\n }> {\n const thread = await this.taskRegistry.getThreadRecord(input.threadId);\n if (!thread) {\n throw new Error(`Task thread ${input.threadId} not found`);\n }\n\n const rootNode = await this.taskRegistry.createTaskNode({\n threadId: input.threadId,\n parentNodeId: null,\n kind: \"goal\",\n status: \"planned\",\n title: input.title,\n instructions: input.originalRequest,\n acceptanceCriteria: thread.acceptanceCriteria,\n priority: 100,\n depth: 0,\n sequence: 0,\n createdFrom: \"planner\",\n metadata: {\n threadKind: thread.kind,\n source: \"swarm-planner\",\n },\n });\n\n // The acceptance verifier is a code-completion safety check: it asks the\n // LLM whether file/test evidence in the workspace matches the criteria,\n // catching agents that lie about completing code work. It's only useful\n // when there is real artifact evidence to verify (a repo) AND real\n // criteria to check against (provided or model-generated, not the\n // baseline placeholder fallback). For chat / question-answering tasks\n // (no repo, response IS the deliverable) the verifier produces false\n // failures because there are no files to inspect.\n const acceptanceCriteriaSource =\n typeof thread.metadata?.acceptanceCriteriaSource === \"string\"\n ? thread.metadata.acceptanceCriteriaSource\n : null;\n const hasRepo =\n typeof thread.metadata?.repo === \"string\" &&\n thread.metadata.repo.trim().length > 0;\n if (\n thread.acceptanceCriteria.length > 0 &&\n acceptanceCriteriaSource !== \"baseline\" &&\n hasRepo\n ) {\n await this.taskRegistry.createTaskVerifierJob({\n threadId: input.threadId,\n nodeId: rootNode.id,\n status: \"pending\",\n verifierType: \"acceptance_criteria\",\n title: `Verify acceptance criteria for ${input.title}`,\n instructions: thread.acceptanceCriteria.join(\"\\n\"),\n config: {\n acceptanceCriteria: thread.acceptanceCriteria,\n },\n metadata: {\n source: \"thread-acceptance\",\n },\n });\n }\n\n if (input.sharedContext?.trim()) {\n await this.taskRegistry.appendTaskMailboxMessage({\n threadId: input.threadId,\n nodeId: rootNode.id,\n sender: \"planner\",\n recipient: \"all-workers\",\n subject: \"shared-context\",\n body: input.sharedContext.trim(),\n deliveryState: \"delivered\",\n deliveredAt: new Date().toISOString(),\n metadata: {\n source: \"swarm-planner\",\n },\n });\n }\n\n const workerNodes: TaskNodeRecord[] = [];\n for (const [index, subtask] of input.subtasks.entries()) {\n const node = await this.taskRegistry.createTaskNode({\n threadId: input.threadId,\n parentNodeId: rootNode.id,\n kind: \"execution\",\n status: \"ready\",\n title: subtask.label,\n instructions: subtask.originalTask,\n requiredCapabilities: [subtask.agentType],\n repo: subtask.repo,\n priority: 10,\n depth: 1,\n sequence: index + 1,\n createdFrom: \"planner\",\n metadata: {\n agentType: subtask.agentType,\n source: \"swarm-planner\",\n },\n });\n await this.taskRegistry.createTaskDependency({\n threadId: input.threadId,\n fromNodeId: node.id,\n toNodeId: rootNode.id,\n dependencyKind: \"parent_child\",\n requiredStatus: \"completed\",\n metadata: {\n source: \"swarm-planner\",\n },\n });\n if (input.sharedContext?.trim()) {\n await this.taskRegistry.appendTaskMailboxMessage({\n threadId: input.threadId,\n nodeId: node.id,\n sender: \"planner\",\n recipient: subtask.label,\n subject: \"task-brief\",\n body: input.sharedContext.trim(),\n deliveryState: \"delivered\",\n deliveredAt: new Date().toISOString(),\n metadata: {\n task: subtask.originalTask,\n agentType: subtask.agentType,\n },\n });\n }\n workerNodes.push(node);\n }\n\n await this.taskRegistry.updateThread(input.threadId, {\n currentPlan: {\n ...thread.currentPlan,\n rootTaskNodeId: rootNode.id,\n taskNodeIds: workerNodes.map((node) => node.id),\n taskNodeCount: workerNodes.length + 1,\n },\n });\n\n return { rootNode, workerNodes };\n }\n\n async listTaskThreads(options?: {\n includeArchived?: boolean;\n status?: TaskThreadStatus;\n statuses?: TaskThreadStatus[];\n kind?: import(\"./task-registry.js\").TaskThreadKind;\n roomId?: string;\n worldId?: string;\n ownerUserId?: string;\n scenarioId?: string;\n batchId?: string;\n createdAfter?: string;\n createdBefore?: string;\n updatedAfter?: string;\n updatedBefore?: string;\n latestActivityAfter?: number;\n latestActivityBefore?: number;\n hasActiveSession?: boolean;\n search?: string;\n limit?: number;\n }): Promise<TaskThreadSummary[]> {\n return this.taskRegistry.listThreads(options);\n }\n\n async getTaskThread(threadId: string): Promise<TaskThreadDetail | null> {\n return this.taskRegistry.getThread(threadId);\n }\n\n async archiveTaskThread(threadId: string): Promise<void> {\n await this.taskRegistry.archiveThread(threadId);\n }\n\n async reopenTaskThread(threadId: string): Promise<void> {\n await this.taskRegistry.reopenThread(threadId);\n }\n\n async countTaskThreads(options?: {\n includeArchived?: boolean;\n status?: TaskThreadStatus;\n statuses?: TaskThreadStatus[];\n kind?: import(\"./task-registry.js\").TaskThreadKind;\n roomId?: string;\n worldId?: string;\n ownerUserId?: string;\n scenarioId?: string;\n batchId?: string;\n createdAfter?: string;\n createdBefore?: string;\n updatedAfter?: string;\n updatedBefore?: string;\n latestActivityAfter?: number;\n latestActivityBefore?: number;\n hasActiveSession?: boolean;\n search?: string;\n }): Promise<number> {\n return this.taskRegistry.countThreads(options);\n }\n\n private getLiveTaskContextsForThread(threadId: string): TaskContext[] {\n return Array.from(this.tasks.values())\n .filter((task) => task.threadId === threadId)\n .sort((left, right) => right.lastActivityAt - left.lastActivityAt);\n }\n\n private async stopLiveThreadSessions(\n threadId: string,\n force: boolean,\n ): Promise<string[]> {\n if (!this.ptyService) {\n return [];\n }\n\n const sessionIds = this.getLiveTaskContextsForThread(threadId)\n .filter(\n (task) =>\n task.status === \"active\" ||\n task.status === \"blocked\" ||\n task.status === \"tool_running\",\n )\n .map((task) => task.sessionId);\n for (const sessionId of sessionIds) {\n const taskCtx = this.tasks.get(sessionId);\n if (taskCtx) {\n taskCtx.status = \"stopped\";\n taskCtx.stoppedAt = Date.now();\n await this.syncTaskContext(taskCtx);\n }\n try {\n await this.ptyService.stopSession(sessionId, force);\n } catch (error) {\n this.log(\n `Failed to stop session ${sessionId} for thread ${threadId}: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n return sessionIds;\n }\n\n private clipText(value: string, limit: number): string {\n if (value.length <= limit) return value;\n return `${value.slice(0, limit)}…`;\n }\n\n private formatResumePrompt(\n thread: TaskThreadDetail,\n instruction?: string,\n ): string {\n const acceptanceCriteria = (thread.acceptanceCriteria ?? [])\n .map((item) => `- ${item}`)\n .join(\"\\n\");\n const recentDecisions = (thread.decisions ?? [])\n .slice(-6)\n .map(\n (decision, index) =>\n `${index + 1}. ${decision.event}: ${decision.reasoning}${decision.response ? ` (response: ${decision.response})` : \"\"}`,\n )\n .join(\"\\n\");\n const recentEvents = (thread.events ?? [])\n .slice(-8)\n .map(\n (event, index) =>\n `${index + 1}. ${event.eventType}: ${this.clipText(event.summary, 180)}`,\n )\n .join(\"\\n\");\n const transcriptExcerpt = (thread.transcripts ?? [])\n .slice(-20)\n .map(\n (entry) =>\n `${entry.direction.toUpperCase()}: ${this.clipText(entry.content.trim(), 220)}`,\n )\n .filter((line) => line.length > 0)\n .join(\"\\n\");\n const latestSession = (thread.sessions ?? [])\n .slice()\n .sort((left, right) => right.lastActivityAt - left.lastActivityAt)[0];\n\n return [\n \"Resume an existing Eliza coordinator task thread.\",\n \"\",\n `Thread: ${thread.title}`,\n `Original request: ${thread.originalRequest}`,\n latestSession?.workdir ? `Workspace: ${latestSession.workdir}` : \"\",\n latestSession?.repo ? `Repository: ${latestSession.repo}` : \"\",\n thread.summary ? `Current summary: ${thread.summary}` : \"\",\n acceptanceCriteria ? `Acceptance criteria:\\n${acceptanceCriteria}` : \"\",\n instruction?.trim()\n ? `Latest user instruction:\\n${instruction.trim()}`\n : \"Continue from the current workspace state without starting over.\",\n recentDecisions\n ? `Recent coordinator decisions:\\n${recentDecisions}`\n : \"\",\n recentEvents ? `Recent task events:\\n${recentEvents}` : \"\",\n transcriptExcerpt\n ? `Recent transcript excerpt:\\n${transcriptExcerpt}`\n : \"\",\n \"Inspect the current workspace, continue the task, run the relevant verification, and summarize what changed.\",\n ]\n .filter(Boolean)\n .join(\"\\n\\n\");\n }\n\n async pauseTaskThread(\n threadId: string,\n note?: string,\n ): Promise<{ threadId: string; stoppedSessionIds: string[] }> {\n const thread = await this.getTaskThread(threadId);\n if (!thread) {\n throw new Error(`Task thread ${threadId} not found`);\n }\n\n const stoppedSessionIds = await this.stopLiveThreadSessions(threadId, true);\n const nowIso = new Date().toISOString();\n await this.taskRegistry.updateThread(threadId, {\n status: \"waiting_on_user\",\n closedAt: null,\n lastCoordinatorTurnAt: nowIso,\n metadata: {\n controlState: \"paused\",\n pauseNote: note ?? null,\n pauseRequestedAt: nowIso,\n },\n });\n await this.taskRegistry.appendEvent({\n threadId,\n eventType: \"task_paused\",\n summary: note?.trim()\n ? `Paused task thread: ${note.trim()}`\n : \"Paused task thread for user review\",\n data: {\n note: note ?? null,\n stoppedSessionIds,\n },\n });\n return { threadId, stoppedSessionIds };\n }\n\n async stopTaskThread(\n threadId: string,\n note?: string,\n ): Promise<{ threadId: string; stoppedSessionIds: string[] }> {\n const thread = await this.getTaskThread(threadId);\n if (!thread) {\n throw new Error(`Task thread ${threadId} not found`);\n }\n\n const stoppedSessionIds = await this.stopLiveThreadSessions(threadId, true);\n const nowIso = new Date().toISOString();\n await this.taskRegistry.updateThread(threadId, {\n status: \"interrupted\",\n closedAt: nowIso,\n lastCoordinatorTurnAt: nowIso,\n metadata: {\n controlState: \"stopped\",\n stopNote: note ?? null,\n stoppedByUserAt: nowIso,\n },\n });\n await this.taskRegistry.appendEvent({\n threadId,\n eventType: \"task_stopped\",\n summary: note?.trim()\n ? `Stopped task thread: ${note.trim()}`\n : \"Stopped task thread at user request\",\n data: {\n note: note ?? null,\n stoppedSessionIds,\n },\n });\n return { threadId, stoppedSessionIds };\n }\n\n async resumeTaskThread(\n threadId: string,\n instruction?: string,\n agentType?: string,\n ): Promise<{\n threadId: string;\n sessionId: string;\n reusedSession: boolean;\n framework: CodingAgentType;\n }> {\n const thread = await this.getTaskThread(threadId);\n if (!thread) {\n throw new Error(`Task thread ${threadId} not found`);\n }\n if (!this.ptyService) {\n throw new Error(\"PTY Service is not available\");\n }\n\n const activeTask = this.getLiveTaskContextsForThread(threadId).find(\n (task) =>\n task.status !== \"stopped\" &&\n task.status !== \"completed\" &&\n task.status !== \"error\",\n );\n if (activeTask) {\n if (instruction?.trim()) {\n await this.ptyService.sendToSession(\n activeTask.sessionId,\n instruction.trim(),\n );\n activeTask.lastInputSentAt = Date.now();\n activeTask.status = \"active\";\n await this.syncTaskContext(activeTask);\n }\n const nowIso = new Date().toISOString();\n await this.taskRegistry.updateThread(threadId, {\n status: \"active\",\n closedAt: null,\n lastCoordinatorTurnAt: nowIso,\n metadata: {\n controlState: null,\n resumedAt: nowIso,\n },\n });\n await this.taskRegistry.appendEvent({\n threadId,\n sessionId: activeTask.sessionId,\n eventType: \"task_resumed\",\n summary: \"Continued the active task thread\",\n data: {\n reusedSession: true,\n instruction: instruction ?? null,\n },\n });\n return {\n threadId,\n sessionId: activeTask.sessionId,\n reusedSession: true,\n framework: activeTask.agentType,\n };\n }\n\n const latestSession = (thread.sessions ?? [])\n .slice()\n .sort((left, right) => right.lastActivityAt - left.lastActivityAt)[0];\n const workdir = latestSession?.workdir ?? thread.latestWorkdir;\n if (!workdir) {\n throw new Error(`Task thread ${threadId} has no resumable workspace`);\n }\n\n const requestedFramework = agentType\n ? normalizeAgentType(agentType)\n : latestSession?.framework\n ? normalizeAgentType(latestSession.framework)\n : normalizeAgentType(await this.ptyService.resolveAgentType());\n const frameworkState = await this.ptyService.getFrameworkState();\n const framework = frameworkState.frameworks.find(\n (entry) => entry.id === requestedFramework,\n );\n const resolvedFramework =\n framework?.installed &&\n framework.authReady &&\n !framework.temporarilyDisabled\n ? requestedFramework\n : normalizeAgentType(await this.ptyService.resolveAgentType());\n const resolvedAvailability = frameworkState.frameworks.find(\n (entry) => entry.id === resolvedFramework,\n );\n\n const session = await this.ptyService.spawnSession({\n name: `task-resume-${thread.id.slice(-8)}`,\n agentType: resolvedFramework,\n workdir,\n initialTask: this.formatResumePrompt(thread, instruction),\n credentials: buildAgentCredentials(this.runtime),\n approvalPreset: this.ptyService.defaultApprovalPreset,\n skipAdapterAutoResponse: true,\n metadata: {\n threadId,\n label: thread.title,\n requestedType: resolvedFramework,\n resumedFromThreadId: threadId,\n resumedFromSessionId: latestSession?.sessionId ?? null,\n resumeInstruction: instruction ?? null,\n resumedAt: Date.now(),\n },\n });\n\n await this.registerTask(session.id, {\n threadId,\n taskNodeId:\n typeof latestSession?.metadata.taskNodeId === \"string\"\n ? latestSession.metadata.taskNodeId\n : undefined,\n agentType: resolvedFramework,\n label: latestSession?.label ?? thread.title,\n originalTask: instruction?.trim() || thread.originalRequest,\n workdir,\n repo: latestSession?.repo ?? thread.latestRepo ?? undefined,\n providerSource: resolvedAvailability\n ? inferProviderSource(resolvedAvailability)\n : null,\n metadata:\n session.metadata &&\n typeof session.metadata === \"object\" &&\n !Array.isArray(session.metadata)\n ? (session.metadata as Record<string, unknown>)\n : undefined,\n });\n\n const nowIso = new Date().toISOString();\n await this.taskRegistry.updateThread(threadId, {\n status: \"active\",\n closedAt: null,\n lastCoordinatorTurnAt: nowIso,\n metadata: {\n controlState: null,\n resumedAt: nowIso,\n lastResumedSessionId: session.id,\n },\n });\n await this.taskRegistry.appendEvent({\n threadId,\n sessionId: session.id,\n eventType: \"task_resumed\",\n summary: \"Resumed the task thread on a new session\",\n data: {\n reusedSession: false,\n fromSessionId: latestSession?.sessionId ?? null,\n toSessionId: session.id,\n instruction: instruction ?? null,\n framework: resolvedFramework,\n },\n });\n\n return {\n threadId,\n sessionId: session.id,\n reusedSession: false,\n framework: resolvedFramework,\n };\n }\n\n async continueTaskThread(\n threadId: string,\n instruction: string,\n agentType?: string,\n ): Promise<{\n threadId: string;\n sessionId: string;\n reusedSession: boolean;\n framework: CodingAgentType;\n }> {\n const latestLiveTask = this.getLiveTaskContextsForThread(threadId).find(\n (task) =>\n task.status === \"active\" ||\n task.status === \"blocked\" ||\n task.status === \"tool_running\",\n );\n if (latestLiveTask && this.ptyService) {\n await this.ptyService.sendToSession(\n latestLiveTask.sessionId,\n instruction,\n );\n latestLiveTask.lastInputSentAt = Date.now();\n latestLiveTask.status = \"active\";\n await this.syncTaskContext(latestLiveTask);\n const nowIso = new Date().toISOString();\n await this.taskRegistry.updateThread(threadId, {\n status: \"active\",\n closedAt: null,\n lastCoordinatorTurnAt: nowIso,\n metadata: {\n controlState: null,\n continuedAt: nowIso,\n },\n });\n await this.taskRegistry.appendEvent({\n threadId,\n sessionId: latestLiveTask.sessionId,\n eventType: \"task_resumed\",\n summary: \"Sent follow-up instructions to the active task thread\",\n data: {\n reusedSession: true,\n instruction,\n },\n });\n return {\n threadId,\n sessionId: latestLiveTask.sessionId,\n reusedSession: true,\n framework: latestLiveTask.agentType,\n };\n }\n return this.resumeTaskThread(threadId, instruction, agentType);\n }\n\n async syncTaskContext(taskCtx: TaskContext): Promise<void> {\n await this.taskRegistry.updateSession(taskCtx.sessionId, {\n status:\n taskCtx.status === \"completed\"\n ? \"completed\"\n : taskCtx.status === \"error\"\n ? \"error\"\n : taskCtx.status === \"stopped\"\n ? \"stopped\"\n : taskCtx.status === \"blocked\"\n ? \"blocked\"\n : taskCtx.status === \"tool_running\"\n ? \"tool_running\"\n : \"active\",\n decisionCount: taskCtx.decisions.length,\n autoResolvedCount: taskCtx.autoResolvedCount,\n lastActivityAt: taskCtx.lastActivityAt,\n idleCheckCount: taskCtx.idleCheckCount,\n taskDelivered: taskCtx.taskDelivered,\n completionSummary: taskCtx.completionSummary ?? null,\n lastSeenDecisionIndex: taskCtx.lastSeenDecisionIndex,\n lastInputSentAt: taskCtx.lastInputSentAt,\n stoppedAt: taskCtx.stoppedAt,\n metadata: {\n validationSummary: taskCtx.validationSummary ?? null,\n },\n });\n if (!taskCtx.taskNodeId) {\n return;\n }\n\n const nodeStatus = this.mapTaskContextStatusToNodeStatus(taskCtx.status);\n await this.taskRegistry.updateTaskNode(taskCtx.taskNodeId, {\n status: nodeStatus,\n title: taskCtx.label,\n instructions: taskCtx.originalTask,\n assignedSessionId: taskCtx.sessionId,\n assignedLabel: taskCtx.label,\n agentType: taskCtx.agentType,\n workdir: taskCtx.workdir,\n repo: taskCtx.repo ?? null,\n metadata: {\n completionSummary: taskCtx.completionSummary ?? null,\n validationSummary: taskCtx.validationSummary ?? null,\n },\n });\n\n const activeClaim = await this.taskRegistry.findActiveTaskClaim(\n taskCtx.taskNodeId,\n taskCtx.sessionId,\n );\n if (\n taskCtx.status === \"completed\" ||\n taskCtx.status === \"error\" ||\n taskCtx.status === \"stopped\"\n ) {\n if (activeClaim) {\n await this.taskRegistry.updateTaskClaim(activeClaim.id, {\n status:\n taskCtx.status === \"completed\"\n ? \"completed\"\n : taskCtx.status === \"error\"\n ? \"failed\"\n : \"interrupted\",\n releasedAt: new Date().toISOString(),\n metadata: {\n completionSummary: taskCtx.completionSummary ?? null,\n validationSummary: taskCtx.validationSummary ?? null,\n },\n });\n }\n return;\n }\n\n if (!activeClaim) {\n await this.taskRegistry.createTaskClaim({\n threadId: taskCtx.threadId,\n nodeId: taskCtx.taskNodeId,\n sessionId: taskCtx.sessionId,\n claimType: \"execution\",\n status: \"active\",\n metadata: {\n label: taskCtx.label,\n },\n });\n }\n }\n\n private isAutomaticFailoverFramework(\n agentType: CodingAgentType,\n ): agentType is SupportedTaskAgentAdapter {\n return (\n agentType === \"claude\" ||\n agentType === \"codex\" ||\n agentType === \"gemini\" ||\n agentType === \"aider\"\n );\n }\n\n private getFailoverCandidates(\n frameworks: TaskAgentFrameworkAvailability[],\n failedFramework: SupportedTaskAgentAdapter,\n preferredFrameworkId: TaskAgentFrameworkId,\n ): TaskAgentFrameworkAvailability[] {\n const preferred = frameworks.find(\n (framework) => framework.id === preferredFrameworkId,\n );\n const remainder = frameworks.filter(\n (framework) => framework.id !== preferredFrameworkId,\n );\n return [preferred, ...remainder].filter(\n (framework): framework is TaskAgentFrameworkAvailability =>\n Boolean(\n framework &&\n framework.id !== failedFramework &&\n framework.installed &&\n framework.authReady &&\n !framework.temporarilyDisabled,\n ),\n );\n }\n\n private getRecoveryCandidates(\n frameworks: TaskAgentFrameworkAvailability[],\n currentFramework: SupportedTaskAgentAdapter,\n preferredFrameworkId: TaskAgentFrameworkId,\n preferAlternative: boolean,\n ): TaskAgentFrameworkAvailability[] {\n const healthy = frameworks.filter(\n (framework) =>\n framework.installed &&\n framework.authReady &&\n !framework.temporarilyDisabled,\n );\n const byId = new Map(healthy.map((framework) => [framework.id, framework]));\n const orderedIds: TaskAgentFrameworkId[] = [];\n\n if (!preferAlternative) {\n orderedIds.push(currentFramework);\n }\n orderedIds.push(preferredFrameworkId);\n for (const framework of healthy) {\n orderedIds.push(framework.id);\n }\n\n const seen = new Set<TaskAgentFrameworkId>();\n const candidates: TaskAgentFrameworkAvailability[] = [];\n for (const id of orderedIds) {\n if (seen.has(id)) {\n continue;\n }\n seen.add(id);\n if (preferAlternative && id === currentFramework) {\n continue;\n }\n const framework = byId.get(id);\n if (framework) {\n candidates.push(framework);\n }\n }\n return candidates;\n }\n\n private shouldPreferAlternativeFrameworkForError(reason: string): boolean {\n return ALTERNATE_FRAMEWORK_ERROR_RE.test(reason);\n }\n\n private formatFailoverPrompt(\n taskCtx: TaskContext,\n failedFramework: SupportedTaskAgentAdapter,\n reason: string,\n recentOutput: string,\n ): string {\n const cleanedOutput = cleanForFailoverContext(\n recentOutput,\n taskCtx.workdir,\n );\n const trimmedOutput = cleanedOutput.trim();\n const clippedOutput =\n trimmedOutput.length > FAILOVER_OUTPUT_MAX_CHARS\n ? trimmedOutput.slice(-FAILOVER_OUTPUT_MAX_CHARS)\n : trimmedOutput;\n const recentDecisions = taskCtx.decisions\n .slice(-5)\n .map(\n (decision, index) =>\n `${index + 1}. ${decision.event}: ${decision.reasoning}${decision.response ? ` (response: ${decision.response})` : \"\"}`,\n )\n .join(\"\\n\");\n return [\n `Continue an in-progress task after the previous ${failedFramework} session became unavailable because of a quota or credit failure.`,\n \"\",\n \"Original task:\",\n taskCtx.originalTask,\n \"\",\n `Failure reason: ${reason}`,\n `Workspace: ${taskCtx.workdir}`,\n \"\",\n recentDecisions\n ? `Recent coordinator decisions:\\n${recentDecisions}\\n`\n : \"\",\n clippedOutput\n ? `Recent terminal output from the failed session:\\n${clippedOutput}\\n`\n : \"\",\n \"Use the existing workspace state instead of starting from scratch. Inspect the files, continue the task, run the needed validation, and then report what changed and how you verified it.\",\n ]\n .filter(Boolean)\n .join(\"\\n\");\n }\n\n private formatErrorRecoveryPrompt(\n taskCtx: TaskContext,\n recoveryFramework: CodingAgentType,\n reason: string,\n recentOutput: string,\n ): string {\n const cleanedOutput = cleanForFailoverContext(\n recentOutput,\n taskCtx.workdir,\n );\n const trimmedOutput = cleanedOutput.trim();\n const clippedOutput =\n trimmedOutput.length > FAILOVER_OUTPUT_MAX_CHARS\n ? trimmedOutput.slice(-FAILOVER_OUTPUT_MAX_CHARS)\n : trimmedOutput;\n const recentDecisions = taskCtx.decisions\n .slice(-5)\n .map(\n (decision, index) =>\n `${index + 1}. ${decision.event}: ${decision.reasoning}${decision.response ? ` (response: ${decision.response})` : \"\"}`,\n )\n .join(\"\\n\");\n const recoveryMode =\n recoveryFramework === taskCtx.agentType\n ? `a fresh ${recoveryFramework} session`\n : `a ${recoveryFramework} recovery session`;\n return [\n `Continue an in-progress task after the previous session terminated unexpectedly. Eliza started ${recoveryMode} for recovery.`,\n \"\",\n \"Original task:\",\n taskCtx.originalTask,\n \"\",\n `Failure reason: ${reason}`,\n `Workspace: ${taskCtx.workdir}`,\n \"\",\n recentDecisions\n ? `Recent coordinator decisions:\\n${recentDecisions}\\n`\n : \"\",\n clippedOutput\n ? `Recent terminal output from the failed session:\\n${clippedOutput}\\n`\n : \"\",\n \"Use the existing workspace state instead of starting over. Inspect the current files, recover from the failure, continue the task, run the needed validation, and then report exactly what changed and how you verified it.\",\n ]\n .filter(Boolean)\n .join(\"\\n\");\n }\n\n private async handleFrameworkDepletion(\n taskCtx: TaskContext,\n sessionId: string,\n reason: string,\n ): Promise<{\n replacementSessionId: string;\n replacementFramework: TaskAgentFrameworkId;\n replacementLabel: string;\n } | null> {\n if (\n !this.isAutomaticFailoverFramework(taskCtx.agentType) ||\n !isUsageExhaustedTaskAgentError(reason)\n ) {\n return null;\n }\n\n markTaskAgentFrameworkUnavailable(taskCtx.agentType, reason);\n await this.taskRegistry.appendEvent({\n threadId: taskCtx.threadId,\n sessionId,\n eventType: \"framework_unavailable\",\n summary: `${taskCtx.agentType} temporarily disabled after provider depletion`,\n data: {\n framework: taskCtx.agentType,\n reason,\n },\n });\n\n let failoverResult: {\n replacementSessionId: string;\n replacementFramework: TaskAgentFrameworkId;\n replacementLabel: string;\n } | null = null;\n try {\n failoverResult = await this.attemptTaskFailover(taskCtx, reason);\n } catch (failoverError) {\n this.log(\n `Automatic failover failed for \"${taskCtx.label}\": ${failoverError instanceof Error ? failoverError.message : String(failoverError)}`,\n );\n }\n\n if (failoverResult) {\n this.sendChatMessage(\n `\"${taskCtx.label}\" ran into a ${taskCtx.agentType} quota/credit failure. Eliza is continuing the same task on ${failoverResult.replacementFramework}.`,\n \"coding-agent\",\n );\n } else {\n this.sendChatMessage(\n `\"${taskCtx.label}\" ran into a ${taskCtx.agentType} quota/credit failure. Eliza will prefer another task-agent framework until ${taskCtx.agentType} is healthy again.`,\n \"coding-agent\",\n );\n }\n\n return failoverResult;\n }\n\n private async attemptTaskFailover(\n taskCtx: TaskContext,\n errorMsg: string,\n ): Promise<{\n replacementSessionId: string;\n replacementFramework: TaskAgentFrameworkId;\n replacementLabel: string;\n } | null> {\n if (\n !this.ptyService ||\n !this.isAutomaticFailoverFramework(taskCtx.agentType)\n ) {\n return null;\n }\n\n const frameworkState = await this.ptyService.getFrameworkState();\n const candidates = this.getFailoverCandidates(\n frameworkState.frameworks,\n taskCtx.agentType,\n frameworkState.preferred.id,\n );\n const nextFramework = candidates[0];\n if (!nextFramework) {\n return null;\n }\n\n const failedSession = this.ptyService.getSession(taskCtx.sessionId);\n const priorMetadata =\n failedSession?.metadata &&\n typeof failedSession.metadata === \"object\" &&\n !Array.isArray(failedSession.metadata)\n ? (failedSession.metadata as Record<string, unknown>)\n : {};\n const failoverOrdinal =\n typeof priorMetadata.failoverOrdinal === \"number\"\n ? priorMetadata.failoverOrdinal + 1\n : 1;\n const priorOutput = await Promise.race([\n this.ptyService.getSessionOutput(taskCtx.sessionId, 200),\n new Promise<string>((resolve) => setTimeout(() => resolve(\"\"), 5_000)),\n ]);\n const replacementLabel = `${taskCtx.label} (${nextFramework.id} failover ${failoverOrdinal})`;\n const replacementSession = await this.ptyService.spawnSession({\n name:\n failedSession?.name ??\n `task-failover-${Date.now()}-${nextFramework.id}`,\n agentType: nextFramework.id as CodingAgentType,\n workdir: taskCtx.workdir,\n initialTask: this.formatFailoverPrompt(\n taskCtx,\n taskCtx.agentType,\n errorMsg,\n priorOutput,\n ),\n approvalPreset: this.ptyService.defaultApprovalPreset,\n skipAdapterAutoResponse: true,\n metadata: {\n ...priorMetadata,\n threadId: taskCtx.threadId,\n requestedType: nextFramework.id,\n label: replacementLabel,\n failoverOrdinal,\n failoverFromFramework: taskCtx.agentType,\n failoverFromSessionId: taskCtx.sessionId,\n failoverReason: errorMsg,\n failoverAt: Date.now(),\n },\n });\n\n await this.registerTask(replacementSession.id, {\n threadId: taskCtx.threadId,\n taskNodeId: taskCtx.taskNodeId,\n agentType: nextFramework.id as CodingAgentType,\n label: replacementLabel,\n originalTask: taskCtx.originalTask,\n workdir: taskCtx.workdir,\n repo: taskCtx.repo,\n providerSource: inferProviderSource(nextFramework),\n metadata:\n replacementSession.metadata &&\n typeof replacementSession.metadata === \"object\" &&\n !Array.isArray(replacementSession.metadata)\n ? (replacementSession.metadata as Record<string, unknown>)\n : undefined,\n });\n\n await this.taskRegistry.appendEvent({\n threadId: taskCtx.threadId,\n sessionId: replacementSession.id,\n eventType: \"framework_failover_started\",\n summary: `Continuing \"${taskCtx.label}\" on ${nextFramework.label}`,\n data: {\n fromFramework: taskCtx.agentType,\n fromSessionId: taskCtx.sessionId,\n toFramework: nextFramework.id,\n toSessionId: replacementSession.id,\n reason: errorMsg,\n },\n });\n\n return {\n replacementSessionId: replacementSession.id,\n replacementFramework: nextFramework.id,\n replacementLabel,\n };\n }\n\n private async attemptTaskRecovery(\n taskCtx: TaskContext,\n errorMsg: string,\n ): Promise<{\n replacementSessionId: string;\n replacementFramework: CodingAgentType;\n replacementLabel: string;\n } | null> {\n if (!this.ptyService) {\n return null;\n }\n\n const failedSession = this.ptyService.getSession(taskCtx.sessionId);\n const priorMetadata =\n failedSession?.metadata &&\n typeof failedSession.metadata === \"object\" &&\n !Array.isArray(failedSession.metadata)\n ? (failedSession.metadata as Record<string, unknown>)\n : {};\n const recoveryOrdinal =\n typeof priorMetadata.recoveryOrdinal === \"number\"\n ? priorMetadata.recoveryOrdinal + 1\n : 1;\n if (recoveryOrdinal > MAX_AUTOMATIC_ERROR_RECOVERIES) {\n return null;\n }\n\n let recoveryFramework: CodingAgentType = taskCtx.agentType;\n let recoveryAvailability: TaskAgentFrameworkAvailability | null = null;\n if (this.isAutomaticFailoverFramework(taskCtx.agentType)) {\n const frameworkState = await this.ptyService.getFrameworkState();\n const candidates = this.getRecoveryCandidates(\n frameworkState.frameworks,\n taskCtx.agentType,\n frameworkState.preferred.id,\n this.shouldPreferAlternativeFrameworkForError(errorMsg),\n );\n const selected = candidates[0];\n if (!selected) {\n return null;\n }\n recoveryFramework = selected.id as CodingAgentType;\n recoveryAvailability = selected;\n }\n\n const priorOutput = await Promise.race([\n this.ptyService.getSessionOutput(taskCtx.sessionId, 200),\n new Promise<string>((resolve) => setTimeout(() => resolve(\"\"), 5_000)),\n ]);\n const replacementLabel = `${taskCtx.label} (${recoveryFramework} recovery ${recoveryOrdinal})`;\n const replacementSession = await this.ptyService.spawnSession({\n name:\n failedSession?.name ??\n `task-recovery-${Date.now()}-${recoveryFramework}`,\n agentType: recoveryFramework,\n workdir: taskCtx.workdir,\n initialTask: this.formatErrorRecoveryPrompt(\n taskCtx,\n recoveryFramework,\n errorMsg,\n priorOutput,\n ),\n credentials: buildAgentCredentials(this.runtime),\n approvalPreset: this.ptyService.defaultApprovalPreset,\n skipAdapterAutoResponse: true,\n metadata: {\n ...priorMetadata,\n threadId: taskCtx.threadId,\n requestedType: recoveryFramework,\n label: replacementLabel,\n recoveryOrdinal,\n recoveredFromFramework: taskCtx.agentType,\n recoveredFromSessionId: taskCtx.sessionId,\n recoveryReason: errorMsg,\n recoveryAt: Date.now(),\n },\n });\n\n await this.registerTask(replacementSession.id, {\n threadId: taskCtx.threadId,\n taskNodeId: taskCtx.taskNodeId,\n agentType: recoveryFramework,\n label: replacementLabel,\n originalTask: taskCtx.originalTask,\n workdir: taskCtx.workdir,\n repo: taskCtx.repo,\n providerSource: recoveryAvailability\n ? inferProviderSource(recoveryAvailability)\n : null,\n metadata:\n replacementSession.metadata &&\n typeof replacementSession.metadata === \"object\" &&\n !Array.isArray(replacementSession.metadata)\n ? (replacementSession.metadata as Record<string, unknown>)\n : undefined,\n });\n\n await this.taskRegistry.appendEvent({\n threadId: taskCtx.threadId,\n sessionId: replacementSession.id,\n eventType: \"task_error_recovery_started\",\n summary: `Continuing \"${taskCtx.label}\" after an agent error`,\n data: {\n fromFramework: taskCtx.agentType,\n fromSessionId: taskCtx.sessionId,\n toFramework: recoveryFramework,\n toSessionId: replacementSession.id,\n reason: errorMsg,\n recoveryOrdinal,\n },\n });\n\n this.broadcast({\n type: \"task_recovery_started\",\n sessionId: replacementSession.id,\n timestamp: Date.now(),\n data: {\n fromSessionId: taskCtx.sessionId,\n fromFramework: taskCtx.agentType,\n toFramework: recoveryFramework,\n reason: errorMsg,\n },\n });\n\n return {\n replacementSessionId: replacementSession.id,\n replacementFramework: recoveryFramework,\n replacementLabel,\n };\n }\n\n async resumeTaskAfterProviderAuth(\n sessionId: string,\n reason: string,\n ): Promise<{\n replacementSessionId: string;\n replacementFramework: CodingAgentType;\n replacementLabel: string;\n } | null> {\n const taskCtx = this.tasks.get(sessionId);\n if (!taskCtx) {\n return null;\n }\n if (\n taskCtx.status === \"completed\" ||\n taskCtx.status === \"error\" ||\n taskCtx.status === \"stopped\"\n ) {\n return null;\n }\n\n const replacement = await this.attemptTaskRecovery(taskCtx, reason);\n if (!replacement) {\n return null;\n }\n\n taskCtx.suppressStopNotice = true;\n taskCtx.status = \"stopped\";\n try {\n await this.ptyService?.stopSession(sessionId, true);\n } catch (error) {\n this.log(\n `Failed to stop superseded auth-blocked session ${sessionId}: ${\n error instanceof Error ? error.message : String(error)\n }`,\n );\n }\n\n // Successful auto-recovery is runtime-internal; synthesis reports\n // the final outcome. Chat only needs auth prompts the user has to\n // act on, not recovery commentary.\n return replacement;\n }\n\n async markTaskResumedAfterProviderAuth(sessionId: string): Promise<boolean> {\n const taskCtx = this.tasks.get(sessionId);\n if (!taskCtx) {\n return false;\n }\n if (\n taskCtx.status === \"completed\" ||\n taskCtx.status === \"error\" ||\n taskCtx.status === \"stopped\"\n ) {\n return false;\n }\n\n taskCtx.status = \"active\";\n taskCtx.stoppedAt = undefined;\n taskCtx.lastActivityAt = Date.now();\n taskCtx.idleCheckCount = 0;\n\n if (\n taskCtx.agentType === \"claude\" ||\n taskCtx.agentType === \"codex\" ||\n taskCtx.agentType === \"gemini\" ||\n taskCtx.agentType === \"aider\"\n ) {\n markTaskAgentFrameworkHealthy(taskCtx.agentType);\n }\n\n this.broadcast({\n type: \"ready\",\n sessionId,\n timestamp: Date.now(),\n data: {\n reason: \"provider_auth_recovered\",\n source: \"auth_recovery\",\n },\n });\n await this.taskRegistry.appendEvent({\n threadId: taskCtx.threadId,\n sessionId,\n eventType: \"task_status_changed\",\n summary: `Task \"${taskCtx.label}\" resumed after provider authentication`,\n data: {\n status: \"active\",\n reason: \"provider_auth_recovered\",\n },\n });\n // Token refresh is invisible plumbing, no chat message needed.\n return true;\n }\n\n async recordDecision(\n taskCtx: TaskContext,\n decision: CoordinationDecision,\n ): Promise<void> {\n taskCtx.decisions.push(decision);\n await this.taskRegistry.recordDecision({\n threadId: taskCtx.threadId,\n sessionId: taskCtx.sessionId,\n timestamp: decision.timestamp,\n event: decision.event,\n promptText: decision.promptText,\n decision: decision.decision,\n response: decision.response,\n reasoning: decision.reasoning,\n });\n await this.syncTaskContext(taskCtx);\n }\n\n async setTaskDelivered(sessionId: string): Promise<void> {\n const taskCtx = this.tasks.get(sessionId);\n if (!taskCtx) return;\n taskCtx.taskDelivered = true;\n await this.syncTaskContext(taskCtx);\n }\n\n // ─── Unregistered Buffer Retry ───\n\n /**\n * Schedule a retry check for buffered events from an unregistered session.\n * Uses exponential backoff: 2s → 4s → 8s → 16s, max 30s total.\n */\n private scheduleUnregisteredRetry(sessionId: string, attempt: number): void {\n const delay =\n UNREGISTERED_RETRY_DELAYS[\n Math.min(attempt, UNREGISTERED_RETRY_DELAYS.length - 1)\n ];\n\n const timer = setTimeout(() => {\n this.unregisteredRetryTimers.delete(sessionId);\n const stillBuffered = this.unregisteredBuffer.get(sessionId);\n if (!stillBuffered || stillBuffered.length === 0) return;\n\n const ctx = this.tasks.get(sessionId);\n if (ctx) {\n // Task was registered, flush\n this.unregisteredBuffer.delete(sessionId);\n for (const entry of stillBuffered) {\n this.handleNormalizedSessionEvent(entry.normalized).catch((err) => {\n this.log(\n `Failed to replay buffered event for ${sessionId}: ${err}`,\n );\n });\n }\n return;\n }\n\n // Check if we've exceeded the absolute max wait\n const oldest = stillBuffered[0].receivedAt;\n const totalElapsed = Date.now() - oldest;\n if (totalElapsed >= UNREGISTERED_MAX_TOTAL_MS) {\n this.unregisteredBuffer.delete(sessionId);\n this.log(\n `Discarding ${stillBuffered.length} buffered events for unregistered session ${sessionId} after ${Math.round(totalElapsed / 1000)}s`,\n );\n return;\n }\n\n // Schedule next retry\n this.log(\n `Retry ${attempt + 1} for unregistered session ${sessionId} (next in ${delay}ms)`,\n );\n this.scheduleUnregisteredRetry(sessionId, attempt + 1);\n }, delay);\n\n this.unregisteredRetryTimers.set(sessionId, timer);\n }\n\n // ─── SSE Client Management ───\n\n /**\n * Register an SSE client. Returns an unsubscribe function.\n * Sends a snapshot of current state on connect.\n */\n addSseClient(res: ServerResponse): () => void {\n this.sseClients.add(res);\n\n // Send snapshot on connect\n const snapshot: SwarmEvent = {\n type: \"snapshot\",\n sessionId: \"*\",\n timestamp: Date.now(),\n data: {\n tasks: this.getAllTaskContexts(),\n supervisionLevel: this.supervisionLevel,\n pendingCount: this.pendingDecisions.size,\n },\n };\n this.writeSseEvent(res, snapshot);\n\n // Remove on close\n const cleanup = () => {\n this.sseClients.delete(res);\n };\n res.on(\"close\", cleanup);\n\n return cleanup;\n }\n\n broadcast(event: SwarmEvent): void {\n const dead: ServerResponse[] = [];\n for (const client of this.sseClients) {\n if (client.writableEnded) {\n dead.push(client);\n continue;\n }\n this.writeSseEvent(client, event);\n }\n // Cleanup dead connections\n for (const d of dead) {\n this.sseClients.delete(d);\n }\n // Relay to WebSocket clients, buffer if bridge isn't wired yet\n if (this.wsBroadcast) {\n this.wsBroadcast(event);\n } else if (this.preBridgeBroadcastBuffer.length < MAX_PRE_BRIDGE_BUFFER) {\n this.preBridgeBroadcastBuffer.push(event);\n }\n // In-process listeners. Each runs in its own try so one listener cannot\n // break delivery for the next.\n for (const listener of this.eventListeners) {\n try {\n listener(event);\n } catch (err) {\n this.log(\n `Swarm event listener threw: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n }\n }\n\n /** @see SwarmCoordinatorContext.subscribe */\n subscribe(listener: SwarmEventListener): () => void {\n this.eventListeners.add(listener);\n return () => {\n this.eventListeners.delete(listener);\n };\n }\n\n private writeSseEvent(res: ServerResponse, event: SwarmEvent): void {\n try {\n res.write(`data: ${JSON.stringify(event)}\\n\\n`);\n } catch {\n // Connection may have closed\n }\n }\n\n // ─── Event Handling ───\n\n async handleSessionEvent(\n sessionId: string,\n event: string,\n data: unknown,\n ): Promise<void> {\n const normalized = normalizeCoordinatorEvent(sessionId, event, data);\n if (!normalized) {\n this.broadcast({\n type: event,\n sessionId,\n timestamp: Date.now(),\n data,\n });\n return;\n }\n await this.handleNormalizedSessionEvent(normalized);\n }\n\n private async handleNormalizedSessionEvent(\n normalized: CoordinatorNormalizedEvent,\n ): Promise<void> {\n const sessionId = normalized.sessionId;\n const event = normalized.name;\n const data = normalized.rawData;\n // Lazy-wire scratch decision callback if not yet connected\n if (!this.scratchDecisionWired) {\n this.wireScratchDecisionCallback();\n }\n\n // Ignore events from sessions created before this coordinator started.\n // Session IDs are formatted as \"pty-{timestamp}-{hex}\" — extract the timestamp.\n // Some events may arrive without a sessionId (worker-level errors, etc.) — bail.\n if (typeof sessionId !== \"string\" || sessionId.length === 0) return;\n const tsMatch = sessionId.match(/^pty-(\\d+)-/);\n if (tsMatch) {\n const sessionCreatedAt = Number(tsMatch[1]);\n if (sessionCreatedAt < this.startedAt - 60_000) {\n // Session is from before this coordinator's lifetime (with 1min grace)\n return;\n }\n }\n\n const taskCtx = this.tasks.get(sessionId);\n\n // Buffer events for unregistered sessions with exponential backoff retry.\n // Events arriving before registerTask() are buffered and retried at\n // 2s → 4s → 8s → 16s intervals (max 30s total) before being discarded.\n if (!taskCtx) {\n if (\n event === \"blocked\" ||\n event === \"task_complete\" ||\n event === \"error\"\n ) {\n let buffer = this.unregisteredBuffer.get(sessionId);\n if (!buffer) {\n buffer = [];\n this.unregisteredBuffer.set(sessionId, buffer);\n }\n buffer.push({ normalized, receivedAt: Date.now() });\n\n // Only schedule retry if not already retrying for this session\n if (!this.unregisteredRetryTimers.has(sessionId)) {\n this.scheduleUnregisteredRetry(sessionId, 0);\n }\n }\n return;\n }\n\n // Skip decision-making events for terminal states, but always allow\n // \"stopped\" and \"error\" through: they're definitive lifecycle signals\n // that the frontend needs to close consoles and clean up.\n // Exception: allow a late \"task_complete\" to recover a recently-stopped task.\n let recoveredFromStopped = false;\n if (\n taskCtx.status === \"stopped\" ||\n taskCtx.status === \"error\" ||\n taskCtx.status === \"completed\"\n ) {\n if (taskCtx.status === \"stopped\" && event === \"task_complete\") {\n const stoppedAt = taskCtx.stoppedAt ?? 0;\n const ageMs = Date.now() - stoppedAt;\n if (stoppedAt > 0 && ageMs <= STOPPED_RECOVERY_WINDOW_MS) {\n this.log(\n `Recovering \"${taskCtx.label}\" from stopped on late task_complete (${Math.round(ageMs / 1000)}s old)`,\n );\n taskCtx.status = \"active\";\n taskCtx.stoppedAt = undefined;\n recoveredFromStopped = true;\n } else {\n this.log(\n `Ignoring \"${event}\" for ${taskCtx.label} (status: stopped, age=${Math.round(ageMs / 1000)}s)`,\n );\n return;\n }\n }\n if (!recoveredFromStopped && event !== \"stopped\" && event !== \"error\") {\n this.log(\n `Ignoring \"${event}\" for ${taskCtx.label} (status: ${taskCtx.status})`,\n );\n return;\n }\n }\n\n // Update activity timestamp: resets idle watchdog for this session.\n // This runs before buffering so buffered events still reset the idle timer.\n taskCtx.lastActivityAt = Date.now();\n taskCtx.idleCheckCount = 0;\n\n // Buffer decision-making events when paused (user sent a chat message).\n // Auto-responses still flow through handleBlocked. Only LLM decisions are deferred.\n if (this._paused && (event === \"blocked\" || event === \"task_complete\")) {\n // Auto-responded blocked events don't need LLM, let them through\n const blockedAutoResponded =\n event === \"blocked\" &&\n (normalized as CoordinatorBlockedEvent).autoResponded === true;\n if (!blockedAutoResponded) {\n // Broadcast buffered state for dashboard visibility\n this.broadcast({\n type:\n event === \"blocked\" ? \"blocked_buffered\" : \"turn_complete_buffered\",\n sessionId,\n timestamp: Date.now(),\n data,\n });\n this.pauseBuffer.push(normalized);\n this.log(\n `Buffered \"${event}\" for ${taskCtx.label} (coordinator paused)`,\n );\n return;\n }\n // Auto-responded: fall through to normal handling below\n }\n\n // Route by event type\n switch (event) {\n case \"blocked\": {\n const blockedEvent = normalized as CoordinatorBlockedEvent;\n const blockedPrompt = blockedEvent.promptText;\n if (\n this.isAutomaticFailoverFramework(taskCtx.agentType) &&\n isUsageExhaustedTaskAgentError(blockedPrompt)\n ) {\n const failoverResult = await this.handleFrameworkDepletion(\n taskCtx,\n sessionId,\n blockedPrompt,\n );\n taskCtx.status = \"error\";\n taskCtx.stoppedAt = Date.now();\n this.broadcast({\n type: \"error\",\n sessionId,\n timestamp: Date.now(),\n data: {\n message: blockedPrompt,\n source: \"blocked_prompt\",\n },\n });\n await this.taskRegistry.appendEvent({\n threadId: taskCtx.threadId,\n sessionId,\n eventType: \"task_status_changed\",\n summary: `Task \"${taskCtx.label}\" errored`,\n data: {\n status: \"error\",\n message: blockedPrompt,\n source: \"blocked_prompt\",\n },\n });\n this.ptyService?.stopSession(sessionId, true).catch((err) => {\n this.log(\n `Failed to stop exhausted session \"${taskCtx.label}\": ${err}`,\n );\n });\n if (!failoverResult) {\n checkAllTasksComplete(this);\n }\n break;\n }\n await handleBlocked(this, sessionId, taskCtx, data);\n break;\n }\n\n case \"task_complete\": {\n // Cancel the PTY auto-stop scheduled by pty-service.handleHookEvent\n // so the assessment LLM call (debounced + executed below) doesn't\n // race the 5s grace timer. Without this, the PTY is killed mid-\n // assessment and follow-up \"respond\" decisions hit a dead session.\n // executeDecision (case \"complete\") will explicitly stopSession with\n // force=true when the coordinator decides the agent is done.\n this.ptyService?.cancelTaskCompleteAutoStop?.(sessionId);\n\n // Broadcast immediately for UI visibility, but coalesce the\n // expensive LLM assessment: rapid turn-complete events within\n // 500ms are debounced so only the last one triggers an LLM call.\n this.broadcast({\n type: \"turn_complete\",\n sessionId,\n timestamp: Date.now(),\n data,\n });\n\n const existingCoalesce = this.turnCompleteCoalesceTimers.get(sessionId);\n if (existingCoalesce) clearTimeout(existingCoalesce);\n\n const coalescedData = data;\n const coalesceTimer = setTimeout(() => {\n this.turnCompleteCoalesceTimers.delete(sessionId);\n const currentTask = this.tasks.get(sessionId);\n if (\n currentTask?.completionSummary &&\n !this.ptyService?.getSession(sessionId)\n ) {\n currentTask.status = \"completed\";\n this.log(\n `Skipping coalesced turn-complete for \"${currentTask.label}\": PTY is gone after captured completion`,\n );\n void this.syncTaskContext(currentTask)\n .catch((err) => {\n this.log(\n `Failed to sync completed task after coalesced turn-complete: ${err}`,\n );\n })\n .then(() => checkAllTasksComplete(this))\n .catch((err) => {\n this.log(\n `Failed to finish swarm after coalesced completion: ${err}`,\n );\n });\n return;\n }\n // Accept both \"active\" and \"tool_running\" as live pre-validation\n // states. Subagents that use tools (curl, file ops, etc.) sit in\n // \"tool_running\" almost continuously, so by the time task_complete\n // arrives the status is usually \"tool_running\"; the prior strict\n // \"=== active\" check meant validation never ran for tool-heavy\n // scratch tasks, leaving them stuck and propagating goal failure\n // through the watchdog.\n if (\n currentTask &&\n (currentTask.status === \"active\" ||\n currentTask.status === \"tool_running\")\n ) {\n handleTurnComplete(\n this,\n sessionId,\n currentTask,\n coalescedData,\n ).catch((err) => {\n this.log(`Coalesced turn-complete failed: ${err}`);\n });\n }\n }, TURN_COMPLETE_COALESCE_MS);\n this.turnCompleteCoalesceTimers.set(sessionId, coalesceTimer);\n break;\n }\n\n case \"error\": {\n this.broadcast({\n type: \"error\",\n sessionId,\n timestamp: Date.now(),\n data,\n });\n\n // Send error message to chat UI\n const errorMsg =\n (data as { message?: string }).message ?? \"unknown error\";\n const failoverResult = await this.handleFrameworkDepletion(\n taskCtx,\n sessionId,\n errorMsg,\n );\n let recoveryResult: Awaited<\n ReturnType<typeof this.attemptTaskRecovery>\n > = null;\n if (!failoverResult) {\n try {\n recoveryResult = await this.attemptTaskRecovery(taskCtx, errorMsg);\n } catch (recoveryError) {\n this.log(\n `Automatic error recovery failed for \"${taskCtx.label}\": ${recoveryError instanceof Error ? recoveryError.message : String(recoveryError)}`,\n );\n }\n }\n if (recoveryResult) {\n // Auto-recovery succeeded: stay quiet; synthesis will report.\n } else if (!failoverResult) {\n this.sendChatMessage(\n `\"${taskCtx.label}\" hit an error and needs your attention: ${errorMsg}`,\n \"coding-agent\",\n );\n }\n taskCtx.status = \"error\";\n await this.taskRegistry.appendEvent({\n threadId: taskCtx.threadId,\n sessionId,\n eventType: \"task_status_changed\",\n summary: `Task \"${taskCtx.label}\" errored`,\n data: { status: \"error\", message: errorMsg },\n });\n if (!failoverResult && !recoveryResult) {\n checkAllTasksComplete(this);\n }\n break;\n }\n\n case \"stopped\": {\n if (\n shouldIgnoreStoppedEventDuringCompletion({\n task: taskCtx,\n hasInFlightDecision: this.inFlightDecisions.has(sessionId),\n hasPendingTurnComplete: this.pendingTurnComplete.has(sessionId),\n })\n ) {\n this.log(\n `Ignoring stopped event for ${taskCtx.label}; completion is already being finalized`,\n );\n break;\n }\n // Don't downgrade \"completed\" or \"error\" to \"stopped\": the async\n // stopSession fires after executeDecision already marked the task.\n if (taskCtx.status !== \"completed\" && taskCtx.status !== \"error\") {\n taskCtx.status = \"stopped\";\n taskCtx.stoppedAt = Date.now();\n }\n this.inFlightDecisions.delete(sessionId);\n this.broadcast({\n type: \"stopped\",\n sessionId,\n timestamp: Date.now(),\n data,\n });\n await this.taskRegistry.appendEvent({\n threadId: taskCtx.threadId,\n sessionId,\n eventType: \"task_status_changed\",\n summary: `Task \"${taskCtx.label}\" stopped`,\n data: { status: taskCtx.status },\n });\n // \"Stopped before completion\" is redundant with the synthesis\n // path, which reports the actual state on terminal events.\n checkAllTasksComplete(this);\n break;\n }\n\n case \"ready\":\n taskCtx.status = \"active\";\n if (\n taskCtx.agentType === \"claude\" ||\n taskCtx.agentType === \"codex\" ||\n taskCtx.agentType === \"gemini\" ||\n taskCtx.agentType === \"aider\"\n ) {\n markTaskAgentFrameworkHealthy(taskCtx.agentType);\n }\n this.broadcast({\n type: \"ready\",\n sessionId,\n timestamp: Date.now(),\n data,\n });\n await this.taskRegistry.appendEvent({\n threadId: taskCtx.threadId,\n sessionId,\n eventType: \"session_updated\",\n summary: `Session \"${taskCtx.label}\" ready`,\n data: { status: \"ready\" },\n });\n break;\n\n case \"login_required\": {\n const loginEvent = normalized as CoordinatorLoginRequiredEvent;\n let recoveryResult:\n | (TaskAgentAuthLaunchResult & {\n recoveryStarted: boolean;\n status: \"recovered\" | \"recovering\" | \"failed\";\n })\n | null = null;\n try {\n if (\n this.ptyService &&\n (taskCtx.agentType === \"claude\" ||\n taskCtx.agentType === \"codex\" ||\n taskCtx.agentType === \"gemini\" ||\n taskCtx.agentType === \"aider\")\n ) {\n recoveryResult = await this.ptyService.startSessionAuthRecovery(\n sessionId,\n taskCtx.agentType,\n {\n instructions: loginEvent.instructions,\n url: loginEvent.url,\n deviceCode: loginEvent.deviceCode,\n method: loginEvent.method,\n promptSnippet: loginEvent.promptSnippet,\n },\n );\n }\n } catch (error) {\n this.log(\n `Provider auth recovery failed for \"${taskCtx.label}\": ${\n error instanceof Error ? error.message : String(error)\n }`,\n );\n }\n\n if (recoveryResult?.status === \"recovered\") {\n if (recoveryResult.recoveryTarget === \"replacement_session\") {\n break;\n }\n await this.markTaskResumedAfterProviderAuth(sessionId);\n break;\n }\n\n taskCtx.status = \"blocked\";\n this.broadcast({\n type: \"login_required\",\n sessionId,\n timestamp: Date.now(),\n data,\n });\n await this.taskRegistry.appendEvent({\n threadId: taskCtx.threadId,\n sessionId,\n eventType: \"task_status_changed\",\n summary: `Task \"${taskCtx.label}\" is waiting for login`,\n data: {\n status: \"blocked\",\n reason: \"login_required\",\n instructions: loginEvent.instructions ?? null,\n url: loginEvent.url ?? null,\n deviceCode: loginEvent.deviceCode ?? null,\n method: loginEvent.method ?? null,\n recoveryStatus: recoveryResult?.status ?? null,\n },\n });\n const loginParts = [\n recoveryResult?.status === \"recovering\"\n ? `\"${taskCtx.label}\" needs provider authentication, and Eliza has started the recovery flow. It will continue automatically when sign-in completes.`\n : `\"${taskCtx.label}\" needs a provider login before it can continue.`,\n recoveryResult?.instructions?.trim() ||\n loginEvent.instructions?.trim() ||\n \"\",\n recoveryResult?.deviceCode || loginEvent.deviceCode\n ? `Device code: ${\n recoveryResult?.deviceCode ?? loginEvent.deviceCode\n }`\n : \"\",\n recoveryResult?.browserDetail || \"\",\n loginEvent.url ? `Login link: ${loginEvent.url}` : \"\",\n recoveryResult?.url && recoveryResult.url !== loginEvent.url\n ? `Login link: ${recoveryResult.url}`\n : \"\",\n ].filter(Boolean);\n this.sendChatMessage(loginParts.join(\" \"), \"coding-agent\");\n break;\n }\n\n case \"tool_running\": {\n // Agent is actively working via an external tool, keep watchdog happy\n taskCtx.status = \"tool_running\";\n taskCtx.lastActivityAt = Date.now();\n taskCtx.idleCheckCount = 0;\n\n this.broadcast({\n type: \"tool_running\",\n sessionId,\n timestamp: Date.now(),\n data,\n });\n\n // Hook-sourced tool_running events fire for every tool call.\n // Only broadcast to SSE (for activity box), skip chat messages.\n const toolData = data as {\n toolName?: string;\n description?: string;\n source?: string;\n };\n if (toolData.source === \"hook\") {\n break;\n }\n\n // Throttle chat notifications: at most one per 30s per session.\n // Suppress during the first 10s after registration: startup status\n // lines (e.g. \"Claude in Chrome enabled\") can trigger tool_running\n // before the agent has actually begun working.\n const now = Date.now();\n const STARTUP_GRACE_MS = 10_000;\n if (now - taskCtx.registeredAt < STARTUP_GRACE_MS) {\n break;\n }\n const lastNotif = this.lastToolNotification.get(sessionId) ?? 0;\n if (now - lastNotif > 30_000) {\n this.lastToolNotification.set(sessionId, now);\n const toolDesc =\n toolData.description ?? toolData.toolName ?? \"an external tool\";\n\n // Try to extract a dev server URL from recent output\n let urlSuffix = \"\";\n if (this.ptyService) {\n try {\n const recentOutput = await this.ptyService.getSessionOutput(\n sessionId,\n 50,\n );\n const devUrl = extractDevServerUrl(recentOutput);\n if (devUrl) {\n urlSuffix = ` Dev server running at ${devUrl}`;\n }\n } catch {\n // Best-effort, don't block on failure\n }\n }\n\n const message = `[${taskCtx.label}] Running ${toolDesc}.${urlSuffix} The agent is working outside the terminal.`;\n this.log(message);\n // Tool-running progress is broadcast to the web UI above; chat\n // stays quiet (synthesis delivers the final result).\n }\n break;\n }\n\n default:\n // Broadcast unknown events for observability\n this.broadcast({\n type: event,\n sessionId,\n timestamp: Date.now(),\n data,\n });\n }\n await this.syncTaskContext(taskCtx);\n }\n\n // ─── LLM Decision (delegated) ───\n\n async makeCoordinationDecision(\n taskCtx: TaskContext,\n promptText: string,\n recentOutput: string,\n ): Promise<CoordinationLLMResponse | null> {\n // Keep this method on the coordinator while the implementation lives in\n // the decision-loop module.\n const { makeCoordinationDecision: mkDecision } = await import(\n \"./swarm-decision-loop.js\"\n );\n return mkDecision(this, taskCtx, promptText, recentOutput);\n }\n\n async executeDecision(\n sessionId: string,\n decision: CoordinationLLMResponse,\n ): Promise<void> {\n return execDecision(this, sessionId, decision);\n }\n\n /**\n * Public entry point for external callers (e.g. server.ts) to execute\n * a coordination decision on a session. Wraps the internal executeDecision.\n */\n async executeEventDecision(\n sessionId: string,\n decision: CoordinationLLMResponse,\n ): Promise<void> {\n return execDecision(this, sessionId, decision);\n }\n\n // ─── Supervision ───\n\n setSupervisionLevel(level: SupervisionLevel): void {\n this.supervisionLevel = level;\n this.broadcast({\n type: \"supervision_changed\",\n sessionId: \"*\",\n timestamp: Date.now(),\n data: { level },\n });\n this.log(`Supervision level set to: ${level}`);\n }\n\n getSupervisionLevel(): SupervisionLevel {\n return this.supervisionLevel;\n }\n\n // ─── Confirmation Queue ───\n\n getPendingConfirmations(): PendingDecision[] {\n return Array.from(this.pendingDecisions.values());\n }\n\n async confirmDecision(\n sessionId: string,\n approved: boolean,\n override?: { response?: string; useKeys?: boolean; keys?: string[] },\n ): Promise<void> {\n const pending = this.pendingDecisions.get(sessionId);\n if (!pending) {\n throw new Error(`No pending decision for session ${sessionId}`);\n }\n\n const taskCtx = this.tasks.get(sessionId);\n\n if (approved) {\n // Use override if provided, otherwise use LLM suggestion\n const decision: CoordinationLLMResponse = override\n ? {\n action: \"respond\",\n response: override.response,\n useKeys: override.useKeys,\n keys: override.keys,\n reasoning: \"Human-approved (with override)\",\n }\n : pending.llmDecision;\n\n if (taskCtx) {\n taskCtx.status = \"active\";\n taskCtx.autoResolvedCount = 0;\n await this.recordDecision(taskCtx, {\n timestamp: Date.now(),\n event: \"blocked\",\n promptText: pending.promptText,\n decision: decision.action,\n response:\n decision.action === \"respond\"\n ? decision.useKeys\n ? `keys:${decision.keys?.join(\",\")}`\n : decision.response\n : undefined,\n reasoning: `Human-approved: ${decision.reasoning}`,\n });\n await this.syncTaskContext(taskCtx);\n }\n\n await this.executeDecision(sessionId, decision);\n this.pendingDecisions.delete(sessionId);\n await this.taskRegistry.deletePendingDecision(sessionId);\n if (taskCtx) {\n await this.taskRegistry.appendEvent({\n threadId: taskCtx.threadId,\n sessionId,\n eventType: \"confirmation_approved\",\n summary: `Approved pending confirmation for \"${taskCtx.label}\"`,\n data: {\n action: decision.action,\n response: decision.response ?? null,\n },\n });\n }\n\n this.broadcast({\n type: \"confirmation_approved\",\n sessionId,\n timestamp: Date.now(),\n data: {\n action: decision.action,\n response: decision.response,\n useKeys: decision.useKeys,\n keys: decision.keys,\n },\n });\n if (taskCtx) {\n this.sendChatMessage(\n `\"${taskCtx.label}\" was approved. Eliza is continuing the task now.`,\n \"coding-agent\",\n );\n }\n } else {\n // Rejected: record and broadcast\n if (taskCtx) {\n taskCtx.status = \"blocked\";\n await this.recordDecision(taskCtx, {\n timestamp: Date.now(),\n event: \"blocked\",\n promptText: pending.promptText,\n decision: \"escalate\",\n reasoning: \"Human rejected the suggested action\",\n });\n await this.syncTaskContext(taskCtx);\n }\n this.pendingDecisions.delete(sessionId);\n await this.taskRegistry.deletePendingDecision(sessionId);\n if (pending.taskContext.threadId) {\n await this.taskRegistry.appendEvent({\n threadId: pending.taskContext.threadId,\n sessionId,\n eventType: \"confirmation_rejected\",\n summary: `Rejected pending confirmation for \"${pending.taskContext.label}\"`,\n data: { prompt: pending.promptText },\n });\n }\n\n this.broadcast({\n type: \"confirmation_rejected\",\n sessionId,\n timestamp: Date.now(),\n data: { prompt: pending.promptText },\n });\n this.sendChatMessage(\n `\"${pending.taskContext.label}\" remains blocked after the suggested action was rejected. Prompt: ${pending.promptText}`,\n \"coding-agent\",\n );\n }\n }\n\n // ─── Internal ───\n\n log(message: string): void {\n logger.info(`[SwarmCoordinator] ${message}`);\n }\n}\n",
|
|
36
|
+
"import {\n type ChildProcessByStdio,\n execFile as execFileCallback,\n spawn as spawnChildProcess,\n} from \"node:child_process\";\nimport type { Readable } from \"node:stream\";\nimport type { IAgentRuntime } from \"@elizaos/core\";\nimport type { PreflightResult } from \"coding-agent-adapters\";\nimport { readConfigCloudKey, readConfigEnvKey } from \"./config-env.js\";\nimport type { SupportedTaskAgentAdapter } from \"./task-agent-frameworks.js\";\n\nexport type TaskAgentAuthStatusValue =\n | \"authenticated\"\n | \"auth_error\"\n | \"unauthenticated\"\n | \"unknown\";\n\nexport interface TaskAgentAuthStatus {\n status: TaskAgentAuthStatusValue;\n method?: string;\n detail?: string;\n loginHint?: string;\n}\n\nexport interface TaskAgentAuthLaunchResult {\n launched: boolean;\n url?: string;\n deviceCode?: string;\n instructions?: string;\n browserOpened?: boolean;\n browserClicked?: boolean;\n browserDetail?: string;\n recoveryTarget?: \"same_session\" | \"replacement_session\";\n replacementSessionId?: string;\n replacementFramework?: string;\n}\n\nexport interface TaskAgentAuthFlowHandle {\n agentType: SupportedTaskAgentAdapter;\n startedAt: number;\n completion: Promise<{ code: number | null; signal: NodeJS.Signals | null }>;\n snapshot: () => TaskAgentAuthLaunchResult;\n stop: () => void;\n}\n\nfunction toPreflightAuthStatus(\n auth: TaskAgentAuthStatus,\n): PreflightResult[\"auth\"] {\n return {\n status: auth.status === \"auth_error\" ? \"unauthenticated\" : auth.status,\n method: auth.method,\n detail: auth.detail,\n loginHint: auth.loginHint,\n };\n}\n\ntype ExecFileFn = (\n file: string,\n args: string[],\n options?: {\n encoding?: BufferEncoding;\n env?: NodeJS.ProcessEnv;\n timeout?: number;\n },\n) => Promise<{ stdout: string; stderr: string }>;\n\ntype SpawnFn = typeof spawnChildProcess;\n\ntype FetchFn = typeof fetch;\n\ninterface TaskAgentAuthDeps {\n execFile: ExecFileFn;\n fetch: FetchFn;\n spawn: SpawnFn;\n}\n\ninterface TaskAgentAuthOptions {\n deps?: Partial<TaskAgentAuthDeps>;\n env?: NodeJS.ProcessEnv;\n runtime?: IAgentRuntime;\n}\n\nconst DEFAULT_TRUSTED_AUTH_HOSTS = new Set([\n \"claude.ai\",\n \"claude.com\",\n \"auth.openai.com\",\n \"chatgpt.com\",\n \"openai.com\",\n \"127.0.0.1\",\n \"localhost\",\n]);\n\nconst DEFAULT_INITIAL_AUTH_WAIT_MS = 2_000;\nconst DEFAULT_COMMAND_TIMEOUT_MS = 5_000;\nconst DEFAULT_BROWSER_ASSIST_TIMEOUT_MS = 750;\nconst CLAUDE_NON_INTERACTIVE_AUTH_FAILURE_RE =\n /\\b401\\b|\\binvalid authentication credentials\\b|\\bauthentication_error\\b|\\bfailed to authenticate\\b/i;\n\nconst DEFAULT_BROWSER_CLICK_SELECTORS: Record<\n SupportedTaskAgentAdapter,\n string[]\n> = {\n claude: [\n 'role=button[name=\"Continue\"]',\n 'role=button[name=\"Sign in\"]',\n 'role=button[name=\"Log in\"]',\n 'role=button[name=\"Authorize\"]',\n 'role=button[name=\"Allow\"]',\n 'button[type=\"submit\"]',\n ],\n codex: [\n 'role=button[name=\"Continue\"]',\n 'role=button[name=\"Sign in\"]',\n 'role=button[name=\"Log in\"]',\n 'role=button[name=\"Authorize\"]',\n 'role=button[name=\"Allow\"]',\n 'button[type=\"submit\"]',\n ],\n gemini: ['role=button[name=\"Continue\"]', 'button[type=\"submit\"]'],\n aider: ['role=button[name=\"Continue\"]', 'button[type=\"submit\"]'],\n};\n\nfunction parseTaskAgentAuthStringList(value: unknown): string[] {\n if (Array.isArray(value)) {\n return value\n .map((entry) => (typeof entry === \"string\" ? entry.trim() : \"\"))\n .filter(Boolean);\n }\n if (typeof value !== \"string\") {\n return [];\n }\n const trimmed = value.trim();\n if (!trimmed) {\n return [];\n }\n try {\n const parsed = JSON.parse(trimmed) as unknown;\n if (Array.isArray(parsed)) {\n return parsed\n .map((entry) => (typeof entry === \"string\" ? entry.trim() : \"\"))\n .filter(Boolean);\n }\n } catch {\n // Fall back to comma/newline-delimited values.\n }\n return trimmed\n .split(/[,\\n]/)\n .map((entry) => entry.trim())\n .filter(Boolean);\n}\n\nfunction defaultExecFile(\n file: string,\n args: string[],\n options?: {\n encoding?: BufferEncoding;\n env?: NodeJS.ProcessEnv;\n timeout?: number;\n },\n): Promise<{ stdout: string; stderr: string }> {\n return new Promise((resolve, reject) => {\n execFileCallback(\n file,\n args,\n {\n encoding: options?.encoding ?? \"utf8\",\n env: options?.env,\n timeout: options?.timeout,\n // On Windows, execFile uses libuv uv_spawn which does not apply PATHEXT\n // extension resolution — so bare names like \"claude\" fail to find \"claude.cmd\".\n // shell:true routes through cmd.exe which handles PATHEXT correctly.\n shell: process.platform === \"win32\",\n },\n (error, stdout, stderr) => {\n if (error) {\n const wrapped = new Error(\n stderr?.trim() || stdout?.trim() || error.message,\n ) as Error & { stdout?: string; stderr?: string; cause?: unknown };\n wrapped.stdout = stdout;\n wrapped.stderr = stderr;\n wrapped.cause = error;\n reject(wrapped);\n return;\n }\n resolve({\n stdout: typeof stdout === \"string\" ? stdout : String(stdout ?? \"\"),\n stderr: typeof stderr === \"string\" ? stderr : String(stderr ?? \"\"),\n });\n },\n );\n });\n}\n\nfunction getDeps(overrides?: Partial<TaskAgentAuthDeps>): TaskAgentAuthDeps {\n return {\n execFile: overrides?.execFile ?? defaultExecFile,\n fetch: overrides?.fetch ?? fetch,\n spawn: overrides?.spawn ?? spawnChildProcess,\n };\n}\n\nfunction safeRuntimeSetting(\n runtime: IAgentRuntime | undefined,\n key: string,\n): string | undefined {\n const value = runtime?.getSetting(key);\n return typeof value === \"string\" && value.trim() ? value.trim() : undefined;\n}\n\nfunction runtimeSettingValue(\n runtime: IAgentRuntime | undefined,\n key: string,\n): unknown {\n return runtime?.getSetting(key);\n}\n\nfunction readTaskAgentAuthSetting(\n runtime: IAgentRuntime | undefined,\n env: NodeJS.ProcessEnv,\n keys: string[],\n): unknown {\n for (const key of keys) {\n const runtimeValue = runtimeSettingValue(runtime, key);\n if (\n runtimeValue !== undefined &&\n runtimeValue !== null &&\n (!Array.isArray(runtimeValue) ||\n runtimeValue.some(\n (entry) => !(typeof entry === \"string\" && !entry.trim()),\n ))\n ) {\n return runtimeValue;\n }\n const envValue = env[key];\n if (typeof envValue === \"string\" && envValue.trim()) {\n return envValue.trim();\n }\n }\n return undefined;\n}\n\nfunction parseHttpBaseUrl(value: unknown): string | null {\n if (typeof value !== \"string\" || !value.trim()) {\n return null;\n }\n try {\n const parsed = new URL(value);\n if (!/^https?:$/i.test(parsed.protocol)) {\n return null;\n }\n return parsed.toString().replace(/\\/+$/, \"\");\n } catch {\n return null;\n }\n}\n\nfunction getConfiguredTaskAgentAuthHosts(\n runtime: IAgentRuntime | undefined,\n env: NodeJS.ProcessEnv,\n): Set<string> {\n const configured = parseTaskAgentAuthStringList(\n readTaskAgentAuthSetting(runtime, env, [\n \"TASK_AGENT_AUTH_TRUSTED_HOSTS\",\n \"ELIZA_TASK_AGENT_AUTH_TRUSTED_HOSTS\",\n ]),\n );\n return new Set([\n ...DEFAULT_TRUSTED_AUTH_HOSTS,\n ...configured.map((host) => host.toLowerCase()),\n ]);\n}\n\nfunction getTaskAgentBrowserClickSelectors(\n agentType: SupportedTaskAgentAdapter,\n runtime: IAgentRuntime | undefined,\n env: NodeJS.ProcessEnv,\n): string[] {\n const suffix = agentType.toUpperCase();\n const configured = parseTaskAgentAuthStringList(\n readTaskAgentAuthSetting(runtime, env, [\n `TASK_AGENT_AUTH_SELECTORS_${suffix}`,\n `ELIZA_TASK_AGENT_AUTH_SELECTORS_${suffix}`,\n ]),\n );\n return Array.from(\n new Set([...configured, ...DEFAULT_BROWSER_CLICK_SELECTORS[agentType]]),\n );\n}\n\nfunction normalizeTaskAgentAuthText(value: unknown): string | undefined {\n return typeof value === \"string\" && value.trim() ? value.trim() : undefined;\n}\n\nexport function normalizeTaskAgentAdapterId(\n value: string | undefined,\n): SupportedTaskAgentAdapter | null {\n const normalized = value?.trim().toLowerCase();\n switch (normalized) {\n case \"claude\":\n case \"claude code\":\n return \"claude\";\n case \"codex\":\n case \"openai codex\":\n return \"codex\";\n case \"gemini\":\n case \"gemini cli\":\n return \"gemini\";\n case \"aider\":\n return \"aider\";\n default:\n return null;\n }\n}\n\nexport function getTaskAgentLoginHint(\n agentType: SupportedTaskAgentAdapter,\n): string | undefined {\n switch (agentType) {\n case \"claude\":\n return \"Run `claude setup-token` to refresh Claude Code non-interactive subscription auth, or `claude auth login --claudeai` if the CLI is logged out.\";\n case \"codex\":\n return \"codex login\";\n case \"gemini\":\n return \"Run /auth inside the Gemini CLI session or configure a Google AI API key.\";\n case \"aider\":\n return \"Configure an API key for Aider (for example OPENAI_API_KEY or ANTHROPIC_API_KEY).\";\n }\n}\n\nexport function isTaskAgentNonInteractiveAuthFailure(\n agentType: SupportedTaskAgentAdapter,\n ...details: Array<string | undefined>\n): boolean {\n if (agentType !== \"claude\") {\n return false;\n }\n return details.some(\n (detail) =>\n typeof detail === \"string\" &&\n CLAUDE_NON_INTERACTIVE_AUTH_FAILURE_RE.test(detail),\n );\n}\n\nfunction mergeAuthOutput(\n current: TaskAgentAuthLaunchResult,\n next: Partial<TaskAgentAuthLaunchResult>,\n): TaskAgentAuthLaunchResult {\n return {\n ...current,\n ...Object.fromEntries(\n Object.entries(next).filter(([, value]) => value !== undefined),\n ),\n };\n}\n\nfunction extractTaskAgentAuthHints(\n output: string,\n): Partial<TaskAgentAuthLaunchResult> {\n const hints: Partial<TaskAgentAuthLaunchResult> = {};\n const urlMatch = output.match(/https?:\\/\\/[^\\s\"'<>]+/i);\n if (urlMatch?.[0]) {\n hints.url = urlMatch[0];\n }\n const deviceCodeMatch = output.match(\n /\\b(?:device code|enter code|code)[:\\s]+([A-Z0-9-]{4,})\\b/i,\n );\n if (deviceCodeMatch?.[1]) {\n hints.deviceCode = deviceCodeMatch[1];\n }\n const trimmed = output\n .split(/\\r?\\n/)\n .map((line) => line.trim())\n .filter(Boolean)\n .slice(-4)\n .join(\" \");\n if (trimmed) {\n hints.instructions = trimmed;\n }\n return hints;\n}\n\nfunction hasGeminiCredential(runtime?: IAgentRuntime): boolean {\n return Boolean(\n process.env.GOOGLE_GENERATIVE_AI_API_KEY?.trim() ||\n process.env.GOOGLE_API_KEY?.trim() ||\n readConfigEnvKey(\"GOOGLE_GENERATIVE_AI_API_KEY\") ||\n readConfigEnvKey(\"GOOGLE_API_KEY\") ||\n safeRuntimeSetting(runtime, \"GOOGLE_GENERATIVE_AI_API_KEY\") ||\n safeRuntimeSetting(runtime, \"GOOGLE_API_KEY\"),\n );\n}\n\nfunction hasAiderCredential(runtime?: IAgentRuntime): boolean {\n return Boolean(\n process.env.ANTHROPIC_API_KEY?.trim() ||\n process.env.OPENAI_API_KEY?.trim() ||\n process.env.GOOGLE_GENERATIVE_AI_API_KEY?.trim() ||\n process.env.GOOGLE_API_KEY?.trim() ||\n readConfigEnvKey(\"ANTHROPIC_API_KEY\") ||\n readConfigEnvKey(\"OPENAI_API_KEY\") ||\n readConfigEnvKey(\"GOOGLE_GENERATIVE_AI_API_KEY\") ||\n readConfigEnvKey(\"GOOGLE_API_KEY\") ||\n safeRuntimeSetting(runtime, \"ANTHROPIC_API_KEY\") ||\n safeRuntimeSetting(runtime, \"OPENAI_API_KEY\") ||\n safeRuntimeSetting(runtime, \"GOOGLE_GENERATIVE_AI_API_KEY\") ||\n safeRuntimeSetting(runtime, \"GOOGLE_API_KEY\"),\n );\n}\n\nfunction hasCloudProxyCredential(): boolean {\n return Boolean(readConfigCloudKey(\"apiKey\"));\n}\n\nexport async function probeTaskAgentAuth(\n agentType: SupportedTaskAgentAdapter,\n options: TaskAgentAuthOptions = {},\n): Promise<TaskAgentAuthStatus> {\n const deps = getDeps(options.deps);\n const env = options.env ?? process.env;\n switch (agentType) {\n case \"claude\": {\n try {\n const { stdout, stderr } = await deps.execFile(\n \"claude\",\n [\"auth\", \"status\"],\n {\n encoding: \"utf8\",\n env,\n timeout: DEFAULT_COMMAND_TIMEOUT_MS,\n },\n );\n const combined = `${stdout}\\n${stderr}`.trim();\n try {\n const parsed = JSON.parse(combined) as {\n loggedIn?: boolean;\n authMethod?: string;\n };\n if (parsed.loggedIn === true) {\n return {\n status: \"authenticated\",\n method:\n normalizeTaskAgentAuthText(parsed.authMethod) ?? \"claude.ai\",\n };\n }\n if (parsed.loggedIn === false) {\n return {\n status: \"unauthenticated\",\n method: normalizeTaskAgentAuthText(parsed.authMethod),\n loginHint: getTaskAgentLoginHint(agentType),\n };\n }\n } catch {\n if (/\\blogged in\\b/i.test(combined)) {\n return {\n status: \"authenticated\",\n method: \"claude.ai\",\n };\n }\n }\n return {\n status: \"unknown\",\n detail: combined || \"Unable to determine Claude Code auth status.\",\n loginHint: getTaskAgentLoginHint(agentType),\n };\n } catch (error) {\n const detail = error instanceof Error ? error.message : String(error);\n return {\n status:\n /\\bnot logged in\\b|\\bunauthenticated\\b|\\binvalid authentication credentials\\b/i.test(\n detail,\n )\n ? \"unauthenticated\"\n : \"unknown\",\n detail,\n loginHint: getTaskAgentLoginHint(agentType),\n };\n }\n }\n case \"codex\": {\n try {\n const { stdout, stderr } = await deps.execFile(\n \"codex\",\n [\"login\", \"status\"],\n {\n encoding: \"utf8\",\n env,\n timeout: DEFAULT_COMMAND_TIMEOUT_MS,\n },\n );\n const combined = `${stdout}\\n${stderr}`.trim();\n if (/\\bnot logged in\\b|\\bno stored credentials\\b/i.test(combined)) {\n return {\n status: \"unauthenticated\",\n loginHint: getTaskAgentLoginHint(agentType),\n };\n }\n if (/\\blogged in\\b/i.test(combined)) {\n return {\n status: \"authenticated\",\n method: combined.replace(/\\s+/g, \" \").trim(),\n };\n }\n return {\n status: \"unknown\",\n detail: combined || \"Unable to determine Codex auth status.\",\n loginHint: getTaskAgentLoginHint(agentType),\n };\n } catch (error) {\n const detail = error instanceof Error ? error.message : String(error);\n return {\n status: /\\bnot logged in\\b|\\bunauthenticated\\b/i.test(detail)\n ? \"unauthenticated\"\n : \"unknown\",\n detail,\n loginHint: getTaskAgentLoginHint(agentType),\n };\n }\n }\n case \"gemini\":\n if (hasGeminiCredential(options.runtime)) {\n return { status: \"authenticated\", method: \"api_key\" };\n }\n return {\n status: \"unauthenticated\",\n loginHint: getTaskAgentLoginHint(agentType),\n };\n case \"aider\":\n if (hasCloudProxyCredential() || hasAiderCredential(options.runtime)) {\n return {\n status: \"authenticated\",\n method: hasCloudProxyCredential() ? \"cloud\" : \"api_key\",\n };\n }\n return {\n status: \"unauthenticated\",\n loginHint: getTaskAgentLoginHint(agentType),\n };\n }\n}\n\nfunction getTaskAgentAuthCommand(\n agentType: SupportedTaskAgentAdapter,\n): { command: string; args: string[] } | null {\n switch (agentType) {\n case \"claude\":\n return { command: \"claude\", args: [\"auth\", \"login\", \"--claudeai\"] };\n case \"codex\":\n return { command: \"codex\", args: [\"login\"] };\n default:\n return null;\n }\n}\n\nexport async function launchTaskAgentAuthFlow(\n agentType: SupportedTaskAgentAdapter,\n options: TaskAgentAuthOptions = {},\n): Promise<{\n handle: TaskAgentAuthFlowHandle | null;\n result: TaskAgentAuthLaunchResult;\n}> {\n const command = getTaskAgentAuthCommand(agentType);\n if (!command) {\n return {\n handle: null,\n result: {\n launched: false,\n instructions:\n getTaskAgentLoginHint(agentType) ??\n `No automated auth flow is available for ${agentType}.`,\n },\n };\n }\n\n const deps = getDeps(options.deps);\n const env = options.env ?? process.env;\n const child = deps.spawn(command.command, command.args, {\n cwd: process.cwd(),\n env,\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n // On Windows, .cmd files require the shell to resolve PATHEXT extensions.\n shell: process.platform === \"win32\",\n });\n const childProcess: ChildProcessByStdio<null, Readable, Readable> = child;\n\n let current: TaskAgentAuthLaunchResult = {\n launched: true,\n instructions: `Starting ${agentType} authentication…`,\n };\n let handle!: TaskAgentAuthFlowHandle;\n let settled = false;\n let resolveInitial:\n | ((value: {\n handle: TaskAgentAuthFlowHandle;\n result: TaskAgentAuthLaunchResult;\n }) => void)\n | null = null;\n const initialPromise = new Promise<{\n handle: TaskAgentAuthFlowHandle;\n result: TaskAgentAuthLaunchResult;\n }>((resolve) => {\n resolveInitial = resolve;\n });\n\n const settleInitial = (handle: TaskAgentAuthFlowHandle): void => {\n if (settled) return;\n settled = true;\n resolveInitial?.({ handle, result: { ...current } });\n };\n\n const applyOutput = (chunk: string): void => {\n const text = chunk.trim();\n if (!text) return;\n current = mergeAuthOutput(current, extractTaskAgentAuthHints(text));\n if (current.url || current.deviceCode) {\n settleInitial(handle);\n }\n };\n\n childProcess.stdout.setEncoding(\"utf8\");\n childProcess.stderr.setEncoding(\"utf8\");\n childProcess.stdout.on(\"data\", (chunk: string) => applyOutput(chunk));\n childProcess.stderr.on(\"data\", (chunk: string) => applyOutput(chunk));\n\n const completion = new Promise<{\n code: number | null;\n signal: NodeJS.Signals | null;\n }>((resolve) => {\n child.once(\"error\", (error) => {\n current = mergeAuthOutput(current, {\n launched: false,\n instructions: error.message,\n });\n settleInitial(handle);\n resolve({ code: null, signal: null });\n });\n child.once(\"exit\", (code, signal) => {\n settleInitial(handle);\n resolve({ code, signal });\n });\n });\n\n handle = {\n agentType,\n startedAt: Date.now(),\n completion,\n snapshot: () => ({ ...current }),\n stop: () => {\n if (!child.killed) {\n child.kill(\"SIGTERM\");\n }\n },\n };\n\n setTimeout(() => settleInitial(handle), DEFAULT_INITIAL_AUTH_WAIT_MS);\n\n return await initialPromise;\n}\n\nfunction resolveLocalApiBaseUrl(\n runtime: IAgentRuntime | undefined,\n env: NodeJS.ProcessEnv,\n): string {\n const configured = parseHttpBaseUrl(\n readTaskAgentAuthSetting(runtime, env, [\n \"TASK_AGENT_AUTH_API_BASE_URL\",\n \"ELIZA_TASK_AGENT_AUTH_API_BASE_URL\",\n ]),\n );\n if (configured) {\n return configured;\n }\n const rawPort =\n safeRuntimeSetting(runtime, \"SERVER_PORT\") ||\n env.SERVER_PORT?.trim() ||\n env.ELIZA_API_PORT?.trim() ||\n env.ELIZA_PORT?.trim() ||\n \"31337\";\n return `http://127.0.0.1:${rawPort}`;\n}\n\nfunction isTrustedTaskAgentAuthUrl(\n rawUrl: string,\n runtime: IAgentRuntime | undefined,\n env: NodeJS.ProcessEnv,\n): boolean {\n try {\n const parsed = new URL(rawUrl);\n if (!/^https?:$/i.test(parsed.protocol)) return false;\n return getConfiguredTaskAgentAuthHosts(runtime, env).has(\n parsed.hostname.toLowerCase(),\n );\n } catch {\n return false;\n }\n}\n\nexport async function assistTaskAgentBrowserLogin(\n agentType: SupportedTaskAgentAdapter,\n rawUrl: string,\n options: TaskAgentAuthOptions = {},\n): Promise<{\n opened: boolean;\n clicked: boolean;\n detail?: string;\n}> {\n const deps = getDeps(options.deps);\n const env = options.env ?? process.env;\n const commandUrl = `${resolveLocalApiBaseUrl(\n options.runtime,\n env,\n )}/api/browser-workspace/command`;\n const selectors = getTaskAgentBrowserClickSelectors(\n agentType,\n options.runtime,\n env,\n );\n if (!rawUrl.trim()) {\n return { opened: false, clicked: false, detail: \"Missing auth URL.\" };\n }\n if (!isTrustedTaskAgentAuthUrl(rawUrl, options.runtime, env)) {\n return {\n opened: false,\n clicked: false,\n detail: `Refused to auto-open untrusted auth URL: ${rawUrl}`,\n };\n }\n\n try {\n const openResponse = await deps.fetch(commandUrl, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n subaction: \"open\",\n show: true,\n url: rawUrl,\n }),\n });\n if (!openResponse.ok) {\n return {\n opened: false,\n clicked: false,\n detail: `Browser workspace open failed with ${openResponse.status}.`,\n };\n }\n const openedPayload = (await openResponse.json()) as {\n tab?: { id?: string };\n };\n const tabId = openedPayload.tab?.id;\n if (!tabId) {\n return {\n opened: true,\n clicked: false,\n detail: \"Browser workspace opened the auth page without a tab id.\",\n };\n }\n\n const waitResponse = await deps\n .fetch(commandUrl, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n subaction: \"wait\",\n id: tabId,\n timeoutMs: DEFAULT_BROWSER_ASSIST_TIMEOUT_MS,\n }),\n })\n .catch(() => null);\n if (waitResponse && !waitResponse.ok) {\n // Ignore wait failures. The click probes below are still safe.\n }\n\n for (const selector of selectors) {\n const clickResponse = await deps\n .fetch(commandUrl, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n subaction: \"click\",\n id: tabId,\n selector,\n }),\n })\n .catch(() => null);\n if (clickResponse?.ok) {\n return {\n opened: true,\n clicked: true,\n };\n }\n }\n\n return {\n opened: true,\n clicked: false,\n detail:\n \"Opened the provider sign-in page. No trusted first-party button was clicked automatically.\",\n };\n } catch (error) {\n return {\n opened: false,\n clicked: false,\n detail: error instanceof Error ? error.message : String(error),\n };\n }\n}\n\nexport async function augmentTaskAgentPreflightResults(\n results: PreflightResult[],\n options: TaskAgentAuthOptions = {},\n): Promise<PreflightResult[]> {\n return await Promise.all(\n results.map(async (result) => {\n const adapterId = normalizeTaskAgentAdapterId(result.adapter);\n if (!adapterId) return result;\n const auth = await probeTaskAgentAuth(adapterId, options);\n return {\n ...result,\n auth: toPreflightAuthStatus(auth),\n } satisfies PreflightResult;\n }),\n );\n}\n",
|
|
37
|
+
"/** @module services/pty-service */\n\nimport {\n appendFile,\n mkdir,\n mkdtemp,\n readFile,\n rm,\n writeFile,\n} from \"node:fs/promises\";\nimport { homedir, tmpdir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport { type IAgentRuntime, logger, type Service } from \"@elizaos/core\";\nimport {\n type AdapterType,\n type AgentCredentials,\n type AgentFileDescriptor,\n type ApprovalConfig,\n type ApprovalPreset,\n type BaseCodingAdapter,\n checkAdapters,\n createAdapter,\n generateApprovalConfig,\n type PreflightResult,\n type WriteMemoryOptions,\n} from \"coding-agent-adapters\";\nimport { PTYConsoleBridge } from \"pty-console\";\nimport type {\n BunCompatiblePTYManager,\n PTYManager,\n SessionFilter,\n SessionHandle,\n SessionMessage,\n SpawnConfig,\n StallClassification,\n WorkerSessionHandle,\n} from \"pty-manager\";\nimport { buildOpencodeSpawnConfig } from \"./agent-credentials.js\";\nimport { AgentMetricsTracker } from \"./agent-metrics.js\";\nimport type { AgentSelectionStrategy } from \"./agent-selection.js\";\nimport {\n captureTaskResponse,\n cleanForChat,\n extractCompletionSummary,\n peekTaskResponse,\n} from \"./ansi-utils.js\";\nimport { ensureBundledClaudeCodeSkills } from \"./claude-code-skill-installer.js\";\nimport { readConfigEnvKey } from \"./config-env.js\";\nimport {\n type CoordinatorNormalizedEvent,\n normalizeCoordinatorEvent,\n} from \"./coordinator-event-normalizer.js\";\nimport {\n captureFeed,\n captureLifecycle,\n captureSessionOpen,\n isDebugCaptureEnabled,\n} from \"./debug-capture.js\";\nimport {\n handleGeminiAuth as handleGeminiAuthFlow,\n pushDefaultRules as pushDefaultAutoResponseRules,\n} from \"./pty-auto-response.js\";\nimport { initializePTYManager } from \"./pty-init.js\";\nimport {\n getSessionOutput as getSessionOutputIO,\n type SessionIOContext,\n sendKeysToSession as sendKeysToSessionIO,\n sendToSession as sendToSessionIO,\n stopSession as stopSessionIO,\n subscribeToOutput as subscribeToOutputIO,\n} from \"./pty-session-io.js\";\nimport {\n buildSpawnConfig,\n setupDeferredTaskDelivery,\n setupOutputBuffer,\n shouldUseCodexExecMode,\n} from \"./pty-spawn.js\";\nimport type {\n CodingAgentType,\n PTYServiceConfig,\n SessionEventCallback,\n SessionInfo,\n SpawnSessionOptions,\n} from \"./pty-types.js\";\nimport {\n isOpencodeAgentType,\n isPiAgentType,\n toOpencodeCommand,\n toPiCommand,\n} from \"./pty-types.js\";\nimport { CLAUDE_SKILL_ESSENTIALS } from \"./skill-essentials.js\";\nimport {\n TRAJECTORY_CHILD_STEP_ENV_KEY,\n TRAJECTORY_CHILD_STEP_METADATA_KEY,\n TRAJECTORY_PARENT_STEP_METADATA_KEY,\n withLinkedSpawn,\n} from \"./spawn-trajectory.js\";\nimport {\n classifyAndDecideForCoordinator,\n classifyStallOutput,\n} from \"./stall-classifier.js\";\nimport { ensureStructuredProofBridge } from \"./structured-proof-bridge.js\";\nimport { SwarmCoordinator } from \"./swarm-coordinator.js\";\nimport { POST_SEND_COOLDOWN_MS } from \"./swarm-decision-loop.js\";\nimport {\n assistTaskAgentBrowserLogin,\n augmentTaskAgentPreflightResults,\n getTaskAgentLoginHint,\n isTaskAgentNonInteractiveAuthFailure,\n launchTaskAgentAuthFlow,\n probeTaskAgentAuth,\n type TaskAgentAuthFlowHandle,\n type TaskAgentAuthLaunchResult,\n type TaskAgentAuthStatus,\n} from \"./task-agent-auth.js\";\nimport {\n buildTaskAgentTaskProfile,\n clearTaskAgentFrameworkStateCache,\n getTaskAgentFrameworkState,\n getTaskAgentModelPrefs,\n readTaskAgentModelPrefs,\n type SupportedTaskAgentAdapter,\n type TaskAgentFrameworkState,\n type TaskAgentTaskProfileInput,\n} from \"./task-agent-frameworks.js\";\n\n/**\n * Grace period after `task_complete` before auto-stopping a PTY session.\n * Short enough that stale subagents don't linger (spurious stall\n * classifications fire phantom heartbeats in downstream streamers), long\n * enough that backgrounded processes spawned by the agent can detach from\n * the PTY parent before it exits.\n */\nconst TASK_COMPLETE_STOP_DELAY_MS = 5_000;\n\nexport function shouldSuppressCodexExecPtyManagerEvent(options: {\n codexExecMode: boolean;\n event: string;\n data: unknown;\n}): boolean {\n if (!options.codexExecMode) return false;\n const payload = options.data as\n | {\n source?: unknown;\n }\n | undefined;\n if (payload?.source !== \"pty_manager\") return false;\n\n // `codex exec` is non-interactive. Process exit and --output-last-message\n // are the authoritative completion signals; TUI prompt detectors can\n // misclassify ordinary exec output as login/blocking prompts.\n return options.event === \"blocked\" || options.event === \"login_required\";\n}\n\nexport function shouldSuppressCodexExecHookEvent(options: {\n codexExecMode: boolean;\n event: string;\n}): boolean {\n return options.codexExecMode && options.event === \"session_end\";\n}\n\n/**\n * Portable safety floor injected into every spawned coding-agent's memory\n * file. Locks the agent to its allocated workspace dir so it never wanders\n * into $HOME or /tmp regardless of caller-supplied memoryContent. Deployment-\n * specific conventions (hosting, URLs, etc.) belong in caller memoryContent.\n */\nconst COMMON_LOCK_PREFIX = `# Operating mode\n\nYou are an autonomous Eliza sub-agent — there is no interactive human in this session. If you cannot do something, surface a \\`DECISION: cannot continue because <reason>\\` line on stdout (the orchestrator tails for those) and stop; do not ask a user to run a command for you.`;\n\nconst TOOL_DISCOVERY_HINTS: Record<CodingAgentType, string> = {\n claude: CLAUDE_SKILL_ESSENTIALS,\n gemini:\n \"Your tool list is defined in `.gemini/settings.json`. Use `run_shell_command` for shell, `read_file`/`write_file` for I/O. Read settings before assuming a tool is missing.\",\n codex:\n \"Your tool list is the OpenAI Codex runtime's built-in set (`exec_command`, `apply_patch`, `read_file`, etc.). Session approval settings are injected by the Eliza runtime before startup.\",\n aider:\n \"Your tools are aider's slash commands (`/run`, `/edit`, `/add`, etc.); see `.aider.conf.yml` if present for any overrides.\",\n hermes: \"\",\n shell: \"\",\n pi: \"\",\n opencode: \"\",\n};\n\nfunction buildWorkspaceLockMemory(\n workdir: string,\n agentType: CodingAgentType,\n): string {\n const workspace = buildWorkspaceTaskPrefix(workdir);\n const hint = TOOL_DISCOVERY_HINTS[agentType] ?? \"\";\n return `${workspace}\\n\\n${COMMON_LOCK_PREFIX}${hint ? ` ${hint}` : \"\"}`;\n}\n\nfunction buildWorkspaceTaskPrefix(workdir: string): string {\n return `# Workspace\n\nYour working directory is \\`${workdir}\\`. Stay inside it: do not \\`cd\\` to \\`/tmp\\`, \\`/\\`, \\`$HOME\\`, or any other path outside the workspace. Create all files, run all builds, and start all servers from this directory. If you need scratch space, make a subdirectory here.`;\n}\n\nfunction buildInlineWorkspaceTaskPrefix(workdir: string): string {\n return `Work only in \\`${workdir}\\`; do not leave that workspace.`;\n}\n\nfunction buildParentRuntimeBridgeMemory(\n sessionId: string,\n port: string,\n): string {\n const base = `http://127.0.0.1:${port}/api/coding-agents/${encodeURIComponent(sessionId)}`;\n return `# Parent Eliza Runtime\n\nYou can read parent-runtime state via these loopback endpoints:\n\n- \\`curl ${base}/parent-context\\` returns the parent's character, current room, model preferences, and your workdir.\n- \\`curl \"${base}/memory?q=<query>\"\\` searches parent memory for matching entities, facts, messages, and knowledge.\n- \\`curl ${base}/active-workspaces\\` lists the parent's known workspaces and task-agent sessions.\n\nThese endpoints are read-only. Do not POST to them. The parent already receives your lifecycle events through the hook channel installed in your workspace settings.`;\n}\n\ntype CodexApprovalSettings = {\n approvalPolicy: \"untrusted\" | \"on-failure\" | \"on-request\" | \"never\";\n sandboxMode: \"read-only\" | \"workspace-write\";\n webSearch: boolean;\n};\n\nconst CODEX_APPROVAL_SETTINGS: Record<ApprovalPreset, CodexApprovalSettings> = {\n readonly: {\n approvalPolicy: \"untrusted\",\n sandboxMode: \"read-only\",\n webSearch: false,\n },\n standard: {\n approvalPolicy: \"on-failure\",\n sandboxMode: \"workspace-write\",\n webSearch: true,\n },\n permissive: {\n approvalPolicy: \"on-request\",\n sandboxMode: \"workspace-write\",\n webSearch: true,\n },\n autonomous: {\n approvalPolicy: \"never\",\n sandboxMode: \"workspace-write\",\n webSearch: true,\n },\n};\n\nfunction tomlString(value: string): string {\n return JSON.stringify(value);\n}\n\nfunction buildCodexApprovalConfigToml(\n preset: ApprovalPreset,\n credentials?: AgentCredentials,\n): string {\n const settings = CODEX_APPROVAL_SETTINGS[preset];\n const topLevel = [\n `approval_policy = ${tomlString(settings.approvalPolicy)}`,\n `sandbox_mode = ${tomlString(settings.sandboxMode)}`,\n ];\n\n if (credentials?.openaiBaseUrl?.trim()) {\n topLevel.push(`openai_base_url = ${tomlString(credentials.openaiBaseUrl)}`);\n }\n\n const extraConfigToml = credentials?.extraConfigToml?.trim();\n const sections = [\n topLevel.join(\"\\n\"),\n extraConfigToml,\n [\"[tools]\", `web_search = ${settings.webSearch}`].join(\"\\n\"),\n ].filter((section): section is string => Boolean(section?.trim()));\n\n return `${sections.join(\"\\n\\n\")}\\n`;\n}\n\nasync function readFileIfPresent(filePath: string): Promise<string | null> {\n try {\n return await readFile(filePath, \"utf8\");\n } catch (err) {\n if ((err as NodeJS.ErrnoException)?.code === \"ENOENT\") {\n return null;\n }\n throw err;\n }\n}\n\nasync function writeCodexAuthFile(\n codexHome: string,\n credentials?: AgentCredentials,\n): Promise<void> {\n const openaiKey = credentials?.openaiKey?.trim();\n if (openaiKey) {\n await writeFile(\n join(codexHome, \"auth.json\"),\n JSON.stringify(\n {\n auth_mode: \"apikey\",\n OPENAI_API_KEY: openaiKey,\n tokens: null,\n last_refresh: null,\n },\n null,\n 2,\n ),\n \"utf8\",\n );\n return;\n }\n\n const configuredCodexHome = process.env.CODEX_HOME?.trim();\n const candidateAuthPaths = [\n configuredCodexHome ? join(configuredCodexHome, \"auth.json\") : undefined,\n join(homedir(), \".codex\", \"auth.json\"),\n ].filter((candidate): candidate is string => Boolean(candidate));\n\n for (const authPath of candidateAuthPaths) {\n const existingAuth = await readFileIfPresent(authPath);\n if (!existingAuth) continue;\n await writeFile(join(codexHome, \"auth.json\"), existingAuth, \"utf8\");\n return;\n }\n}\n\nasync function prepareCodexHome(\n sessionId: string,\n preset: ApprovalPreset,\n credentials?: AgentCredentials,\n): Promise<string> {\n const codexHome = await mkdtemp(join(tmpdir(), `eliza-codex-${sessionId}-`));\n await mkdir(codexHome, { recursive: true });\n await writeCodexAuthFile(codexHome, credentials);\n await writeFile(\n join(codexHome, \"config.toml\"),\n buildCodexApprovalConfigToml(preset, credentials),\n \"utf8\",\n );\n return codexHome;\n}\n\nfunction prependWorkspaceLockToTask(\n task: string | undefined,\n workspaceLock: string,\n): string | undefined {\n if (!task?.trim()) {\n return undefined;\n }\n return `${workspaceLock} ${task}`;\n}\n\nfunction resolveServerPort(runtime: IAgentRuntime): string {\n const raw = runtime.getSetting(\"SERVER_PORT\");\n if (typeof raw === \"number\" && Number.isFinite(raw)) return String(raw);\n if (typeof raw === \"string\" && raw.trim().length > 0) return raw.trim();\n return \"2138\";\n}\n\nexport type {\n CodingAgentType,\n PTYServiceConfig,\n SessionEventName,\n SessionInfo,\n SpawnSessionOptions,\n} from \"./pty-types.js\";\n\n/**\n * Narrow shape of `~/.claude.json` that we read/write here. Claude Code owns\n * the full schema; we touch only the `projects` map and its per-workdir\n * `hasTrustDialogAccepted` flag. Unknown keys are preserved via the\n * index signature so we never clobber fields we don't model.\n */\ninterface ClaudeProjectEntry {\n hasTrustDialogAccepted?: boolean;\n [key: string]: unknown;\n}\ninterface ClaudeConfig {\n projects?: Record<string, ClaudeProjectEntry>;\n [key: string]: unknown;\n}\n\n/**\n * In-process serializer for `~/.claude.json` writes. Multiple subagents\n * spawning concurrently for different workdirs would otherwise each\n * read-modify-write the same file: last writer wins, intermediate trust\n * entries are lost. Chain writes per config path so each runs to\n * completion before the next starts.\n *\n * This only protects writes inside one process. If a user has another\n * claude CLI running that also writes the file, we still rely on the\n * read-on-startup + idempotent re-seed on next spawn to self-heal.\n */\nconst claudeConfigWriteQueue = new Map<string, Promise<void>>();\n\n/**\n * Pre-accept Claude Code's one-time trust dialog for a workdir by writing\n * `hasTrustDialogAccepted: true` into `~/.claude.json`'s `projects` map.\n *\n * Why: Claude Code shows a Bypass Permissions / Trust dialog the first time\n * it runs in any unrecognised directory. On a fresh scratch workdir that\n * dialog is blocking: the auto-response path ends up pressing Enter, which\n * defaults to \"No, exit\" and kills the subagent with exit code 1 before any\n * work happens. Seeding the trust entry upfront skips the dialog entirely.\n *\n * Idempotent and best-effort: returns without throwing if the config file\n * does not yet exist, is unreadable, or is not valid JSON. In those cases\n * claude will show the dialog the normal way, which is no worse than before.\n *\n * Concurrency: serialized per config path via `claudeConfigWriteQueue` so\n * parallel swarm spawns don't clobber each other's trust entries.\n */\nasync function seedClaudeTrustForWorkdir(\n workdir: string,\n overrideConfigPath?: string,\n): Promise<void> {\n const configPath = overrideConfigPath ?? join(homedir(), \".claude.json\");\n const prior = claudeConfigWriteQueue.get(configPath) ?? Promise.resolve();\n const next = prior\n .catch(() => undefined)\n .then(() => seedClaudeTrustForWorkdirUnsafe(configPath, workdir));\n claudeConfigWriteQueue.set(configPath, next);\n try {\n await next;\n } finally {\n if (claudeConfigWriteQueue.get(configPath) === next) {\n claudeConfigWriteQueue.delete(configPath);\n }\n }\n}\n\nexport const seedClaudeTrustForWorkdirForTesting = seedClaudeTrustForWorkdir;\n\nasync function seedClaudeTrustForWorkdirUnsafe(\n configPath: string,\n workdir: string,\n): Promise<void> {\n let raw: string;\n try {\n raw = await readFile(configPath, \"utf8\");\n } catch (err) {\n // ENOENT on first-run is expected (claude has never run here); any\n // other read error (EACCES, EIO, etc.) is unexpected: log so we\n // don't silently skip trust-seeding on a genuinely broken config.\n if ((err as NodeJS.ErrnoException)?.code !== \"ENOENT\") {\n logger.warn(\n `[pty-service] seedClaudeTrustForWorkdir: failed to read ${configPath}: ${err}`,\n );\n return;\n }\n // ENOENT: create a minimal config so the write below has somewhere\n // to land. Claude Code is tolerant of extra projects entries and\n // will merge its own keys on first run.\n raw = \"{}\";\n }\n let parsed: ClaudeConfig;\n try {\n parsed = JSON.parse(raw) as ClaudeConfig;\n } catch (err) {\n // Malformed JSON: possible after an aborted claude write or manual\n // edit. Skip seeding (claude will show the dialog normally) but warn\n // so we can spot a corrupted config instead of silently bypassing.\n logger.warn(\n `[pty-service] seedClaudeTrustForWorkdir: ${configPath} is not valid JSON: ${err}`,\n );\n return;\n }\n const projects = parsed.projects ?? {};\n const existing = projects[workdir];\n if (existing && existing.hasTrustDialogAccepted === true) {\n return;\n }\n projects[workdir] = { ...existing, hasTrustDialogAccepted: true };\n parsed.projects = projects;\n await writeFile(configPath, JSON.stringify(parsed, null, 2), \"utf8\");\n}\n\n/**\n * Retrieve the SwarmCoordinator from the PTYService registered on the runtime.\n * Returns undefined if PTYService or coordinator is not available.\n */\nexport function getPtyService(runtime: IAgentRuntime): PTYService | null {\n const service = runtime.getService(\"PTY_SERVICE\");\n return service instanceof PTYService ? service : null;\n}\n\nexport function getCoordinator(\n runtime: IAgentRuntime,\n): SwarmCoordinator | undefined {\n return getPtyService(runtime)?.coordinator ?? undefined;\n}\n\nexport class PTYService {\n static serviceType = \"PTY_SERVICE\";\n capabilityDescription =\n \"Manages asynchronous PTY task-agent sessions for open-ended background work\";\n\n private runtime: IAgentRuntime;\n private manager: PTYManager | BunCompatiblePTYManager | null = null;\n private usingBunWorker: boolean = false;\n private serviceConfig: PTYServiceConfig;\n private sessionNames: Map<string, string> = new Map();\n private sessionMetadata: Map<string, Record<string, unknown>> = new Map();\n private sessionWorkdirs: Map<string, string> = new Map();\n private eventCallbacks: SessionEventCallback[] = [];\n private normalizedEventCallbacks: Array<\n (event: CoordinatorNormalizedEvent) => void\n > = [];\n private outputUnsubscribers: Map<string, () => void> = new Map();\n private transcriptUnsubscribers: Map<string, () => void> = new Map();\n private sessionOutputBuffers: Map<string, string[]> = new Map();\n private completionReconcileTimers: Map<\n string,\n ReturnType<typeof setInterval>\n > = new Map();\n private completionSignalSince: Map<string, number> = new Map();\n private terminalSessionStates: Map<\n string,\n {\n status: SessionInfo[\"status\"];\n createdAt: Date;\n lastActivityAt: Date;\n reason?: string;\n }\n > = new Map();\n private adapterCache: Map<string, BaseCodingAdapter> = new Map();\n /** Tracks the buffer index when a task was sent, so we can capture the response on completion */\n private taskResponseMarkers: Map<string, number> = new Map();\n /** Captures \"Task completion trace\" log entries from worker stderr (rolling, capped at 200) */\n private traceEntries: Array<string | Record<string, unknown>> = [];\n private static readonly MAX_TRACE_ENTRIES = 200;\n /** Lightweight per-agent-type metrics for observability */\n private metricsTracker = new AgentMetricsTracker();\n /** Active provider auth helper processes keyed by agent type. */\n private activeAuthFlows: Map<string, TaskAgentAuthFlowHandle> = new Map();\n private preflightCache: Map<\n string,\n { expiresAt: number; results: PreflightResult[] }\n > = new Map();\n private preflightInFlight: Map<string, Promise<PreflightResult[]>> =\n new Map();\n // Coalesces concurrent listSessions() calls against the Bun worker.\n // pty-manager keys its pending-response map by the command name (\"list\"),\n // so when two list() promises are in flight the second overwrites the\n // first's resolver. The worker only ever resolves the most recent one;\n // the earlier promise is orphaned and rejects with \"Operation list timed\n // out\" 30s later. Sharing a single in-flight call across concurrent\n // callers avoids the race entirely.\n private pendingBunList: ReturnType<BunCompatiblePTYManager[\"list\"]> | null =\n null;\n\n private coalescedBunList(): ReturnType<BunCompatiblePTYManager[\"list\"]> {\n if (!this.pendingBunList) {\n const bunManager = this.manager as BunCompatiblePTYManager;\n const fresh = bunManager.list();\n // Reset slot once the call settles. Rejection is handled by callers\n // awaiting `fresh` directly; the reset chain must not surface it as\n // an unhandled rejection of its own.\n const clear = () => {\n if (this.pendingBunList === fresh) this.pendingBunList = null;\n };\n fresh.then(clear, clear);\n this.pendingBunList = fresh;\n }\n return this.pendingBunList;\n }\n /** Pending task_complete → auto-stop timers, cancellable by the coordinator. */\n private taskCompleteAutoStopTimers: Map<\n string,\n ReturnType<typeof setTimeout>\n > = new Map();\n /** Background auth-recovery watchers keyed by blocked session id. */\n private authRecoveryTimers: Map<string, ReturnType<typeof setInterval>> =\n new Map();\n /** Console bridge for terminal output streaming and buffered hydration */\n consoleBridge: PTYConsoleBridge | null = null;\n /** Swarm coordinator instance (if active). Accessed via getCoordinator(runtime). */\n coordinator: SwarmCoordinator | null = null;\n\n constructor(runtime: IAgentRuntime, config: PTYServiceConfig = {}) {\n this.runtime = runtime;\n this.serviceConfig = {\n maxLogLines: config.maxLogLines ?? 1000,\n debug: config.debug ?? false,\n registerCodingAdapters: config.registerCodingAdapters ?? true,\n maxConcurrentSessions: config.maxConcurrentSessions ?? 8,\n defaultApprovalPreset: config.defaultApprovalPreset ?? \"autonomous\",\n };\n }\n\n static async start(runtime: IAgentRuntime): Promise<PTYService> {\n const config = runtime.getSetting(\"PTY_SERVICE_CONFIG\") as\n | PTYServiceConfig\n | null\n | undefined;\n const service = new PTYService(runtime, config ?? {});\n await service.initialize();\n\n // Install bundled Claude Code skills (e.g. eliza-runtime) into\n // ~/.claude/skills/ so spawned sub-agents see them on first use.\n // Skip-if-exists semantics — never stomps user customizations.\n try {\n ensureBundledClaudeCodeSkills(logger);\n } catch (err) {\n logger.warn(\n `[PTYService] bundled claude-code skill install failed: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n\n // Wire the SwarmCoordinator here instead of plugin init()\n // because ElizaOS calls Service.start() reliably but may not call\n // plugin.init() depending on the registration path.\n // Guard: the framework may call start() more than once, skip if\n // a coordinator is already registered on this runtime.\n const servicesMap = runtime.services as Map<string, Service[]> | undefined;\n const existing = servicesMap?.get?.(\"SWARM_COORDINATOR\");\n if (existing && existing.length > 0) {\n service.coordinator = existing[0] as Service & SwarmCoordinator;\n logger.info(\n \"[PTYService] SwarmCoordinator already registered, skipping duplicate start\",\n );\n } else {\n try {\n const coordinator = new SwarmCoordinator(runtime);\n await coordinator.start(service);\n service.coordinator = coordinator;\n\n // Register the coordinator as a discoverable runtime service so\n // server.ts can find it via runtime.getService(\"SWARM_COORDINATOR\")\n // without a hard import from this plugin package.\n // We bypass registerService() (which would call start() again) and\n // write directly to the services map that getService() reads from.\n servicesMap?.set?.(\"SWARM_COORDINATOR\", [\n coordinator as Service & SwarmCoordinator,\n ]);\n\n logger.info(\"[PTYService] SwarmCoordinator wired and started\");\n } catch (err) {\n logger.error(`[PTYService] Failed to wire SwarmCoordinator: ${err}`);\n }\n }\n\n // Install the structured-proof bridge once per runtime. It listens for\n // APP_CREATE_DONE / PLUGIN_CREATE_DONE sentinels in child PTY output and\n // persists the structured claim to the owning task's session metadata so\n // a custom validator can cross-check the claim against actual disk state.\n // Mirrors how `ensureSkillCallbackBridge` is registered per spawn — the\n // ensure-helper is internally idempotent.\n ensureStructuredProofBridge(runtime, service);\n\n return service;\n }\n\n static async stopRuntime(runtime: IAgentRuntime): Promise<void> {\n const service = getPtyService(runtime);\n if (service) {\n await service.stop();\n }\n }\n\n private async initialize(): Promise<void> {\n const result = await initializePTYManager({\n serviceConfig: this.serviceConfig,\n classifyStall: (id, out) => this.classifyStall(id, out),\n emitEvent: (id, event, data) => this.emitEvent(id, event, data),\n handleGeminiAuth: (id) => this.handleGeminiAuth(id),\n sessionMetadata: this.sessionMetadata,\n sessionOutputBuffers: this.sessionOutputBuffers,\n taskResponseMarkers: this.taskResponseMarkers,\n metricsTracker: this.metricsTracker,\n traceEntries: this.traceEntries,\n maxTraceEntries: PTYService.MAX_TRACE_ENTRIES,\n log: (msg) => this.log(msg),\n handleWorkerExit: (info) => this.handleWorkerExit(info),\n hasActiveTask: (sessionId) => {\n const coordinator = this.coordinator;\n if (!coordinator) return false;\n const taskCtx = coordinator.getTaskContext(sessionId);\n // tool_running counts as active for PTY purposes: the task is\n // still alive, just executing a tool. matches the same expansion\n // applied to handleTurnComplete and drainPendingTurnComplete so\n // tool-heavy scratch tasks aren't treated as inactive mid-run.\n return (\n taskCtx?.status === \"active\" || taskCtx?.status === \"tool_running\"\n );\n },\n hasTaskActivity: (sessionId) => {\n const coordinator = this.coordinator;\n if (!coordinator) return false;\n const taskCtx = coordinator.getTaskContext(sessionId);\n if (!taskCtx) return false;\n // Task has activity if the initial task was delivered (agent started\n // working) OR coordinator made decisions. The taskDelivered flag\n // covers agents that finish without hitting any blocking prompts.\n return taskCtx.taskDelivered || taskCtx.decisions.length > 0;\n },\n markTaskDelivered: (sessionId) => {\n const coordinator = this.coordinator;\n if (!coordinator) return;\n void coordinator.setTaskDelivered(sessionId);\n },\n });\n const manager = result.manager;\n this.manager = manager;\n this.usingBunWorker = result.usingBunWorker;\n\n // Wire console bridge for terminal output streaming / hydration\n try {\n this.consoleBridge = new PTYConsoleBridge(manager, {\n maxBufferedCharsPerSession: 100_000,\n });\n this.log(\"PTYConsoleBridge wired\");\n } catch (err) {\n this.log(`Failed to wire PTYConsoleBridge: ${err}`);\n }\n\n this.log(\"PTYService initialized\");\n }\n\n async stop(): Promise<void> {\n // Stop the coordinator if one was wired to this service\n if (this.coordinator) {\n await this.coordinator.stop();\n // Remove from runtime services map\n (this.runtime.services as Map<string, Service[]>).delete(\n \"SWARM_COORDINATOR\",\n );\n this.coordinator = null;\n }\n\n if (this.consoleBridge) {\n this.consoleBridge.close();\n this.consoleBridge = null;\n }\n\n for (const unsubscribe of this.outputUnsubscribers.values()) {\n unsubscribe();\n }\n this.outputUnsubscribers.clear();\n for (const unsubscribe of this.transcriptUnsubscribers.values()) {\n unsubscribe();\n }\n this.transcriptUnsubscribers.clear();\n for (const timer of this.taskCompleteAutoStopTimers.values()) {\n clearTimeout(timer);\n }\n this.taskCompleteAutoStopTimers.clear();\n for (const timer of this.completionReconcileTimers.values()) {\n clearInterval(timer);\n }\n this.completionReconcileTimers.clear();\n this.completionSignalSince.clear();\n for (const timer of this.authRecoveryTimers.values()) {\n clearInterval(timer);\n }\n this.authRecoveryTimers.clear();\n for (const flow of this.activeAuthFlows.values()) {\n try {\n flow.stop();\n } catch {\n // Ignore auth-helper cleanup failures on shutdown.\n }\n }\n this.activeAuthFlows.clear();\n\n if (this.manager) {\n await this.manager.shutdown();\n this.manager = null;\n }\n this.sessionMetadata.clear();\n this.sessionNames.clear();\n this.sessionWorkdirs.clear();\n this.sessionOutputBuffers.clear();\n this.log(\"PTYService shutdown complete\");\n }\n\n private generateSessionId(): string {\n return `pty-${Date.now()}-${crypto.randomUUID().slice(0, 8)}`;\n }\n\n /** Build a SessionIOContext from current instance state. */\n private ioContext(): SessionIOContext {\n return {\n manager: this.manager as PTYManager | BunCompatiblePTYManager,\n usingBunWorker: this.usingBunWorker,\n sessionOutputBuffers: this.sessionOutputBuffers,\n taskResponseMarkers: this.taskResponseMarkers,\n outputUnsubscribers: this.outputUnsubscribers,\n };\n }\n\n /**\n * Spawn a new PTY session for a coding agent\n */\n async spawnSession(options: SpawnSessionOptions): Promise<SessionInfo> {\n return withLinkedSpawn(\n this.runtime,\n {\n source: \"plugin-agent-orchestrator:pty-spawn\",\n metadata: {\n name: options.name,\n requestedType: options.agentType,\n ...options.metadata,\n },\n env: options.env,\n childId: (session) => session.id,\n },\n (trajectory) =>\n this.spawnSessionInternal({\n ...options,\n env: trajectory.env,\n metadata: trajectory.metadata,\n }),\n );\n }\n\n private async spawnSessionInternal(\n options: SpawnSessionOptions,\n ): Promise<SessionInfo> {\n if (!this.manager) {\n throw new Error(\"PTYService not initialized\");\n }\n\n const piRequested = isPiAgentType(options.agentType);\n const opencodeRequested = isOpencodeAgentType(options.agentType);\n const resolvedAgentType: CodingAgentType =\n piRequested || opencodeRequested ? \"shell\" : options.agentType;\n const effectiveApprovalPreset =\n options.approvalPreset ??\n (resolvedAgentType !== \"shell\" ? this.defaultApprovalPreset : undefined);\n\n let opencodeConfigEnv: Record<string, string> | undefined;\n if (opencodeRequested) {\n const spawnConfig = buildOpencodeSpawnConfig(this.runtime);\n if (!spawnConfig) {\n throw new Error(\n \"OpenCode is requested but no model provider is configured. \" +\n \"Set PARALLAX_LLM_PROVIDER=cloud and pair an Eliza Cloud key, \" +\n \"set PARALLAX_OPENCODE_LOCAL=1 to use a local provider, \" +\n \"or set PARALLAX_OPENCODE_MODEL_POWERFUL to defer to your global opencode.json.\",\n );\n }\n opencodeConfigEnv = {\n OPENCODE_CONFIG_CONTENT: spawnConfig.configContent,\n OPENCODE_DISABLE_AUTOUPDATE: \"1\",\n OPENCODE_DISABLE_TERMINAL_TITLE: \"1\",\n };\n this.log(\n `OpenCode spawn provider: ${spawnConfig.providerLabel} (model=${spawnConfig.model}${spawnConfig.smallModel ? `, small=${spawnConfig.smallModel}` : \"\"})`,\n );\n }\n\n const maxSessions = this.serviceConfig.maxConcurrentSessions ?? 8;\n const activeSessions = (await this.listSessions()).length;\n if (activeSessions >= maxSessions) {\n throw new Error(`Concurrent session limit reached (${maxSessions})`);\n }\n\n const sessionId = this.generateSessionId();\n const hasParentTrajectoryStep =\n typeof options.metadata?.[TRAJECTORY_PARENT_STEP_METADATA_KEY] ===\n \"string\" &&\n options.metadata[TRAJECTORY_PARENT_STEP_METADATA_KEY].trim().length > 0;\n const linkedMetadata = hasParentTrajectoryStep\n ? {\n ...options.metadata,\n [TRAJECTORY_CHILD_STEP_METADATA_KEY]: sessionId,\n }\n : options.metadata;\n const linkedEnv = hasParentTrajectoryStep\n ? {\n ...options.env,\n [TRAJECTORY_CHILD_STEP_ENV_KEY]: sessionId,\n }\n : options.env;\n const workdir = options.workdir ?? process.cwd();\n const workspaceLock = buildWorkspaceLockMemory(workdir, resolvedAgentType);\n const workspaceTaskPrefix = buildInlineWorkspaceTaskPrefix(workdir);\n const serverPort = resolveServerPort(this.runtime);\n const parentRuntimeBridge = buildParentRuntimeBridgeMemory(\n sessionId,\n serverPort,\n );\n const shouldWriteMemoryFile = resolvedAgentType !== \"shell\";\n const hasCallerMemoryContent = Boolean(options.memoryContent?.trim());\n // The workspace lock is markdown prose meant to be read as CLAUDE.md\n // (or equivalent) by a reasoning subagent. Shell sessions receive\n // `initialTask` as literal stdin for /bin/bash, so any prose we prepend\n // would land as garbage \"command not found\" output and kick the\n // coordinator into a respond-loop. For shell agents we never prepend\n // the lock: shell tasks are expected to be bare commands, and staying\n // inside the workdir is enforced by the `cwd` we spawn the PTY with\n // (not by an advisory markdown note).\n const effectiveInitialTask =\n hasCallerMemoryContent || resolvedAgentType === \"shell\"\n ? options.initialTask\n : prependWorkspaceLockToTask(options.initialTask, workspaceTaskPrefix);\n const resolvedInitialTask = piRequested\n ? toPiCommand(effectiveInitialTask)\n : opencodeRequested\n ? toOpencodeCommand(effectiveInitialTask)\n : effectiveInitialTask;\n\n // Store workdir for later retrieval\n this.sessionWorkdirs.set(sessionId, workdir);\n\n // Pre-seed trust-dialog acceptance for claude workdirs. Claude Code shows\n // a one-time \"Bypass Permissions\" confirmation in every workdir whose\n // trust dialog hasn't been accepted. The dialog defaults \"No, exit\" on\n // Enter and kills the subagent before any work runs. Writing\n // `hasTrustDialogAccepted: true` into ~/.claude.json's `projects` map\n // skips both that dialog and the per-workdir trust prompt. No-op for\n // other agent types.\n if (resolvedAgentType === \"claude\") {\n await seedClaudeTrustForWorkdir(workdir).catch((err) =>\n this.log(`Failed to pre-seed claude trust for ${workdir}: ${err}`),\n );\n }\n\n // Write memory content before spawning so the agent reads it on startup.\n // Always include the workspace lock and parent bridge so spawned agents\n // stay in-bounds and can read narrowly-scoped parent context.\n if (shouldWriteMemoryFile) {\n const fullMemory = [\n workspaceLock,\n parentRuntimeBridge,\n options.memoryContent,\n ]\n .filter((section) => section?.trim())\n .join(\"\\n\\n---\\n\\n\");\n try {\n const writtenPath = await this.writeMemoryFile(\n resolvedAgentType as AdapterType,\n workdir,\n fullMemory,\n );\n this.log(`Wrote memory file for ${resolvedAgentType}: ${writtenPath}`);\n } catch (err) {\n this.log(\n `Failed to write memory file for ${resolvedAgentType}: ${err}`,\n );\n }\n }\n\n let codexApprovalEnv: Record<string, string> | undefined;\n\n // Write approval config files before spawn.\n if (effectiveApprovalPreset && resolvedAgentType !== \"shell\") {\n if (resolvedAgentType === \"codex\") {\n const codexHome = await prepareCodexHome(\n sessionId,\n effectiveApprovalPreset,\n options.credentials,\n );\n codexApprovalEnv = { CODEX_HOME: codexHome };\n this.log(\n `Wrote Codex approval config (${effectiveApprovalPreset}) to ${join(codexHome, \"config.toml\")}`,\n );\n } else {\n try {\n const written = await this.getAdapter(\n resolvedAgentType as AdapterType,\n ).writeApprovalConfig(workdir, {\n name: options.name,\n type: resolvedAgentType,\n workdir,\n adapterConfig: { approvalPreset: effectiveApprovalPreset },\n } as SpawnConfig);\n this.log(\n `Wrote approval config (${effectiveApprovalPreset}) for ${resolvedAgentType}: ${written.join(\", \")}`,\n );\n } catch (err) {\n this.log(`Failed to write approval config: ${err}`);\n }\n }\n }\n\n // Inject agent-specific settings and HTTP hooks\n const hookUrl = `http://localhost:${serverPort}/api/coding-agents/hooks`;\n\n if (resolvedAgentType === \"claude\") {\n try {\n const settingsPath = join(workdir, \".claude\", \"settings.json\");\n let settings: Record<string, unknown> = {};\n try {\n settings = JSON.parse(await readFile(settingsPath, \"utf-8\"));\n } catch {\n // File may not exist yet\n }\n const permissions =\n (settings.permissions as Record<string, unknown>) ?? {};\n permissions.allowedDirectories = [workdir];\n settings.permissions = permissions;\n\n // Inject HTTP hooks for deterministic state detection.\n // Merge with existing hooks to preserve workspace-owned hook entries.\n const adapter = this.getAdapter(\"claude\");\n const hookProtocol = adapter.getHookTelemetryProtocol({\n httpUrl: hookUrl,\n sessionId,\n });\n if (hookProtocol) {\n const existingHooks = (settings.hooks ?? {}) as Record<\n string,\n unknown\n >;\n settings.hooks = { ...existingHooks, ...hookProtocol.settingsHooks };\n this.log(`Injecting HTTP hooks for session ${sessionId}`);\n }\n\n await mkdir(dirname(settingsPath), { recursive: true });\n await writeFile(\n settingsPath,\n JSON.stringify(settings, null, 2),\n \"utf-8\",\n );\n this.log(`Wrote allowedDirectories [${workdir}] to ${settingsPath}`);\n } catch (err) {\n this.log(`Failed to write Claude settings: ${err}`);\n }\n }\n\n if (resolvedAgentType === \"gemini\") {\n try {\n const settingsPath = join(workdir, \".gemini\", \"settings.json\");\n let settings: Record<string, unknown> = {};\n try {\n settings = JSON.parse(await readFile(settingsPath, \"utf-8\"));\n } catch {\n // File may not exist yet\n }\n\n // Inject command hooks that curl the orchestrator endpoint.\n // Merge with existing hooks to preserve workspace-owned hook entries.\n const adapter = this.getAdapter(\"gemini\");\n const hookProtocol = adapter.getHookTelemetryProtocol({\n httpUrl: hookUrl,\n sessionId,\n });\n if (hookProtocol) {\n const existingHooks = (settings.hooks ?? {}) as Record<\n string,\n unknown\n >;\n settings.hooks = { ...existingHooks, ...hookProtocol.settingsHooks };\n this.log(`Injecting Gemini CLI hooks for session ${sessionId}`);\n }\n\n await mkdir(dirname(settingsPath), { recursive: true });\n await writeFile(\n settingsPath,\n JSON.stringify(settings, null, 2),\n \"utf-8\",\n );\n } catch (err) {\n this.log(`Failed to write Gemini settings: ${err}`);\n }\n }\n\n // Ensure injected config/memory files are gitignored so agents don't\n // commit them. Appends to existing .gitignore if present.\n if (resolvedAgentType !== \"shell\" && workdir !== process.cwd()) {\n await this.ensureOrchestratorGitignore(workdir);\n }\n\n // Centralize model-pref resolution across spawn paths. Reads runtime\n // settings (PARALLAX_*_MODEL_POWERFUL/FAST) and merges in any caller-\n // supplied options.metadata.modelPrefs. Restored after a merge that\n // accidentally took feat's narrower path.\n const resolvedModelPrefs = getTaskAgentModelPrefs(\n this.runtime,\n resolvedAgentType,\n readTaskAgentModelPrefs(linkedMetadata?.modelPrefs),\n );\n const metadataWithoutModelPrefs = { ...linkedMetadata };\n delete metadataWithoutModelPrefs.modelPrefs;\n const codexExecMode = shouldUseCodexExecMode({\n agentType: resolvedAgentType,\n initialTask: resolvedInitialTask,\n });\n const codexExecOutputDir = codexExecMode\n ? await mkdtemp(join(tmpdir(), `eliza-codex-${sessionId}-`))\n : undefined;\n const codexExecOutputFile = codexExecOutputDir\n ? join(codexExecOutputDir, \"last-message.txt\")\n : undefined;\n const resolvedMetadata = {\n ...metadataWithoutModelPrefs,\n requestedType: linkedMetadata?.requestedType ?? options.agentType,\n agentType: resolvedAgentType,\n coordinatorManaged: !!options.skipAdapterAutoResponse,\n ...(codexExecMode ? { codexExecMode: true } : {}),\n ...(codexExecOutputDir ? { codexExecOutputDir } : {}),\n ...(codexExecOutputFile ? { codexExecOutputFile } : {}),\n ...(resolvedModelPrefs ? { modelPrefs: resolvedModelPrefs } : {}),\n };\n\n const mergedSpawnEnv = {\n ...linkedEnv,\n ...codexApprovalEnv,\n ...opencodeConfigEnv,\n };\n const spawnConfig = buildSpawnConfig(\n sessionId,\n {\n ...options,\n env:\n Object.keys(mergedSpawnEnv).length > 0 ? mergedSpawnEnv : undefined,\n agentType: resolvedAgentType,\n initialTask: resolvedInitialTask,\n approvalPreset: effectiveApprovalPreset,\n metadata: resolvedMetadata,\n },\n workdir,\n );\n this.sessionMetadata.set(sessionId, resolvedMetadata);\n let session: SessionHandle | WorkerSessionHandle;\n try {\n session = await this.manager.spawn(spawnConfig);\n } catch (error) {\n if (codexExecOutputDir) {\n await rm(codexExecOutputDir, { recursive: true, force: true }).catch(\n (cleanupError) =>\n this.log(\n `Failed to remove Codex exec output dir ${codexExecOutputDir}: ${cleanupError}`,\n ),\n );\n }\n this.sessionMetadata.delete(sessionId);\n throw error;\n }\n this.terminalSessionStates.delete(session.id);\n this.sessionNames.set(session.id, options.name);\n\n // Store metadata separately (always include agentType for stall classification)\n this.sessionMetadata.set(session.id, resolvedMetadata);\n\n // Build spawn context for delegating to extracted spawn modules\n const ctx = {\n manager: this.manager as PTYManager | BunCompatiblePTYManager,\n usingBunWorker: this.usingBunWorker,\n serviceConfig: this.serviceConfig,\n sessionMetadata: this.sessionMetadata,\n sessionWorkdirs: this.sessionWorkdirs,\n sessionOutputBuffers: this.sessionOutputBuffers,\n outputUnsubscribers: this.outputUnsubscribers,\n taskResponseMarkers: this.taskResponseMarkers,\n getAdapter: (t: AdapterType) => this.getAdapter(t),\n sendToSession: (id: string, input: string) =>\n this.sendToSession(id, input),\n sendKeysToSession: (id: string, keys: string | string[]) =>\n this.sendKeysToSession(id, keys),\n writeRawToSession: async (id: string, data: string) => {\n if (!this.manager) return;\n if (this.usingBunWorker) {\n await (this.manager as BunCompatiblePTYManager).writeRaw(id, data);\n return;\n }\n const ptySession = (this.manager as PTYManager).getSession(id);\n ptySession?.writeRaw(data);\n },\n pushDefaultRules: (id: string, type: string) =>\n this.pushDefaultRules(id, type),\n toSessionInfo: (s: SessionHandle | WorkerSessionHandle, w?: string) =>\n this.toSessionInfo(s, w),\n log: (msg: string) => this.log(msg),\n markTaskDelivered: (sessionId: string) => {\n const coordinator = this.coordinator;\n if (!coordinator) return;\n void coordinator.setTaskDelivered(sessionId);\n },\n };\n\n // Buffer output for Bun worker path (no logs() method available)\n if (this.usingBunWorker) {\n setupOutputBuffer(ctx, session.id);\n }\n\n // Debug capture: open a capture session and wire stdout feed.\n // Capture files persist after the agent is killed for offline analysis.\n if (isDebugCaptureEnabled()) {\n captureSessionOpen(session.id, resolvedAgentType).catch(() => {});\n if (this.usingBunWorker) {\n (this.manager as BunCompatiblePTYManager).onSessionData(\n session.id,\n (data: string) => {\n captureFeed(session.id, data, \"stdout\");\n },\n );\n } else {\n const ptySession = (this.manager as PTYManager).getSession(session.id);\n if (ptySession) {\n ptySession.on(\"output\", (data: string) => {\n captureFeed(session.id, data, \"stdout\");\n });\n }\n }\n }\n\n this.wireTranscriptCapture(session.id);\n\n // Defer initial task until session is ready.\n // IMPORTANT: Set up the listener BEFORE pushDefaultRules (which has a 1500ms sleep),\n // otherwise session_ready fires during pushDefaultRules and the listener misses it.\n if (resolvedInitialTask) {\n setupDeferredTaskDelivery(\n ctx,\n session,\n resolvedInitialTask,\n resolvedAgentType,\n );\n }\n\n await this.pushDefaultRules(session.id, resolvedAgentType);\n this.metricsTracker.get(resolvedAgentType).spawned++;\n this.log(`Spawned session ${session.id} (${resolvedAgentType})`);\n return this.toSessionInfo(session, workdir);\n }\n\n private autoResponseContext() {\n return {\n manager: this.manager as PTYManager | BunCompatiblePTYManager,\n usingBunWorker: this.usingBunWorker,\n runtime: this.runtime,\n log: (msg: string) => this.log(msg),\n };\n }\n\n private async pushDefaultRules(\n sessionId: string,\n agentType: string,\n ): Promise<void> {\n if (!this.manager) return;\n await pushDefaultAutoResponseRules(\n this.autoResponseContext(),\n sessionId,\n agentType,\n );\n }\n\n private async handleGeminiAuth(sessionId: string): Promise<void> {\n await handleGeminiAuthFlow(\n this.autoResponseContext(),\n sessionId,\n (id, keys) => this.sendKeysToSession(id, keys),\n );\n }\n\n async sendToSession(\n sessionId: string,\n input: string,\n ): Promise<SessionMessage | undefined> {\n if (!this.manager) throw new Error(\"PTYService not initialized\");\n captureFeed(sessionId, input, \"stdin\");\n void this.persistTranscript(sessionId, \"stdin\", input);\n const metadata = this.sessionMetadata.get(sessionId);\n if (metadata) {\n metadata.lastSentInput = input;\n }\n // Caller is feeding the session new work — cancel any pending\n // task_complete auto-stop so the agent gets to actually process this\n // input. (Without this, the SwarmCoordinator's small-LLM correction\n // for hallucinated refusals races against the 5s grace timer and the\n // PTY gets killed before the corrected turn completes.)\n this.cancelTaskCompleteAutoStop(sessionId);\n const message = await sendToSessionIO(this.ioContext(), sessionId, input);\n this.scheduleCompletionReconcile(sessionId);\n return message;\n }\n\n async sendKeysToSession(\n sessionId: string,\n keys: string | string[],\n ): Promise<void> {\n if (!this.manager) throw new Error(\"PTYService not initialized\");\n const content = Array.isArray(keys) ? keys.join(\",\") : keys;\n void this.persistTranscript(sessionId, \"keys\", content);\n return sendKeysToSessionIO(this.ioContext(), sessionId, keys);\n }\n\n /**\n * Cancel a pending task_complete auto-stop for this session. Returns true\n * if a timer was cancelled, false if none was pending. Safe to call any\n * number of times. Intended for the swarm coordinator's task_complete\n * handler so the assessment LLM has time to decide whether to keep the\n * session alive (respond) or stop it (complete/escalate/ignore).\n */\n cancelTaskCompleteAutoStop(sessionId: string): boolean {\n const timer = this.taskCompleteAutoStopTimers.get(sessionId);\n if (!timer) return false;\n clearTimeout(timer);\n this.taskCompleteAutoStopTimers.delete(sessionId);\n return true;\n }\n\n async stopSession(sessionId: string, force = false): Promise<void> {\n if (!this.manager) throw new Error(\"PTYService not initialized\");\n // Any explicit stop supersedes a pending auto-stop.\n const pending = this.taskCompleteAutoStopTimers.get(sessionId);\n if (pending) {\n clearTimeout(pending);\n this.taskCompleteAutoStopTimers.delete(sessionId);\n }\n captureLifecycle(sessionId, \"session_stopped\", force ? \"force\" : undefined);\n this.cancelTaskCompleteAutoStop(sessionId);\n try {\n return await stopSessionIO(\n this.ioContext(),\n sessionId,\n this.sessionMetadata,\n this.sessionWorkdirs,\n (msg) => this.log(msg),\n force,\n );\n } finally {\n this.clearCompletionReconcile(sessionId);\n const authRecoveryTimer = this.authRecoveryTimers.get(sessionId);\n if (authRecoveryTimer) {\n clearInterval(authRecoveryTimer);\n this.authRecoveryTimers.delete(sessionId);\n }\n this.clearTranscriptCapture(sessionId);\n }\n }\n\n /** Default approval preset. Runtime env var takes precedence over config. */\n get defaultApprovalPreset(): ApprovalPreset {\n const fromEnv = this.runtime.getSetting(\n \"PARALLAX_DEFAULT_APPROVAL_PRESET\",\n ) as string | undefined;\n if (\n fromEnv &&\n [\"readonly\", \"standard\", \"permissive\", \"autonomous\"].includes(fromEnv)\n ) {\n return fromEnv as ApprovalPreset;\n }\n return this.serviceConfig.defaultApprovalPreset ?? \"autonomous\";\n }\n\n /** Agent selection strategy. Env var takes precedence. */\n get agentSelectionStrategy(): AgentSelectionStrategy {\n const fromEnv = this.runtime.getSetting(\n \"PARALLAX_AGENT_SELECTION_STRATEGY\",\n ) as string | undefined;\n if (fromEnv && (fromEnv === \"fixed\" || fromEnv === \"ranked\")) {\n return fromEnv;\n }\n return \"fixed\";\n }\n\n /**\n * Default agent type when strategy is \"fixed\".\n * Precedence: config file (`eliza.json` env section, written by the UI)\n * > runtime/env setting > \"claude\" fallback.\n */\n get defaultAgentType(): AdapterType {\n return this.explicitDefaultAgentType ?? \"claude\";\n }\n\n private get explicitDefaultAgentType(): AdapterType | null {\n const fromConfig = readConfigEnvKey(\"PARALLAX_DEFAULT_AGENT_TYPE\");\n const fromRuntimeOrEnv =\n fromConfig ||\n (this.runtime.getSetting(\"PARALLAX_DEFAULT_AGENT_TYPE\") as\n | string\n | undefined);\n if (\n fromRuntimeOrEnv &&\n [\"claude\", \"gemini\", \"codex\", \"aider\"].includes(\n fromRuntimeOrEnv.toLowerCase(),\n )\n ) {\n return fromRuntimeOrEnv.toLowerCase() as AdapterType;\n }\n return null;\n }\n\n /**\n * Resolve which agent type to use when the caller didn't specify one.\n *\n * When the caller explicitly configured a fixed default agent type, fixed\n * mode returns that pinned framework. Otherwise the resolver scores the\n * available frameworks from task shape, auth/install state, and recent\n * metrics so dynamic routing still works on unconfigured installs.\n */\n async resolveAgentType(\n selection?: TaskAgentTaskProfileInput,\n ): Promise<string> {\n if (\n this.agentSelectionStrategy === \"fixed\" &&\n this.explicitDefaultAgentType\n ) {\n return this.explicitDefaultAgentType;\n }\n const frameworkState = await this.getFrameworkState(selection);\n return frameworkState.preferred.id;\n }\n\n async getFrameworkState(\n selection?: TaskAgentTaskProfileInput,\n ): Promise<TaskAgentFrameworkState> {\n const profile = selection\n ? buildTaskAgentTaskProfile(selection)\n : undefined;\n return getTaskAgentFrameworkState(\n this.runtime,\n {\n checkAvailableAgents: (types) => this.checkAvailableAgents(types),\n getAgentMetrics: () => this.metricsTracker.getAll(),\n },\n profile\n ? {\n task: selection?.task,\n repo: selection?.repo,\n workdir: selection?.workdir,\n threadKind: profile.kind,\n subtaskCount: profile.subtaskCount,\n acceptanceCriteria: selection?.acceptanceCriteria,\n }\n : selection,\n );\n }\n\n getSession(sessionId: string): SessionInfo | undefined {\n if (!this.manager) return undefined;\n const session = this.manager.get(sessionId);\n if (!session) return this.toTerminalSessionInfo(sessionId);\n return this.toSessionInfo(session, this.sessionWorkdirs.get(sessionId));\n }\n\n async listSessions(filter?: SessionFilter): Promise<SessionInfo[]> {\n if (!this.manager) return [];\n const sessions = this.usingBunWorker\n ? await this.coalescedBunList()\n : (this.manager as PTYManager).list(filter);\n const liveSessions = sessions.map((session) => {\n const cached = this.manager?.get(session.id);\n return this.toSessionInfo(\n cached ?? session,\n this.sessionWorkdirs.get(session.id),\n );\n });\n const terminalSessions = Array.from(this.terminalSessionStates.keys())\n .filter(\n (sessionId) => !sessions.some((session) => session.id === sessionId),\n )\n .map((sessionId) => this.toTerminalSessionInfo(sessionId))\n .filter((session): session is SessionInfo => session !== undefined);\n return [...liveSessions, ...terminalSessions];\n }\n\n subscribeToOutput(\n sessionId: string,\n callback: (data: string) => void,\n ): () => void {\n if (!this.manager) throw new Error(\"PTYService not initialized\");\n return subscribeToOutputIO(this.ioContext(), sessionId, callback);\n }\n\n async getSessionOutput(sessionId: string, lines?: number): Promise<string> {\n if (!this.manager) throw new Error(\"PTYService not initialized\");\n return getSessionOutputIO(this.ioContext(), sessionId, lines);\n }\n\n /**\n * Whether the adapter currently classifies the session as actively\n * processing work (e.g. Codex's \"esc to interrupt\" status row).\n *\n * The swarm idle watchdog consults this before assuming a session is\n * idle based on output byte diffs, which are fooled by TUIs that\n * redraw the same status row in place via cursor positioning.\n *\n * Returns `false` for unknown sessions or adapters that don't\n * implement `detectLoading`. For Bun-compat mode this round-trips to\n * the worker; for in-process mode it reads the session directly.\n */\n async isSessionLoading(sessionId: string): Promise<boolean> {\n if (!this.manager) return false;\n if (this.usingBunWorker) {\n return (\n (\n this.manager as BunCompatiblePTYManager & {\n isSessionLoading?: (id: string) => Promise<boolean>;\n }\n ).isSessionLoading?.(sessionId) ?? false\n );\n }\n return (\n (\n this.manager as PTYManager & {\n isSessionLoading?: (id: string) => Promise<boolean>;\n }\n ).isSessionLoading?.(sessionId) ?? false\n );\n }\n\n private clearTranscriptCapture(sessionId: string): void {\n const unsubscribe = this.transcriptUnsubscribers.get(sessionId);\n if (unsubscribe) {\n try {\n unsubscribe();\n } catch {\n // Ignore cleanup failures on dead sessions.\n }\n }\n this.transcriptUnsubscribers.delete(sessionId);\n }\n\n private async resolveTaskThreadId(sessionId: string): Promise<string | null> {\n const liveThreadId = this.coordinator?.getTaskContext(sessionId)?.threadId;\n if (liveThreadId) return liveThreadId;\n const metadataThreadId = this.sessionMetadata.get(sessionId)?.threadId;\n if (typeof metadataThreadId === \"string\" && metadataThreadId.trim()) {\n return metadataThreadId;\n }\n return (\n (await this.coordinator?.taskRegistry.findThreadIdBySessionId(\n sessionId,\n )) ?? null\n );\n }\n\n private async persistTranscript(\n sessionId: string,\n direction: \"stdout\" | \"stderr\" | \"stdin\" | \"keys\" | \"system\",\n content: string,\n ): Promise<void> {\n if (!content || !this.coordinator) return;\n const threadId = await this.resolveTaskThreadId(sessionId);\n if (!threadId) return;\n await this.coordinator.taskRegistry.recordTranscript({\n threadId,\n sessionId,\n direction,\n content,\n });\n }\n\n private wireTranscriptCapture(sessionId: string): void {\n if (!this.manager) return;\n this.clearTranscriptCapture(sessionId);\n\n if (this.usingBunWorker) {\n const unsubscribe = (\n this.manager as BunCompatiblePTYManager\n ).onSessionData(sessionId, (data: string) => {\n void this.persistTranscript(sessionId, \"stdout\", data);\n });\n this.transcriptUnsubscribers.set(sessionId, unsubscribe);\n return;\n }\n\n const ptySession = (this.manager as PTYManager).getSession(sessionId);\n if (\n !ptySession ||\n typeof (ptySession as { on?: unknown }).on !== \"function\" ||\n typeof (ptySession as { off?: unknown }).off !== \"function\"\n ) {\n return;\n }\n const onOutput = (data: string) => {\n void this.persistTranscript(sessionId, \"stdout\", data);\n };\n ptySession.on(\"output\", onOutput);\n this.transcriptUnsubscribers.set(sessionId, () => {\n ptySession.off(\"output\", onOutput);\n });\n }\n\n isSessionBlocked(sessionId: string): boolean {\n const session = this.getSession(sessionId);\n return session?.status === \"authenticating\";\n }\n\n /**\n * Find a PTY session ID by its working directory.\n * Used by the HTTP hooks endpoint to correlate Claude's cwd with our session.\n */\n findSessionIdByCwd(cwd: string): string | undefined {\n for (const [sessionId, workdir] of this.sessionWorkdirs) {\n if (workdir === cwd) return sessionId;\n }\n return undefined;\n }\n\n /**\n * Handle an incoming hook event from Claude Code's HTTP hooks.\n * Translates hook events into PTY service events.\n */\n handleHookEvent(\n sessionId: string,\n event: string,\n data: Record<string, unknown>,\n ): void {\n if (\n shouldSuppressCodexExecHookEvent({\n codexExecMode:\n this.sessionMetadata.get(sessionId)?.codexExecMode === true,\n event,\n })\n ) {\n this.log(\n `Ignoring Codex exec hook ${event} for ${sessionId}; process exit fast-path owns completion`,\n );\n return;\n }\n\n // Log high-frequency events (tool_running, permission) at debug level;\n // completion events at info level.\n const summary =\n event === \"tool_running\"\n ? `tool=${(data as { toolName?: string }).toolName ?? \"?\"}`\n : event === \"permission_approved\"\n ? `tool=${(data as { tool?: string }).tool ?? \"?\"}`\n : JSON.stringify(data);\n if (event === \"tool_running\" || event === \"permission_approved\") {\n logger.debug(\n `[PTYService] Hook event for ${sessionId}: ${event} ${summary}`,\n );\n } else {\n this.log(`Hook event for ${sessionId}: ${event} ${summary}`);\n }\n\n // Forward hook event to the underlying PTY session so it can reset its\n // stall timer and update internal status. Without this, the stall detector\n // runs independently of hooks and can falsely escalate hook-managed sessions.\n if (this.manager && this.usingBunWorker) {\n (this.manager as BunCompatiblePTYManager)\n .notifyHookEvent(sessionId, event)\n .catch((err) =>\n logger.debug(\n `[PTYService] Failed to forward hook event to session: ${err}`,\n ),\n );\n }\n\n switch (event) {\n case \"tool_running\":\n this.emitEvent(sessionId, \"tool_running\", { ...data, source: \"hook\" });\n break;\n case \"task_complete\":\n this.emitEvent(sessionId, \"task_complete\", { ...data, source: \"hook\" });\n // Auto-stop the PTY after a short grace period. Without this,\n // subagents sit around firing stall classifications that trigger\n // phantom heartbeats in downstream streamers minutes after the\n // user already got their answer. The coordinator's task_complete\n // handler calls cancelTaskCompleteAutoStop when it needs the\n // session for a follow-up assess+continuation, so the stop only\n // fires when the coordinator is genuinely done with the session.\n this.cancelTaskCompleteAutoStop(sessionId);\n this.taskCompleteAutoStopTimers.set(\n sessionId,\n setTimeout(() => {\n this.taskCompleteAutoStopTimers.delete(sessionId);\n this.stopSession(sessionId).catch((err) => {\n this.log(\n `Auto-stop after task_complete failed for ${sessionId}: ${err instanceof Error ? err.message : String(err)}`,\n );\n });\n }, TASK_COMPLETE_STOP_DELAY_MS),\n );\n break;\n case \"permission_approved\":\n // Permission was auto-approved via PermissionRequest hook.\n // No PTY event needed. The hook response already allowed it.\n break;\n case \"notification\":\n this.emitEvent(sessionId, \"message\", { ...data, source: \"hook\" });\n break;\n case \"session_end\":\n // CLI session is ending. Treat as a stopped event so the coordinator\n // and frontend see the session transition to terminal state.\n this.emitEvent(sessionId, \"stopped\", {\n ...data,\n reason: \"session_end\",\n source: \"hook\",\n });\n break;\n default:\n break;\n }\n }\n\n async checkAvailableAgents(\n types?: AdapterType[],\n ): Promise<PreflightResult[]> {\n const agentTypes =\n types ?? ([\"claude\", \"gemini\", \"codex\", \"aider\"] as AdapterType[]);\n const cacheKey = agentTypes.join(\",\");\n const now = Date.now();\n const cached = this.preflightCache.get(cacheKey);\n if (cached && cached.expiresAt > now) {\n return cached.results;\n }\n\n const active = this.preflightInFlight.get(cacheKey);\n if (active) {\n return active;\n }\n\n const probe = (async () => {\n const results = await checkAdapters(agentTypes);\n const augmented = await augmentTaskAgentPreflightResults(results, {\n runtime: this.runtime,\n });\n this.preflightCache.set(cacheKey, {\n expiresAt: Date.now() + 60_000,\n results: augmented,\n });\n return augmented;\n })();\n\n this.preflightInFlight.set(cacheKey, probe);\n try {\n return await probe;\n } finally {\n this.preflightInFlight.delete(cacheKey);\n }\n }\n\n async getAgentAuthStatus(\n agentType: SupportedTaskAgentAdapter,\n ): Promise<TaskAgentAuthStatus> {\n return await probeTaskAgentAuth(agentType, { runtime: this.runtime });\n }\n\n async triggerAgentAuth(\n agentType: SupportedTaskAgentAdapter,\n ): Promise<TaskAgentAuthLaunchResult> {\n const existing = this.activeAuthFlows.get(agentType);\n if (existing) {\n return existing.snapshot();\n }\n\n clearTaskAgentFrameworkStateCache();\n const currentStatus = await this.getAgentAuthStatus(agentType);\n if (currentStatus.status === \"authenticated\") {\n return {\n launched: true,\n instructions: `${agentType} is already authenticated.`,\n };\n }\n\n const launched = await launchTaskAgentAuthFlow(agentType, {\n runtime: this.runtime,\n });\n if (!launched.handle) {\n return launched.result;\n }\n\n this.activeAuthFlows.set(agentType, launched.handle);\n void launched.handle.completion.finally(() => {\n const active = this.activeAuthFlows.get(agentType);\n if (active === launched.handle) {\n this.activeAuthFlows.delete(agentType);\n }\n clearTaskAgentFrameworkStateCache();\n });\n\n let result = launched.result;\n if (result.url) {\n const browserAssist = await assistTaskAgentBrowserLogin(\n agentType,\n result.url,\n { runtime: this.runtime },\n );\n result = {\n ...result,\n browserOpened: browserAssist.opened,\n browserClicked: browserAssist.clicked,\n browserDetail: browserAssist.detail,\n };\n }\n return result;\n }\n\n async startSessionAuthRecovery(\n sessionId: string,\n agentType: SupportedTaskAgentAdapter,\n login: {\n instructions?: string;\n url?: string;\n deviceCode?: string;\n method?: string;\n promptSnippet?: string;\n },\n ): Promise<\n TaskAgentAuthLaunchResult & {\n recoveryStarted: boolean;\n status: \"recovered\" | \"recovering\" | \"failed\";\n }\n > {\n clearTaskAgentFrameworkStateCache();\n const claudeNonInteractiveAuthError = isTaskAgentNonInteractiveAuthFailure(\n agentType,\n login.instructions,\n login.promptSnippet,\n login.method,\n );\n const status = claudeNonInteractiveAuthError\n ? ({\n status: \"auth_error\",\n detail:\n \"Claude Code non-interactive auth returned 401 invalid credentials.\",\n loginHint: getTaskAgentLoginHint(agentType),\n } satisfies TaskAgentAuthStatus)\n : await this.getAgentAuthStatus(agentType);\n if (status.status === \"authenticated\") {\n const resumed = await this.resumeSessionAfterRecoveredAuth(\n sessionId,\n agentType,\n );\n if (resumed) {\n return {\n launched: true,\n instructions: `${agentType} authentication is already valid. Eliza resumed the blocked session.`,\n recoveryStarted: true,\n status: \"recovered\",\n recoveryTarget: \"same_session\",\n };\n }\n\n const replacement = await this.coordinator?.resumeTaskAfterProviderAuth?.(\n sessionId,\n `${agentType} authentication was refreshed`,\n );\n if (replacement) {\n return {\n launched: true,\n instructions: `${agentType} authentication is already valid. Eliza restarted the task on a fresh session.`,\n recoveryStarted: true,\n status: \"recovered\",\n recoveryTarget: \"replacement_session\",\n replacementSessionId: replacement.replacementSessionId,\n replacementFramework: replacement.replacementFramework,\n };\n }\n\n return {\n launched: false,\n instructions: `${agentType} authentication is valid, but Eliza could not resume the task automatically.`,\n recoveryStarted: false,\n status: \"failed\",\n };\n }\n\n let launch: TaskAgentAuthLaunchResult = {\n launched: false,\n // Whitespace-only auth instructions are not actionable; use the agent\n // hint unless the CLI provides a concrete login prompt.\n instructions:\n (status.status === \"auth_error\"\n ? `Claude Code non-interactive auth failed with 401 invalid credentials. ${status.loginHint ?? getTaskAgentLoginHint(agentType)}`\n : login.instructions?.trim()) ||\n getTaskAgentLoginHint(agentType) ||\n `Authentication is required for ${agentType}.`,\n ...(login.url ? { url: login.url } : {}),\n ...(login.deviceCode ? { deviceCode: login.deviceCode } : {}),\n };\n\n if (status.status !== \"auth_error\" && !launch.url && !launch.deviceCode) {\n launch = await this.triggerAgentAuth(agentType);\n } else if (launch.url) {\n const browserAssist = await assistTaskAgentBrowserLogin(\n agentType,\n launch.url,\n { runtime: this.runtime },\n );\n launch = {\n ...launch,\n launched: true,\n browserOpened: browserAssist.opened,\n browserClicked: browserAssist.clicked,\n browserDetail: browserAssist.detail,\n };\n }\n\n this.monitorSessionAuthRecovery(sessionId, agentType);\n\n return {\n ...launch,\n recoveryStarted: true,\n status: launch.launched ? \"recovering\" : \"failed\",\n };\n }\n\n private monitorSessionAuthRecovery(\n sessionId: string,\n agentType: SupportedTaskAgentAdapter,\n ): void {\n const existing = this.authRecoveryTimers.get(sessionId);\n if (existing) return;\n\n const startedAt = Date.now();\n const timer = setInterval(() => {\n void (async () => {\n const session = this.getSession(sessionId);\n if (\n !session ||\n session.status === \"stopped\" ||\n session.status === \"error\"\n ) {\n clearInterval(timer);\n this.authRecoveryTimers.delete(sessionId);\n return;\n }\n\n const auth = await this.getAgentAuthStatus(agentType);\n if (auth.status === \"authenticated\") {\n clearInterval(timer);\n this.authRecoveryTimers.delete(sessionId);\n clearTaskAgentFrameworkStateCache();\n const resumed = await this.resumeSessionAfterRecoveredAuth(\n sessionId,\n agentType,\n );\n if (resumed) {\n await this.coordinator?.markTaskResumedAfterProviderAuth?.(\n sessionId,\n );\n return;\n }\n await this.coordinator?.resumeTaskAfterProviderAuth?.(\n sessionId,\n `${agentType} authentication was refreshed`,\n );\n return;\n }\n\n if (Date.now() - startedAt > 5 * 60_000) {\n clearInterval(timer);\n this.authRecoveryTimers.delete(sessionId);\n }\n })().catch((error) => {\n this.log(`Auth recovery watcher failed for ${sessionId}: ${error}`);\n clearInterval(timer);\n this.authRecoveryTimers.delete(sessionId);\n });\n }, 2_500);\n\n this.authRecoveryTimers.set(sessionId, timer);\n }\n\n private async resumeSessionAfterRecoveredAuth(\n sessionId: string,\n agentType: SupportedTaskAgentAdapter,\n ): Promise<boolean> {\n const session = this.getSession(sessionId);\n if (!session) return false;\n if (session.status === \"ready\" || session.status === \"busy\") {\n return true;\n }\n\n try {\n await this.sendKeysToSession(sessionId, \"enter\");\n await new Promise((resolve) => setTimeout(resolve, 250));\n await this.sendKeysToSession(sessionId, \"enter\");\n } catch (error) {\n this.log(\n `Failed to nudge ${agentType} session ${sessionId} after auth recovery: ${error}`,\n );\n return false;\n }\n\n const deadline = Date.now() + 8_000;\n while (Date.now() < deadline) {\n const current = this.getSession(sessionId);\n if (!current) return false;\n if (current.status === \"ready\" || current.status === \"busy\") {\n return true;\n }\n if (current.status === \"stopped\" || current.status === \"error\") {\n return false;\n }\n await new Promise((resolve) => setTimeout(resolve, 400));\n }\n\n return false;\n }\n\n getSupportedAgentTypes(): CodingAgentType[] {\n return [\"shell\", \"claude\", \"gemini\", \"codex\", \"aider\", \"pi\", \"opencode\"];\n }\n\n private async classifyStall(\n sessionId: string,\n recentOutput: string,\n ): Promise<StallClassification | null> {\n const meta = this.sessionMetadata.get(sessionId);\n const agentType = (meta?.agentType as string) ?? \"unknown\";\n\n // For coordinator-managed sessions in autonomous mode: use combined\n // classify+decide in a single LLM call. The suggestedResponse is kept\n // intact so pty-manager auto-responds, and the coordinator receives\n // autoResponded: true, skipping the second LLM call in handleBlocked().\n if (\n meta?.coordinatorManaged &&\n this.coordinator?.getSupervisionLevel() === \"autonomous\"\n ) {\n const taskCtx = this.coordinator.getTaskContext(sessionId);\n if (taskCtx) {\n // Suppress stall classification during the post-send cooldown.\n // The agent is processing coordinator input. The output buffer\n // still contains the previous response, so classifying now would\n // produce a stale \"task_complete\" that triggers cascading follow-ups.\n if (taskCtx.lastInputSentAt) {\n const elapsed = Date.now() - taskCtx.lastInputSentAt;\n if (elapsed < POST_SEND_COOLDOWN_MS) {\n this.log(\n `Suppressing stall classification for ${sessionId}: ` +\n `${Math.round(elapsed / 1000)}s since coordinator sent input`,\n );\n return null;\n }\n }\n return classifyAndDecideForCoordinator({\n sessionId,\n recentOutput,\n agentType,\n buffers: this.sessionOutputBuffers,\n traceEntries: this.traceEntries,\n runtime: this.runtime,\n manager: this.manager,\n metricsTracker: this.metricsTracker,\n debugSnapshots: this.serviceConfig.debug === true,\n lastSentInput:\n typeof meta?.lastSentInput === \"string\"\n ? meta.lastSentInput\n : undefined,\n log: (msg: string) => this.log(msg),\n taskContext: {\n sessionId: taskCtx.sessionId,\n agentType: taskCtx.agentType,\n label: taskCtx.label,\n originalTask: taskCtx.originalTask,\n workdir: taskCtx.workdir,\n repo: taskCtx.repo,\n },\n decisionHistory: taskCtx.decisions\n .filter((d) => d.decision !== \"auto_resolved\")\n .slice(-5)\n .map((d) => ({\n event: d.event,\n promptText: d.promptText,\n action: d.decision,\n response: d.response,\n reasoning: d.reasoning,\n })),\n });\n }\n }\n\n const classification = await classifyStallOutput({\n sessionId,\n recentOutput,\n agentType,\n buffers: this.sessionOutputBuffers,\n traceEntries: this.traceEntries,\n runtime: this.runtime,\n manager: this.manager,\n metricsTracker: this.metricsTracker,\n debugSnapshots: this.serviceConfig.debug === true,\n lastSentInput:\n typeof meta?.lastSentInput === \"string\"\n ? meta.lastSentInput\n : undefined,\n log: (msg: string) => this.log(msg),\n });\n\n // When the SwarmCoordinator manages this session (non-autonomous mode),\n // strip suggestedResponse so the PTY worker doesn't auto-respond.\n // The coordinator's LLM decision loop will handle blocked prompts instead.\n if (\n classification &&\n meta?.coordinatorManaged &&\n classification.suggestedResponse\n ) {\n this.log(\n `Suppressing stall auto-response for coordinator-managed session ${sessionId} ` +\n `(would have sent: \"${classification.suggestedResponse}\")`,\n );\n classification.suggestedResponse = undefined;\n }\n\n return classification;\n }\n\n // ─── Workspace Files ───\n\n private getAdapter(agentType: AdapterType): BaseCodingAdapter {\n let adapter = this.adapterCache.get(agentType);\n if (!adapter) {\n adapter = createAdapter(agentType);\n this.adapterCache.set(agentType, adapter);\n }\n return adapter;\n }\n\n getWorkspaceFiles(agentType: AdapterType): AgentFileDescriptor[] {\n return this.getAdapter(agentType).getWorkspaceFiles();\n }\n\n getMemoryFilePath(agentType: AdapterType): string {\n return this.getAdapter(agentType).memoryFilePath;\n }\n\n getApprovalConfig(\n agentType: AdapterType,\n preset: ApprovalPreset,\n ): ApprovalConfig {\n return generateApprovalConfig(agentType, preset);\n }\n\n async writeMemoryFile(\n agentType: AdapterType,\n workspacePath: string,\n content: string,\n options?: WriteMemoryOptions,\n ): Promise<string> {\n return this.getAdapter(agentType).writeMemoryFile(\n workspacePath,\n content,\n options,\n );\n }\n\n // ─── Gitignore for Orchestrator Files ───\n\n /** Marker comment used to detect orchestrator-managed gitignore entries. */\n private static readonly GITIGNORE_MARKER =\n \"# orchestrator-injected (do not commit agent config/memory files)\";\n\n /** Per-path lock to serialize concurrent gitignore updates for the same workdir. */\n private static gitignoreLocks = new Map<string, Promise<void>>();\n\n /**\n * Ensure that orchestrator-injected files (CLAUDE.md, .claude/, GEMINI.md, etc.)\n * are listed in the workspace .gitignore so agents don't commit them.\n * Appends to an existing .gitignore or creates one. Idempotent: skips if\n * the marker comment is already present. Serialized per-path to prevent\n * duplicate entries from concurrent spawns.\n */\n private async ensureOrchestratorGitignore(workdir: string): Promise<void> {\n const gitignorePath = join(workdir, \".gitignore\");\n\n // Serialize per-path: wait for any in-flight update to the same file.\n const existing_lock = PTYService.gitignoreLocks.get(gitignorePath);\n if (existing_lock) await existing_lock;\n\n const task = this.doEnsureGitignore(gitignorePath, workdir);\n PTYService.gitignoreLocks.set(gitignorePath, task);\n try {\n await task;\n } finally {\n // Only delete if we're still the current holder\n if (PTYService.gitignoreLocks.get(gitignorePath) === task) {\n PTYService.gitignoreLocks.delete(gitignorePath);\n }\n }\n }\n\n private async doEnsureGitignore(\n gitignorePath: string,\n workdir: string,\n ): Promise<void> {\n let existing = \"\";\n try {\n existing = await readFile(gitignorePath, \"utf-8\");\n } catch {\n // No .gitignore yet, we'll create one\n }\n\n // Idempotent: skip if we already added our entries\n if (existing.includes(PTYService.GITIGNORE_MARKER)) return;\n\n // Include all common patterns so multi-agent swarms with mixed types are covered.\n const entries = [\n \"\",\n PTYService.GITIGNORE_MARKER,\n \"CLAUDE.md\",\n \".claude/\",\n \"GEMINI.md\",\n \".gemini/\",\n \".aider*\",\n ];\n\n try {\n if (existing.length === 0) {\n // No .gitignore yet, create with just our entries\n await writeFile(gitignorePath, `${entries.join(\"\\n\")}\\n`, \"utf-8\");\n } else {\n // Append-only to avoid clobbering concurrent edits\n const separator = existing.endsWith(\"\\n\") ? \"\" : \"\\n\";\n await appendFile(\n gitignorePath,\n `${separator + entries.join(\"\\n\")}\\n`,\n \"utf-8\",\n );\n }\n } catch (err) {\n this.log(`Failed to update .gitignore in ${workdir}: ${err}`);\n }\n }\n\n // ─── Event & Adapter Registration ───\n\n onSessionEvent(callback: SessionEventCallback): () => void {\n this.eventCallbacks.push(callback);\n return () => {\n const idx = this.eventCallbacks.indexOf(callback);\n if (idx !== -1) this.eventCallbacks.splice(idx, 1);\n };\n }\n\n onNormalizedSessionEvent(\n callback: (event: CoordinatorNormalizedEvent) => void,\n ): () => void {\n this.normalizedEventCallbacks.push(callback);\n return () => {\n const idx = this.normalizedEventCallbacks.indexOf(callback);\n if (idx !== -1) this.normalizedEventCallbacks.splice(idx, 1);\n };\n }\n\n registerAdapter(adapter: unknown): void {\n if (!this.manager) {\n throw new Error(\"PTYService not initialized\");\n }\n\n if (this.usingBunWorker) {\n this.log(\n \"registerAdapter not available with Bun worker - adapters must be in the worker\",\n );\n return;\n }\n\n (this.manager as PTYManager).registerAdapter(\n adapter as Parameters<PTYManager[\"registerAdapter\"]>[0],\n );\n this.log(`Registered adapter`);\n }\n\n private toSessionInfo(\n session: SessionHandle | WorkerSessionHandle,\n workdir?: string,\n ): SessionInfo {\n const metadata = this.sessionMetadata.get(session.id);\n const requestedType =\n typeof metadata?.requestedType === \"string\"\n ? metadata.requestedType\n : undefined;\n const displayAgentType =\n session.type === \"shell\" && isPiAgentType(requestedType)\n ? \"pi\"\n : session.type === \"shell\" && isOpencodeAgentType(requestedType)\n ? \"opencode\"\n : session.type;\n return {\n id: session.id,\n name: session.name,\n agentType: displayAgentType,\n workdir: workdir ?? process.cwd(),\n status: session.status,\n createdAt: session.startedAt ? new Date(session.startedAt) : new Date(),\n lastActivityAt: session.lastActivityAt\n ? new Date(session.lastActivityAt)\n : new Date(),\n metadata,\n };\n }\n\n private toTerminalSessionInfo(sessionId: string): SessionInfo | undefined {\n const terminal = this.terminalSessionStates.get(sessionId);\n if (!terminal) return undefined;\n const metadata = this.sessionMetadata.get(sessionId);\n const requestedType =\n typeof metadata?.requestedType === \"string\"\n ? metadata.requestedType\n : undefined;\n const storedAgentType =\n typeof metadata?.agentType === \"string\" ? metadata.agentType : \"unknown\";\n const displayAgentType =\n storedAgentType === \"shell\" && isPiAgentType(requestedType)\n ? \"pi\"\n : storedAgentType === \"shell\" && isOpencodeAgentType(requestedType)\n ? \"opencode\"\n : storedAgentType;\n return {\n id: sessionId,\n name: this.sessionNames.get(sessionId) ?? sessionId,\n agentType: displayAgentType,\n workdir: this.sessionWorkdirs.get(sessionId) ?? process.cwd(),\n status: terminal.status,\n createdAt: terminal.createdAt,\n lastActivityAt: terminal.lastActivityAt,\n metadata,\n };\n }\n\n private emitEvent(sessionId: string, event: string, data: unknown): void {\n if (\n shouldSuppressCodexExecPtyManagerEvent({\n codexExecMode:\n this.sessionMetadata.get(sessionId)?.codexExecMode === true,\n event,\n data,\n })\n ) {\n return;\n }\n if (\n event === \"blocked\" &&\n this.shouldSuppressBlockedEvent(sessionId, data)\n ) {\n return;\n }\n if (\n event === \"ready\" ||\n event === \"task_complete\" ||\n event === \"stopped\" ||\n event === \"error\"\n ) {\n this.clearCompletionReconcile(sessionId);\n }\n if (event === \"stopped\" || event === \"error\") {\n const authRecoveryTimer = this.authRecoveryTimers.get(sessionId);\n if (authRecoveryTimer) {\n clearInterval(authRecoveryTimer);\n this.authRecoveryTimers.delete(sessionId);\n }\n const liveSession = this.manager?.get(sessionId);\n const createdAt =\n liveSession?.startedAt instanceof Date\n ? liveSession.startedAt\n : liveSession?.startedAt\n ? new Date(liveSession.startedAt)\n : new Date();\n const lastActivityAt =\n liveSession?.lastActivityAt instanceof Date\n ? liveSession.lastActivityAt\n : liveSession?.lastActivityAt\n ? new Date(liveSession.lastActivityAt)\n : new Date();\n const reason =\n event === \"stopped\"\n ? (data as { reason?: string } | undefined)?.reason\n : (data as { message?: string } | undefined)?.message;\n this.terminalSessionStates.set(sessionId, {\n status: event,\n createdAt,\n lastActivityAt,\n reason,\n });\n }\n\n for (const callback of this.eventCallbacks) {\n try {\n callback(sessionId, event, data);\n } catch (err) {\n this.log(`Event callback error: ${err}`);\n }\n }\n const normalized = normalizeCoordinatorEvent(sessionId, event, data);\n if (!normalized) return;\n for (const callback of this.normalizedEventCallbacks) {\n try {\n callback(normalized);\n } catch (err) {\n this.log(`Normalized event callback error: ${err}`);\n }\n }\n }\n\n // ─── Metrics ───\n\n getAgentMetrics() {\n return this.metricsTracker.getAll();\n }\n\n private log(message: string): void {\n logger.debug(`[PTYService] ${message}`);\n }\n\n private handleWorkerExit(info: {\n code: number | null;\n signal: string | null;\n }): void {\n const trackedSessionIds = new Set([\n ...this.sessionMetadata.keys(),\n ...this.sessionWorkdirs.keys(),\n ]);\n if (trackedSessionIds.size === 0) {\n return;\n }\n\n const reason = info.signal\n ? `PTY worker exited unexpectedly (signal ${info.signal})`\n : `PTY worker exited unexpectedly (code ${info.code ?? \"unknown\"})`;\n\n for (const sessionId of trackedSessionIds) {\n const terminalState = this.terminalSessionStates.get(sessionId);\n if (\n terminalState?.status === \"stopped\" ||\n terminalState?.status === \"error\"\n ) {\n continue;\n }\n this.emitEvent(sessionId, \"error\", {\n message: reason,\n workerExit: info,\n source: \"pty_manager\",\n });\n }\n }\n\n private clearCompletionReconcile(sessionId: string): void {\n const timer = this.completionReconcileTimers.get(sessionId);\n if (timer) {\n clearInterval(timer);\n this.completionReconcileTimers.delete(sessionId);\n }\n this.completionSignalSince.delete(sessionId);\n }\n\n private scheduleCompletionReconcile(sessionId: string): void {\n this.clearCompletionReconcile(sessionId);\n const timer = setInterval(() => {\n void this.reconcileBusySessionFromOutput(sessionId);\n }, 1000);\n this.completionReconcileTimers.set(sessionId, timer);\n void this.reconcileBusySessionFromOutput(sessionId);\n }\n\n private isAdapterBackedAgentType(value: unknown): value is AdapterType {\n return (\n value === \"claude\" ||\n value === \"gemini\" ||\n value === \"codex\" ||\n value === \"aider\" ||\n value === \"hermes\"\n );\n }\n\n private shouldSuppressBlockedEvent(\n sessionId: string,\n data: unknown,\n ): boolean {\n const payload = data as\n | {\n promptInfo?: unknown;\n source?: unknown;\n }\n | undefined;\n if (payload?.source !== \"pty_manager\") {\n return false;\n }\n const promptInfo =\n payload.promptInfo &&\n typeof payload.promptInfo === \"object\" &&\n !Array.isArray(payload.promptInfo)\n ? (payload.promptInfo as Record<string, unknown>)\n : undefined;\n if (!promptInfo) {\n return false;\n }\n const promptType =\n typeof promptInfo.type === \"string\" ? promptInfo.type.toLowerCase() : \"\";\n if (promptType && promptType !== \"unknown\") {\n return false;\n }\n const promptText =\n typeof promptInfo.prompt === \"string\"\n ? cleanForChat(promptInfo.prompt)\n : \"\";\n if (!promptText) {\n return false;\n }\n const compactPrompt = promptText.replace(/\\s+/g, \" \").trim();\n const hasWorkspacePath = /(\\/private\\/|\\/var\\/folders\\/)/.test(\n compactPrompt,\n );\n const looksLikeWorkingStatus =\n /working \\(\\d+s .*esc to interrupt\\)/i.test(compactPrompt) ||\n /messages to be submitted after next tool call/i.test(compactPrompt) ||\n /find and fix a bug in @filename/i.test(compactPrompt) ||\n /use \\/skills to list available skills/i.test(compactPrompt);\n const looksLikeSpinnerTail =\n /\\b\\d+% left\\b/i.test(compactPrompt) && hasWorkspacePath;\n const looksLikeSpinnerFragments =\n hasWorkspacePath &&\n /(?:\\bW Wo\\b|• Wor|• Work|Worki|Workin|Working)/i.test(compactPrompt);\n if (\n !looksLikeWorkingStatus &&\n !looksLikeSpinnerTail &&\n !looksLikeSpinnerFragments\n ) {\n return false;\n }\n this.log(\n `Suppressing false blocked prompt noise for ${sessionId}: ${compactPrompt.slice(0, 160)}`,\n );\n return true;\n }\n\n private responseLooksMeaningful(\n response: string,\n rawOutput: string,\n ): boolean {\n if (extractCompletionSummary(rawOutput).trim().length > 0) {\n return true;\n }\n const cleaned = response.trim();\n if (!cleaned) return false;\n const substantiveLines = cleaned\n .split(\"\\n\")\n .map((line) => line.trim())\n .filter((line) => line.length > 0)\n .filter(\n (line) =>\n !line.startsWith(\"› \") &&\n !/^Work(?:i|in|ing)?(?:\\s+\\d+)?$/i.test(line) &&\n !/^\\d+% left\\b/i.test(line) &&\n !/context left/i.test(line) &&\n !/esc to interrupt/i.test(line) &&\n !/Use \\/skills/i.test(line) &&\n !/Messages to be submitted after next tool call/i.test(line),\n );\n if (\n substantiveLines.some((line) =>\n /\\b(Added|Created|Creating|Updated|Wrote|Deleted|Renamed|Verified|Completed|Finished|Saved|Ran|LIVE_)\\b/i.test(\n line,\n ),\n )\n ) {\n return true;\n }\n return false;\n }\n\n private async reconcileBusySessionFromOutput(\n sessionId: string,\n ): Promise<void> {\n if (!this.manager) {\n this.clearCompletionReconcile(sessionId);\n return;\n }\n\n const liveSession = this.manager.get(sessionId);\n if (!liveSession) {\n this.clearCompletionReconcile(sessionId);\n return;\n }\n\n if (liveSession.status !== \"busy\") {\n this.clearCompletionReconcile(sessionId);\n return;\n }\n\n const agentType = this.sessionMetadata.get(sessionId)?.agentType;\n if (!this.isAdapterBackedAgentType(agentType)) {\n this.clearCompletionReconcile(sessionId);\n return;\n }\n\n const adapter = this.getAdapter(agentType);\n const rawOutput = await this.getSessionOutput(sessionId);\n if (!rawOutput.trim()) {\n this.completionSignalSince.delete(sessionId);\n return;\n }\n\n if (adapter.detectLoading?.(rawOutput)) {\n this.completionSignalSince.delete(sessionId);\n return;\n }\n\n if (adapter.detectLogin(rawOutput).required) {\n this.completionSignalSince.delete(sessionId);\n return;\n }\n\n if (adapter.detectBlockingPrompt(rawOutput).detected) {\n this.completionSignalSince.delete(sessionId);\n return;\n }\n\n const completionSignal = adapter.detectTaskComplete\n ? adapter.detectTaskComplete(rawOutput)\n : adapter.detectReady(rawOutput);\n if (!completionSignal) {\n this.completionSignalSince.delete(sessionId);\n return;\n }\n\n const previewResponse = this.taskResponseMarkers.has(sessionId)\n ? peekTaskResponse(\n sessionId,\n this.sessionOutputBuffers,\n this.taskResponseMarkers,\n )\n : cleanForChat(rawOutput);\n if (!this.responseLooksMeaningful(previewResponse, rawOutput)) {\n this.completionSignalSince.delete(sessionId);\n return;\n }\n\n const firstSeenAt = this.completionSignalSince.get(sessionId);\n if (firstSeenAt === undefined) {\n this.completionSignalSince.set(sessionId, Date.now());\n return;\n }\n\n if (Date.now() - firstSeenAt < 2500) {\n return;\n }\n\n const response = this.taskResponseMarkers.has(sessionId)\n ? captureTaskResponse(\n sessionId,\n this.sessionOutputBuffers,\n this.taskResponseMarkers,\n )\n : previewResponse;\n const durationMs = liveSession.startedAt\n ? Date.now() - new Date(liveSession.startedAt).getTime()\n : 0;\n liveSession.status = \"ready\";\n liveSession.lastActivityAt = new Date();\n this.metricsTracker.recordCompletion(\n agentType,\n \"output-reconcile\",\n durationMs,\n );\n this.log(\n `Reconciled ${sessionId} from busy to task_complete using stable adapter output`,\n );\n this.emitEvent(sessionId, \"task_complete\", {\n session: liveSession,\n response,\n source: \"output_reconcile\",\n });\n }\n}\n",
|
|
38
|
+
"import { readFileSync } from \"node:fs\";\nimport path from \"node:path\";\nimport { getElizaNamespace, resolveStateDir, resolveUserPath } from \"@elizaos/core\";\nimport { extractDevServerUrl } from \"./ansi-utils.js\";\nimport type { SwarmCoordinator } from \"./swarm-coordinator.js\";\nimport type { TaskArtifactRecord, TaskThreadDetail } from \"./task-registry.js\";\n\nexport type TaskShareTargetType =\n | \"artifact_uri\"\n | \"artifact_path\"\n | \"preview_url\"\n | \"workspace\";\n\nexport interface TaskShareTarget {\n type: TaskShareTargetType;\n label: string;\n value: string;\n source: string;\n remoteAccessible: boolean;\n}\n\nexport interface TaskShareDiscovery {\n threadId: string;\n title: string;\n shareCapabilities: string[];\n preferredTarget: TaskShareTarget | null;\n targets: TaskShareTarget[];\n}\n\nconst URL_RE = /\\bhttps?:\\/\\/[^\\s<>\"'`]+/gi;\n\nfunction resolveConfigPath(): string {\n const explicit = process.env.ELIZA_CONFIG_PATH?.trim();\n if (explicit) return resolveUserPath(explicit);\n\n const namespace = getElizaNamespace();\n const filename = namespace === \"eliza\" ? \"eliza.json\" : `${namespace}.json`;\n return path.join(resolveStateDir(), filename);\n}\n\nfunction readElizaConfig(): Record<string, unknown> | null {\n try {\n const raw = readFileSync(resolveConfigPath(), \"utf8\");\n const parsed = JSON.parse(raw) as unknown;\n return parsed && typeof parsed === \"object\" && !Array.isArray(parsed)\n ? (parsed as Record<string, unknown>)\n : null;\n } catch {\n return null;\n }\n}\n\nfunction detectShareCapabilities(): string[] {\n const config = readElizaConfig();\n const capabilities: string[] = [];\n const gateway =\n config && typeof config.gateway === \"object\" && config.gateway\n ? (config.gateway as Record<string, unknown>)\n : null;\n const gatewayTailscale =\n gateway && typeof gateway.tailscale === \"object\" && gateway.tailscale\n ? (gateway.tailscale as Record<string, unknown>)\n : null;\n const gatewayRemote =\n gateway && typeof gateway.remote === \"object\" && gateway.remote\n ? (gateway.remote as Record<string, unknown>)\n : null;\n\n const tailscaleMode =\n typeof gatewayTailscale?.mode === \"string\" ? gatewayTailscale.mode : null;\n if (tailscaleMode && tailscaleMode !== \"off\") {\n capabilities.push(`tailscale:${tailscaleMode}`);\n }\n if (typeof gatewayRemote?.url === \"string\" && gatewayRemote.url.trim()) {\n capabilities.push(\"gateway-remote-url\");\n }\n if (\n typeof gatewayRemote?.sshTarget === \"string\" &&\n gatewayRemote.sshTarget.trim()\n ) {\n capabilities.push(\"gateway-remote-ssh\");\n }\n return capabilities;\n}\n\nfunction isRemoteAccessibleUrl(value: string): boolean {\n try {\n const parsed = new URL(value);\n const host = parsed.hostname.trim().toLowerCase();\n return ![\"localhost\", \"127.0.0.1\", \"0.0.0.0\"].includes(host);\n } catch {\n return false;\n }\n}\n\nfunction pushTarget(\n targets: TaskShareTarget[],\n seen: Set<string>,\n target: TaskShareTarget,\n): void {\n const key = `${target.type}:${target.value}`;\n if (seen.has(key)) return;\n seen.add(key);\n targets.push(target);\n}\n\nfunction artifactTargets(\n artifacts: TaskArtifactRecord[],\n targets: TaskShareTarget[],\n seen: Set<string>,\n): void {\n for (const artifact of artifacts) {\n if (artifact.uri?.trim()) {\n pushTarget(targets, seen, {\n type: \"artifact_uri\",\n label: artifact.title,\n value: artifact.uri,\n source: `artifact:${artifact.artifactType}`,\n remoteAccessible: isRemoteAccessibleUrl(artifact.uri),\n });\n }\n if (artifact.path?.trim()) {\n pushTarget(targets, seen, {\n type: \"artifact_path\",\n label: artifact.title,\n value: artifact.path,\n source: `artifact:${artifact.artifactType}`,\n remoteAccessible: false,\n });\n }\n }\n}\n\nfunction transcriptTargets(\n thread: TaskThreadDetail,\n targets: TaskShareTarget[],\n seen: Set<string>,\n): void {\n const recentTranscript = (thread.transcripts ?? [])\n .slice(-100)\n .map((entry) => entry.content)\n .join(\"\\n\");\n const previewUrl = extractDevServerUrl(recentTranscript);\n if (previewUrl) {\n pushTarget(targets, seen, {\n type: \"preview_url\",\n label: \"Live preview\",\n value: previewUrl,\n source: \"transcript:dev-server\",\n remoteAccessible: isRemoteAccessibleUrl(previewUrl),\n });\n }\n\n const discoveredUrls = recentTranscript.match(URL_RE) ?? [];\n for (const value of discoveredUrls) {\n pushTarget(targets, seen, {\n type: \"preview_url\",\n label: \"Discovered URL\",\n value,\n source: \"transcript:url\",\n remoteAccessible: isRemoteAccessibleUrl(value),\n });\n }\n}\n\nfunction workspaceTargets(\n thread: TaskThreadDetail,\n targets: TaskShareTarget[],\n seen: Set<string>,\n): void {\n if (thread.latestWorkdir?.trim()) {\n pushTarget(targets, seen, {\n type: \"workspace\",\n label: \"Workspace\",\n value: thread.latestWorkdir,\n source: \"thread:latest-workdir\",\n remoteAccessible: false,\n });\n }\n}\n\nfunction preferredTarget(targets: TaskShareTarget[]): TaskShareTarget | null {\n const remote = targets.find((target) => target.remoteAccessible);\n if (remote) return remote;\n const preview = targets.find((target) => target.type === \"preview_url\");\n if (preview) return preview;\n const artifact = targets.find((target) => target.type === \"artifact_path\");\n if (artifact) return artifact;\n return targets[0] ?? null;\n}\n\nexport async function discoverTaskShareOptions(\n coordinator: SwarmCoordinator,\n threadId: string,\n): Promise<TaskShareDiscovery | null> {\n const thread = await coordinator.getTaskThread(threadId);\n if (!thread) return null;\n\n const targets: TaskShareTarget[] = [];\n const seen = new Set<string>();\n artifactTargets(thread.artifacts ?? [], targets, seen);\n transcriptTargets(thread, targets, seen);\n workspaceTargets(thread, targets, seen);\n\n return {\n threadId: thread.id,\n title: thread.title,\n shareCapabilities: detectShareCapabilities(),\n preferredTarget: preferredTarget(targets),\n targets,\n };\n}\n",
|
|
39
|
+
"/**\n * GitHub integration for Coding Workspace Service\n *\n * Extracted from workspace-service.ts — provides GitHub API access\n * via PAT or OAuth device flow, plus all issue management operations.\n *\n * @module services/workspace-github\n */\n\nimport type { IAgentRuntime } from \"@elizaos/core\";\nimport {\n type CreateIssueOptions,\n GitHubPatClient,\n type IssueComment,\n type IssueInfo,\n type IssueState,\n OAuthDeviceFlow,\n} from \"git-workspace-service\";\n\n/**\n * Callback for surfacing auth prompts to the user.\n * Returns true only when the prompt was delivered through an immediate\n * user-visible channel. Buffered action callbacks are unsafe here because the\n * device flow blocks until the user sees and completes the prompt.\n */\nexport type AuthPromptCallback = (prompt: {\n verificationUri: string;\n userCode: string;\n expiresIn: number;\n}) => boolean | Promise<boolean>;\n\n/**\n * Context object passed by CodingWorkspaceService into every GitHub function.\n * Lets us keep the extracted functions stateless while still mutating shared state.\n */\nexport interface GitHubContext {\n runtime: IAgentRuntime;\n githubClient: GitHubPatClient | null;\n setGithubClient: (client: GitHubPatClient) => void;\n githubAuthInProgress: Promise<GitHubPatClient> | null;\n setGithubAuthInProgress: (p: Promise<GitHubPatClient> | null) => void;\n authPromptCallback: AuthPromptCallback | null;\n log: (msg: string) => void;\n}\n\n// ── Helpers ────────────────────────────────────────────────────────\n\nexport function parseOwnerRepo(repo: string): {\n owner: string;\n repo: string;\n} {\n // Handle URLs like https://github.com/owner/repo or owner/repo\n const match = repo.match(/(?:github\\.com\\/)?([^/]+)\\/([^/.]+)/);\n if (!match) {\n throw new Error(`Cannot parse owner/repo from: ${repo}`);\n }\n return { owner: match[1], repo: match[2] };\n}\n\n// ── Auth ───────────────────────────────────────────────────────────\n\nexport async function ensureGitHubClient(\n ctx: GitHubContext,\n): Promise<GitHubPatClient> {\n // Already have a client\n if (ctx.githubClient) return ctx.githubClient;\n\n // Auth already in progress (another call triggered it) - wait for it\n if (ctx.githubAuthInProgress) return ctx.githubAuthInProgress;\n\n // Check for PAT (re-check in case it was set after init)\n const githubToken = ctx.runtime.getSetting(\"GITHUB_TOKEN\") as\n | string\n | undefined;\n if (githubToken) {\n const client = new GitHubPatClient({ token: githubToken });\n ctx.setGithubClient(client);\n ctx.log(\"GitHubPatClient initialized with PAT (late binding)\");\n return client;\n }\n\n // Try OAuth device flow (explicit user consent, scoped permissions)\n const clientId = ctx.runtime.getSetting(\"GITHUB_OAUTH_CLIENT_ID\") as\n | string\n | undefined;\n if (!clientId) {\n throw new Error(\n \"GitHub access required but no credentials available. \" +\n \"Set GITHUB_TOKEN (PAT) or GITHUB_OAUTH_CLIENT_ID (for OAuth device flow).\",\n );\n }\n\n // Start OAuth - deduplicate concurrent requests\n const authPromise = performOAuthFlow(ctx, clientId);\n ctx.setGithubAuthInProgress(authPromise);\n try {\n const client = await authPromise;\n return client;\n } finally {\n ctx.setGithubAuthInProgress(null);\n }\n}\n\nexport async function performOAuthFlow(\n ctx: GitHubContext,\n clientId: string,\n): Promise<GitHubPatClient> {\n // Read directly from process.env — this is a server-side secret that\n // should not be exposed through the plugin getSetting() allowlist.\n const clientSecret = process.env.GITHUB_OAUTH_CLIENT_SECRET;\n\n const oauth = new OAuthDeviceFlow({\n clientId,\n clientSecret,\n permissions: {\n repositories: { type: \"public\" },\n contents: \"write\",\n issues: \"write\",\n pullRequests: \"write\",\n metadata: \"read\",\n },\n timeout: 300, // 5 minutes\n });\n\n // Step 1: Request device code\n const deviceCode = await oauth.requestDeviceCode();\n\n // Step 2: Surface the auth prompt to the user\n const delivered = ctx.authPromptCallback\n ? await ctx.authPromptCallback({\n verificationUri: deviceCode.verificationUri,\n userCode: deviceCode.userCode,\n expiresIn: deviceCode.expiresIn,\n })\n : false;\n\n if (!delivered) {\n throw new Error(\n \"GitHub OAuth device flow requires an immediate chat delivery path before polling. \" +\n \"Wire the SwarmCoordinator chat callback or set GITHUB_TOKEN.\",\n );\n }\n\n // Step 3: Poll until user completes auth\n const token = await oauth.pollForToken(deviceCode);\n\n // Step 4: Create client with the obtained token\n const client = new GitHubPatClient({ token: token.accessToken });\n ctx.setGithubClient(client);\n ctx.log(\"GitHubPatClient initialized via OAuth device flow\");\n return client;\n}\n\n// ── Issue Management ───────────────────────────────────────────────\n\nexport async function createIssue(\n ctx: GitHubContext,\n repo: string,\n options: CreateIssueOptions,\n): Promise<IssueInfo> {\n const client = await ensureGitHubClient(ctx);\n const { owner, repo: repoName } = parseOwnerRepo(repo);\n const issue = await client.createIssue(owner, repoName, options);\n ctx.log(`Created issue #${issue.number}: ${issue.title}`);\n return issue;\n}\n\nexport async function getIssue(\n ctx: GitHubContext,\n repo: string,\n issueNumber: number,\n): Promise<IssueInfo> {\n const client = await ensureGitHubClient(ctx);\n const { owner, repo: repoName } = parseOwnerRepo(repo);\n return client.getIssue(owner, repoName, issueNumber);\n}\n\nexport async function listIssues(\n ctx: GitHubContext,\n repo: string,\n options?: {\n state?: IssueState | \"all\";\n labels?: string[];\n assignee?: string;\n },\n): Promise<IssueInfo[]> {\n const client = await ensureGitHubClient(ctx);\n const { owner, repo: repoName } = parseOwnerRepo(repo);\n return client.listIssues(owner, repoName, options);\n}\n\nexport async function updateIssue(\n ctx: GitHubContext,\n repo: string,\n issueNumber: number,\n options: {\n title?: string;\n body?: string;\n state?: IssueState;\n labels?: string[];\n assignees?: string[];\n },\n): Promise<IssueInfo> {\n const client = await ensureGitHubClient(ctx);\n const { owner, repo: repoName } = parseOwnerRepo(repo);\n return client.updateIssue(owner, repoName, issueNumber, options);\n}\n\nexport async function addComment(\n ctx: GitHubContext,\n repo: string,\n issueNumber: number,\n body: string,\n): Promise<IssueComment> {\n const client = await ensureGitHubClient(ctx);\n const { owner, repo: repoName } = parseOwnerRepo(repo);\n return client.addComment(owner, repoName, issueNumber, { body });\n}\n\nexport async function listComments(\n ctx: GitHubContext,\n repo: string,\n issueNumber: number,\n): Promise<IssueComment[]> {\n const client = await ensureGitHubClient(ctx);\n const { owner, repo: repoName } = parseOwnerRepo(repo);\n return client.listComments(owner, repoName, issueNumber);\n}\n\nexport async function closeIssue(\n ctx: GitHubContext,\n repo: string,\n issueNumber: number,\n): Promise<IssueInfo> {\n const client = await ensureGitHubClient(ctx);\n const { owner, repo: repoName } = parseOwnerRepo(repo);\n const issue = await client.closeIssue(owner, repoName, issueNumber);\n ctx.log(`Closed issue #${issueNumber}`);\n return issue;\n}\n\nexport async function reopenIssue(\n ctx: GitHubContext,\n repo: string,\n issueNumber: number,\n): Promise<IssueInfo> {\n const client = await ensureGitHubClient(ctx);\n const { owner, repo: repoName } = parseOwnerRepo(repo);\n return client.reopenIssue(owner, repoName, issueNumber);\n}\n\nexport async function addLabels(\n ctx: GitHubContext,\n repo: string,\n issueNumber: number,\n labels: string[],\n): Promise<void> {\n const client = await ensureGitHubClient(ctx);\n const { owner, repo: repoName } = parseOwnerRepo(repo);\n await client.addLabels(owner, repoName, issueNumber, labels);\n}\n",
|
|
40
|
+
"/**\n * Repository input normalization for coding task workspaces.\n *\n * Accepts canonical clone URLs plus common shorthand forms such as:\n * - owner/repo\n * - github.com/owner/repo\n * - https://github.com/owner/repo\n *\n * Bare owner/repo inputs default to GitHub because the coding workspace\n * flows in this plugin are GitHub-centric.\n *\n * @module services/repo-input\n */\n\nconst KNOWN_GIT_HOSTS = new Set([\"github.com\", \"gitlab.com\", \"bitbucket.org\"]);\n\nfunction stripGitSuffix(value: string): string {\n return value.replace(/\\.git$/i, \"\");\n}\n\nfunction normalizePathSegments(pathname: string): string[] {\n return pathname\n .replace(/^\\/+|\\/+$/g, \"\")\n .split(\"/\")\n .map((segment) => segment.trim())\n .filter(Boolean);\n}\n\nfunction toHttpsCloneUrl(host: string, owner: string, repo: string): string {\n return `https://${host}/${owner}/${repo}.git`;\n}\n\nexport function normalizeRepositoryInput(repo: string): string {\n const trimmed = repo.trim();\n if (!trimmed) return trimmed;\n\n // Preserve SSH-style clone URLs; they are already explicit and may be\n // intentionally configured to bypass HTTPS auth.\n if (/^[^@\\s]+@[^:\\s]+:[^/\\s]+\\/[^/\\s]+(?:\\.git)?$/i.test(trimmed)) {\n return trimmed;\n }\n\n const withoutTrailingSlash = trimmed.replace(/\\/+$/, \"\");\n\n if (/^https?:\\/\\//i.test(withoutTrailingSlash)) {\n try {\n const parsed = new URL(withoutTrailingSlash);\n const host = parsed.hostname.toLowerCase();\n if (KNOWN_GIT_HOSTS.has(host)) {\n const segments = normalizePathSegments(parsed.pathname);\n if (segments.length >= 2) {\n const owner = segments[0];\n const repoName = stripGitSuffix(segments[1]);\n return toHttpsCloneUrl(host, owner, repoName);\n }\n }\n } catch {\n return withoutTrailingSlash;\n }\n return withoutTrailingSlash;\n }\n\n const hostMatch = withoutTrailingSlash.match(\n /^(github\\.com|gitlab\\.com|bitbucket\\.org)\\/([^/]+)\\/([^/]+?)(?:\\.git)?$/i,\n );\n if (hostMatch) {\n return toHttpsCloneUrl(\n hostMatch[1].toLowerCase(),\n hostMatch[2],\n stripGitSuffix(hostMatch[3]),\n );\n }\n\n const shorthandMatch = withoutTrailingSlash.match(\n /^([A-Za-z0-9_.-]+)\\/([A-Za-z0-9_.-]+?)(?:\\.git)?$/,\n );\n if (shorthandMatch) {\n return toHttpsCloneUrl(\n \"github.com\",\n shorthandMatch[1],\n stripGitSuffix(shorthandMatch[2]),\n );\n }\n\n return withoutTrailingSlash;\n}\n\nexport function diagnoseWorkspaceBootstrapFailure(\n repo: string,\n errorMessage: string,\n): string {\n const normalizedRepo = normalizeRepositoryInput(repo);\n\n if (\n normalizedRepo !== repo &&\n /could not resolve host|not appear to be a git repository|invalid repo/i.test(\n errorMessage,\n )\n ) {\n return (\n `The repo reference looked malformed for a clone. ` +\n `Expected a real Git remote such as ${normalizedRepo}.`\n );\n }\n\n if (\n /repository not found|not found/i.test(errorMessage) &&\n !/file not found/i.test(errorMessage)\n ) {\n return (\n `The repository could not be found or is not readable. ` +\n `Verify the repo exists and that the configured Git credentials can access it.`\n );\n }\n\n if (\n /authentication failed|permission denied|could not read username|terminal prompts disabled|access denied/i.test(\n errorMessage,\n )\n ) {\n return (\n `Workspace bootstrap reached the provider but Git authentication failed. ` +\n `Verify the configured PAT, OAuth session, or SSH key for repository access.`\n );\n }\n\n if (\n /could not resolve host|name or service not known|getaddrinfo/i.test(\n errorMessage,\n )\n ) {\n return (\n `Workspace bootstrap failed on DNS or network resolution. ` +\n `Verify the clone host is valid and reachable from this machine.`\n );\n }\n\n return (\n `Workspace bootstrap failed before the agent launched. ` +\n `The orchestrator exhausted its automatic recovery path and needs a valid repo remote or working Git/network access.`\n );\n}\n",
|
|
41
|
+
"/**\n * Git operations for Coding Workspace Service\n *\n * Extracted from workspace-service.ts — provides git status, commit, push,\n * and PR creation as standalone functions operating on workspace paths.\n *\n * @module services/workspace-git-ops\n */\n\nimport type {\n PullRequestInfo,\n WorkspaceFinalization,\n WorkspaceService,\n} from \"git-workspace-service\";\nimport type {\n CommitOptions,\n PROptions,\n PushOptions,\n WorkspaceResult,\n WorkspaceStatusResult,\n} from \"./workspace-service.js\";\n\n/**\n * Get workspace git status (branch, staged/modified/untracked files).\n */\nexport async function getStatus(\n workspacePath: string,\n): Promise<WorkspaceStatusResult> {\n const { execFileSync } = await import(\"node:child_process\");\n\n const statusOutput = execFileSync(\"git\", [\"status\", \"--porcelain\"], {\n cwd: workspacePath,\n encoding: \"utf-8\",\n });\n\n const branchOutput = execFileSync(\"git\", [\"branch\", \"--show-current\"], {\n cwd: workspacePath,\n encoding: \"utf-8\",\n }).trim();\n\n const lines = statusOutput.split(\"\\n\").filter(Boolean);\n const modified: string[] = [];\n const staged: string[] = [];\n const untracked: string[] = [];\n\n for (const line of lines) {\n const indexStatus = line[0];\n const workTreeStatus = line[1];\n const filename = line.slice(3);\n\n if (indexStatus === \"?\" && workTreeStatus === \"?\") {\n untracked.push(filename);\n } else if (indexStatus !== \" \" && indexStatus !== \"?\") {\n staged.push(filename);\n } else if (workTreeStatus !== \" \") {\n modified.push(filename);\n }\n }\n\n return {\n branch: branchOutput,\n clean: lines.length === 0,\n modified,\n staged,\n untracked,\n };\n}\n\n/**\n * Commit changes in a workspace directory.\n * Returns the commit hash.\n */\nexport async function commit(\n workspacePath: string,\n options: CommitOptions,\n log: (msg: string) => void,\n): Promise<string> {\n const { execFileSync } = await import(\"node:child_process\");\n\n if (options.all) {\n execFileSync(\"git\", [\"add\", \"-A\"], { cwd: workspacePath });\n }\n\n execFileSync(\"git\", [\"commit\", \"-m\", options.message], {\n cwd: workspacePath,\n });\n\n const hash = execFileSync(\"git\", [\"rev-parse\", \"HEAD\"], {\n cwd: workspacePath,\n encoding: \"utf-8\",\n }).trim();\n\n log(`Committed ${hash.slice(0, 8)} in workspace at ${workspacePath}`);\n return hash;\n}\n\n/**\n * Push changes to remote for a workspace.\n */\nexport async function push(\n workspacePath: string,\n branch: string,\n options: PushOptions | undefined,\n log: (msg: string) => void,\n): Promise<void> {\n const { execFileSync } = await import(\"node:child_process\");\n\n const args = [\"push\"];\n if (options?.setUpstream) {\n args.push(\"-u\", \"origin\", branch);\n }\n if (options?.force) {\n args.push(\"--force\");\n }\n\n execFileSync(\"git\", args, { cwd: workspacePath });\n log(`Pushed workspace at ${workspacePath}`);\n}\n\n/**\n * Create a pull request for a workspace via the underlying WorkspaceService.\n */\nexport async function createPR(\n workspaceService: WorkspaceService,\n workspace: WorkspaceResult,\n workspaceId: string,\n options: PROptions,\n log: (msg: string) => void,\n): Promise<PullRequestInfo> {\n const finalization: WorkspaceFinalization = {\n push: false, // Already pushed\n createPr: true,\n pr: {\n title: options.title,\n body: options.body,\n targetBranch: options.base ?? workspace.baseBranch,\n draft: options.draft,\n labels: options.labels,\n reviewers: options.reviewers,\n },\n cleanup: false,\n };\n\n const result = await workspaceService.finalize(workspaceId, finalization);\n if (!result) {\n throw new Error(\"Failed to create PR\");\n }\n\n log(`Created PR #${result.number} for workspace ${workspaceId}`);\n return result;\n}\n",
|
|
42
|
+
"/**\n * Workspace lifecycle utilities — garbage collection and scratch directory cleanup.\n *\n * Extracted from workspace-service.ts to reduce module size.\n *\n * @module services/workspace-lifecycle\n */\n\nimport * as fs from \"node:fs\";\nimport * as os from \"node:os\";\nimport * as path from \"node:path\";\n\n/**\n * Remove a scratch directory (non-git workspace used for ad-hoc tasks).\n * Safe to call for any path under the workspaces base dir.\n */\nexport async function removeScratchDir(\n dirPath: string,\n baseDir: string,\n log: (msg: string) => void,\n allowedDirs?: string[],\n): Promise<void> {\n const resolved = path.resolve(dirPath);\n\n // Safety: only remove if under baseDir or one of the allowed directories\n const expandTilde = (p: string) =>\n p.startsWith(\"~\") ? path.join(os.homedir(), p.slice(1)) : p;\n const allAllowed = [baseDir, ...(allowedDirs ?? [])];\n const isAllowed = allAllowed.some((dir) => {\n const resolvedDir = path.resolve(expandTilde(dir)) + path.sep;\n return (\n resolved.startsWith(resolvedDir) ||\n resolved === path.resolve(expandTilde(dir))\n );\n });\n\n if (!isAllowed) {\n console.warn(\n `[CodingWorkspaceService] Refusing to remove dir outside allowed paths: ${resolved}`,\n );\n return;\n }\n try {\n await fs.promises.rm(resolved, { recursive: true, force: true });\n log(`Removed scratch dir ${resolved}`);\n } catch (err) {\n console.warn(\n `[CodingWorkspaceService] Failed to remove scratch dir ${resolved}:`,\n err,\n );\n }\n}\n\n/**\n * Garbage-collect orphaned workspace directories.\n * Removes directories older than the given TTL that aren't tracked by the current session.\n */\nexport async function gcOrphanedWorkspaces(\n baseDir: string,\n workspaceTtlMs: number,\n trackedWorkspaceIds: Set<string>,\n log: (msg: string) => void,\n): Promise<void> {\n if (workspaceTtlMs === 0) {\n log(\"Workspace GC disabled (workspaceTtlMs=0)\");\n return;\n }\n\n let entries: fs.Dirent[];\n try {\n entries = await fs.promises.readdir(baseDir, { withFileTypes: true });\n } catch {\n // Base dir doesn't exist yet — nothing to clean\n return;\n }\n\n const now = Date.now();\n let removed = 0;\n let skipped = 0;\n\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n\n // Skip directories tracked by the current session\n if (trackedWorkspaceIds.has(entry.name)) {\n skipped++;\n continue;\n }\n\n const dirPath = path.join(baseDir, entry.name);\n try {\n const stat = await fs.promises.stat(dirPath);\n const age = now - stat.mtimeMs;\n\n if (age > workspaceTtlMs) {\n await fs.promises.rm(dirPath, { recursive: true, force: true });\n removed++;\n } else {\n skipped++;\n }\n } catch (err) {\n // Stat or remove failed — skip\n log(`GC: skipping ${entry.name}: ${err}`);\n skipped++;\n }\n }\n\n if (removed > 0 || skipped > 0) {\n console.log(\n `[CodingWorkspaceService] Startup GC: removed ${removed} orphaned workspace(s), kept ${skipped}`,\n );\n }\n}\n",
|
|
43
|
+
"/**\n * Coding Workspace Service - Manages git workspaces for coding tasks\n *\n * Delegates to:\n * - workspace-github.ts (issue management, OAuth, PAT auth)\n * - workspace-git-ops.ts (status, commit, push, PR creation)\n * - workspace-lifecycle.ts (GC, scratch dir cleanup)\n * - workspace-types.ts (shared interface definitions)\n *\n * @module services/workspace-service\n */\n\nimport { execFile } from \"node:child_process\";\nimport * as fs from \"node:fs/promises\";\nimport * as os from \"node:os\";\nimport * as path from \"node:path\";\nimport type { IAgentRuntime } from \"@elizaos/core\";\nimport {\n type CreateIssueOptions,\n CredentialService,\n GitHubPatClient,\n type IssueComment,\n type IssueInfo,\n type IssueState,\n MemoryTokenStore,\n type PullRequestInfo,\n type WorkspaceConfig,\n type WorkspaceEvent,\n WorkspaceService,\n} from \"git-workspace-service\";\n\nimport type { AuthPromptCallback } from \"./workspace-github.js\";\nimport {\n type GitHubContext,\n addComment as ghAddComment,\n addLabels as ghAddLabels,\n closeIssue as ghCloseIssue,\n createIssue as ghCreateIssue,\n getIssue as ghGetIssue,\n listComments as ghListComments,\n listIssues as ghListIssues,\n reopenIssue as ghReopenIssue,\n updateIssue as ghUpdateIssue,\n} from \"./workspace-github.js\";\n\nexport type { AuthPromptCallback } from \"./workspace-github.js\";\n\nimport { readConfigEnvKey } from \"./config-env.js\";\nimport { normalizeRepositoryInput } from \"./repo-input.js\";\nimport {\n commit as gitCommit,\n createPR as gitCreatePR,\n getStatus as gitGetStatus,\n push as gitPush,\n} from \"./workspace-git-ops.js\";\nimport {\n gcOrphanedWorkspaces,\n removeScratchDir,\n} from \"./workspace-lifecycle.js\";\n\nexport type {\n CodingWorkspaceConfig,\n CommitOptions,\n PROptions,\n ProvisionWorkspaceOptions,\n PushOptions,\n WorkspaceResult,\n WorkspaceStatusResult,\n} from \"./workspace-types.js\";\n\nimport type {\n CodingWorkspaceConfig,\n CommitOptions,\n PROptions,\n ProvisionWorkspaceOptions,\n PushOptions,\n WorkspaceResult,\n WorkspaceStatusResult,\n} from \"./workspace-types.js\";\n\ntype WorkspaceEventCallback = (event: WorkspaceEvent) => void;\ntype ScratchRetentionPolicy = \"ephemeral\" | \"pending_decision\" | \"persistent\";\ntype ScratchTerminalEvent = \"stopped\" | \"task_complete\" | \"error\";\n\nexport interface ScratchWorkspaceRecord {\n sessionId: string;\n label: string;\n path: string;\n status: \"pending_decision\" | \"kept\" | \"promoted\";\n createdAt: number;\n terminalAt: number;\n terminalEvent: ScratchTerminalEvent;\n expiresAt?: number;\n}\n\n/**\n * Resolve the default branch of a remote repository via `git ls-remote\n * --symref`. Returns \"main\" if the lookup fails or the response can't be\n * parsed — callers that hardcoded \"main\" before keep working unchanged.\n *\n * Used as a fallback when the workspace caller doesn't pin a base branch.\n * Without this, repos whose default is \"alpha\" / \"master\" / \"develop\"\n * (e.g. elizaos-plugins/plugin-discord uses \"alpha\") fail at clone with\n * \"fatal: Remote branch main not found in upstream origin\".\n *\n * Process-lifetime cache keyed by repoUrl: concurrent and repeated lookups\n * against the same repo share one Promise so a swarm of N agents on the\n * same repo costs one ls-remote, not N. Cleared on process restart, which\n * is fine — default branches change rarely and a fresh boot rediscovers.\n */\nconst defaultBranchCache = new Map<string, Promise<string>>();\n\nfunction lookupDefaultBranch(repoUrl: string): Promise<string | null> {\n return new Promise((resolve) => {\n execFile(\n \"git\",\n [\"ls-remote\", \"--symref\", repoUrl, \"HEAD\"],\n { timeout: 10_000, encoding: \"utf-8\" },\n (err, stdout) => {\n if (err) {\n // Network failure, private repo without creds, etc.\n resolve(null);\n return;\n }\n const match = stdout.match(/^ref:\\s+refs\\/heads\\/(\\S+)\\s+HEAD/m);\n resolve(match?.[1] ?? null);\n },\n );\n });\n}\n\nexport function resolveDefaultBranch(repoUrl: string): Promise<string> {\n const cached = defaultBranchCache.get(repoUrl);\n if (cached) return cached;\n const pending = lookupDefaultBranch(repoUrl).then((branch) => {\n if (branch === null) {\n // Don't cache failures — a transient network blip shouldn't poison\n // subsequent calls. Drop the cache slot so a retry hits the network.\n defaultBranchCache.delete(repoUrl);\n return \"main\";\n }\n return branch;\n });\n defaultBranchCache.set(repoUrl, pending);\n return pending;\n}\n\n/** Test hook: drop the per-repo cache so each test starts clean. */\nexport function _clearDefaultBranchCache(): void {\n defaultBranchCache.clear();\n}\n\n/**\n * Resolve the default base directory for coding workspaces.\n *\n * Resolution order:\n * 1. `MILADY_WORKSPACE_DIR` runtime setting (set by store builds after the\n * user picks a folder via the native picker — see desktopPickWorkspaceFolder).\n * 2. `MILADY_WORKSPACE_DIR` env var.\n * 3. `~/.eliza/workspaces` (direct-build default; invisible inside an OS\n * sandbox container, hence the picker requirement for store builds).\n */\nfunction resolveDefaultBaseDir(runtime: IAgentRuntime): string {\n const fromSetting = runtime.getSetting(\"MILADY_WORKSPACE_DIR\");\n if (typeof fromSetting === \"string\" && fromSetting.trim().length > 0) {\n return expandHome(fromSetting.trim());\n }\n const fromEnv = process.env.MILADY_WORKSPACE_DIR;\n if (typeof fromEnv === \"string\" && fromEnv.trim().length > 0) {\n return expandHome(fromEnv.trim());\n }\n return path.join(os.homedir(), \".eliza\", \"workspaces\");\n}\n\nfunction expandHome(p: string): string {\n if (p.startsWith(\"~/\")) return path.join(os.homedir(), p.slice(2));\n if (p === \"~\") return os.homedir();\n return path.resolve(p);\n}\n\nexport function getCodingWorkspaceService(\n runtime: IAgentRuntime,\n): CodingWorkspaceService | null {\n const service = runtime.getService(\"CODING_WORKSPACE_SERVICE\");\n return service instanceof CodingWorkspaceService ? service : null;\n}\n\nexport class CodingWorkspaceService {\n static serviceType = \"CODING_WORKSPACE_SERVICE\";\n capabilityDescription = \"Manages git workspaces for coding tasks\";\n\n private runtime: IAgentRuntime;\n private workspaceService: WorkspaceService | null = null;\n private credentialService: CredentialService | null = null;\n private githubClient: GitHubPatClient | null = null;\n private githubAuthInProgress: Promise<GitHubPatClient> | null = null;\n private serviceConfig: CodingWorkspaceConfig;\n private workspaces: Map<string, WorkspaceResult> = new Map();\n private labels: Map<string, string> = new Map(); // label -> workspaceId\n private scratchBySession: Map<string, ScratchWorkspaceRecord> = new Map();\n private scratchCleanupTimers: Map<string, ReturnType<typeof setTimeout>> =\n new Map();\n private eventCallbacks: WorkspaceEventCallback[] = [];\n private authPromptCallback: AuthPromptCallback | null = null;\n /** Callback fired when a scratch workspace enters pending_decision state. */\n private scratchDecisionCallback:\n | ((record: ScratchWorkspaceRecord) => Promise<void>)\n | null = null;\n\n constructor(runtime: IAgentRuntime, config: CodingWorkspaceConfig = {}) {\n this.runtime = runtime;\n this.serviceConfig = {\n baseDir: config.baseDir ?? resolveDefaultBaseDir(runtime),\n branchPrefix: config.branchPrefix ?? \"eliza\",\n debug: config.debug ?? false,\n workspaceTtlMs: config.workspaceTtlMs ?? 24 * 60 * 60 * 1000,\n };\n }\n\n static async start(runtime: IAgentRuntime): Promise<CodingWorkspaceService> {\n const config = runtime.getSetting(\"CODING_WORKSPACE_CONFIG\") as\n | CodingWorkspaceConfig\n | null\n | undefined;\n const service = new CodingWorkspaceService(runtime, config ?? {});\n await service.initialize();\n return service;\n }\n\n static async stopRuntime(runtime: IAgentRuntime): Promise<void> {\n const service = getCodingWorkspaceService(runtime);\n if (service) {\n await service.stop();\n }\n }\n\n private async initialize(): Promise<void> {\n this.credentialService = new CredentialService({\n tokenStore: new MemoryTokenStore(),\n });\n\n this.workspaceService = new WorkspaceService({\n config: {\n baseDir: this.serviceConfig.baseDir as string,\n branchPrefix: this.serviceConfig.branchPrefix,\n },\n credentialService: this.credentialService,\n logger: this.serviceConfig.debug\n ? {\n info: (data: unknown, msg?: string) =>\n console.log(`[WorkspaceService] ${msg ?? \"\"}`, data),\n warn: (data: unknown, msg?: string) =>\n console.warn(`[WorkspaceService] ${msg ?? \"\"}`, data),\n error: (data: unknown, msg?: string) =>\n console.error(`[WorkspaceService] ${msg ?? \"\"}`, data),\n debug: (_data: unknown, msg?: string) => this.log(`${msg ?? \"\"}`),\n }\n : undefined,\n });\n\n await this.workspaceService.initialize();\n\n const githubToken = this.runtime.getSetting(\"GITHUB_TOKEN\") as\n | string\n | undefined;\n if (githubToken) {\n this.githubClient = new GitHubPatClient({ token: githubToken });\n this.log(\"GitHubPatClient initialized with PAT\");\n } else {\n this.log(\n \"GITHUB_TOKEN not set - will use OAuth device flow when GitHub access is needed\",\n );\n }\n\n this.workspaceService.onEvent((event: WorkspaceEvent) => {\n this.emitEvent(event);\n });\n\n this.log(\"CodingWorkspaceService initialized\");\n\n // Run startup GC in background (non-blocking)\n this.gcOrphanedWorkspaces().catch((err) => {\n console.warn(\"[CodingWorkspaceService] Startup GC failed:\", err);\n });\n }\n\n async stop(): Promise<void> {\n for (const timer of this.scratchCleanupTimers.values()) {\n clearTimeout(timer);\n }\n this.scratchCleanupTimers.clear();\n for (const [id] of this.workspaces) {\n try {\n await this.removeWorkspace(id);\n } catch (err) {\n this.log(`Error cleaning up workspace ${id}: ${err}`);\n }\n }\n this.workspaces.clear();\n this.workspaceService = null;\n this.credentialService = null;\n this.githubClient = null;\n this.log(\"CodingWorkspaceService shutdown complete\");\n }\n\n /** Provision a new workspace */\n async provisionWorkspace(\n options: ProvisionWorkspaceOptions,\n ): Promise<WorkspaceResult> {\n if (!this.workspaceService) {\n throw new Error(\"CodingWorkspaceService not initialized\");\n }\n\n // Normalize common shorthand like owner/repo before handing it to the\n // lower-level clone service, which expects an actual remote URL.\n const repo = normalizeRepositoryInput(options.repo);\n const executionId = options.execution?.id ?? `exec-${Date.now()}`;\n const taskId = options.task?.id ?? `task-${Date.now()}`;\n const baseBranch = options.baseBranch ?? (await resolveDefaultBranch(repo));\n\n const workspaceConfig: WorkspaceConfig = {\n repo,\n strategy: options.useWorktree ? \"worktree\" : \"clone\",\n parentWorkspace: options.parentWorkspaceId,\n branchStrategy: \"feature_branch\",\n branchName: options.branchName,\n baseBranch,\n execution: {\n id: executionId,\n patternName: options.execution?.patternName ?? \"eliza-coding\",\n },\n task: {\n id: taskId,\n role: options.task?.role ?? \"coding-agent\",\n slug: options.task?.slug,\n },\n userCredentials: options.userCredentials\n ? {\n type: options.userCredentials.type,\n token: options.userCredentials.token ?? \"\",\n provider: \"github\",\n }\n : undefined,\n };\n\n const workspace = await this.workspaceService.provision(workspaceConfig);\n const result: WorkspaceResult = {\n id: workspace.id,\n path: workspace.path,\n branch: workspace.branch.name,\n baseBranch: workspace.branch.baseBranch,\n isWorktree: workspace.strategy === \"worktree\",\n repo: workspace.repo,\n status: workspace.status,\n };\n\n this.workspaces.set(workspace.id, result);\n this.log(`Provisioned workspace ${workspace.id}`);\n return result;\n }\n\n getWorkspace(id: string): WorkspaceResult | undefined {\n return this.workspaces.get(id);\n }\n\n listWorkspaces(): WorkspaceResult[] {\n return Array.from(this.workspaces.values());\n }\n\n /**\n * Assign a semantic label to a workspace (e.g. \"auth-bugfix\").\n * If the label already exists, it is reassigned to the new workspace.\n */\n setLabel(workspaceId: string, label: string): void {\n const workspace = this.workspaces.get(workspaceId);\n if (!workspace) {\n throw new Error(`Workspace ${workspaceId} not found`);\n }\n if (workspace.label) {\n this.labels.delete(workspace.label);\n }\n const existing = this.labels.get(label);\n if (existing && existing !== workspaceId) {\n const oldWs = this.workspaces.get(existing);\n if (oldWs) oldWs.label = undefined;\n }\n workspace.label = label;\n this.labels.set(label, workspaceId);\n this.log(`Labeled workspace ${workspaceId} as \"${label}\"`);\n }\n\n getWorkspaceByLabel(label: string): WorkspaceResult | undefined {\n const id = this.labels.get(label);\n return id ? this.workspaces.get(id) : undefined;\n }\n\n /** Resolve a workspace by label or ID. */\n resolveWorkspace(labelOrId: string): WorkspaceResult | undefined {\n return (\n this.getWorkspaceByLabel(labelOrId) ?? this.workspaces.get(labelOrId)\n );\n }\n\n // === Delegated Git Operations ===\n\n async getStatus(workspaceId: string): Promise<WorkspaceStatusResult> {\n const workspace = this.workspaces.get(workspaceId);\n if (!workspace) {\n throw new Error(`Workspace ${workspaceId} not found`);\n }\n return gitGetStatus(workspace.path);\n }\n\n async commit(workspaceId: string, options: CommitOptions): Promise<string> {\n const workspace = this.workspaces.get(workspaceId);\n if (!workspace) {\n throw new Error(`Workspace ${workspaceId} not found`);\n }\n const hash = await gitCommit(workspace.path, options, (msg) =>\n this.log(msg),\n );\n this.log(`Committed ${hash.slice(0, 8)} in workspace ${workspaceId}`);\n return hash;\n }\n\n async push(workspaceId: string, options?: PushOptions): Promise<void> {\n const workspace = this.workspaces.get(workspaceId);\n if (!workspace) {\n throw new Error(`Workspace ${workspaceId} not found`);\n }\n await gitPush(workspace.path, workspace.branch, options, (msg) =>\n this.log(msg),\n );\n this.log(`Pushed workspace ${workspaceId}`);\n }\n\n async createPR(\n workspaceId: string,\n options: PROptions,\n ): Promise<PullRequestInfo> {\n if (!this.workspaceService) {\n throw new Error(\"CodingWorkspaceService not initialized\");\n }\n const workspace = this.workspaces.get(workspaceId);\n if (!workspace) {\n throw new Error(`Workspace ${workspaceId} not found`);\n }\n return gitCreatePR(\n this.workspaceService,\n workspace,\n workspaceId,\n options,\n (msg) => this.log(msg),\n );\n }\n\n // === Delegated GitHub / Issue Management ===\n\n private getGitHubContext(): GitHubContext {\n return {\n runtime: this.runtime,\n githubClient: this.githubClient,\n setGithubClient: (client: GitHubPatClient) => {\n this.githubClient = client;\n },\n githubAuthInProgress: this.githubAuthInProgress,\n setGithubAuthInProgress: (p: Promise<GitHubPatClient> | null) => {\n this.githubAuthInProgress = p;\n },\n authPromptCallback: this.authPromptCallback,\n log: (msg: string) => this.log(msg),\n };\n }\n\n /** Set a callback to surface OAuth auth prompts to the user. */\n setAuthPromptCallback(callback: AuthPromptCallback): void {\n this.authPromptCallback = callback;\n }\n\n /**\n * Register a callback fired when a scratch workspace enters pending_decision.\n * Used to prompt the user via chat: \"Want to keep this code?\"\n */\n setScratchDecisionCallback(\n callback: (record: ScratchWorkspaceRecord) => Promise<void>,\n ): void {\n this.scratchDecisionCallback = callback;\n }\n\n async createIssue(\n repo: string,\n options: CreateIssueOptions,\n ): Promise<IssueInfo> {\n return ghCreateIssue(this.getGitHubContext(), repo, options);\n }\n\n async getIssue(repo: string, issueNumber: number): Promise<IssueInfo> {\n return ghGetIssue(this.getGitHubContext(), repo, issueNumber);\n }\n\n async listIssues(\n repo: string,\n options?: {\n state?: IssueState | \"all\";\n labels?: string[];\n assignee?: string;\n },\n ): Promise<IssueInfo[]> {\n return ghListIssues(this.getGitHubContext(), repo, options);\n }\n\n async updateIssue(\n repo: string,\n issueNumber: number,\n options: {\n title?: string;\n body?: string;\n state?: IssueState;\n labels?: string[];\n assignees?: string[];\n },\n ): Promise<IssueInfo> {\n return ghUpdateIssue(this.getGitHubContext(), repo, issueNumber, options);\n }\n\n async addComment(\n repo: string,\n issueNumber: number,\n body: string,\n ): Promise<IssueComment> {\n return ghAddComment(this.getGitHubContext(), repo, issueNumber, body);\n }\n\n async listComments(\n repo: string,\n issueNumber: number,\n ): Promise<IssueComment[]> {\n return ghListComments(this.getGitHubContext(), repo, issueNumber);\n }\n\n async closeIssue(repo: string, issueNumber: number): Promise<IssueInfo> {\n return ghCloseIssue(this.getGitHubContext(), repo, issueNumber);\n }\n\n async reopenIssue(repo: string, issueNumber: number): Promise<IssueInfo> {\n return ghReopenIssue(this.getGitHubContext(), repo, issueNumber);\n }\n\n async addLabels(\n repo: string,\n issueNumber: number,\n labels: string[],\n ): Promise<void> {\n return ghAddLabels(this.getGitHubContext(), repo, issueNumber, labels);\n }\n\n // === Workspace Lifecycle ===\n\n async removeWorkspace(workspaceId: string): Promise<void> {\n if (!this.workspaceService) {\n throw new Error(\"CodingWorkspaceService not initialized\");\n }\n await this.workspaceService.cleanup(workspaceId);\n const workspace = this.workspaces.get(workspaceId);\n if (workspace?.label) {\n this.labels.delete(workspace.label);\n }\n this.workspaces.delete(workspaceId);\n this.log(`Removed workspace ${workspaceId}`);\n }\n\n onEvent(callback: WorkspaceEventCallback): () => void {\n this.eventCallbacks.push(callback);\n return () => {\n const index = this.eventCallbacks.indexOf(callback);\n if (index !== -1) {\n this.eventCallbacks.splice(index, 1);\n }\n };\n }\n\n private emitEvent(event: WorkspaceEvent): void {\n for (const callback of this.eventCallbacks) {\n try {\n callback(event);\n } catch (err) {\n this.log(`Event callback error: ${err}`);\n }\n }\n }\n\n /** Remove a scratch directory — allowed under base dir or user coding directory. */\n async removeScratchDir(dirPath: string): Promise<void> {\n const rawCodingDir =\n (this.runtime.getSetting(\"PARALLAX_CODING_DIRECTORY\") as string) ??\n this.readConfigEnvKey(\"PARALLAX_CODING_DIRECTORY\") ??\n process.env.PARALLAX_CODING_DIRECTORY;\n const codingDir = rawCodingDir?.trim()\n ? rawCodingDir.trim().startsWith(\"~\")\n ? path.join(os.homedir(), rawCodingDir.trim().slice(1))\n : path.resolve(rawCodingDir.trim())\n : undefined;\n const allowedDirs = codingDir ? [codingDir] : undefined;\n return removeScratchDir(\n dirPath,\n this.serviceConfig.baseDir as string,\n (msg) => this.log(msg),\n allowedDirs,\n );\n }\n\n listScratchWorkspaces(): ScratchWorkspaceRecord[] {\n return Array.from(this.scratchBySession.values()).sort(\n (a, b) => b.terminalAt - a.terminalAt,\n );\n }\n\n async registerScratchWorkspace(\n sessionId: string,\n dirPath: string,\n label: string,\n terminalEvent: ScratchTerminalEvent,\n ): Promise<ScratchWorkspaceRecord | null> {\n const now = Date.now();\n const existing = this.scratchBySession.get(sessionId);\n const base: ScratchWorkspaceRecord = existing ?? {\n sessionId,\n label,\n path: dirPath,\n createdAt: now,\n terminalAt: now,\n terminalEvent,\n status: \"pending_decision\",\n };\n\n const policy = this.getScratchRetentionPolicy();\n this.log(`Scratch retention policy: \"${policy}\" for \"${label}\"`);\n if (policy === \"ephemeral\") {\n await this.removeScratchDir(dirPath);\n this.scratchBySession.delete(sessionId);\n this.clearScratchCleanupTimer(sessionId);\n return null;\n }\n\n const record: ScratchWorkspaceRecord = {\n ...base,\n label,\n path: dirPath,\n terminalAt: now,\n terminalEvent,\n status: policy === \"persistent\" ? \"kept\" : \"pending_decision\",\n expiresAt: undefined,\n };\n this.scratchBySession.set(sessionId, record);\n\n if (record.status === \"pending_decision\") {\n const ttlMs = this.getScratchDecisionTtlMs();\n record.expiresAt = now + ttlMs;\n this.scheduleScratchCleanup(sessionId, ttlMs);\n // Prompt user via chat: \"Want to keep this code?\"\n if (this.scratchDecisionCallback) {\n this.log(`Firing scratch decision prompt for \"${label}\" at ${dirPath}`);\n this.scratchDecisionCallback(record).catch((err) => {\n console.warn(\n `[workspace] Failed to send scratch decision prompt: ${err}`,\n );\n });\n } else {\n this.log(\n `No scratch decision callback wired — skipping prompt for \"${label}\"`,\n );\n }\n } else {\n this.clearScratchCleanupTimer(sessionId);\n }\n return record;\n }\n\n async keepScratchWorkspace(\n sessionId: string,\n ): Promise<ScratchWorkspaceRecord> {\n const record = this.requireScratchWorkspace(sessionId);\n const next: ScratchWorkspaceRecord = {\n ...record,\n status: \"kept\",\n expiresAt: undefined,\n };\n this.scratchBySession.set(sessionId, next);\n this.clearScratchCleanupTimer(sessionId);\n return next;\n }\n\n async deleteScratchWorkspace(sessionId: string): Promise<void> {\n const record = this.requireScratchWorkspace(sessionId);\n await this.removeScratchDir(record.path);\n this.scratchBySession.delete(sessionId);\n this.clearScratchCleanupTimer(sessionId);\n }\n\n async promoteScratchWorkspace(\n sessionId: string,\n name?: string,\n ): Promise<ScratchWorkspaceRecord> {\n const record = this.requireScratchWorkspace(sessionId);\n const baseDir = this.serviceConfig.baseDir as string;\n const suggestedName = this.sanitizeWorkspaceName(name || record.label);\n const targetPath = await this.allocatePromotedPath(baseDir, suggestedName);\n try {\n await fs.rename(record.path, targetPath);\n } catch (error) {\n const isExdev =\n typeof error === \"object\" &&\n error !== null &&\n \"code\" in error &&\n (error as { code?: unknown }).code === \"EXDEV\";\n if (!isExdev) throw error;\n await fs.cp(record.path, targetPath, { recursive: true });\n await fs.access(targetPath);\n await fs.rm(record.path, { recursive: true, force: true });\n }\n\n const next: ScratchWorkspaceRecord = {\n ...record,\n path: targetPath,\n status: \"promoted\",\n expiresAt: undefined,\n };\n this.scratchBySession.set(sessionId, next);\n this.clearScratchCleanupTimer(sessionId);\n return next;\n }\n\n /** GC orphaned workspace directories older than workspaceTtlMs. */\n private async gcOrphanedWorkspaces(): Promise<void> {\n return gcOrphanedWorkspaces(\n this.serviceConfig.baseDir as string,\n this.serviceConfig.workspaceTtlMs ?? 24 * 60 * 60 * 1000,\n new Set(this.workspaces.keys()),\n (msg) => this.log(msg),\n );\n }\n\n private log(message: string): void {\n if (this.serviceConfig.debug) {\n console.log(`[CodingWorkspaceService] ${message}`);\n }\n }\n\n /** Read a key from the config file's env section (live, no restart needed). */\n private readConfigEnvKey(key: string): string | undefined {\n return readConfigEnvKey(key);\n }\n\n private getScratchRetentionPolicy(): ScratchRetentionPolicy {\n const setting = (this.runtime.getSetting(\"PARALLAX_SCRATCH_RETENTION\") ??\n this.readConfigEnvKey(\"PARALLAX_SCRATCH_RETENTION\") ??\n process.env.PARALLAX_SCRATCH_RETENTION) as string | undefined;\n const normalized = setting?.trim().toLowerCase();\n if (normalized === \"ephemeral\") return \"ephemeral\";\n if (normalized === \"persistent\" || normalized === \"keep\") {\n return \"persistent\";\n }\n // When a coding directory is configured and no explicit retention was set,\n // default to persistent — users don't expect named folders in ~/Projects\n // to auto-delete. If the user explicitly chose pending_decision, respect it.\n if (!normalized) {\n const codingDir =\n (this.runtime.getSetting(\"PARALLAX_CODING_DIRECTORY\") as string) ??\n this.readConfigEnvKey(\"PARALLAX_CODING_DIRECTORY\") ??\n process.env.PARALLAX_CODING_DIRECTORY;\n if (codingDir?.trim()) return \"persistent\";\n }\n return \"pending_decision\";\n }\n\n private getScratchDecisionTtlMs(): number {\n const setting = this.runtime.getSetting(\n \"PARALLAX_SCRATCH_DECISION_TTL_MS\",\n ) as string | number | undefined;\n const parsed = Number(\n setting ?? process.env.PARALLAX_SCRATCH_DECISION_TTL_MS,\n );\n if (Number.isFinite(parsed) && parsed > 0) return parsed;\n return 24 * 60 * 60 * 1000;\n }\n\n private requireScratchWorkspace(sessionId: string): ScratchWorkspaceRecord {\n const record = this.scratchBySession.get(sessionId);\n if (!record) {\n throw new Error(`Scratch workspace for session ${sessionId} not found`);\n }\n return record;\n }\n\n private clearScratchCleanupTimer(sessionId: string): void {\n const timer = this.scratchCleanupTimers.get(sessionId);\n if (timer) {\n clearTimeout(timer);\n this.scratchCleanupTimers.delete(sessionId);\n }\n }\n\n private scheduleScratchCleanup(sessionId: string, ttlMs: number): void {\n this.clearScratchCleanupTimer(sessionId);\n const timer = setTimeout(async () => {\n try {\n const record = this.scratchBySession.get(sessionId);\n if (!record || record.status !== \"pending_decision\") return;\n await this.removeScratchDir(record.path);\n } catch (error) {\n console.warn(\n `[CodingWorkspaceService] scratch cleanup failed for ${sessionId}: ${String(error)}`,\n );\n } finally {\n this.scratchBySession.delete(sessionId);\n this.scratchCleanupTimers.delete(sessionId);\n }\n }, ttlMs);\n this.scratchCleanupTimers.set(sessionId, timer);\n }\n\n private sanitizeWorkspaceName(raw: string): string {\n const compact = raw\n .toLowerCase()\n .replace(/[^a-z0-9._-]+/g, \"-\")\n .replace(/-+/g, \"-\")\n .replace(/^-|-$/g, \"\");\n return compact || `scratch-${Date.now().toString(36)}`;\n }\n\n private async allocatePromotedPath(\n baseDir: string,\n baseName: string,\n ): Promise<string> {\n const baseResolved = path.resolve(baseDir);\n for (let i = 0; i < 1000; i++) {\n const candidateName = i === 0 ? baseName : `${baseName}-${i}`;\n const candidate = path.resolve(baseResolved, candidateName);\n if (\n candidate !== baseResolved &&\n !candidate.startsWith(`${baseResolved}${path.sep}`)\n ) {\n continue;\n }\n try {\n await fs.access(candidate);\n } catch {\n return candidate;\n }\n }\n throw new Error(\"Unable to allocate promoted workspace path\");\n }\n}\n",
|
|
44
|
+
"/**\n * Provider that injects active workspace and task-agent context into every prompt.\n *\n * Eliza needs to know what workspaces exist, which agents are running, and\n * their current status. This provider reads from the workspace service, PTY\n * service, and coordinator to build a live context summary that's always\n * available in the prompt.\n *\n * @module providers/active-workspace-context\n */\n\nimport type { IAgentRuntime, Memory, Provider, State } from \"@elizaos/core\";\nimport { getCoordinator, getPtyService } from \"../services/pty-service.js\";\nimport type { SessionInfo } from \"../services/pty-types.js\";\nimport {\n formatTaskAgentStatus,\n getTaskAgentFrameworkState,\n TASK_AGENT_FRAMEWORK_LABELS,\n truncateTaskAgentText,\n} from \"../services/task-agent-frameworks.js\";\nimport type { WorkspaceResult } from \"../services/workspace-service.js\";\nimport { getCodingWorkspaceService } from \"../services/workspace-service.js\";\n\ninterface TaskLike {\n sessionId: string;\n agentType: string;\n label: string;\n originalTask: string;\n status: string;\n decisions: Array<{ reasoning?: string }>;\n completionSummary?: string;\n registeredAt: number;\n}\n\ntype FrameworkState = Awaited<ReturnType<typeof getTaskAgentFrameworkState>>;\n\nconst FALLBACK_FRAMEWORK_STATE: FrameworkState = {\n configuredSubscriptionProvider: undefined,\n frameworks: [],\n preferred: {\n id: \"codex\",\n reason: \"Task-agent framework state unavailable.\",\n },\n};\n\nfunction uniqueTasks(tasks: TaskLike[]): TaskLike[] {\n const seen = new Set<string>();\n const result: TaskLike[] = [];\n for (const task of tasks) {\n if (seen.has(task.sessionId)) continue;\n seen.add(task.sessionId);\n result.push(task);\n }\n return result;\n}\n\nexport const activeWorkspaceContextProvider: Provider = {\n name: \"ACTIVE_WORKSPACE_CONTEXT\",\n description:\n \"Live status of active workspaces, task-agent sessions, and current task progress\",\n descriptionCompressed:\n \"Live status of workspaces, task agents, and progress.\",\n position: 1,\n contexts: [\"code\", \"tasks\", \"agent_internal\"],\n contextGate: { anyOf: [\"code\", \"tasks\", \"agent_internal\"] },\n cacheStable: false,\n cacheScope: \"turn\",\n\n get: async (runtime: IAgentRuntime, _message: Memory, _state: State) => {\n const ptyService = getPtyService(runtime) ?? undefined;\n const wsService = getCodingWorkspaceService(runtime);\n const coordinator = getCoordinator(runtime);\n let frameworkState = FALLBACK_FRAMEWORK_STATE;\n try {\n frameworkState = await getTaskAgentFrameworkState(runtime, ptyService);\n } catch {\n frameworkState = FALLBACK_FRAMEWORK_STATE;\n }\n\n let sessions: SessionInfo[] = [];\n if (ptyService) {\n try {\n sessions = await Promise.race([\n ptyService.listSessions(),\n new Promise<SessionInfo[]>((resolve) =>\n setTimeout(() => resolve([]), 2000),\n ),\n ]);\n } catch {\n sessions = [];\n }\n }\n\n let workspaces: WorkspaceResult[] = [];\n try {\n workspaces = wsService?.listWorkspaces() ?? [];\n } catch {\n workspaces = [];\n }\n const tasks = uniqueTasks(\n ((coordinator?.getAllTaskContexts?.() ?? []) as TaskLike[]).slice(),\n );\n const reusableSessions = sessions.filter((session) => {\n const currentTask = tasks.find((task) => task.sessionId === session.id);\n return !currentTask || currentTask.status !== \"active\";\n });\n\n const lines: string[] = [\n \"active_workspace_context:\",\n ` preferredFramework: ${TASK_AGENT_FRAMEWORK_LABELS[frameworkState.preferred.id]}`,\n ` preferredReason: ${frameworkState.preferred.reason}`,\n ` workspaceCount: ${workspaces.length}`,\n ` sessionCount: ${sessions.length}`,\n ` taskCount: ${tasks.length}`,\n ];\n\n if (\n workspaces.length === 0 &&\n sessions.length === 0 &&\n tasks.length === 0\n ) {\n lines.push(\"guidance:\");\n lines.push(\n \" createTask: Use ACPX CREATE_AGENT_TASK when the user needs anything more involved than a simple direct reply.\",\n );\n } else {\n if (workspaces.length > 0) {\n lines.push(\n `workspaces[${workspaces.length}]{label,repo,branch,agents}:`,\n );\n for (const workspace of workspaces) {\n const workspaceSessions = sessions.filter(\n (session) => session.workdir === workspace.path,\n );\n const agentSummary =\n workspaceSessions.length > 0\n ? workspaceSessions\n .map(\n (session) =>\n `${session.agentType}:${formatTaskAgentStatus(session.status)}`,\n )\n .join(\", \")\n : \"no task agents\";\n lines.push(\n ` ${workspace.label ?? workspace.id.slice(0, 8)},${workspace.repo ?? \"scratch\"},${workspace.branch ?? \"no branch\"},${agentSummary}`,\n );\n }\n }\n\n const trackedPaths = new Set(\n workspaces.map((workspace) => workspace.path),\n );\n const standaloneSessions = sessions.filter(\n (session) => !trackedPaths.has(session.workdir),\n );\n\n if (standaloneSessions.length > 0) {\n lines.push(\n `standaloneSessions[${standaloneSessions.length}]{label,agentType,status,sessionId}:`,\n );\n for (const session of standaloneSessions) {\n const label =\n typeof session.metadata?.label === \"string\"\n ? session.metadata.label\n : session.name;\n lines.push(\n ` ${label},${session.agentType},${formatTaskAgentStatus(session.status)},${session.id}`,\n );\n }\n }\n\n if (tasks.length > 0) {\n lines.push(`tasks[${tasks.length}]{status,label,agentType,detail}:`);\n for (const task of tasks\n .slice()\n .sort((left, right) => right.registeredAt - left.registeredAt)) {\n const latestDecision = task.decisions.at(-1);\n const detail =\n task.completionSummary ||\n latestDecision?.reasoning ||\n truncateTaskAgentText(task.originalTask, 110);\n lines.push(\n ` ${task.status},${task.label},${task.agentType},${detail.replace(/\\s+/g, \" \").trim()}`,\n );\n }\n }\n\n const pending = coordinator?.getPendingConfirmations?.() ?? [];\n if (pending.length > 0) {\n lines.push(\"pendingConfirmations:\");\n lines.push(` count: ${pending.length}`);\n lines.push(\n ` supervision: ${coordinator?.getSupervisionLevel?.() ?? \"unknown\"}`,\n );\n lines.push(\n `pendingItems[${pending.length}]{label,prompt,suggestedAction}:`,\n );\n for (const confirmation of pending) {\n lines.push(\n ` ${confirmation.taskContext.label},${truncateTaskAgentText(confirmation.promptText, 140)},${confirmation.llmDecision.action ?? \"review\"}`,\n );\n }\n }\n\n if (reusableSessions.length > 0) {\n lines.push(\n `reusableAgents[${reusableSessions.length}]{label,agentType,status,nextAction}:`,\n );\n for (const session of reusableSessions) {\n const label =\n typeof session.metadata?.label === \"string\"\n ? session.metadata.label\n : session.name;\n lines.push(\n ` ${label},${session.agentType},${formatTaskAgentStatus(session.status)},SEND_TO_AGENT`,\n );\n }\n }\n }\n\n if (sessions.length > 0 || tasks.length > 0) {\n lines.push(\"actions:\");\n lines.push(\" unblockOrAssign: SEND_TO_AGENT\");\n lines.push(\" inspectProgress: provider.active_workspace_context\");\n lines.push(\" cancel: STOP_AGENT\");\n lines.push(\" wrapUp: FINALIZE_WORKSPACE\");\n }\n\n const text = lines.join(\"\\n\");\n return {\n data: {\n activeWorkspaces: workspaces.map((ws: WorkspaceResult) => ({\n id: ws.id,\n label: ws.label,\n repo: ws.repo,\n branch: ws.branch,\n path: ws.path,\n })),\n activeSessions: sessions.map((session) => ({\n id: session.id,\n label:\n typeof session.metadata?.label === \"string\"\n ? session.metadata.label\n : session.name,\n agentType: session.agentType,\n status: session.status,\n workdir: session.workdir,\n })),\n currentTasks: tasks,\n preferredTaskAgent: frameworkState.preferred,\n frameworks: frameworkState.frameworks,\n },\n values: { activeWorkspaceContext: text },\n text,\n };\n },\n};\n",
|
|
45
|
+
"import type { Memory } from \"@elizaos/core\";\n\nfunction asRecord(value: unknown): Record<string, unknown> | null {\n return value && typeof value === \"object\" && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : null;\n}\n\nfunction readString(\n source: Record<string, unknown> | null,\n ...keys: string[]\n): string | undefined {\n if (!source) return undefined;\n for (const key of keys) {\n const value = source[key];\n if (typeof value === \"string\" && value.trim().length > 0) {\n return value.trim();\n }\n }\n return undefined;\n}\n\nexport function extractEvalRunMetadata(\n value: Memory | Record<string, unknown> | null | undefined,\n): {\n scenarioId?: string;\n batchId?: string;\n} {\n const record =\n value && \"content\" in value\n ? asRecord((value as Memory).content)\n : asRecord(value);\n const contentMetadata = asRecord(record?.metadata);\n const nestedSources = [\n asRecord(contentMetadata?.eval),\n asRecord(contentMetadata?.evaluation),\n asRecord(contentMetadata?.scenario),\n ];\n\n const scenarioId =\n readString(record, \"scenarioId\", \"scenario_id\") ??\n readString(contentMetadata, \"scenarioId\", \"scenario_id\") ??\n nestedSources\n .map((source) => readString(source, \"scenarioId\", \"scenario_id\"))\n .find(Boolean);\n const batchId =\n readString(record, \"batchId\", \"batch_id\") ??\n readString(contentMetadata, \"batchId\", \"batch_id\") ??\n nestedSources\n .map((source) => readString(source, \"batchId\", \"batch_id\"))\n .find(Boolean);\n\n return { scenarioId, batchId };\n}\n\nexport function mergeTaskThreadEvalMetadata(\n message: Memory | null | undefined,\n metadata: Record<string, unknown> | undefined,\n): {\n scenarioId?: string;\n batchId?: string;\n metadata: Record<string, unknown>;\n} {\n const merged = {\n ...(metadata ?? {}),\n };\n const { scenarioId, batchId } = extractEvalRunMetadata(message);\n\n if (scenarioId) {\n merged.scenarioId = scenarioId;\n }\n if (batchId) {\n merged.batchId = batchId;\n }\n\n return {\n scenarioId,\n batchId,\n metadata: merged,\n };\n}\n",
|
|
46
|
+
"import type { IncomingMessage, ServerResponse } from \"node:http\";\nimport type { IAgentRuntime } from \"@elizaos/core\";\nimport type { PTYService } from \"../services/pty-service.js\";\nimport type { SwarmCoordinator } from \"../services/swarm-coordinator.js\";\nimport type { CodingWorkspaceService } from \"../services/workspace-service.js\";\n\nexport type JsonValue =\n | string\n | number\n | boolean\n | null\n | JsonValue[]\n | { [key: string]: JsonValue };\n\nexport interface RouteContext {\n runtime: IAgentRuntime;\n ptyService: PTYService | null;\n workspaceService: CodingWorkspaceService | null;\n coordinator?: SwarmCoordinator;\n}\n\n// Max request body size (1 MB)\nconst MAX_BODY_SIZE = 1024 * 1024;\n\n// Helper to parse JSON body with size limit\nexport async function parseBody(\n req: IncomingMessage,\n): Promise<Record<string, unknown>> {\n return new Promise((resolve, reject) => {\n let body = \"\";\n let size = 0;\n req.on(\"data\", (chunk: Buffer | string) => {\n size += typeof chunk === \"string\" ? chunk.length : chunk.byteLength;\n if (size > MAX_BODY_SIZE) {\n req.destroy();\n reject(new Error(\"Request body too large\"));\n return;\n }\n body += chunk;\n });\n req.on(\"end\", () => {\n try {\n resolve(body ? JSON.parse(body) : {});\n } catch {\n reject(new Error(\"Invalid JSON body\"));\n }\n });\n req.on(\"error\", reject);\n });\n}\n\n// Helper to send JSON response\nexport function sendJson(\n res: ServerResponse,\n data: unknown,\n status = 200,\n): void {\n res.writeHead(status, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify(data));\n}\n\n// Helper to send error\nexport function sendError(\n res: ServerResponse,\n message: string,\n status = 400,\n): void {\n sendJson(res, { error: message }, status);\n}\n",
|
|
47
|
+
"/**\n * Task Agent Route Handlers\n *\n * Handles routes for PTY-based task-agent management:\n * - Preflight checks, metrics, workspace files\n * - Approval presets and config\n * - Agent CRUD: list, spawn, get, send, stop, output\n *\n * @module api/agent-routes\n */\n\nimport { execFile } from \"node:child_process\";\nimport { createHash } from \"node:crypto\";\nimport { access, readFile, realpath, rm } from \"node:fs/promises\";\nimport type { IncomingMessage, ServerResponse } from \"node:http\";\nimport * as os from \"node:os\";\nimport * as path from \"node:path\";\nimport { promisify } from \"node:util\";\nimport { extractEvalRunMetadata } from \"../actions/eval-metadata.js\";\nimport {\n buildAgentCredentials,\n isAnthropicOAuthToken,\n sanitizeCustomCredentials,\n} from \"../services/agent-credentials.js\";\nimport { getCoordinator } from \"../services/pty-service.js\";\nimport {\n isPiAgentType,\n normalizeAgentType,\n toPiCommand,\n} from \"../services/pty-types.js\";\nimport { getTaskAgentFrameworkState } from \"../services/task-agent-frameworks.js\";\nimport type { RouteContext } from \"./route-utils.js\";\nimport { parseBody, sendError, sendJson } from \"./route-utils.js\";\n\nconst execFileAsync = promisify(execFile);\nconst PREFLIGHT_DONE = new Set<string>();\nconst PREFLIGHT_INFLIGHT = new Map<string, Promise<void>>();\n\nfunction shouldAutoPreflight(): boolean {\n if (process.env.PARALLAX_BENCHMARK_PREFLIGHT_AUTO === \"1\") return true;\n return false;\n}\n\nfunction isPathInside(parent: string, candidate: string): boolean {\n return candidate === parent || candidate.startsWith(`${parent}${path.sep}`);\n}\n\nasync function resolveSafeVenvPath(\n workdir: string,\n venvDirRaw: string,\n): Promise<string> {\n const venvDir = venvDirRaw.trim();\n if (!venvDir) {\n throw new Error(\"PARALLAX_BENCHMARK_PREFLIGHT_VENV must be non-empty\");\n }\n if (path.isAbsolute(venvDir)) {\n throw new Error(\n \"PARALLAX_BENCHMARK_PREFLIGHT_VENV must be relative to workdir\",\n );\n }\n\n const normalized = path.normalize(venvDir);\n if (\n normalized === \".\" ||\n normalized === \"..\" ||\n normalized.startsWith(`..${path.sep}`)\n ) {\n throw new Error(\n \"PARALLAX_BENCHMARK_PREFLIGHT_VENV must stay within workdir\",\n );\n }\n\n const workdirResolved = path.resolve(workdir);\n const workdirReal = await realpath(workdirResolved);\n const resolved = path.resolve(workdirReal, normalized);\n if (!isPathInside(workdirReal, resolved)) {\n throw new Error(\n \"PARALLAX_BENCHMARK_PREFLIGHT_VENV resolves outside workdir\",\n );\n }\n if (resolved === workdirReal) {\n throw new Error(\n \"PARALLAX_BENCHMARK_PREFLIGHT_VENV must not resolve to workdir root\",\n );\n }\n\n // Canonicalize candidate when present to reject symlink escapes.\n try {\n const resolvedReal = await realpath(resolved);\n if (\n !isPathInside(workdirReal, resolvedReal) ||\n resolvedReal === workdirReal\n ) {\n throw new Error(\n \"PARALLAX_BENCHMARK_PREFLIGHT_VENV resolves outside workdir\",\n );\n }\n } catch (err) {\n const maybeErr = err as NodeJS.ErrnoException;\n if (maybeErr?.code !== \"ENOENT\") throw err;\n const parentReal = await realpath(path.dirname(resolved));\n if (!isPathInside(workdirReal, parentReal)) {\n throw new Error(\n \"PARALLAX_BENCHMARK_PREFLIGHT_VENV parent resolves outside workdir\",\n );\n }\n }\n\n return resolved;\n}\n\nasync function fileExists(filePath: string): Promise<boolean> {\n try {\n await access(filePath);\n return true;\n } catch {\n return false;\n }\n}\n\nasync function resolveRequirementsPath(\n workdir: string,\n): Promise<string | null> {\n const workdirReal = await realpath(path.resolve(workdir));\n const candidates = [\n path.join(workdir, \"apps\", \"api\", \"requirements.txt\"),\n path.join(workdir, \"requirements.txt\"),\n ];\n for (const candidate of candidates) {\n if (!(await fileExists(candidate))) continue;\n try {\n const candidateReal = await realpath(candidate);\n if (isPathInside(workdirReal, candidateReal)) return candidateReal;\n } catch {\n // Ignore malformed candidate and keep scanning.\n }\n }\n return null;\n}\n\nasync function fingerprintRequirementsFile(\n requirementsPath: string,\n): Promise<string> {\n const file = await readFile(requirementsPath);\n return createHash(\"sha256\").update(file).digest(\"hex\");\n}\n\nasync function runBenchmarkPreflight(workdir: string): Promise<void> {\n if (!shouldAutoPreflight()) return;\n\n const requirementsPath = await resolveRequirementsPath(workdir);\n if (!requirementsPath) return;\n const requirementsFingerprint =\n await fingerprintRequirementsFile(requirementsPath);\n\n const mode =\n process.env.PARALLAX_BENCHMARK_PREFLIGHT_MODE?.toLowerCase() === \"warm\"\n ? \"warm\"\n : \"cold\";\n const venvDir =\n process.env.PARALLAX_BENCHMARK_PREFLIGHT_VENV || \".benchmark-venv\";\n const venvPath = await resolveSafeVenvPath(workdir, venvDir);\n const pythonInVenv = path.join(\n venvPath,\n process.platform === \"win32\" ? \"Scripts\" : \"bin\",\n process.platform === \"win32\" ? \"python.exe\" : \"python\",\n );\n const key = `${workdir}::${mode}::${venvPath}::${requirementsFingerprint}`;\n if (PREFLIGHT_DONE.has(key)) {\n if (await fileExists(pythonInVenv)) return;\n PREFLIGHT_DONE.delete(key);\n }\n const existing = PREFLIGHT_INFLIGHT.get(key);\n if (existing) {\n await existing;\n return;\n }\n\n const run = (async () => {\n const pythonCommand = process.platform === \"win32\" ? \"python\" : \"python3\";\n\n if (mode === \"cold\") {\n await rm(venvPath, { recursive: true, force: true });\n }\n\n const hasVenv = await fileExists(pythonInVenv);\n if (!hasVenv) {\n await execFileAsync(pythonCommand, [\"-m\", \"venv\", venvPath], {\n cwd: workdir,\n timeout: 120_000,\n maxBuffer: 8 * 1024 * 1024,\n });\n }\n\n await execFileAsync(\n pythonInVenv,\n [\"-m\", \"pip\", \"install\", \"--upgrade\", \"pip\"],\n {\n cwd: workdir,\n timeout: 300_000,\n maxBuffer: 8 * 1024 * 1024,\n },\n );\n\n await execFileAsync(\n pythonInVenv,\n [\"-m\", \"pip\", \"install\", \"-r\", requirementsPath],\n {\n cwd: workdir,\n timeout: 600_000,\n maxBuffer: 16 * 1024 * 1024,\n },\n );\n\n PREFLIGHT_DONE.add(key);\n })();\n PREFLIGHT_INFLIGHT.set(key, run);\n try {\n await run;\n } finally {\n PREFLIGHT_INFLIGHT.delete(key);\n }\n}\n\n/**\n * Handle task-agent routes (/api/coding-agents/*)\n * Returns true if the route was handled, false otherwise\n */\nexport async function handleAgentRoutes(\n req: IncomingMessage,\n res: ServerResponse,\n pathname: string,\n ctx: RouteContext,\n): Promise<boolean> {\n const method = req.method?.toUpperCase();\n\n // === Preflight Check ===\n // GET /api/coding-agents/preflight\n if (method === \"GET\" && pathname === \"/api/coding-agents/preflight\") {\n if (!ctx.ptyService) {\n sendError(res, \"PTY Service not available\", 503);\n return true;\n }\n\n try {\n const results = await ctx.ptyService.checkAvailableAgents();\n sendJson(res, results);\n } catch (error) {\n sendError(\n res,\n error instanceof Error ? error.message : \"Preflight check failed\",\n 500,\n );\n }\n return true;\n }\n\n // POST /api/coding-agents/auth/:agent — trigger CLI auth flow\n const authMatch = pathname.match(/^\\/api\\/coding-agents\\/auth\\/(\\w+)$/);\n if (method === \"POST\" && authMatch) {\n if (!ctx.ptyService) {\n sendError(res, \"PTY Service not available\", 503);\n return true;\n }\n const rawAgentType = authMatch[1];\n\n // Validate agent type before instantiating an adapter.\n // Must stay in sync with PTYService.checkAvailableAgents() default list.\n const SUPPORTED_AGENTS: ReadonlyArray<string> = [\n \"claude\",\n \"codex\",\n \"gemini\",\n \"aider\",\n ];\n if (!SUPPORTED_AGENTS.includes(rawAgentType)) {\n sendError(res, `Unsupported agent type: ${rawAgentType}`, 400);\n return true;\n }\n\n const agentType =\n rawAgentType as import(\"../services/task-agent-frameworks.js\").SupportedTaskAgentAdapter;\n try {\n const result = await ctx.ptyService.triggerAgentAuth(agentType);\n if (!result) {\n sendError(res, `No auth flow available for ${agentType}`, 400);\n } else {\n sendJson(res, result);\n }\n } catch (error) {\n const msg =\n error instanceof Error ? error.message : \"Auth trigger failed\";\n // Defensive fallback: primary input validation is handled by\n // SUPPORTED_AGENTS above, so reaching here means the adapter package's\n // own validation failed (e.g. internal lookup table mismatch). The regex\n // is brittle if `coding-agent-adapters` changes its error wording, but\n // it lets us return 400 instead of 500 for likely client errors.\n const status = /unknown adapter|unsupported/i.test(msg) ? 400 : 500;\n sendError(res, msg, status);\n }\n return true;\n }\n\n // GET /api/coding-agents/metrics\n if (method === \"GET\" && pathname === \"/api/coding-agents/metrics\") {\n if (!ctx.ptyService) {\n sendError(res, \"PTY Service not available\", 503);\n return true;\n }\n sendJson(res, ctx.ptyService.getAgentMetrics());\n return true;\n }\n\n // === Scratch Workspace Retention ===\n // GET /api/coding-agents/scratch\n if (method === \"GET\" && pathname === \"/api/coding-agents/scratch\") {\n if (!ctx.workspaceService) {\n sendError(res, \"Workspace Service not available\", 503);\n return true;\n }\n sendJson(res, ctx.workspaceService.listScratchWorkspaces());\n return true;\n }\n\n // POST /api/coding-agents/:id/scratch/(keep|delete|promote)\n const scratchActionMatch = pathname.match(\n /^\\/api\\/coding-agents\\/([^/]+)\\/scratch\\/(keep|delete|promote)$/,\n );\n if (method === \"POST\" && scratchActionMatch) {\n if (!ctx.workspaceService) {\n sendError(res, \"Workspace Service not available\", 503);\n return true;\n }\n const sessionId = scratchActionMatch[1];\n const action = scratchActionMatch[2];\n try {\n if (action === \"keep\") {\n const scratch =\n await ctx.workspaceService.keepScratchWorkspace(sessionId);\n sendJson(res, { success: true, scratch });\n return true;\n }\n if (action === \"delete\") {\n await ctx.workspaceService.deleteScratchWorkspace(sessionId);\n sendJson(res, {\n success: true,\n deleted: true,\n sessionId,\n });\n return true;\n }\n const body = await parseBody(req);\n const promoteName = typeof body.name === \"string\" ? body.name : undefined;\n const scratch = await ctx.workspaceService.promoteScratchWorkspace(\n sessionId,\n promoteName,\n );\n sendJson(res, { success: true, scratch });\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n const status = message.includes(\"not found\") ? 404 : 500;\n sendError(res, message, status);\n }\n return true;\n }\n\n // === Workspace Files ===\n // GET /api/coding-agents/workspace-files?agentType=claude\n if (method === \"GET\" && pathname === \"/api/coding-agents/workspace-files\") {\n if (!ctx.ptyService) {\n sendError(res, \"PTY Service not available\", 503);\n return true;\n }\n\n try {\n const url = new URL(req.url || \"\", `http://${req.headers.host}`);\n const agentType = url.searchParams.get(\"agentType\");\n if (!agentType) {\n sendError(\n res,\n \"agentType query parameter required (claude, gemini, codex, aider, pi)\",\n 400,\n );\n return true;\n }\n\n if (isPiAgentType(agentType)) {\n sendJson(res, {\n agentType: \"pi\",\n memoryFilePath: \".pi/agent/settings.json\",\n files: [],\n });\n return true;\n }\n\n const files = ctx.ptyService.getWorkspaceFiles(\n agentType as import(\"coding-agent-adapters\").AdapterType,\n );\n const memoryFilePath = ctx.ptyService.getMemoryFilePath(\n agentType as import(\"coding-agent-adapters\").AdapterType,\n );\n sendJson(res, {\n agentType,\n memoryFilePath,\n files,\n });\n } catch (error) {\n sendError(\n res,\n error instanceof Error\n ? error.message\n : \"Failed to get workspace files\",\n 500,\n );\n }\n return true;\n }\n\n // === Approval Presets ===\n // GET /api/coding-agents/approval-presets\n if (method === \"GET\" && pathname === \"/api/coding-agents/approval-presets\") {\n try {\n const { listPresets } = await import(\"coding-agent-adapters\");\n const presets = listPresets();\n sendJson(res, presets);\n } catch (error) {\n sendError(\n res,\n error instanceof Error ? error.message : \"Failed to list presets\",\n 500,\n );\n }\n return true;\n }\n\n // GET /api/coding-agents/settings\n if (method === \"GET\" && pathname === \"/api/coding-agents/settings\") {\n if (!ctx.ptyService) {\n sendError(res, \"PTY Service not available\", 503);\n return true;\n }\n const frameworkState = await getTaskAgentFrameworkState(\n ctx.runtime,\n ctx.ptyService,\n );\n sendJson(res, {\n defaultApprovalPreset: ctx.ptyService.defaultApprovalPreset,\n agentSelectionStrategy: ctx.ptyService.agentSelectionStrategy,\n defaultAgentType: ctx.ptyService.defaultAgentType,\n preferredAgentType: frameworkState.preferred.id,\n preferredAgentReason: frameworkState.preferred.reason,\n configuredSubscriptionProvider:\n frameworkState.configuredSubscriptionProvider,\n frameworks: frameworkState.frameworks,\n });\n return true;\n }\n\n // GET /api/coding-agents/approval-config?agentType=claude&preset=autonomous\n if (method === \"GET\" && pathname === \"/api/coding-agents/approval-config\") {\n if (!ctx.ptyService) {\n sendError(res, \"PTY Service not available\", 503);\n return true;\n }\n\n const url = new URL(req.url || \"\", `http://${req.headers.host}`);\n const agentType = url.searchParams.get(\"agentType\");\n const preset = url.searchParams.get(\"preset\");\n if (!agentType || !preset) {\n sendError(res, \"agentType and preset query parameters required\", 400);\n return true;\n }\n\n try {\n const config = ctx.ptyService.getApprovalConfig(\n agentType as import(\"coding-agent-adapters\").AdapterType,\n preset as import(\"coding-agent-adapters\").ApprovalPreset,\n );\n sendJson(res, config);\n } catch (error) {\n sendError(\n res,\n error instanceof Error ? error.message : \"Failed to generate config\",\n 500,\n );\n }\n return true;\n }\n\n // === List Agents ===\n // GET /api/coding-agents\n if (method === \"GET\" && pathname === \"/api/coding-agents\") {\n if (!ctx.ptyService) {\n sendError(res, \"PTY Service not available\", 503);\n return true;\n }\n\n try {\n const sessions = await ctx.ptyService.listSessions();\n sendJson(res, sessions);\n } catch (error) {\n sendError(\n res,\n error instanceof Error ? error.message : \"Failed to list agents\",\n 500,\n );\n }\n return true;\n }\n\n // === Spawn Agent ===\n // POST /api/coding-agents/spawn\n if (method === \"POST\" && pathname === \"/api/coding-agents/spawn\") {\n if (!ctx.ptyService) {\n sendError(res, \"PTY Service not available\", 503);\n return true;\n }\n\n try {\n const body = await parseBody(req);\n const {\n agentType,\n workdir: rawWorkdir,\n task,\n initialTask,\n memoryContent,\n approvalPreset,\n customCredentials,\n metadata,\n } = body;\n const taskText =\n typeof task === \"string\"\n ? task\n : typeof initialTask === \"string\"\n ? initialTask\n : undefined;\n\n // Validate workdir: must be within workspace base dir or cwd\n const workspaceBaseDir = path.join(os.homedir(), \".eliza\", \"workspaces\");\n const workspaceBaseDirResolved = path.resolve(workspaceBaseDir);\n const cwdResolved = path.resolve(process.cwd());\n const workspaceBaseDirReal = await realpath(\n workspaceBaseDirResolved,\n ).catch(() => workspaceBaseDirResolved);\n const cwdReal = await realpath(cwdResolved).catch(() => cwdResolved);\n const allowedPrefixes = [workspaceBaseDirReal, cwdReal];\n let workdir = rawWorkdir as string | undefined;\n if (workdir) {\n const resolved = path.resolve(workdir);\n const resolvedReal = await realpath(resolved).catch(() => null);\n if (!resolvedReal) {\n sendError(res, \"workdir must exist\", 403);\n return true;\n }\n const isAllowed = allowedPrefixes.some(\n (prefix) =>\n resolvedReal === prefix ||\n resolvedReal.startsWith(prefix + path.sep),\n );\n if (!isAllowed) {\n sendError(\n res,\n \"workdir must be within workspace base directory or cwd\",\n 403,\n );\n return true;\n }\n workdir = resolvedReal;\n }\n\n // Check concurrency limit before spawning\n const activeSessions = await ctx.ptyService.listSessions();\n const maxSessions = 8;\n if (activeSessions.length >= maxSessions) {\n sendError(\n res,\n `Concurrent session limit reached (${maxSessions})`,\n 429,\n );\n return true;\n }\n\n if (workdir) {\n try {\n await runBenchmarkPreflight(workdir);\n } catch (preflightError) {\n console.warn(\n `[coding-agent] benchmark preflight failed for ${workdir}:`,\n preflightError,\n );\n }\n }\n\n // Build credentials from runtime\n const rawAnthropicKey = ctx.runtime.getSetting(\"ANTHROPIC_API_KEY\") as\n | string\n | undefined;\n let credentials: ReturnType<typeof buildAgentCredentials>;\n try {\n credentials = buildAgentCredentials(ctx.runtime);\n } catch (error) {\n const message =\n error instanceof Error\n ? error.message\n : \"Failed to build credentials\";\n sendError(res, message, 400);\n return true;\n }\n\n // Resolve requested framework; PTYService applies model preferences centrally.\n const agentStr = agentType\n ? (agentType as string).toLowerCase()\n : await ctx.ptyService.resolveAgentType();\n const piRequested = isPiAgentType(agentStr);\n const normalizedType = normalizeAgentType(agentStr);\n const aiderProvider =\n agentStr === \"aider\"\n ? (ctx.runtime.getSetting(\"PARALLAX_AIDER_PROVIDER\") as string | null)\n : null;\n\n // Check if coordinator is active — route blocking prompts through it\n const coordinator = getCoordinator(ctx.runtime);\n const requestedThreadId =\n typeof (metadata as Record<string, unknown>)?.threadId === \"string\"\n ? ((metadata as Record<string, unknown>).threadId as string)\n : null;\n const evalRunMetadata = extractEvalRunMetadata(\n metadata as Record<string, unknown>,\n );\n const taskThread =\n coordinator && taskText && !requestedThreadId\n ? await coordinator.createTaskThread({\n title:\n ((metadata as Record<string, unknown>)?.label as\n | string\n | undefined) ?? `Task ${Date.now()}`,\n originalRequest: taskText,\n scenarioId: evalRunMetadata.scenarioId,\n batchId: evalRunMetadata.batchId,\n metadata: {\n workdir: workdir ?? null,\n source: \"api-spawn\",\n ...(evalRunMetadata.scenarioId\n ? { scenarioId: evalRunMetadata.scenarioId }\n : {}),\n ...(evalRunMetadata.batchId\n ? { batchId: evalRunMetadata.batchId }\n : {}),\n },\n })\n : requestedThreadId\n ? await coordinator?.getTaskThread(requestedThreadId)\n : null;\n\n const session = await ctx.ptyService.spawnSession({\n name: `agent-${Date.now()}`,\n agentType: normalizedType,\n workdir: workdir as string,\n initialTask: piRequested ? toPiCommand(taskText) : taskText,\n memoryContent: memoryContent as string | undefined,\n credentials,\n approvalPreset: approvalPreset as\n | import(\"coding-agent-adapters\").ApprovalPreset\n | undefined,\n customCredentials: sanitizeCustomCredentials(\n customCredentials as Record<string, string> | undefined,\n isAnthropicOAuthToken(rawAnthropicKey) ? [rawAnthropicKey] : [],\n ),\n // Let adapter auto-response handle known prompts (permissions, trust, etc.)\n // instantly. The coordinator handles only unrecognized prompts via LLM.\n metadata: {\n threadId: taskThread?.id ?? requestedThreadId,\n requestedType: agentStr,\n ...(metadata as Record<string, unknown>),\n ...(aiderProvider ? { provider: aiderProvider } : {}),\n },\n });\n if (coordinator) {\n const label = (metadata as Record<string, unknown>)?.label as\n | string\n | undefined;\n const defaultLabelPrefix =\n normalizedType === \"shell\" ? \"shell\" : \"agent\";\n await coordinator.registerTask(session.id, {\n threadId: taskThread?.id ?? requestedThreadId ?? session.id,\n agentType:\n agentStr as import(\"../services/pty-service.js\").CodingAgentType,\n label: label || `${defaultLabelPrefix}-${session.id.slice(-8)}`,\n originalTask: taskText ?? \"\",\n workdir: session.workdir,\n });\n }\n\n sendJson(\n res,\n {\n sessionId: session.id,\n agentType: session.agentType,\n workdir: session.workdir,\n status: session.status,\n },\n 201,\n );\n } catch (error) {\n sendError(\n res,\n error instanceof Error ? error.message : \"Failed to spawn agent\",\n 500,\n );\n }\n return true;\n }\n\n // === Get Agent Status ===\n // GET /api/coding-agents/:id\n const agentMatch = pathname.match(/^\\/api\\/coding-agents\\/([^/]+)$/);\n if (method === \"GET\" && agentMatch) {\n if (!ctx.ptyService) {\n sendError(res, \"PTY Service not available\", 503);\n return true;\n }\n\n const sessionId = agentMatch[1];\n const session = ctx.ptyService.getSession(sessionId);\n\n if (!session) {\n sendError(res, \"Agent session not found\", 404);\n return true;\n }\n\n sendJson(res, session);\n return true;\n }\n\n // === Send to Agent ===\n // POST /api/coding-agents/:id/send\n const sendMatch = pathname.match(/^\\/api\\/coding-agents\\/([^/]+)\\/send$/);\n if (method === \"POST\" && sendMatch) {\n if (!ctx.ptyService) {\n sendError(res, \"PTY Service not available\", 503);\n return true;\n }\n\n try {\n const sessionId = sendMatch[1];\n const body = await parseBody(req);\n const { input, keys } = body;\n\n if (keys) {\n // Send special keys (e.g. \"enter\", [\"down\",\"enter\"], \"Ctrl-C\")\n await ctx.ptyService.sendKeysToSession(\n sessionId,\n keys as string | string[],\n );\n sendJson(res, { success: true });\n } else if (input && typeof input === \"string\") {\n await ctx.ptyService.sendToSession(sessionId, input);\n sendJson(res, { success: true });\n } else {\n sendError(\n res,\n \"Either 'input' (string) or 'keys' (string|string[]) required\",\n 400,\n );\n return true;\n }\n } catch (error) {\n sendError(\n res,\n error instanceof Error ? error.message : \"Failed to send input\",\n 500,\n );\n }\n return true;\n }\n\n // === Stop Agent ===\n // POST /api/coding-agents/:id/stop\n const stopMatch = pathname.match(/^\\/api\\/coding-agents\\/([^/]+)\\/stop$/);\n if (method === \"POST\" && stopMatch) {\n if (!ctx.ptyService) {\n sendError(res, \"PTY Service not available\", 503);\n return true;\n }\n\n try {\n const sessionId = stopMatch[1];\n await ctx.ptyService.stopSession(sessionId);\n sendJson(res, { success: true, sessionId });\n } catch (error) {\n sendError(\n res,\n error instanceof Error ? error.message : \"Failed to stop agent\",\n 500,\n );\n }\n return true;\n }\n\n // === Get Agent Output ===\n // GET /api/coding-agents/:id/output\n const outputMatch = pathname.match(/^\\/api\\/coding-agents\\/([^/]+)\\/output$/);\n if (method === \"GET\" && outputMatch) {\n if (!ctx.ptyService) {\n sendError(res, \"PTY Service not available\", 503);\n return true;\n }\n\n try {\n const sessionId = outputMatch[1];\n const url = new URL(req.url || \"\", `http://${req.headers.host}`);\n const lines = parseInt(url.searchParams.get(\"lines\") || \"100\", 10);\n\n const output = await ctx.ptyService.getSessionOutput(sessionId, lines);\n sendJson(res, { sessionId, output });\n } catch (error) {\n sendError(\n res,\n error instanceof Error ? error.message : \"Failed to get output\",\n 500,\n );\n }\n return true;\n }\n\n // === Get Buffered Terminal Output (raw ANSI for xterm.js hydration) ===\n // GET /api/coding-agents/:id/buffered-output\n const bufferedMatch = pathname.match(\n /^\\/api\\/coding-agents\\/([^/]+)\\/buffered-output$/,\n );\n if (method === \"GET\" && bufferedMatch) {\n if (!ctx.ptyService?.consoleBridge) {\n sendError(res, \"Console bridge not available\", 503);\n return true;\n }\n try {\n const sessionId = bufferedMatch[1];\n const output = ctx.ptyService.consoleBridge.getBufferedOutput(sessionId);\n sendJson(res, { sessionId, output });\n } catch (error) {\n sendError(\n res,\n error instanceof Error\n ? error.message\n : \"Failed to get buffered output\",\n 500,\n );\n }\n return true;\n }\n\n // Route not handled\n return false;\n}\n",
|
|
48
|
+
"/**\n * Sub-agent bridge routes — read-only HTTP endpoints exposing parent state.\n *\n * Spawned coding sub-agents (Claude Code, Codex) live in sealed PTY workspaces\n * with no direct access to the parent Eliza runtime's memory, character, or\n * room context. These routes give them a constrained read channel so they can\n * resolve pronouns (\"the user's dad\") and align with parent context the\n * orchestrator's task brief didn't surface.\n *\n * Endpoints (loopback-only, agentId-authed via the path):\n *\n * GET /api/coding-agents/:sessionId/parent-context\n * GET /api/coding-agents/:sessionId/memory?q=<query>&limit=<N>\n * GET /api/coding-agents/:sessionId/active-workspaces\n *\n * All responses are read-only. Mutations stay with the orchestrator —\n * sub-agents can't write parent state through the bridge.\n *\n * Validation: every request's :sessionId is checked against the coordinator's\n * `tasks` map. Unknown / stale sessions get 404. Tasks in stopped/error/completed\n * status get 410 (so the sub-agent can fall back to no-parent-context mode\n * cleanly).\n *\n * @module api/bridge-routes\n */\n\nimport type { IncomingMessage, ServerResponse } from \"node:http\";\nimport type { TaskContext } from \"../services/swarm-coordinator.js\";\nimport type { RouteContext } from \"./route-utils.js\";\nimport { sendError, sendJson } from \"./route-utils.js\";\n\nconst SESSION_ID_PATTERN = /^pty-\\d+-[0-9a-f]+$/;\n\n/** Bridge endpoint path matcher. */\nconst BRIDGE_PATH =\n /^\\/api\\/coding-agents\\/(pty-\\d+-[0-9a-f]+)\\/(parent-context|memory|active-workspaces)\\/?$/;\n\n/**\n * Parsed bridge request.\n */\ninterface BridgeRequest {\n sessionId: string;\n endpoint: \"parent-context\" | \"memory\" | \"active-workspaces\";\n query: URLSearchParams;\n}\n\nfunction parseBridgeRequest(\n pathname: string,\n rawUrl: string | undefined,\n): BridgeRequest | null {\n const match = pathname.match(BRIDGE_PATH);\n if (!match) return null;\n const sessionId = match[1];\n const endpoint = match[2] as BridgeRequest[\"endpoint\"];\n const fullUrl = rawUrl ?? \"\";\n const queryStart = fullUrl.indexOf(\"?\");\n const query =\n queryStart >= 0\n ? new URLSearchParams(fullUrl.slice(queryStart + 1))\n : new URLSearchParams();\n return { sessionId, endpoint, query };\n}\n\n/**\n * Resolve the TaskContext for a sessionId from the coordinator. Returns the\n * task plus a \"freshness\" indicator the caller uses to decide between 200,\n * 404 (unknown), and 410 (stale).\n */\nfunction resolveTaskContext(\n ctx: RouteContext,\n sessionId: string,\n): { task: TaskContext | null; status: \"active\" | \"stale\" | \"unknown\" } {\n if (!SESSION_ID_PATTERN.test(sessionId)) {\n return { task: null, status: \"unknown\" };\n }\n const coordinator = ctx.coordinator;\n if (!coordinator) {\n return { task: null, status: \"unknown\" };\n }\n const task = coordinator.tasks.get(sessionId) ?? null;\n if (!task) {\n return { task: null, status: \"unknown\" };\n }\n const stale =\n task.status === \"stopped\" ||\n task.status === \"error\" ||\n task.status === \"completed\";\n return { task, status: stale ? \"stale\" : \"active\" };\n}\n\n/**\n * GET /api/coding-agents/:sessionId/parent-context\n *\n * Returns the agent's character profile, the originating room (so the\n * sub-agent knows where its work eventually surfaces), and the task's spawn\n * metadata.\n */\nasync function handleParentContext(\n res: ServerResponse,\n ctx: RouteContext,\n task: TaskContext,\n): Promise<void> {\n const character = ctx.runtime.character;\n const thread = task.threadId\n ? await ctx.coordinator?.taskRegistry\n .getThread(task.threadId)\n .catch(() => null)\n : null;\n sendJson(res, {\n session_id: task.sessionId,\n agent_label: task.label,\n workdir: task.workdir,\n repo: task.repo ?? null,\n agent_type: task.agentType,\n character: {\n name: character?.name ?? null,\n bio: Array.isArray(character?.bio)\n ? character.bio\n : typeof character?.bio === \"string\"\n ? [character.bio]\n : [],\n topics: Array.isArray(character?.topics) ? character.topics : [],\n },\n room: thread?.roomId\n ? {\n id: thread.roomId,\n thread_id: task.threadId,\n }\n : null,\n original_task: task.originalTask ?? null,\n });\n}\n\n/**\n * GET /api/coding-agents/:sessionId/memory?q=<query>&limit=<N>\n *\n * Returns recent messages from the originating room, optionally filtered by\n * a substring query. Useful for the sub-agent to resolve pronouns or recover\n * context the task brief didn't capture. Read-only — no write API exists.\n */\nasync function handleMemory(\n res: ServerResponse,\n ctx: RouteContext,\n task: TaskContext,\n query: URLSearchParams,\n): Promise<void> {\n const thread = task.threadId\n ? await ctx.coordinator?.taskRegistry\n .getThread(task.threadId)\n .catch(() => null)\n : null;\n if (!thread?.roomId) {\n sendJson(res, { messages: [], count: 0, room_id: null });\n return;\n }\n\n const rawLimit = Number(query.get(\"limit\") ?? \"10\");\n const limit = Math.max(\n 1,\n Math.min(50, Number.isFinite(rawLimit) ? rawLimit : 10),\n );\n const queryText = (query.get(\"q\") ?? \"\").trim().toLowerCase();\n\n const memories = await ctx.runtime\n .getMemories({\n roomId: thread.roomId,\n count: limit * 2,\n tableName: \"messages\",\n })\n .catch(() => []);\n\n const matched = memories\n .map((m) => {\n const text = (m.content as { text?: string }).text;\n if (typeof text !== \"string\" || text.length === 0) return null;\n if (queryText && !text.toLowerCase().includes(queryText)) return null;\n return {\n speaker: m.entityId === ctx.runtime.agentId ? \"agent\" : \"user\",\n text: text.length > 600 ? `${text.slice(0, 600)}...` : text,\n created_at: m.createdAt ? new Date(m.createdAt).toISOString() : null,\n };\n })\n .filter((x): x is NonNullable<typeof x> => x !== null)\n .slice(0, limit);\n\n sendJson(res, {\n room_id: thread.roomId,\n query: queryText || null,\n count: matched.length,\n messages: matched.reverse(),\n });\n}\n\n/**\n * GET /api/coding-agents/:sessionId/active-workspaces\n *\n * Returns the orchestrator's currently-active task workspaces (other than\n * the requesting one). Lets a sub-agent see its siblings when running under\n * a swarm without parsing the injected CLAUDE.md.\n */\nfunction handleActiveWorkspaces(\n res: ServerResponse,\n ctx: RouteContext,\n requesting: TaskContext,\n): void {\n const coordinator = ctx.coordinator;\n if (!coordinator) {\n sendJson(res, { workspaces: [], count: 0 });\n return;\n }\n const peers = [...coordinator.tasks.values()]\n .filter(\n (t) =>\n t.sessionId !== requesting.sessionId &&\n (t.status === \"active\" || t.status === \"tool_running\"),\n )\n .map((t) => ({\n session_id: t.sessionId,\n label: t.label,\n agent_type: t.agentType,\n workdir: t.workdir,\n repo: t.repo ?? null,\n }));\n sendJson(res, { workspaces: peers, count: peers.length });\n}\n\n/**\n * Entry point — dispatches to the right handler based on parsed path.\n */\nexport async function handleBridgeRoutes(\n req: IncomingMessage,\n res: ServerResponse,\n pathname: string,\n ctx: RouteContext,\n): Promise<boolean> {\n const parsed = parseBridgeRequest(pathname, req.url);\n if (!parsed) return false;\n\n if ((req.method ?? \"\").toUpperCase() !== \"GET\") {\n sendError(res, \"Bridge endpoints are GET-only\", 405);\n return true;\n }\n\n const { task, status } = resolveTaskContext(ctx, parsed.sessionId);\n if (status === \"unknown\" || !task) {\n sendError(res, `Unknown sessionId ${parsed.sessionId}`, 404);\n return true;\n }\n if (status === \"stale\") {\n sendError(\n res,\n `Session ${parsed.sessionId} is in terminal state (${task.status}); no parent context available`,\n 410,\n );\n return true;\n }\n\n switch (parsed.endpoint) {\n case \"parent-context\":\n await handleParentContext(res, ctx, task);\n return true;\n case \"memory\":\n await handleMemory(res, ctx, task, parsed.query);\n return true;\n case \"active-workspaces\":\n handleActiveWorkspaces(res, ctx, task);\n return true;\n }\n}\n",
|
|
49
|
+
"/**\n * Swarm Coordinator Route Handlers\n *\n * Provides SSE streaming and HTTP API for the coordination layer:\n * - SSE event stream for real-time dashboard\n * - Task status and context queries\n * - Pending confirmation management\n * - Supervision level control\n *\n * @module api/coordinator-routes\n */\n\nimport type { IncomingMessage, ServerResponse } from \"node:http\";\nimport type { SwarmCoordinator } from \"../services/swarm-coordinator.js\";\nimport { getTaskAgentFrameworkState } from \"../services/task-agent-frameworks.js\";\nimport type {\n TaskThreadKind,\n TaskThreadStatus,\n} from \"../services/task-registry.js\";\nimport { discoverTaskShareOptions } from \"../services/task-share.js\";\nimport type { RouteContext } from \"./route-utils.js\";\nimport { parseBody, sendError, sendJson } from \"./route-utils.js\";\n\nconst COORDINATOR_PREFIX = \"/api/coding-agents/coordinator\";\n\n/**\n * Handle coordinator routes (/api/coding-agents/coordinator/*)\n * Returns true if the route was handled, false otherwise.\n */\nexport async function handleCoordinatorRoutes(\n req: IncomingMessage,\n res: ServerResponse,\n pathname: string,\n ctx: RouteContext & { coordinator?: SwarmCoordinator },\n): Promise<boolean> {\n if (!pathname.startsWith(COORDINATOR_PREFIX)) {\n return false;\n }\n\n const method = req.method?.toUpperCase();\n const subPath = pathname.slice(COORDINATOR_PREFIX.length);\n\n if (!ctx.coordinator) {\n sendError(res, \"Swarm Coordinator not available\", 503);\n return true;\n }\n\n const coordinator = ctx.coordinator;\n\n // === SSE Event Stream ===\n // GET /api/coding-agents/coordinator/events\n if (method === \"GET\" && subPath === \"/events\") {\n // CORS is handled by the server middleware — no need to set it here.\n res.writeHead(200, {\n \"Content-Type\": \"text/event-stream\",\n \"Cache-Control\": \"no-cache\",\n Connection: \"keep-alive\",\n });\n\n // Send initial comment to establish connection\n res.write(\":ok\\n\\n\");\n\n // Register as SSE client (sends snapshot on connect)\n const unsubscribe = coordinator.addSseClient(res);\n\n // Clean up on close\n req.on(\"close\", unsubscribe);\n\n // Keep-alive ping every 30s\n const keepAlive = setInterval(() => {\n if (res.writableEnded) {\n clearInterval(keepAlive);\n return;\n }\n res.write(\":ping\\n\\n\");\n }, 30_000);\n\n req.on(\"close\", () => clearInterval(keepAlive));\n\n return true;\n }\n\n // === All Task Contexts ===\n // GET /api/coding-agents/coordinator/status\n if (method === \"GET\" && subPath === \"/status\") {\n const allTasks = coordinator.getAllTaskContexts();\n const persistedThreads = await coordinator.listTaskThreads({\n includeArchived: false,\n limit: 50,\n });\n // Only return active tasks — stopped/completed/error are terminal states\n // and should not appear in the UI after refresh.\n const tasks = allTasks.filter(\n (t) =>\n t.status !== \"stopped\" &&\n t.status !== \"completed\" &&\n t.status !== \"error\",\n );\n const recentTasks = allTasks\n .slice()\n .sort((left, right) => right.registeredAt - left.registeredAt)\n .slice(0, 10);\n const frameworkState = await getTaskAgentFrameworkState(\n ctx.runtime,\n ctx.ptyService ?? undefined,\n );\n sendJson(res, {\n supervisionLevel: coordinator.getSupervisionLevel(),\n taskCount: tasks.length,\n tasks: tasks.map((t) => ({\n threadId: t.threadId,\n taskNodeId: t.taskNodeId ?? null,\n sessionId: t.sessionId,\n agentType: t.agentType,\n label: t.label,\n originalTask: t.originalTask,\n workdir: t.workdir,\n status: t.status,\n decisionCount: t.decisions.length,\n autoResolvedCount: t.autoResolvedCount,\n completionSummary: t.completionSummary,\n lastActivityAt: t.lastActivityAt,\n })),\n recentTasks: recentTasks.map((t) => ({\n threadId: t.threadId,\n taskNodeId: t.taskNodeId ?? null,\n sessionId: t.sessionId,\n agentType: t.agentType,\n label: t.label,\n status: t.status,\n originalTask: t.originalTask,\n completionSummary: t.completionSummary,\n registeredAt: t.registeredAt,\n lastActivityAt: t.lastActivityAt,\n })),\n taskThreadCount: persistedThreads.length,\n taskThreads: persistedThreads.map((thread) => ({\n id: thread.id,\n title: thread.title,\n kind: thread.kind,\n status: thread.status,\n scenarioId: thread.scenarioId,\n batchId: thread.batchId,\n originalRequest: thread.originalRequest,\n summary: thread.summary,\n sessionCount: thread.sessionCount,\n activeSessionCount: thread.activeSessionCount,\n latestSessionId: thread.latestSessionId,\n latestSessionLabel: thread.latestSessionLabel,\n latestWorkdir: thread.latestWorkdir,\n latestRepo: thread.latestRepo,\n latestActivityAt: thread.latestActivityAt,\n decisionCount: thread.decisionCount,\n nodeCount: thread.nodeCount,\n readyNodeCount: thread.readyNodeCount,\n completedNodeCount: thread.completedNodeCount,\n verifierJobCount: thread.verifierJobCount,\n evidenceCount: thread.evidenceCount,\n createdAt: thread.createdAt,\n updatedAt: thread.updatedAt,\n closedAt: thread.closedAt,\n archivedAt: thread.archivedAt,\n })),\n pendingConfirmations: coordinator.getPendingConfirmations().length,\n preferredAgentType: frameworkState.preferred.id,\n preferredAgentReason: frameworkState.preferred.reason,\n frameworks: frameworkState.frameworks,\n });\n return true;\n }\n\n // === Task Threads ===\n // GET /api/coding-agents/coordinator/threads\n if (method === \"GET\" && subPath === \"/threads\") {\n const url = new URL(req.url ?? pathname, \"http://localhost\");\n const includeArchived = url.searchParams.get(\"includeArchived\") === \"true\";\n const status = url.searchParams.get(\"status\") ?? undefined;\n const statusesRaw = url.searchParams.get(\"statuses\");\n const statuses = statusesRaw\n ?.split(\",\")\n .map((value) => value.trim())\n .filter(Boolean) as TaskThreadStatus[] | undefined;\n const kind = (url.searchParams.get(\"kind\") ?? undefined) as\n | TaskThreadKind\n | undefined;\n const roomId = url.searchParams.get(\"roomId\") ?? undefined;\n const worldId = url.searchParams.get(\"worldId\") ?? undefined;\n const ownerUserId = url.searchParams.get(\"ownerUserId\") ?? undefined;\n const scenarioId = url.searchParams.get(\"scenarioId\") ?? undefined;\n const batchId = url.searchParams.get(\"batchId\") ?? undefined;\n const createdAfter = url.searchParams.get(\"createdAfter\") ?? undefined;\n const createdBefore = url.searchParams.get(\"createdBefore\") ?? undefined;\n const updatedAfter = url.searchParams.get(\"updatedAfter\") ?? undefined;\n const updatedBefore = url.searchParams.get(\"updatedBefore\") ?? undefined;\n const latestActivityAfterRaw = url.searchParams.get(\"latestActivityAfter\");\n const latestActivityBeforeRaw = url.searchParams.get(\n \"latestActivityBefore\",\n );\n const latestActivityAfter =\n latestActivityAfterRaw && Number.isFinite(Number(latestActivityAfterRaw))\n ? Number(latestActivityAfterRaw)\n : undefined;\n const latestActivityBefore =\n latestActivityBeforeRaw &&\n Number.isFinite(Number(latestActivityBeforeRaw))\n ? Number(latestActivityBeforeRaw)\n : undefined;\n const hasActiveSessionRaw = url.searchParams.get(\"hasActiveSession\");\n const hasActiveSession =\n hasActiveSessionRaw === null ? undefined : hasActiveSessionRaw === \"true\";\n const search = url.searchParams.get(\"search\") ?? undefined;\n const limitRaw = url.searchParams.get(\"limit\");\n const limit =\n limitRaw && Number.isFinite(Number(limitRaw))\n ? Number(limitRaw)\n : undefined;\n\n const threads = await coordinator.listTaskThreads({\n includeArchived,\n status: (status as TaskThreadStatus | null) ?? undefined,\n statuses,\n kind,\n roomId,\n worldId,\n ownerUserId,\n scenarioId,\n batchId,\n createdAfter,\n createdBefore,\n updatedAfter,\n updatedBefore,\n latestActivityAfter,\n latestActivityBefore,\n hasActiveSession,\n search,\n limit,\n });\n sendJson(res, threads);\n return true;\n }\n\n if (method === \"GET\" && subPath === \"/threads/count\") {\n const url = new URL(req.url ?? pathname, \"http://localhost\");\n const includeArchived = url.searchParams.get(\"includeArchived\") === \"true\";\n const status = url.searchParams.get(\"status\") ?? undefined;\n const statusesRaw = url.searchParams.get(\"statuses\");\n const statuses = statusesRaw\n ?.split(\",\")\n .map((value) => value.trim())\n .filter(Boolean) as TaskThreadStatus[] | undefined;\n const kind = (url.searchParams.get(\"kind\") ?? undefined) as\n | TaskThreadKind\n | undefined;\n const roomId = url.searchParams.get(\"roomId\") ?? undefined;\n const worldId = url.searchParams.get(\"worldId\") ?? undefined;\n const ownerUserId = url.searchParams.get(\"ownerUserId\") ?? undefined;\n const scenarioId = url.searchParams.get(\"scenarioId\") ?? undefined;\n const batchId = url.searchParams.get(\"batchId\") ?? undefined;\n const createdAfter = url.searchParams.get(\"createdAfter\") ?? undefined;\n const createdBefore = url.searchParams.get(\"createdBefore\") ?? undefined;\n const updatedAfter = url.searchParams.get(\"updatedAfter\") ?? undefined;\n const updatedBefore = url.searchParams.get(\"updatedBefore\") ?? undefined;\n const latestActivityAfterRaw = url.searchParams.get(\"latestActivityAfter\");\n const latestActivityBeforeRaw = url.searchParams.get(\n \"latestActivityBefore\",\n );\n const latestActivityAfter =\n latestActivityAfterRaw && Number.isFinite(Number(latestActivityAfterRaw))\n ? Number(latestActivityAfterRaw)\n : undefined;\n const latestActivityBefore =\n latestActivityBeforeRaw &&\n Number.isFinite(Number(latestActivityBeforeRaw))\n ? Number(latestActivityBeforeRaw)\n : undefined;\n const hasActiveSessionRaw = url.searchParams.get(\"hasActiveSession\");\n const hasActiveSession =\n hasActiveSessionRaw === null ? undefined : hasActiveSessionRaw === \"true\";\n const search = url.searchParams.get(\"search\") ?? undefined;\n\n const total = await coordinator.countTaskThreads({\n includeArchived,\n status: (status as TaskThreadStatus | null) ?? undefined,\n statuses,\n kind,\n roomId,\n worldId,\n ownerUserId,\n scenarioId,\n batchId,\n createdAfter,\n createdBefore,\n updatedAfter,\n updatedBefore,\n latestActivityAfter,\n latestActivityBefore,\n hasActiveSession,\n search,\n });\n sendJson(res, { total });\n return true;\n }\n\n // GET /api/coding-agents/coordinator/threads/:threadId\n const threadMatch = subPath.match(/^\\/threads\\/([^/]+)$/);\n if (method === \"GET\" && threadMatch) {\n const thread = await coordinator.getTaskThread(threadMatch[1]);\n if (!thread) {\n sendError(res, \"Task thread not found\", 404);\n return true;\n }\n sendJson(res, thread);\n return true;\n }\n\n const shareMatch = subPath.match(/^\\/threads\\/([^/]+)\\/share$/);\n if (method === \"GET\" && shareMatch) {\n const share = await discoverTaskShareOptions(coordinator, shareMatch[1]);\n if (!share) {\n sendError(res, \"Task thread not found\", 404);\n return true;\n }\n sendJson(res, share);\n return true;\n }\n\n // POST /api/coding-agents/coordinator/threads/:threadId/archive\n const archiveMatch = subPath.match(/^\\/threads\\/([^/]+)\\/archive$/);\n if (method === \"POST\" && archiveMatch) {\n await coordinator.archiveTaskThread(archiveMatch[1]);\n sendJson(res, {\n success: true,\n threadId: archiveMatch[1],\n status: \"archived\",\n });\n return true;\n }\n\n // POST /api/coding-agents/coordinator/threads/:threadId/reopen\n const reopenMatch = subPath.match(/^\\/threads\\/([^/]+)\\/reopen$/);\n if (method === \"POST\" && reopenMatch) {\n await coordinator.reopenTaskThread(reopenMatch[1]);\n sendJson(res, { success: true, threadId: reopenMatch[1], status: \"open\" });\n return true;\n }\n\n const controlMatch = subPath.match(/^\\/threads\\/([^/]+)\\/control$/);\n if (method === \"POST\" && controlMatch) {\n try {\n const body = await parseBody(req);\n const action = typeof body.action === \"string\" ? body.action.trim() : \"\";\n const note = typeof body.note === \"string\" ? body.note : undefined;\n const instruction =\n typeof body.instruction === \"string\" ? body.instruction : undefined;\n const agentType =\n typeof body.agentType === \"string\" ? body.agentType : undefined;\n\n if (action === \"pause\") {\n const result = await coordinator.pauseTaskThread(controlMatch[1], note);\n sendJson(res, { success: true, action, ...result });\n return true;\n }\n if (action === \"stop\") {\n const result = await coordinator.stopTaskThread(controlMatch[1], note);\n sendJson(res, { success: true, action, ...result });\n return true;\n }\n if (action === \"resume\") {\n const result = await coordinator.resumeTaskThread(\n controlMatch[1],\n instruction,\n agentType,\n );\n sendJson(res, { success: true, action, ...result });\n return true;\n }\n if (action === \"continue\") {\n const result = await coordinator.continueTaskThread(\n controlMatch[1],\n instruction ?? `Continue task thread ${controlMatch[1]}.`,\n agentType,\n );\n sendJson(res, { success: true, action, ...result });\n return true;\n }\n\n sendError(\n res,\n 'Invalid control action. Must be \"pause\", \"stop\", \"resume\", or \"continue\".',\n 400,\n );\n } catch (error) {\n sendError(\n res,\n error instanceof Error\n ? error.message\n : \"Failed to control task thread\",\n 500,\n );\n }\n return true;\n }\n\n // === Single Task Context ===\n // GET /api/coding-agents/coordinator/tasks/:sessionId\n const taskMatch = subPath.match(/^\\/tasks\\/([^/]+)$/);\n if (method === \"GET\" && taskMatch) {\n const sessionId = taskMatch[1];\n const task = await coordinator.getTaskContextSnapshot(sessionId);\n if (!task) {\n sendError(res, \"Task context not found\", 404);\n return true;\n }\n sendJson(res, task);\n return true;\n }\n\n // === Pending Confirmations ===\n // GET /api/coding-agents/coordinator/pending\n if (method === \"GET\" && subPath === \"/pending\") {\n const pending = coordinator.getPendingConfirmations();\n sendJson(\n res,\n pending.map((p) => ({\n sessionId: p.sessionId,\n promptText: p.promptText,\n suggestedAction: p.llmDecision.action,\n suggestedResponse: p.llmDecision.response,\n reasoning: p.llmDecision.reasoning,\n agentType: p.taskContext.agentType,\n label: p.taskContext.label,\n createdAt: p.createdAt,\n })),\n );\n return true;\n }\n\n // === Confirm/Reject Pending Decision ===\n // POST /api/coding-agents/coordinator/confirm/:sessionId\n const confirmMatch = subPath.match(/^\\/confirm\\/([^/]+)$/);\n if (method === \"POST\" && confirmMatch) {\n try {\n const sessionId = confirmMatch[1];\n const body = await parseBody(req);\n const approved = body.approved !== false; // default: approved\n const override = body.override as\n | { response?: string; useKeys?: boolean; keys?: string[] }\n | undefined;\n\n await coordinator.confirmDecision(sessionId, approved, override);\n sendJson(res, { success: true, sessionId, approved });\n } catch (error) {\n sendError(\n res,\n error instanceof Error ? error.message : \"Failed to confirm decision\",\n error instanceof Error && error.message.includes(\"No pending\")\n ? 404\n : 500,\n );\n }\n return true;\n }\n\n // === Supervision Level ===\n // GET /api/coding-agents/coordinator/supervision\n if (method === \"GET\" && subPath === \"/supervision\") {\n sendJson(res, { level: coordinator.getSupervisionLevel() });\n return true;\n }\n\n // POST /api/coding-agents/coordinator/supervision\n if (method === \"POST\" && subPath === \"/supervision\") {\n try {\n const body = await parseBody(req);\n const level = body.level as string;\n if (![\"autonomous\", \"confirm\", \"notify\"].includes(level)) {\n sendError(\n res,\n 'Invalid supervision level. Must be \"autonomous\", \"confirm\", or \"notify\"',\n 400,\n );\n return true;\n }\n coordinator.setSupervisionLevel(\n level as \"autonomous\" | \"confirm\" | \"notify\",\n );\n sendJson(res, { success: true, level });\n } catch (error) {\n sendError(\n res,\n error instanceof Error\n ? error.message\n : \"Failed to set supervision level\",\n 500,\n );\n }\n return true;\n }\n\n // Not a coordinator route we recognize\n return false;\n}\n",
|
|
50
|
+
"/**\n * Coding Agent HTTP Hooks — Webhook Endpoint\n *\n * Receives structured hook events from coding agent CLI hooks systems.\n * Claude Code sends native HTTP hooks; Gemini CLI bridges via curl commands.\n * Replaces fragile PTY output scraping for state detection with deterministic\n * event-driven signals.\n *\n * @module api/hook-routes\n */\n\nimport type { IncomingMessage, ServerResponse } from \"node:http\";\nimport type { RouteContext } from \"./route-utils.js\";\nimport { parseBody, sendError, sendJson } from \"./route-utils.js\";\n\n/**\n * Hook event payload (subset of fields we use).\n * Supports both Claude Code (native HTTP) and Gemini CLI (curl bridge).\n *\n * Claude docs: https://docs.anthropic.com/en/docs/claude-code/hooks\n * Gemini docs: https://geminicli.com/docs/hooks/reference\n */\ninterface HookEventPayload {\n hook_event_name: string;\n session_id?: string;\n cwd?: string;\n // Claude uses snake_case, Gemini uses camelCase\n tool_name?: string;\n toolName?: string;\n tool_input?: Record<string, unknown>;\n notification_type?: string;\n notificationType?: string;\n message?: string;\n}\n\nfunction asHookEventPayload(\n body: Record<string, unknown>,\n): HookEventPayload | null {\n if (typeof body.hook_event_name !== \"string\" || !body.hook_event_name) {\n return null;\n }\n return {\n hook_event_name: body.hook_event_name,\n session_id:\n typeof body.session_id === \"string\" ? body.session_id : undefined,\n cwd: typeof body.cwd === \"string\" ? body.cwd : undefined,\n tool_name: typeof body.tool_name === \"string\" ? body.tool_name : undefined,\n toolName: typeof body.toolName === \"string\" ? body.toolName : undefined,\n tool_input:\n body.tool_input &&\n typeof body.tool_input === \"object\" &&\n !Array.isArray(body.tool_input)\n ? { ...body.tool_input }\n : undefined,\n notification_type:\n typeof body.notification_type === \"string\"\n ? body.notification_type\n : undefined,\n notificationType:\n typeof body.notificationType === \"string\"\n ? body.notificationType\n : undefined,\n message: typeof body.message === \"string\" ? body.message : undefined,\n };\n}\n\n/**\n * Handle Claude Code HTTP hook routes.\n * Returns true if the route was handled, false otherwise.\n */\nexport async function handleHookRoutes(\n req: IncomingMessage,\n res: ServerResponse,\n pathname: string,\n ctx: RouteContext,\n): Promise<boolean> {\n if (pathname !== \"/api/coding-agents/hooks\") return false;\n\n const method = req.method?.toUpperCase();\n if (method !== \"POST\") {\n sendError(res, \"Method not allowed\", 405);\n return true;\n }\n\n if (!ctx.ptyService) {\n sendError(res, \"PTY Service not available\", 503);\n return true;\n }\n\n let body: Record<string, unknown>;\n try {\n body = await parseBody(req);\n } catch (err) {\n sendError(\n res,\n err instanceof Error ? err.message : \"Failed to parse request body\",\n 400,\n );\n return true;\n }\n\n const payload = asHookEventPayload(body);\n if (!payload) {\n sendError(res, \"Missing hook_event_name\", 400);\n return true;\n }\n const eventName = payload.hook_event_name;\n\n // Normalize field names: Gemini uses camelCase, Claude uses snake_case\n const toolName = payload.tool_name ?? payload.toolName;\n const notificationType =\n payload.notification_type ?? payload.notificationType;\n\n // Look up PTY session: prefer explicit header, fall back to cwd-based lookup\n const headerSessionId = req.headers[\"x-parallax-session-id\"] as\n | string\n | undefined;\n const sessionId = headerSessionId\n ? headerSessionId\n : payload.cwd\n ? ctx.ptyService.findSessionIdByCwd(payload.cwd)\n : undefined;\n\n if (!sessionId) {\n // Not fatal — the hook may fire before we've tracked the session.\n // Return success so the CLI doesn't retry.\n sendJson(res, { status: \"ignored\", reason: \"session_not_found\" });\n return true;\n }\n\n // Dispatch by event type\n switch (eventName) {\n // ── Claude Code events ──────────────────────────────────────────\n\n case \"PermissionRequest\": {\n // Auto-approve all tool permissions natively — no PTY keystroke needed.\n sendJson(res, {\n hookSpecificOutput: {\n hookEventName: \"PermissionRequest\",\n decision: { behavior: \"allow\" },\n },\n });\n ctx.ptyService.handleHookEvent(sessionId, \"permission_approved\", {\n tool: toolName,\n });\n return true;\n }\n\n case \"PreToolUse\": {\n // Track which tool is running — suppress stall detection.\n ctx.ptyService.handleHookEvent(sessionId, \"tool_running\", {\n toolName,\n source: \"hook\",\n });\n // Return allow decision so the tool proceeds without permission prompt.\n sendJson(res, {\n hookSpecificOutput: {\n hookEventName: \"PreToolUse\",\n permissionDecision: \"allow\",\n },\n });\n return true;\n }\n\n case \"Stop\": {\n // Agent finished responding — mark task complete.\n ctx.ptyService.handleHookEvent(sessionId, \"task_complete\", {\n source: \"hook\",\n });\n sendJson(res, {});\n return true;\n }\n\n case \"TaskCompleted\": {\n ctx.ptyService.handleHookEvent(sessionId, \"task_complete\", {\n source: \"hook_task_completed\",\n });\n sendJson(res, {});\n return true;\n }\n\n // ── Gemini CLI events ───────────────────────────────────────────\n\n case \"BeforeTool\": {\n // Track which tool is running — suppress stall detection.\n ctx.ptyService.handleHookEvent(sessionId, \"tool_running\", {\n toolName,\n source: \"gemini_hook\",\n });\n // Return allow + continue so Gemini proceeds without permission prompt.\n sendJson(res, { decision: \"allow\", continue: true });\n return true;\n }\n\n case \"AfterTool\": {\n // Tool finished — update activity (back to \"active\" state).\n ctx.ptyService.handleHookEvent(sessionId, \"notification\", {\n type: \"tool_complete\",\n message: `Tool ${toolName ?? \"unknown\"} finished`,\n });\n sendJson(res, { continue: true });\n return true;\n }\n\n case \"AfterAgent\": {\n // Agent loop ended — mark task complete.\n ctx.ptyService.handleHookEvent(sessionId, \"task_complete\", {\n source: \"gemini_hook\",\n });\n sendJson(res, { continue: true });\n return true;\n }\n\n case \"SessionEnd\": {\n // Session ending — mark exit.\n ctx.ptyService.handleHookEvent(sessionId, \"session_end\", {\n source: \"hook\",\n });\n sendJson(res, { continue: true });\n return true;\n }\n\n // ── Shared events ───────────────────────────────────────────────\n\n case \"Notification\": {\n // State change notifications (idle, permission, auth).\n // Gemini ToolPermission notifications get auto-approved.\n if (notificationType === \"ToolPermission\") {\n ctx.ptyService.handleHookEvent(sessionId, \"permission_approved\", {\n tool: toolName,\n });\n sendJson(res, { decision: \"allow\", continue: true });\n return true;\n }\n ctx.ptyService.handleHookEvent(sessionId, \"notification\", {\n type: notificationType,\n message: payload.message,\n });\n sendJson(res, { continue: true });\n return true;\n }\n\n default: {\n // Unknown event — acknowledge without action.\n sendJson(res, { status: \"ignored\", reason: \"unknown_event\" });\n return true;\n }\n }\n}\n",
|
|
51
|
+
"/**\n * Issue Route Handlers\n *\n * Handles routes for GitHub issue management:\n * - List issues, create issue\n * - Get issue, comment on issue, close issue\n *\n * @module api/issue-routes\n */\n\nimport type { IncomingMessage, ServerResponse } from \"node:http\";\nimport type { RouteContext } from \"./route-utils.js\";\nimport { parseBody, sendError, sendJson } from \"./route-utils.js\";\n\n/**\n * Handle issue routes (/api/issues/*)\n * Returns true if the route was handled, false otherwise\n */\nexport async function handleIssueRoutes(\n req: IncomingMessage,\n res: ServerResponse,\n pathname: string,\n ctx: RouteContext,\n): Promise<boolean> {\n const method = req.method?.toUpperCase();\n\n // GET /api/issues?repo=owner/repo&state=open\n if (method === \"GET\" && pathname === \"/api/issues\") {\n if (!ctx.workspaceService) {\n sendError(res, \"Workspace Service not available\", 503);\n return true;\n }\n\n try {\n const url = new URL(req.url || \"\", `http://${req.headers.host}`);\n const repo = url.searchParams.get(\"repo\");\n if (!repo) {\n sendError(res, \"repo query parameter required\", 400);\n return true;\n }\n const state = url.searchParams.get(\"state\") as\n | \"open\"\n | \"closed\"\n | \"all\"\n | null;\n const labelsParam = url.searchParams.get(\"labels\");\n const labels = labelsParam\n ? labelsParam.split(\",\").map((s) => s.trim())\n : undefined;\n\n const issues = await ctx.workspaceService.listIssues(repo, {\n state: state ?? \"open\",\n labels,\n });\n sendJson(res, issues);\n } catch (error) {\n sendError(\n res,\n error instanceof Error ? error.message : \"Failed to list issues\",\n 500,\n );\n }\n return true;\n }\n\n // POST /api/issues\n if (method === \"POST\" && pathname === \"/api/issues\") {\n if (!ctx.workspaceService) {\n sendError(res, \"Workspace Service not available\", 503);\n return true;\n }\n\n try {\n const body = await parseBody(req);\n const { repo, title, body: issueBody, labels } = body;\n if (!repo || !title) {\n sendError(res, \"repo and title are required\", 400);\n return true;\n }\n\n const issue = await ctx.workspaceService.createIssue(repo as string, {\n title: title as string,\n body: (issueBody as string) ?? \"\",\n labels: labels as string[] | undefined,\n });\n sendJson(res, issue, 201);\n } catch (error) {\n sendError(\n res,\n error instanceof Error ? error.message : \"Failed to create issue\",\n 500,\n );\n }\n return true;\n }\n\n // GET /api/issues/:repo/:number (e.g., /api/issues/owner/repo/42)\n const issueGetMatch = pathname.match(\n /^\\/api\\/issues\\/([^/]+)\\/([^/]+)\\/(\\d+)$/,\n );\n if (method === \"GET\" && issueGetMatch) {\n if (!ctx.workspaceService) {\n sendError(res, \"Workspace Service not available\", 503);\n return true;\n }\n\n try {\n const repo = `${issueGetMatch[1]}/${issueGetMatch[2]}`;\n const issueNumber = parseInt(issueGetMatch[3], 10);\n const issue = await ctx.workspaceService.getIssue(repo, issueNumber);\n sendJson(res, issue);\n } catch (error) {\n sendError(\n res,\n error instanceof Error ? error.message : \"Failed to get issue\",\n 500,\n );\n }\n return true;\n }\n\n // POST /api/issues/:repo/:number/comment\n const commentMatch = pathname.match(\n /^\\/api\\/issues\\/([^/]+)\\/([^/]+)\\/(\\d+)\\/comment$/,\n );\n if (method === \"POST\" && commentMatch) {\n if (!ctx.workspaceService) {\n sendError(res, \"Workspace Service not available\", 503);\n return true;\n }\n\n try {\n const repo = `${commentMatch[1]}/${commentMatch[2]}`;\n const issueNumber = parseInt(commentMatch[3], 10);\n const body = await parseBody(req);\n if (!body.body) {\n sendError(res, \"body is required\", 400);\n return true;\n }\n const comment = await ctx.workspaceService.addComment(\n repo,\n issueNumber,\n body.body as string,\n );\n sendJson(res, comment, 201);\n } catch (error) {\n sendError(\n res,\n error instanceof Error ? error.message : \"Failed to add comment\",\n 500,\n );\n }\n return true;\n }\n\n // POST /api/issues/:repo/:number/close\n const closeMatch = pathname.match(\n /^\\/api\\/issues\\/([^/]+)\\/([^/]+)\\/(\\d+)\\/close$/,\n );\n if (method === \"POST\" && closeMatch) {\n if (!ctx.workspaceService) {\n sendError(res, \"Workspace Service not available\", 503);\n return true;\n }\n\n try {\n const repo = `${closeMatch[1]}/${closeMatch[2]}`;\n const issueNumber = parseInt(closeMatch[3], 10);\n const issue = await ctx.workspaceService.closeIssue(repo, issueNumber);\n sendJson(res, issue);\n } catch (error) {\n sendError(\n res,\n error instanceof Error ? error.message : \"Failed to close issue\",\n 500,\n );\n }\n return true;\n }\n\n // Route not handled\n return false;\n}\n",
|
|
52
|
+
"/**\n * Read-only parent-runtime context bridge for spawned task agents.\n *\n * Child CLI agents receive their session id in the injected memory file. These\n * routes let that child read narrowly-scoped parent state without exposing any\n * mutation surface back into the parent runtime.\n *\n * @module api/parent-context-routes\n */\n\nimport type { IncomingMessage, ServerResponse } from \"node:http\";\nimport type { IAgentRuntime, Memory } from \"@elizaos/core\";\nimport { ModelType } from \"@elizaos/core\";\nimport { activeWorkspaceContextProvider } from \"../providers/active-workspace-context.js\";\nimport type { SessionInfo } from \"../services/pty-types.js\";\nimport type { TaskContext } from \"../services/swarm-coordinator.js\";\nimport type { RouteContext } from \"./route-utils.js\";\nimport { sendJson } from \"./route-utils.js\";\n\ntype JsonValue =\n | string\n | number\n | boolean\n | null\n | JsonValue[]\n | { [key: string]: JsonValue };\n\ntype ParentMemoryHit = { [key: string]: JsonValue } & {\n id: string | null;\n tableName: string;\n text: string;\n similarity: number | null;\n roomId: string | null;\n worldId: string | null;\n entityId: string | null;\n createdAt: number | null;\n metadata: JsonValue;\n};\n\nconst BRIDGE_TIMEOUT_MS = 5_000;\nconst DEFAULT_MEMORY_LIMIT = 10;\nconst MAX_MEMORY_LIMIT = 50;\nconst MEMORY_TABLES = [\"facts\", \"messages\", \"documents\"] as const;\nconst TERMINAL_TASK_STATUSES = new Set([\"completed\", \"error\", \"stopped\"]);\nconst TERMINAL_SESSION_STATUSES = new Set([\"stopped\", \"error\", \"exited\"]);\n\nclass BridgeRouteError extends Error {\n constructor(\n readonly code: string,\n readonly status: number,\n message: string,\n ) {\n super(message);\n }\n}\n\nfunction sendBridgeError(\n res: ServerResponse,\n code: string,\n message: string,\n status: number,\n): void {\n sendJson(res, { error: message, code }, status);\n}\n\nfunction isLoopbackRemoteAddress(\n remoteAddress: string | null | undefined,\n): boolean {\n if (!remoteAddress) return false;\n const normalized = remoteAddress.trim().toLowerCase();\n return (\n normalized === \"127.0.0.1\" ||\n normalized === \"::1\" ||\n normalized === \"::ffff:127.0.0.1\" ||\n normalized === \"::ffff:0:127.0.0.1\"\n );\n}\n\nfunction parseSessionId(raw: string): string | null {\n let decoded = \"\";\n try {\n decoded = decodeURIComponent(raw);\n } catch {\n return null;\n }\n if (!decoded || decoded.includes(\"/\") || decoded.includes(\"..\")) {\n return null;\n }\n return decoded;\n}\n\nfunction parseLimit(raw: string | null): number {\n if (!raw) return DEFAULT_MEMORY_LIMIT;\n const parsed = Number(raw);\n if (!Number.isFinite(parsed)) return DEFAULT_MEMORY_LIMIT;\n return Math.max(1, Math.min(MAX_MEMORY_LIMIT, Math.floor(parsed)));\n}\n\nfunction withBridgeTimeout<T>(promise: Promise<T>): Promise<T> {\n return new Promise<T>((resolve, reject) => {\n const timer = setTimeout(() => {\n reject(\n new BridgeRouteError(\n \"parent_context_timeout\",\n 503,\n \"Parent runtime context bridge timed out.\",\n ),\n );\n }, BRIDGE_TIMEOUT_MS);\n promise.then(\n (value) => {\n clearTimeout(timer);\n resolve(value);\n },\n (error) => {\n clearTimeout(timer);\n reject(error);\n },\n );\n });\n}\n\nfunction getSession(ctx: RouteContext, sessionId: string): SessionInfo | null {\n return ctx.ptyService?.getSession(sessionId) ?? null;\n}\n\nfunction getTask(ctx: RouteContext, sessionId: string): TaskContext | null {\n return ctx.coordinator?.getTaskContext(sessionId) ?? null;\n}\n\nfunction isActiveSession(\n task: TaskContext | null,\n session: SessionInfo | null,\n): boolean {\n if (task && !TERMINAL_TASK_STATUSES.has(task.status)) return true;\n if (session && !TERMINAL_SESSION_STATUSES.has(String(session.status))) {\n return true;\n }\n return false;\n}\n\nfunction readSessionMetadata(\n task: TaskContext | null,\n session: SessionInfo | null,\n): Record<string, unknown> {\n const raw = session?.metadata;\n if (raw && typeof raw === \"object\" && !Array.isArray(raw)) {\n return raw;\n }\n return task?.originMetadata ?? {};\n}\n\nfunction readString(value: unknown): string | null {\n return typeof value === \"string\" && value.trim().length > 0\n ? value.trim()\n : null;\n}\n\nfunction toJsonValue(value: unknown): JsonValue {\n return JSON.parse(JSON.stringify(value ?? null));\n}\n\nfunction readOriginRoomId(\n task: TaskContext | null,\n metadata: Record<string, unknown>,\n): string | null {\n return (\n readString(task?.originRoomId) ??\n readString(metadata.originRoomId) ??\n readString(metadata.roomId)\n );\n}\n\nfunction normalizeDocumentSources(value: unknown): JsonValue[] {\n if (!Array.isArray(value)) return [];\n return value.flatMap((entry): JsonValue[] => {\n if (typeof entry === \"string\" && entry.trim()) return [entry.trim()];\n if (!entry || typeof entry !== \"object\") return [];\n const raw = entry as {\n item?: { case?: string; value?: unknown };\n path?: unknown;\n directory?: unknown;\n };\n if (typeof raw.path === \"string\" && raw.path.trim()) {\n return [raw.path.trim()];\n }\n if (typeof raw.directory === \"string\" && raw.directory.trim()) {\n return [raw.directory.trim()];\n }\n if (raw.item?.case === \"path\" && typeof raw.item.value === \"string\") {\n return [raw.item.value];\n }\n if (\n raw.item?.case === \"directory\" &&\n raw.item.value &&\n typeof raw.item.value === \"object\"\n ) {\n const directory = raw.item.value as {\n path?: unknown;\n directory?: unknown;\n };\n const pathValue =\n readString(directory.path) ?? readString(directory.directory);\n return pathValue ? [pathValue] : [];\n }\n return [];\n });\n}\n\nfunction normalizeModel(\n task: TaskContext | null,\n session: SessionInfo | null,\n metadata: Record<string, unknown>,\n): JsonValue {\n const rawPrefs = metadata.modelPrefs;\n const modelPrefs =\n rawPrefs && typeof rawPrefs === \"object\" && !Array.isArray(rawPrefs)\n ? (rawPrefs as Record<string, unknown>)\n : {};\n return {\n agentType: session?.agentType ?? task?.agentType ?? null,\n powerful: readString(modelPrefs.powerful),\n fast: readString(modelPrefs.fast),\n };\n}\n\nasync function loadRoom(\n runtime: IAgentRuntime,\n roomId: string | null,\n): Promise<JsonValue> {\n if (!roomId) return null;\n const room = await runtime.getRoom(roomId as Memory[\"roomId\"]);\n if (!room) return { id: roomId, channel: null, platform: null };\n return {\n id: room.id,\n channel: room.channelId ?? room.name ?? null,\n platform: room.source ?? null,\n type: room.type ?? null,\n worldId: room.worldId ?? null,\n };\n}\n\nfunction normalizeMemoryHit(\n tableName: string,\n memory: Memory,\n): ParentMemoryHit {\n const raw = memory as Memory & { similarity?: number };\n const text =\n typeof memory.content?.text === \"string\" ? memory.content.text : \"\";\n return {\n id: typeof memory.id === \"string\" ? memory.id : null,\n tableName,\n text,\n similarity:\n typeof raw.similarity === \"number\" && Number.isFinite(raw.similarity)\n ? raw.similarity\n : null,\n roomId: typeof memory.roomId === \"string\" ? memory.roomId : null,\n worldId: typeof memory.worldId === \"string\" ? memory.worldId : null,\n entityId: typeof memory.entityId === \"string\" ? memory.entityId : null,\n createdAt:\n typeof memory.createdAt === \"number\" && Number.isFinite(memory.createdAt)\n ? memory.createdAt\n : null,\n metadata:\n memory.metadata && typeof memory.metadata === \"object\"\n ? toJsonValue(memory.metadata)\n : null,\n };\n}\n\nasync function buildParentContext(\n ctx: RouteContext,\n sessionId: string,\n task: TaskContext | null,\n session: SessionInfo | null,\n): Promise<JsonValue> {\n const metadata = readSessionMetadata(task, session);\n const roomId = readOriginRoomId(task, metadata);\n const character = ctx.runtime.character;\n return {\n sessionId,\n character: {\n name: character.name ?? null,\n bio: Array.isArray(character.bio)\n ? character.bio\n : typeof character.bio === \"string\"\n ? [character.bio]\n : [],\n documents: normalizeDocumentSources([\n ...(Array.isArray(character.documents) ? character.documents : []),\n ...(Array.isArray(character.knowledge) ? character.knowledge : []),\n ]),\n },\n currentRoom: await loadRoom(ctx.runtime, roomId),\n workdir: session?.workdir ?? task?.workdir ?? null,\n model: normalizeModel(task, session, metadata),\n };\n}\n\nasync function searchParentMemory(\n ctx: RouteContext,\n query: string,\n limit: number,\n): Promise<JsonValue> {\n const embedding = await ctx.runtime.useModel(ModelType.TEXT_EMBEDDING, {\n text: query,\n });\n const perTableLimit = Math.max(\n limit,\n Math.ceil(limit / MEMORY_TABLES.length),\n );\n const grouped = await Promise.all(\n MEMORY_TABLES.map(async (tableName) => {\n const hits = await ctx.runtime.searchMemories({\n tableName,\n embedding,\n query,\n limit: perTableLimit,\n });\n return hits.map((hit) => normalizeMemoryHit(tableName, hit));\n }),\n );\n const hits = grouped\n .flat()\n .sort(\n (left, right) =>\n (right.similarity ?? Number.NEGATIVE_INFINITY) -\n (left.similarity ?? Number.NEGATIVE_INFINITY),\n )\n .slice(0, limit);\n return { query, limit, hits };\n}\n\nasync function listActiveWorkspaceContext(\n ctx: RouteContext,\n): Promise<JsonValue> {\n const result = await activeWorkspaceContextProvider.get(\n ctx.runtime,\n {\n id: ctx.runtime.agentId,\n agentId: ctx.runtime.agentId,\n entityId: ctx.runtime.agentId,\n roomId: ctx.runtime.agentId,\n content: { text: \"\" },\n } as Memory,\n { values: {}, data: {}, text: \"\" },\n );\n return toJsonValue(result.data ?? {});\n}\n\n/**\n * Handle read-only parent-runtime bridge routes.\n * Returns true if the route was handled, false otherwise.\n */\nexport async function handleParentContextRoutes(\n req: IncomingMessage,\n res: ServerResponse,\n pathname: string,\n ctx: RouteContext,\n): Promise<boolean> {\n const match = pathname.match(\n /^\\/api\\/coding-agents\\/([^/]+)\\/(parent-context|memory|active-workspaces)$/,\n );\n if (!match) return false;\n\n if (!isLoopbackRemoteAddress(req.socket.remoteAddress)) {\n sendBridgeError(\n res,\n \"loopback_only\",\n \"Bridge routes are loopback-only.\",\n 403,\n );\n return true;\n }\n\n const method = req.method?.toUpperCase() ?? \"GET\";\n if (method !== \"GET\") {\n sendBridgeError(\n res,\n \"method_not_allowed\",\n \"Bridge routes are read-only and only support GET.\",\n 405,\n );\n return true;\n }\n\n const sessionId = parseSessionId(match[1]);\n if (!sessionId) {\n sendBridgeError(res, \"invalid_agent_id\", \"Invalid task-agent id.\", 400);\n return true;\n }\n\n const task = getTask(ctx, sessionId);\n const session = getSession(ctx, sessionId);\n if (!isActiveSession(task, session)) {\n sendBridgeError(\n res,\n \"task_no_longer_active\",\n \"The task-agent session is no longer active in this parent runtime.\",\n 410,\n );\n return true;\n }\n\n try {\n const endpoint = match[2];\n if (endpoint === \"parent-context\") {\n sendJson(\n res,\n await withBridgeTimeout(\n buildParentContext(ctx, sessionId, task, session),\n ),\n );\n return true;\n }\n if (endpoint === \"memory\") {\n const url = new URL(req.url ?? pathname, \"http://localhost\");\n const query = url.searchParams.get(\"q\")?.trim() ?? \"\";\n if (!query) {\n sendBridgeError(\n res,\n \"missing_query\",\n \"memory requires q=<query>.\",\n 400,\n );\n return true;\n }\n sendJson(\n res,\n await withBridgeTimeout(\n searchParentMemory(\n ctx,\n query,\n parseLimit(url.searchParams.get(\"limit\")),\n ),\n ),\n );\n return true;\n }\n sendJson(res, await withBridgeTimeout(listActiveWorkspaceContext(ctx)));\n return true;\n } catch (error) {\n if (error instanceof BridgeRouteError) {\n sendBridgeError(res, error.code, error.message, error.status);\n return true;\n }\n sendBridgeError(\n res,\n \"parent_context_unavailable\",\n error instanceof Error\n ? error.message\n : \"Parent runtime context bridge failed.\",\n 503,\n );\n return true;\n }\n}\n",
|
|
53
|
+
"/**\n * Workspace Route Handlers\n *\n * Handles routes for git workspace management:\n * - Provision (clone repos, create worktrees)\n * - Get status, commit, push, create PR, delete\n *\n * @module api/workspace-routes\n */\n\nimport type { IncomingMessage, ServerResponse } from \"node:http\";\nimport type { RouteContext } from \"./route-utils.js\";\nimport { parseBody, sendError, sendJson } from \"./route-utils.js\";\n\n/**\n * Handle workspace routes (/api/workspace/*)\n * Returns true if the route was handled, false otherwise\n */\nexport async function handleWorkspaceRoutes(\n req: IncomingMessage,\n res: ServerResponse,\n pathname: string,\n ctx: RouteContext,\n): Promise<boolean> {\n const method = req.method?.toUpperCase();\n\n // POST /api/workspace/provision\n if (method === \"POST\" && pathname === \"/api/workspace/provision\") {\n if (!ctx.workspaceService) {\n sendError(res, \"Workspace Service not available\", 503);\n return true;\n }\n\n try {\n const body = await parseBody(req);\n const { repo, baseBranch, useWorktree, parentWorkspaceId, branchName } =\n body;\n\n const workspace = await ctx.workspaceService.provisionWorkspace({\n repo: repo as string,\n baseBranch: baseBranch as string,\n branchName: branchName as string | undefined,\n useWorktree: useWorktree as boolean,\n parentWorkspaceId: parentWorkspaceId as string,\n });\n\n sendJson(\n res,\n {\n id: workspace.id,\n path: workspace.path,\n branch: workspace.branch,\n isWorktree: workspace.isWorktree,\n },\n 201,\n );\n } catch (error) {\n sendError(\n res,\n error instanceof Error\n ? error.message\n : \"Failed to provision workspace\",\n 500,\n );\n }\n return true;\n }\n\n // GET /api/workspace/:id\n const workspaceMatch = pathname.match(/^\\/api\\/workspace\\/([^/]+)$/);\n if (method === \"GET\" && workspaceMatch) {\n if (!ctx.workspaceService) {\n sendError(res, \"Workspace Service not available\", 503);\n return true;\n }\n\n try {\n const workspaceId = workspaceMatch[1];\n const status = await ctx.workspaceService.getStatus(workspaceId);\n sendJson(res, status);\n } catch (error) {\n sendError(\n res,\n error instanceof Error ? error.message : \"Failed to get workspace\",\n 500,\n );\n }\n return true;\n }\n\n // POST /api/workspace/:id/commit\n const commitMatch = pathname.match(/^\\/api\\/workspace\\/([^/]+)\\/commit$/);\n if (method === \"POST\" && commitMatch) {\n if (!ctx.workspaceService) {\n sendError(res, \"Workspace Service not available\", 503);\n return true;\n }\n\n try {\n const workspaceId = commitMatch[1];\n const body = await parseBody(req);\n const { message } = body;\n\n const result = await ctx.workspaceService.commit(workspaceId, {\n message: message as string,\n all: true,\n });\n\n sendJson(res, result);\n } catch (error) {\n sendError(\n res,\n error instanceof Error ? error.message : \"Failed to commit\",\n 500,\n );\n }\n return true;\n }\n\n // POST /api/workspace/:id/push\n const pushMatch = pathname.match(/^\\/api\\/workspace\\/([^/]+)\\/push$/);\n if (method === \"POST\" && pushMatch) {\n if (!ctx.workspaceService) {\n sendError(res, \"Workspace Service not available\", 503);\n return true;\n }\n\n try {\n const workspaceId = pushMatch[1];\n const body = await parseBody(req);\n\n const result = await ctx.workspaceService.push(workspaceId, {\n force: body.force as boolean,\n setUpstream: body.setUpstream as boolean,\n });\n\n sendJson(res, result);\n } catch (error) {\n sendError(\n res,\n error instanceof Error ? error.message : \"Failed to push\",\n 500,\n );\n }\n return true;\n }\n\n // POST /api/workspace/:id/pr\n const prMatch = pathname.match(/^\\/api\\/workspace\\/([^/]+)\\/pr$/);\n if (method === \"POST\" && prMatch) {\n if (!ctx.workspaceService) {\n sendError(res, \"Workspace Service not available\", 503);\n return true;\n }\n\n try {\n const workspaceId = prMatch[1];\n const body = await parseBody(req);\n\n const result = await ctx.workspaceService.createPR(workspaceId, {\n title: body.title as string,\n body: body.body as string,\n base: body.baseBranch as string,\n draft: body.draft as boolean,\n });\n\n sendJson(res, result, 201);\n } catch (error) {\n sendError(\n res,\n error instanceof Error ? error.message : \"Failed to create PR\",\n 500,\n );\n }\n return true;\n }\n\n // DELETE /api/workspace/:id\n const deleteMatch = pathname.match(/^\\/api\\/workspace\\/([^/]+)$/);\n if (method === \"DELETE\" && deleteMatch) {\n if (!ctx.workspaceService) {\n sendError(res, \"Workspace Service not available\", 503);\n return true;\n }\n\n try {\n const workspaceId = deleteMatch[1];\n await ctx.workspaceService.removeWorkspace(workspaceId);\n sendJson(res, { success: true, workspaceId });\n } catch (error) {\n sendError(\n res,\n error instanceof Error ? error.message : \"Failed to remove workspace\",\n 500,\n );\n }\n return true;\n }\n\n // Route not handled\n return false;\n}\n",
|
|
54
|
+
"/**\n * Task Agent API Routes — Dispatcher\n *\n * Provides shared helpers (parseBody, sendJson, sendError), types, and the\n * top-level route dispatcher that delegates to domain-specific route modules.\n *\n * @module api/routes\n */\n\nimport type { IncomingMessage, ServerResponse } from \"node:http\";\nimport type { IAgentRuntime } from \"@elizaos/core\";\nimport { getCoordinator, getPtyService } from \"../services/pty-service.js\";\nimport type { SwarmCoordinator } from \"../services/swarm-coordinator.js\";\nimport { getCodingWorkspaceService } from \"../services/workspace-service.js\";\nimport { handleAgentRoutes } from \"./agent-routes.js\";\nimport { handleBridgeRoutes } from \"./bridge-routes.js\";\nimport { handleCoordinatorRoutes } from \"./coordinator-routes.js\";\nimport { handleHookRoutes } from \"./hook-routes.js\";\nimport { handleIssueRoutes } from \"./issue-routes.js\";\nimport { handleParentContextRoutes } from \"./parent-context-routes.js\";\nimport type { RouteContext } from \"./route-utils.js\";\nimport { handleWorkspaceRoutes } from \"./workspace-routes.js\";\n\n/**\n * Handle task-agent routes\n * Returns true if the route was handled, false otherwise\n */\nexport async function handleCodingAgentRoutes(\n req: IncomingMessage,\n res: ServerResponse,\n pathname: string,\n ctx: RouteContext,\n): Promise<boolean> {\n const normalizedPathname = pathname.startsWith(\"/api/task-agents\")\n ? pathname.replace(/^\\/api\\/task-agents/, \"/api/coding-agents\")\n : pathname;\n\n // Delegate to hook routes first — hooks need fast responses\n if (await handleHookRoutes(req, res, normalizedPathname, ctx)) {\n return true;\n }\n\n // Sub-agent bridge (read-only parent-state queries from spawned coding\n // sub-agents). Pattern is /api/coding-agents/<sessionId>/(parent-context|memory|active-workspaces)\n // and is matched before agent-routes so its more-specific path wins.\n if (await handleBridgeRoutes(req, res, normalizedPathname, ctx)) {\n return true;\n }\n\n // Delegate to coordinator routes (before agent routes — more specific prefix)\n if (await handleCoordinatorRoutes(req, res, normalizedPathname, ctx)) {\n return true;\n }\n\n // Delegate to parent-runtime bridge routes before generic :id agent routes.\n if (await handleParentContextRoutes(req, res, normalizedPathname, ctx)) {\n return true;\n }\n\n // Delegate to agent routes\n if (await handleAgentRoutes(req, res, normalizedPathname, ctx)) {\n return true;\n }\n\n // Delegate to workspace routes\n if (await handleWorkspaceRoutes(req, res, normalizedPathname, ctx)) {\n return true;\n }\n\n // Delegate to issue routes\n if (await handleIssueRoutes(req, res, normalizedPathname, ctx)) {\n return true;\n }\n\n // Route not handled\n return false;\n}\n\n/**\n * Create route handler with services from runtime\n */\nexport function createCodingAgentRouteHandler(\n runtime: IAgentRuntime,\n coordinator?: SwarmCoordinator,\n) {\n return (req: IncomingMessage, res: ServerResponse, pathname: string) => {\n const ctx: RouteContext = {\n runtime,\n ptyService: getPtyService(runtime),\n workspaceService: getCodingWorkspaceService(runtime),\n coordinator: coordinator ?? getCoordinator(runtime),\n };\n return handleCodingAgentRoutes(req, res, pathname, ctx);\n };\n}\n\nexport const createTaskAgentRouteHandler = createCodingAgentRouteHandler;\n",
|
|
55
|
+
"/**\n * Agent Orchestrator Plugin for Eliza\n *\n * Canonical orchestration plugin: combines the ACP-based subprocess spawn\n * surface (acpx) with workspace lifecycle, GitHub integration, task share,\n * task history, runtime-driven sub-agent routing, and supporting services.\n *\n * @module @elizaos/plugin-agent-orchestrator\n */\n\nimport type { Plugin, ServiceClass } from \"@elizaos/core\";\nimport {\n isLocalCodeExecutionAllowed,\n promoteSubactionsToActions,\n} from \"@elizaos/core\";\n// Side-effect: register coding-agent HTTP routes with the runtime route registry.\nimport \"./register-routes.js\";\nimport { tasksSandboxStubAction } from \"./actions/sandbox-stub.js\";\nimport { tasksAction } from \"./actions/tasks.js\";\nimport { codingAgentExamplesProvider } from \"./providers/action-examples.js\";\nimport { activeSubAgentsProvider } from \"./providers/active-sub-agents.js\";\nimport { activeWorkspaceContextProvider } from \"./providers/active-workspace-context.js\";\nimport { availableAgentsProvider } from \"./providers/available-agents.js\";\nimport { AcpService } from \"./services/acp-service.js\";\nimport { PTYService } from \"./services/pty-service.js\";\nimport { SubAgentRouter } from \"./services/sub-agent-router.js\";\nimport { CodingWorkspaceService } from \"./services/workspace-service.js\";\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === \"object\";\n}\n\nfunction assertServiceClass(service: unknown): asserts service is ServiceClass {\n if (\n !isRecord(service) ||\n typeof service.serviceType !== \"string\" ||\n typeof service.start !== \"function\"\n ) {\n throw new TypeError(\"Invalid orchestrator service class\");\n }\n}\n\nfunction serviceClass(service: unknown): ServiceClass {\n assertServiceClass(service);\n return service;\n}\n\nconst codeExecutionAllowed = isLocalCodeExecutionAllowed();\n\n// Store-distributed builds cannot fork user-installed CLIs. Drop the host-CLI\n// services and the spawn-bearing actions; expose a single user-facing stub\n// action so reaches for SPAWN_AGENT / CREATE_TASK / etc. surface a clean error\n// instead of attempting (and failing) to spawn.\nconst orchestratorServices: ServiceClass[] = codeExecutionAllowed\n ? [\n serviceClass(AcpService),\n serviceClass(SubAgentRouter),\n serviceClass(PTYService),\n serviceClass(CodingWorkspaceService),\n ]\n : [];\n\nconst orchestratorActions = codeExecutionAllowed\n ? [...promoteSubactionsToActions(tasksAction)]\n : [tasksSandboxStubAction];\n\nconst orchestratorProviders = codeExecutionAllowed\n ? [\n availableAgentsProvider, // Adapter inventory + raw session list\n activeSubAgentsProvider, // Cache-stable view of routed sub-agent sessions\n activeWorkspaceContextProvider, // Live workspace/session state\n codingAgentExamplesProvider, // Structured action call examples\n ]\n : [];\n\nexport const agentOrchestratorPlugin: Plugin = {\n name: \"@elizaos/plugin-agent-orchestrator\",\n description: codeExecutionAllowed\n ? \"Spawn and orchestrate coding agents via the Agent Client Protocol (acpx) with workspace lifecycle, GitHub integration, task history, sub-agent routing, and skill-recommender support. Single TASKS parent action covers create / spawn_agent / send / stop_agent / list_agents / cancel / history / control / share / provision_workspace / submit_workspace / manage_issues / archive / reopen.\"\n : \"Coding-agent orchestrator (disabled in store builds — install the direct download to enable). Exposes a single TASKS stub that explains the limitation when the planner reaches for a coding-agent action.\",\n // Services manage ACPX subprocesses, PTY sessions, workspaces, and sub-agent routing.\n services: orchestratorServices,\n actions: orchestratorActions,\n providers: orchestratorProviders,\n};\n\nexport default agentOrchestratorPlugin;\n\n// Re-export coding agent adapter types.\nexport type {\n AdapterType,\n AgentCredentials,\n AgentFileDescriptor,\n ApprovalConfig,\n ApprovalPreset as AdapterApprovalPreset,\n PreflightResult,\n PresetDefinition,\n RiskLevel,\n ToolCategory,\n WriteMemoryOptions,\n} from \"coding-agent-adapters\";\n\n// TASKS action surface.\nexport {\n archiveCodingTaskAction,\n cancelTaskAction,\n createTaskAction,\n finalizeWorkspaceAction,\n listAgentsAction,\n listTaskAgentsAction,\n manageIssuesAction,\n provisionWorkspaceAction,\n reopenCodingTaskAction,\n sendToAgentAction,\n sendToTaskAgentAction,\n spawnAgentAction,\n spawnTaskAgentAction,\n startCodingTaskAction,\n stopAgentAction,\n stopTaskAgentAction,\n taskControlAction,\n taskHistoryAction,\n taskShareAction,\n tasksAction,\n} from \"./actions/tasks.js\";\n// API routes\nexport {\n createCodingAgentRouteHandler,\n createTaskAgentRouteHandler,\n handleCodingAgentRoutes,\n} from \"./api/routes.js\";\n// Providers\nexport { activeSubAgentsProvider } from \"./providers/active-sub-agents.js\";\nexport {\n acpAvailableAgentsProvider,\n availableAgentsProvider,\n} from \"./providers/available-agents.js\";\n\n// ACP service surface.\nexport { AcpService } from \"./services/acp-service.js\";\n// PTY service surface.\nexport { cleanForChat } from \"./services/ansi-utils.js\";\nexport type {\n CodingAgentType,\n PTYServiceConfig,\n SessionEventName as PTYSessionEventName,\n SessionInfo as PTYSessionInfo,\n SpawnSessionOptions as PTYSpawnSessionOptions,\n} from \"./services/pty-service.js\";\nexport { getCoordinator, PTYService } from \"./services/pty-service.js\";\nexport {\n AcpSessionStore,\n FileSessionStore,\n InMemorySessionStore,\n RuntimeDbSessionStore,\n} from \"./services/session-store.js\";\nexport { SubAgentRouter } from \"./services/sub-agent-router.js\";\nexport type {\n AgentDecisionCallback,\n ChatMessageCallback,\n CoordinationDecision,\n PendingDecision,\n SupervisionLevel,\n SwarmCompleteCallback,\n SwarmEvent,\n TaskCompletionSummary,\n TaskContext,\n WsBroadcastCallback,\n} from \"./services/swarm-coordinator.js\";\nexport { SwarmCoordinator } from \"./services/swarm-coordinator.js\";\nexport type {\n CoordinationLLMResponse,\n SharedDecision,\n} from \"./services/swarm-coordinator-prompts.js\";\nexport {\n buildBlockedEventMessage,\n buildTurnCompleteEventMessage,\n} from \"./services/swarm-coordinator-prompts.js\";\n// ACP types\nexport type {\n AcpEventCallback,\n AcpJsonRpcMessage,\n AgentType,\n ApprovalPreset,\n AvailableAgentInfo,\n PromptResult,\n SendOptions,\n SessionEventCallback,\n SessionEventName,\n SessionInfo,\n SessionStatus,\n SpawnOptions,\n SpawnResult,\n} from \"./services/types.js\";\nexport type {\n AuthPromptCallback,\n CodingWorkspaceConfig,\n CommitOptions,\n ProvisionWorkspaceOptions,\n PushOptions,\n WorkspaceResult,\n} from \"./services/workspace-service.js\";\nexport { CodingWorkspaceService } from \"./services/workspace-service.js\";\n",
|
|
56
|
+
"/**\n * Sandbox-build stub for the TASKS coding-agent surface.\n *\n * Store-distributed builds (Mac App Store, Microsoft Store, Flathub) run in\n * an OS sandbox that forbids forking arbitrary user-installed binaries. The\n * orchestrator's spawn paths (claude / codex / opencode CLIs via PTY) are\n * therefore not viable in those builds, so we replace the TASKS action with\n * a single stub that explains the limitation and points the user at the\n * direct-download artifact.\n *\n * Behavior:\n * - validate(): always true — we want this stub to win whenever the\n * planner reaches for any coding-agent simile under sandbox.\n * - handler(): returns a single user-facing error result; no spawn\n * attempt, no workspace allocation, no PTY.\n */\n\nimport type {\n Action,\n ActionResult,\n HandlerCallback,\n IAgentRuntime,\n Memory,\n State,\n} from \"@elizaos/core\";\nimport { buildStoreVariantBlockedMessage } from \"@elizaos/core\";\n\nconst BLOCKED_MESSAGE = buildStoreVariantBlockedMessage(\"Coding agents\");\n\nexport const tasksSandboxStubAction: Action & {\n suppressPostActionContinuation: true;\n} = {\n name: \"TASKS\",\n description:\n \"Coding-agent surface (disabled in store builds — install the direct download to enable).\",\n contexts: [\"tasks\", \"code\", \"automation\", \"agent_internal\", \"connectors\"],\n roleGate: { minRole: \"USER\" },\n suppressPostActionContinuation: true,\n similes: [\n \"CREATE_AGENT_TASK\",\n \"CREATE_TASK\",\n \"START_CODING_TASK\",\n \"LAUNCH_CODING_TASK\",\n \"RUN_CODING_TASK\",\n \"START_AGENT_TASK\",\n \"SPAWN_AND_PROVISION\",\n \"CODE_THIS\",\n \"LAUNCH_TASK\",\n \"SPAWN_AGENT\",\n \"SPAWN_CODING_AGENT\",\n \"START_CODING_AGENT\",\n \"LAUNCH_CODING_AGENT\",\n \"CREATE_CODING_AGENT\",\n \"SPAWN_CODER\",\n \"RUN_CODING_AGENT\",\n \"SPAWN_SUB_AGENT\",\n \"START_TASK_AGENT\",\n \"CREATE_AGENT\",\n \"SEND_TO_AGENT\",\n \"SEND_TO_CODING_AGENT\",\n \"MESSAGE_CODING_AGENT\",\n \"STOP_AGENT\",\n \"STOP_CODING_AGENT\",\n \"KILL_CODING_AGENT\",\n \"TERMINATE_AGENT\",\n \"LIST_AGENTS\",\n \"LIST_CODING_AGENTS\",\n \"CANCEL_TASK\",\n \"STOP_TASK\",\n \"TASK_HISTORY\",\n \"TASK_CONTROL\",\n \"TASK_SHARE\",\n \"PROVISION_WORKSPACE\",\n \"FINALIZE_WORKSPACE\",\n \"MANAGE_ISSUES\",\n \"ARCHIVE_CODING_TASK\",\n \"REOPEN_CODING_TASK\",\n ],\n examples: [],\n validate: async () => true,\n handler: async (\n _runtime: IAgentRuntime,\n _message: Memory,\n _state?: State,\n _options?: unknown,\n callback?: HandlerCallback,\n ): Promise<ActionResult> => {\n if (callback) {\n await callback({\n text: BLOCKED_MESSAGE,\n actions: [\"TASKS\"],\n });\n }\n return {\n success: false,\n text: BLOCKED_MESSAGE,\n data: {\n actionName: \"TASKS\",\n reason: \"STORE_BUILD_BLOCKED\",\n },\n };\n },\n};\n",
|
|
57
|
+
"/**\n * TASKS — single Pattern C parent action that subsumes the orchestrator's\n * task-agent lifecycle, workspace lifecycle, GitHub issue management, and\n * coding-task archive/reopen surface.\n *\n * Old leaf actions live as similes; their handlers were folded into per-op\n * runners on this file.\n *\n * Ops:\n * create — CREATE_AGENT_TASK / START_CODING_TASK\n * spawn_agent — SPAWN_AGENT\n * send — SEND_TO_AGENT\n * stop_agent — STOP_AGENT\n * list_agents — LIST_AGENTS\n * cancel — CANCEL_TASK\n * history — TASK_HISTORY\n * control — TASK_CONTROL (action: pause|resume|stop|continue|archive|reopen)\n * share — TASK_SHARE\n * provision_workspace — CREATE_WORKSPACE / PROVISION_WORKSPACE\n * submit_workspace — SUBMIT_WORKSPACE / FINALIZE_WORKSPACE\n * manage_issues — MANAGE_ISSUES (action: create|list|get|update|comment|close|reopen|add_labels)\n * archive — ARCHIVE_CODING_TASK\n * reopen — REOPEN_CODING_TASK\n *\n * @module actions/tasks\n */\n\nimport type {\n Action,\n ActionResult,\n HandlerCallback,\n HandlerOptions,\n IAgentRuntime,\n Memory,\n State,\n} from \"@elizaos/core\";\nimport { logger as coreLogger } from \"@elizaos/core\";\nimport { getCoordinator } from \"../services/pty-service.js\";\nimport { requireTaskAgentAccess } from \"../services/task-policy.js\";\nimport type { ListTaskThreadsOptions } from \"../services/task-registry.js\";\nimport { discoverTaskShareOptions } from \"../services/task-share.js\";\nimport type { AgentType, SpawnResult } from \"../services/types.js\";\nimport type {\n AuthPromptCallback,\n CodingWorkspaceService,\n WorkspaceResult,\n} from \"../services/workspace-service.js\";\nimport { getCodingWorkspaceService } from \"../services/workspace-service.js\";\nimport {\n callbackText,\n contentRecord,\n emitSessionEvent,\n errorResult,\n failureMessage,\n getAcpService,\n getTimeoutMs,\n type HandlerOptionsLike,\n hasExplicitPayload,\n isAuthError,\n labelFor,\n listSessionsWithin,\n logger,\n looksLikeTaskAgentRequest,\n messageText,\n newestSession,\n paramsRecord,\n parseApproval,\n pickBoolean,\n pickString,\n resolveSession,\n setCurrentSession,\n setCurrentSessions,\n shortId,\n} from \"./common.js\";\nimport { resolveTaskThreadTarget } from \"./task-thread-target.js\";\n\nconst MAX_CONCURRENT_AGENTS = 8;\nconst PROVISION_WORKSPACE_TIMEOUT_MS = 60_000;\nconst WORKSPACE_PATH_MAX_CHARS = 500;\nconst ISSUE_RESULT_LIMIT = 25;\nconst ISSUE_BODY_MAX_CHARS = 4_000;\n\ntype TaskOp =\n | \"create\"\n | \"spawn_agent\"\n | \"send\"\n | \"stop_agent\"\n | \"list_agents\"\n | \"cancel\"\n | \"history\"\n | \"control\"\n | \"share\"\n | \"provision_workspace\"\n | \"submit_workspace\"\n | \"manage_issues\"\n | \"archive\"\n | \"reopen\";\n\nconst SUPPORTED_OPS: readonly TaskOp[] = [\n \"create\",\n \"spawn_agent\",\n \"send\",\n \"stop_agent\",\n \"list_agents\",\n \"cancel\",\n \"history\",\n \"control\",\n \"share\",\n \"provision_workspace\",\n \"submit_workspace\",\n \"manage_issues\",\n \"archive\",\n \"reopen\",\n] as const;\n\ntype ControlAction =\n | \"pause\"\n | \"stop\"\n | \"resume\"\n | \"continue\"\n | \"archive\"\n | \"reopen\";\n\ntype HistoryMetric = \"list\" | \"count\" | \"detail\";\ntype HistoryWindow =\n | \"active\"\n | \"today\"\n | \"yesterday\"\n | \"last_7_days\"\n | \"last_30_days\";\n\nfunction readOp(\n params: Record<string, unknown>,\n content: Record<string, unknown>,\n): TaskOp | null {\n const raw =\n pickString(params, content, \"subaction\") ??\n pickString(params, content, \"op\") ??\n pickString(params, content, \"action\");\n if (!raw) return null;\n const normalized = raw.toLowerCase().replace(/-/g, \"_\");\n return (SUPPORTED_OPS as readonly string[]).includes(normalized)\n ? (normalized as TaskOp)\n : null;\n}\n\n// ── op: create (CREATE_AGENT_TASK) ──────────────────────────────────────\n\nfunction taskParts(\n params: Record<string, unknown>,\n content: Record<string, unknown>,\n fallbackText: string,\n): string[] {\n const agents = pickString(params, content, \"agents\");\n if (!agents) return [pickString(params, content, \"task\") ?? fallbackText];\n return agents\n .split(\"|\")\n .map((part) => part.trim())\n .filter(Boolean);\n}\n\nfunction parseAgentPrefix(\n part: string,\n fallbackAgentType: string,\n): { task: string; agentType: string } {\n const match = part.match(/^([a-z][a-z0-9_-]{1,32})\\s*:\\s*(.+)$/i);\n if (!match) return { task: part, agentType: fallbackAgentType };\n return { agentType: match[1] ?? fallbackAgentType, task: match[2] ?? part };\n}\n\nfunction labelFrom(task: string, index: number): string {\n const cleaned = task.replace(/\\s+/g, \" \").trim();\n return cleaned ? cleaned.slice(0, 80) : `task-${index + 1}`;\n}\n\nfunction looksLikePersonalLifeOpsTask(text: string): boolean {\n return /\\b(?:add|create|make|open|save|set)\\s+(?:an?\\s+)?(?:to-?do|task|reminder|note)\\b/i.test(\n text,\n );\n}\n\nasync function runPromptAndClose(\n service: ReturnType<typeof getAcpService> & {},\n session: SpawnResult,\n task: string,\n timeoutMs: number | undefined,\n model: string | undefined,\n): Promise<void> {\n const startedAt = Date.now();\n try {\n const result = service.sendPrompt\n ? await service.sendPrompt(session.sessionId, task, { timeoutMs, model })\n : await service.sendToSession(session.sessionId, task);\n if (result.error || result.stopReason === \"error\") {\n emitSessionEvent(service, session.sessionId, \"error\", {\n message: result.error ?? \"acpx prompt ended with stopReason error\",\n stopReason: result.stopReason,\n });\n throw new Error(result.error ?? \"acpx prompt failed\");\n }\n emitSessionEvent(service, session.sessionId, \"task_complete\", {\n response: result.finalText || result.response,\n durationMs: result.durationMs || Date.now() - startedAt,\n stopReason: result.stopReason,\n });\n } catch (error) {\n emitSessionEvent(service, session.sessionId, \"error\", {\n message: failureMessage(error),\n });\n throw error;\n } finally {\n try {\n await service.stopSession(session.sessionId);\n } finally {\n emitSessionEvent(service, session.sessionId, \"stopped\", {\n sessionId: session.sessionId,\n });\n }\n }\n}\n\nasync function runCreate(\n runtime: IAgentRuntime,\n message: Memory,\n state: State | undefined,\n params: Record<string, unknown>,\n content: Record<string, unknown>,\n callback: HandlerCallback | undefined,\n): Promise<ActionResult> {\n const service = getAcpService(runtime);\n if (!service) {\n const text =\n \"ACP subprocess service is not available. Install acpx and ensure @elizaos/plugin-agent-orchestrator is loaded.\";\n await callbackText(callback, text);\n return errorResult(\"SERVICE_UNAVAILABLE\");\n }\n\n const text = messageText(message);\n const tasks = taskParts(params, content, text);\n if (tasks.length > MAX_CONCURRENT_AGENTS) {\n const msg = `Too many task agents requested (${tasks.length}); maximum is ${MAX_CONCURRENT_AGENTS}.`;\n await callbackText(callback, msg);\n return errorResult(\"TOO_MANY_AGENTS\", msg);\n }\n\n const baseAgentType =\n pickString(params, content, \"agentType\") ??\n String(\n (await service.resolveAgentType?.({\n task: tasks[0],\n subtaskCount: tasks.length,\n })) ?? \"codex\",\n );\n const workdir = pickString(params, content, \"workdir\") ?? process.cwd();\n const model = pickString(params, content, \"model\");\n const memoryContent = pickString(params, content, \"memoryContent\");\n const approvalPreset = parseApproval(\n pickString(params, content, \"approvalPreset\"),\n );\n const timeoutMs = getTimeoutMs(params, content);\n const baseLabel = pickString(params, content, \"label\");\n const settled = await Promise.allSettled(\n tasks.map(async (part, index) => {\n const parsed = parseAgentPrefix(part, baseAgentType);\n const task = parsed.task;\n const agentType = parsed.agentType as AgentType;\n const label = baseLabel ?? labelFrom(task, index);\n const session = await service.spawnSession({\n agentType,\n workdir,\n memoryContent,\n approvalPreset,\n model,\n timeoutMs,\n metadata: {\n requestedType: baseAgentType,\n messageId: message.id,\n roomId: message.roomId,\n worldId: message.worldId,\n userId: message.entityId,\n label,\n source: content.source,\n },\n });\n await runPromptAndClose(service, session, task, timeoutMs, model);\n return { session, label, agentType };\n }),\n );\n\n const results: Array<Record<string, unknown>> = [];\n const sessions: SpawnResult[] = [];\n for (const [index, outcome] of settled.entries()) {\n if (outcome.status === \"fulfilled\") {\n const { session, label } = outcome.value;\n sessions.push(session);\n results.push({\n id: session.sessionId,\n sessionId: session.sessionId,\n agentType: session.agentType,\n name: session.name,\n workdir: session.workdir,\n label,\n status: \"completed\",\n });\n continue;\n }\n const part = tasks[index];\n const parsed = parseAgentPrefix(part, baseAgentType);\n const agentType = parsed.agentType as AgentType;\n const label = baseLabel ?? labelFrom(parsed.task, index);\n const msg = failureMessage(outcome.reason);\n logger(runtime).error?.(\n `TASKS:create launch failed: ${JSON.stringify({\n error: msg,\n agentType,\n workdir,\n })}`,\n );\n results.push({\n sessionId: \"\",\n id: \"\",\n agentType,\n workdir,\n label,\n status: \"failed\",\n error: msg,\n });\n }\n\n setCurrentSessions(state, sessions);\n const failed = results.filter((result) => result.status === \"failed\");\n if (failed.length > 0) {\n const textOut = `I started some task agents, but ${failed.length} failed to launch: ${failed.map((item) => String(item.error)).join(\"; \")}.`;\n await callbackText(callback, textOut);\n return {\n success: false,\n text: textOut,\n data: { agents: results, suppressActionResultClipboard: true },\n };\n }\n\n return {\n success: true,\n text: \"\",\n data: { agents: results, suppressActionResultClipboard: true },\n };\n}\n\n// ── op: spawn_agent (SPAWN_AGENT) ───────────────────────────────────────\n\nasync function runSpawnAgent(\n runtime: IAgentRuntime,\n message: Memory,\n state: State | undefined,\n params: Record<string, unknown>,\n content: Record<string, unknown>,\n callback: HandlerCallback | undefined,\n): Promise<ActionResult> {\n const service = getAcpService(runtime);\n if (!service) {\n const text = \"PTY Service is not available. Cannot spawn a task agent.\";\n await callbackText(callback, text);\n return errorResult(\"SERVICE_UNAVAILABLE\");\n }\n\n try {\n const text = messageText(message);\n const task = pickString(params, content, \"task\") ?? text;\n const explicitAgentType = pickString(params, content, \"agentType\");\n const agentType = (explicitAgentType ??\n (await service.resolveAgentType?.({\n task,\n workdir: pickString(params, content, \"workdir\"),\n })) ??\n \"codex\") as AgentType;\n const workdir = pickString(params, content, \"workdir\") ?? process.cwd();\n const memoryContent = pickString(params, content, \"memoryContent\");\n const approvalPreset = parseApproval(\n pickString(params, content, \"approvalPreset\"),\n );\n const keepAliveAfterComplete = pickBoolean(\n params,\n content,\n \"keepAliveAfterComplete\",\n );\n const label = pickString(params, content, \"label\") ?? task.slice(0, 80);\n\n const session = await service.spawnSession({\n agentType,\n workdir,\n initialTask: task,\n memoryContent,\n approvalPreset,\n metadata: {\n requestedType: explicitAgentType ?? agentType,\n messageId: message.id,\n roomId: message.roomId,\n worldId: message.worldId,\n userId: message.entityId,\n label,\n source: content.source,\n keepAliveAfterComplete,\n },\n });\n\n setCurrentSession(state, session);\n logger(runtime).info?.(\n `Spawned acpx task agent: ${JSON.stringify({\n sessionId: session.sessionId,\n agentType: session.agentType,\n workdir: session.workdir,\n })}`,\n );\n\n return {\n success: true,\n text: \"\",\n data: {\n sessionId: session.sessionId,\n agentType: session.agentType,\n workdir: session.workdir,\n status: session.status,\n label,\n suppressActionResultClipboard: true,\n },\n };\n } catch (error) {\n const messageTextValue = failureMessage(error);\n const code = isAuthError(error) ? \"INVALID_CREDENTIALS\" : messageTextValue;\n await callbackText(\n callback,\n isAuthError(error)\n ? \"Invalid credentials for task agent.\"\n : `Failed to spawn agent: ${messageTextValue}`,\n );\n return { success: false, error: code };\n }\n}\n\n// ── op: send (SEND_TO_AGENT) ────────────────────────────────────────────\n\nasync function runSend(\n runtime: IAgentRuntime,\n _message: Memory,\n state: State | undefined,\n params: Record<string, unknown>,\n content: Record<string, unknown>,\n callback: HandlerCallback | undefined,\n): Promise<ActionResult> {\n const service = getAcpService(runtime);\n if (!service) {\n await callbackText(callback, \"PTY Service is not available.\");\n return errorResult(\"SERVICE_UNAVAILABLE\");\n }\n\n try {\n const sessionId = pickString(params, content, \"sessionId\");\n const input = pickString(params, content, \"input\");\n const task = pickString(params, content, \"task\");\n const keys = pickString(params, content, \"keys\");\n const target = await resolveSession(service, sessionId, state);\n\n if (!target.session) {\n if (target.missingId) {\n const text = `Session ${target.missingId} not found.`;\n await callbackText(callback, text);\n return errorResult(\"SESSION_NOT_FOUND\");\n }\n await callbackText(\n callback,\n \"No active task-agent sessions. Spawn an agent first.\",\n );\n return errorResult(\"NO_SESSION\");\n }\n\n if (keys) {\n await service.sendKeysToSession(target.session.id, keys);\n await callbackText(callback, \"Sent key sequence\");\n return {\n success: true,\n text: \"Sent key sequence\",\n data: { sessionId: target.session.id, keys },\n };\n }\n\n const textInput = input ?? task;\n if (textInput) {\n await service.sendToSession(target.session.id, textInput);\n const text = task ? \"Assigned new task to agent\" : \"Sent input to agent\";\n await callbackText(callback, text);\n return {\n success: true,\n text,\n data: {\n sessionId: target.session.id,\n input: textInput,\n ...(task ? { task } : {}),\n },\n };\n }\n\n await callbackText(\n callback,\n \"No input provided. Specify 'input', 'task', or 'keys' parameter.\",\n );\n return errorResult(\"NO_INPUT\");\n } catch (error) {\n const msg = failureMessage(error);\n await callbackText(callback, `Failed to send to agent: ${msg}`);\n return { success: false, error: msg };\n }\n}\n\n// ── op: stop_agent (STOP_AGENT) ─────────────────────────────────────────\n\nasync function runStopAgent(\n runtime: IAgentRuntime,\n _message: Memory,\n state: State | undefined,\n params: Record<string, unknown>,\n content: Record<string, unknown>,\n callback: HandlerCallback | undefined,\n): Promise<ActionResult> {\n const service = getAcpService(runtime);\n if (!service) {\n await callbackText(callback, \"PTY Service is not available.\");\n return errorResult(\"SERVICE_UNAVAILABLE\");\n }\n\n try {\n const all = pickBoolean(params, content, \"all\") ?? false;\n const sessions = await Promise.resolve(service.listSessions());\n\n if (all) {\n await Promise.all(\n sessions.map((session) => service.stopSession(session.id)),\n );\n if (state)\n (\n state as {\n codingSession?: unknown;\n codingSessions?: unknown;\n }\n ).codingSession = undefined;\n if (state) (state as { codingSessions?: unknown }).codingSessions = [];\n const text = `Stopped ${sessions.length} sessions`;\n await callbackText(callback, text);\n return { success: true, text, data: { stoppedCount: sessions.length } };\n }\n\n const requestedId =\n pickString(params, content, \"sessionId\") ??\n (state as { codingSession?: { id?: string } } | undefined)?.codingSession\n ?.id;\n const target = requestedId\n ? await Promise.resolve(service.getSession(requestedId))\n : newestSession(sessions);\n\n if (!target) {\n if (requestedId) {\n const text = `Session ${requestedId} not found.`;\n await callbackText(callback, text);\n return errorResult(\"SESSION_NOT_FOUND\");\n }\n await callbackText(callback, \"No sessions to stop\");\n return { success: true, text: \"No sessions to stop\" };\n }\n\n await service.stopSession(target.id);\n if (\n (state as { codingSession?: { id?: string } } | undefined)?.codingSession\n ?.id === target.id\n ) {\n (state as { codingSession?: unknown }).codingSession = undefined;\n }\n await callbackText(callback, `Stopped task-agent session ${target.id}.`);\n return {\n success: true,\n text: `Stopped session ${target.id}`,\n data: { sessionId: target.id, agentType: String(target.agentType) },\n };\n } catch (error) {\n const msg = failureMessage(error);\n await callbackText(callback, `Failed to stop agent: ${msg}`);\n return { success: false, error: msg };\n }\n}\n\n// ── op: list_agents (LIST_AGENTS) ───────────────────────────────────────\n\nfunction dateString(value: Date | string | number): string {\n return new Date(value).toISOString();\n}\n\nasync function runListAgents(\n runtime: IAgentRuntime,\n _message: Memory,\n _state: State | undefined,\n _params: Record<string, unknown>,\n _content: Record<string, unknown>,\n callback: HandlerCallback | undefined,\n): Promise<ActionResult> {\n const service = getAcpService(runtime);\n if (!service) {\n await callbackText(callback, \"PTY Service is not available.\");\n return errorResult(\"SERVICE_UNAVAILABLE\");\n }\n\n const sessions = await listSessionsWithin(service, 2000);\n const preferredTaskAgent = {\n id: String((await service.resolveAgentType?.({})) ?? \"codex\"),\n reason: \"acpx default agent\",\n };\n const tasks: Array<Record<string, unknown>> = [];\n const pendingConfirmations = 0;\n\n if (sessions.length === 0) {\n const text =\n 'No active task agents. Use TASKS { op: \"create\" } when the user needs anything more involved than a simple direct reply.';\n await callbackText(callback, text);\n return {\n success: true,\n text,\n data: { sessions: [], tasks, pendingConfirmations, preferredTaskAgent },\n };\n }\n\n const lines = [`Active task agents (${sessions.length}):`];\n for (const session of sessions) {\n lines.push(\n `- ${labelFor(session)} [${shortId(session.id)}] ${session.agentType} ${session.status} in ${session.workdir}`,\n );\n }\n const text = lines.join(\"\\n\");\n await callbackText(callback, text);\n\n return {\n success: true,\n text,\n data: {\n sessions: sessions.map((session) => ({\n id: session.id,\n agentType: String(session.agentType),\n status: String(session.status),\n workdir: session.workdir,\n createdAt: dateString(session.createdAt),\n lastActivity: dateString(session.lastActivityAt),\n label: labelFor(session),\n })),\n tasks,\n pendingConfirmations,\n preferredTaskAgent,\n },\n };\n}\n\n// ── op: cancel (CANCEL_TASK) ────────────────────────────────────────────\n\nasync function runCancel(\n runtime: IAgentRuntime,\n _message: Memory,\n state: State | undefined,\n params: Record<string, unknown>,\n content: Record<string, unknown>,\n callback: HandlerCallback | undefined,\n): Promise<ActionResult> {\n const service = getAcpService(runtime);\n if (!service) {\n await callbackText(callback, \"PTY Service is not available.\");\n return errorResult(\"SERVICE_UNAVAILABLE\");\n }\n\n try {\n const all = pickBoolean(params, content, \"all\") ?? false;\n const threadId = pickString(params, content, \"threadId\");\n const sessionId =\n pickString(params, content, \"sessionId\") ??\n (state as { codingSession?: { id?: string } } | undefined)?.codingSession\n ?.id;\n const search = pickString(params, content, \"search\")?.toLowerCase();\n const sessions = await Promise.resolve(service.listSessions());\n\n if (all) {\n const stoppedSessions: string[] = [];\n for (const session of sessions) {\n await (service.cancelSession?.(session.id) ??\n service.stopSession(session.id));\n stoppedSessions.push(session.id);\n }\n const text = `Canceled ${stoppedSessions.length} task(s).`;\n await callbackText(callback, text);\n return {\n success: true,\n text,\n data: { canceledCount: stoppedSessions.length, stoppedSessions },\n };\n }\n\n const target = sessionId\n ? await Promise.resolve(service.getSession(sessionId))\n : search\n ? sessions.find((session) =>\n `${session.id} ${session.name ?? \"\"} ${session.metadata?.label ?? \"\"}`\n .toLowerCase()\n .includes(search),\n )\n : newestSession(sessions);\n\n if (!target) {\n const code = sessionId ? \"SESSION_NOT_FOUND\" : \"TASK_NOT_FOUND\";\n const text = sessionId\n ? `Session ${sessionId} not found.`\n : \"No matching task found.\";\n await callbackText(callback, text);\n return errorResult(code);\n }\n\n await (service.cancelSession?.(target.id) ??\n service.stopSession(target.id));\n const id = threadId ?? target.id;\n const text = `Canceled task ${id}`;\n await callbackText(callback, text);\n return {\n success: true,\n text,\n data: {\n ...(threadId ? { threadId } : {}),\n sessionId: target.id,\n stoppedSessions: [target.id],\n status: \"canceled\",\n },\n };\n } catch (error) {\n const msg = failureMessage(error);\n await callbackText(callback, `Failed to cancel task: ${msg}`);\n return { success: false, error: msg };\n }\n}\n\n// ── op: history (TASK_HISTORY) ──────────────────────────────────────────\n\nfunction textValue(value: unknown): string | undefined {\n return typeof value === \"string\" && value.trim().length > 0\n ? value.trim()\n : undefined;\n}\n\nfunction startOfDay(date: Date): Date {\n const copy = new Date(date);\n copy.setHours(0, 0, 0, 0);\n return copy;\n}\n\nfunction endOfDay(date: Date): Date {\n const copy = new Date(date);\n copy.setHours(23, 59, 59, 999);\n return copy;\n}\n\nfunction formatDate(date: Date): string {\n return new Intl.DateTimeFormat(\"en-US\", {\n month: \"long\",\n day: \"numeric\",\n year: \"numeric\",\n }).format(date);\n}\n\nfunction inferMetric(text: string, value?: string): HistoryMetric {\n const normalized = value?.trim().toLowerCase();\n if (\n normalized === \"count\" ||\n normalized === \"detail\" ||\n normalized === \"list\"\n ) {\n return normalized;\n }\n if (/\\bhow many\\b|\\bcount\\b/i.test(text)) return \"count\";\n if (/\\bshow me\\b|\\bgive me\\b|\\blist\\b|\\bwhat are\\b/i.test(text))\n return \"list\";\n return \"detail\";\n}\n\nfunction inferStatuses(\n text: string,\n rawStatuses?: string[],\n): string[] | undefined {\n if (rawStatuses && rawStatuses.length > 0) {\n return rawStatuses;\n }\n const statuses = new Set<string>();\n if (/\\bactive\\b|\\bright now\\b|\\bworking on right now\\b/i.test(text)) {\n statuses.add(\"active\");\n }\n if (/\\bblocked\\b/i.test(text)) {\n statuses.add(\"blocked\");\n }\n if (/\\binterrupted\\b|\\bpaused\\b/i.test(text)) {\n statuses.add(\"interrupted\");\n }\n if (/\\bdone\\b|\\bcompleted\\b|\\bfinished\\b/i.test(text)) {\n statuses.add(\"done\");\n }\n if (/\\bfailed\\b|\\berror\\b/i.test(text)) {\n statuses.add(\"failed\");\n }\n return statuses.size > 0 ? Array.from(statuses) : undefined;\n}\n\nfunction inferWindow(text: string, raw?: string): HistoryWindow | undefined {\n const normalized = raw?.trim().toLowerCase();\n if (\n normalized === \"active\" ||\n normalized === \"today\" ||\n normalized === \"yesterday\" ||\n normalized === \"last_7_days\" ||\n normalized === \"last_30_days\"\n ) {\n return normalized;\n }\n if (/\\bright now\\b|\\bcurrently\\b|\\bactive\\b/i.test(text)) return \"active\";\n if (/\\byesterday\\b/i.test(text)) return \"yesterday\";\n if (/\\blast week\\b|\\blast 7 days\\b|\\bin the last week\\b/i.test(text)) {\n return \"last_7_days\";\n }\n if (/\\blast month\\b|\\blast 30 days\\b/i.test(text)) return \"last_30_days\";\n if (/\\btoday\\b/i.test(text)) return \"today\";\n return undefined;\n}\n\nfunction inferSearch(text: string, raw?: string): string | undefined {\n if (raw?.trim()) return raw.trim();\n const quoted =\n text.match(/\"([^\"]{3,120})\"/)?.[1] ?? text.match(/'([^']{3,120})'/)?.[1];\n if (quoted) return quoted.trim();\n const topical =\n text.match(/\\bworking on\\s+(.+?)(?:[?.!,]|$)/i)?.[1] ??\n text.match(\n /\\ball tasks where we were working on\\s+(.+?)(?:[?.!,]|$)/i,\n )?.[1];\n return topical?.trim();\n}\n\nfunction buildWindowFilters(window: HistoryWindow | undefined): {\n latestActivityAfter?: number;\n latestActivityBefore?: number;\n label?: string;\n} {\n const now = new Date();\n if (window === \"active\") {\n return { label: \"active tasks right now\" };\n }\n if (window === \"today\") {\n const start = startOfDay(now);\n const end = endOfDay(now);\n return {\n latestActivityAfter: start.getTime(),\n latestActivityBefore: end.getTime(),\n label: `${formatDate(start)} through ${formatDate(end)}`,\n };\n }\n if (window === \"yesterday\") {\n const start = startOfDay(new Date(now.getTime() - 24 * 60 * 60 * 1000));\n const end = endOfDay(start);\n return {\n latestActivityAfter: start.getTime(),\n latestActivityBefore: end.getTime(),\n label: `${formatDate(start)} through ${formatDate(end)}`,\n };\n }\n if (window === \"last_7_days\") {\n const start = startOfDay(new Date(now.getTime() - 6 * 24 * 60 * 60 * 1000));\n return {\n latestActivityAfter: start.getTime(),\n latestActivityBefore: now.getTime(),\n label: `${formatDate(start)} through ${formatDate(now)}`,\n };\n }\n if (window === \"last_30_days\") {\n const start = startOfDay(\n new Date(now.getTime() - 29 * 24 * 60 * 60 * 1000),\n );\n return {\n latestActivityAfter: start.getTime(),\n latestActivityBefore: now.getTime(),\n label: `${formatDate(start)} through ${formatDate(now)}`,\n };\n }\n return {};\n}\n\nfunction renderThreadLine(entry: {\n title: string;\n status: string;\n latestActivityAt?: number | null;\n summary?: string;\n}): string {\n const activity =\n typeof entry.latestActivityAt === \"number\"\n ? new Date(entry.latestActivityAt).toLocaleString(\"en-US\")\n : \"unknown time\";\n return `- ${entry.title} [${entry.status}] (${activity})${entry.summary ? `: ${entry.summary}` : \"\"}`;\n}\n\nfunction failureResult(\n actionName: string,\n error: string,\n text: string,\n data: Record<string, unknown> = {},\n): ActionResult {\n return {\n success: false,\n error,\n text,\n data: {\n actionName,\n ...data,\n },\n };\n}\n\nasync function runHistory(\n runtime: IAgentRuntime,\n message: Memory,\n _state: State | undefined,\n params: Record<string, unknown>,\n content: Record<string, unknown>,\n callback: HandlerCallback | undefined,\n): Promise<ActionResult> {\n const access = await requireTaskAgentAccess(runtime, message, \"interact\");\n if (!access.allowed) {\n if (callback) await callback({ text: access.reason });\n return failureResult(\"TASKS:history\", \"FORBIDDEN\", access.reason, {\n reason: \"access_denied\",\n });\n }\n\n const coordinator = getCoordinator(runtime);\n if (!coordinator) {\n if (callback) await callback({ text: \"Coordinator is not available.\" });\n return failureResult(\n \"TASKS:history\",\n \"SERVICE_UNAVAILABLE\",\n \"Coordinator is not available.\",\n { reason: \"coordinator_unavailable\" },\n );\n }\n\n const text = typeof content.text === \"string\" ? content.text : \"\";\n\n const metric = inferMetric(\n text,\n textValue(params.metric) ?? textValue(content.metric),\n );\n const statuses = inferStatuses(\n text,\n Array.isArray(params.statuses)\n ? params.statuses.filter(\n (value): value is string => typeof value === \"string\",\n )\n : Array.isArray(content.statuses)\n ? content.statuses.filter(\n (value): value is string => typeof value === \"string\",\n )\n : undefined,\n );\n const window = inferWindow(\n text,\n textValue(params.window) ?? textValue(content.window),\n );\n const search = inferSearch(\n text,\n textValue(params.search) ?? textValue(content.search),\n );\n const limitRaw = Number(\n params.limit ?? content.limit ?? (metric === \"detail\" ? 1 : 10),\n );\n const limit =\n Number.isFinite(limitRaw) && limitRaw > 0 ? Math.trunc(limitRaw) : 10;\n const includeArchived =\n (params.includeArchived as boolean | undefined) ??\n (content.includeArchived as boolean | undefined) ??\n false;\n const windowFilters = buildWindowFilters(window);\n\n const threadFilters: ListTaskThreadsOptions = {\n includeArchived,\n ...(statuses && statuses.length > 0\n ? { statuses: statuses as ListTaskThreadsOptions[\"statuses\"] }\n : {}),\n ...(windowFilters.latestActivityAfter\n ? { latestActivityAfter: windowFilters.latestActivityAfter }\n : {}),\n ...(windowFilters.latestActivityBefore\n ? { latestActivityBefore: windowFilters.latestActivityBefore }\n : {}),\n ...(search ? { search } : {}),\n ...(window === \"active\" ? { hasActiveSession: true } : {}),\n limit,\n };\n\n const [count, threads] = await Promise.all([\n coordinator.countTaskThreads(threadFilters),\n coordinator.listTaskThreads(threadFilters),\n ]);\n\n const summaryWindow =\n windowFilters.label ??\n (window === \"active\"\n ? \"right now\"\n : includeArchived\n ? \"all recorded time\"\n : \"recent task history\");\n const summaryTopic = search ? ` for \"${search}\"` : \"\";\n const summaryStatus =\n statuses && statuses.length > 0\n ? ` with status ${statuses.join(\", \")}`\n : \"\";\n\n let responseText = \"\";\n if (metric === \"count\") {\n responseText = `I found ${count} task${count === 1 ? \"\" : \"s\"} ${summaryWindow}${summaryTopic}${summaryStatus}.`;\n } else if (threads.length === 0) {\n responseText = `I did not find any tasks ${summaryWindow}${summaryTopic}${summaryStatus}.`;\n } else if (metric === \"detail\" && threads[0]) {\n const thread = await coordinator.getTaskThread(threads[0].id);\n responseText = [\n `The most relevant task is \"${threads[0].title}\" [${threads[0].status}].`,\n thread?.summary ? `Summary: ${thread.summary}` : \"\",\n thread?.latestWorkdir ? `Workspace: ${thread.latestWorkdir}` : \"\",\n thread?.latestRepo ? `Repository: ${thread.latestRepo}` : \"\",\n typeof thread?.latestActivityAt === \"number\"\n ? `Latest activity: ${new Date(thread.latestActivityAt).toLocaleString(\"en-US\")}`\n : \"\",\n ]\n .filter(Boolean)\n .join(\"\\n\");\n } else {\n responseText = [\n `I found ${count} task${count === 1 ? \"\" : \"s\"} ${summaryWindow}${summaryTopic}${summaryStatus}.`,\n ...threads.slice(0, limit).map(renderThreadLine),\n ].join(\"\\n\");\n }\n\n if (callback) await callback({ text: responseText });\n return {\n success: true,\n text: responseText,\n data: {\n actionName: \"TASKS:history\",\n filters: threadFilters,\n window,\n count,\n threadIds: threads.map((thread) => thread.id),\n },\n };\n}\n\n// ── op: control (TASK_CONTROL) ──────────────────────────────────────────\n\nfunction inferControlAction(\n text: string,\n value?: string,\n): ControlAction | null {\n const normalized = value?.trim().toLowerCase();\n if (\n normalized === \"pause\" ||\n normalized === \"stop\" ||\n normalized === \"resume\" ||\n normalized === \"continue\" ||\n normalized === \"archive\" ||\n normalized === \"reopen\"\n ) {\n return normalized;\n }\n if (/\\barchive\\b/i.test(text)) return \"archive\";\n if (/\\breopen\\b/i.test(text)) return \"reopen\";\n if (/\\bpause\\b|\\bhold on\\b|\\bthat's not right\\b/i.test(text)) return \"pause\";\n if (/\\bstop\\b|\\bcancel\\b|\\bkill\\b/i.test(text)) return \"stop\";\n if (/\\bresume\\b|\\bmake it so\\b|\\bdo it\\b|\\byea(h)? i'm down\\b/i.test(text)) {\n return \"resume\";\n }\n if (/\\bcontinue\\b|\\bgo ahead\\b/i.test(text)) return \"continue\";\n return null;\n}\n\nasync function runControl(\n runtime: IAgentRuntime,\n message: Memory,\n state: State | undefined,\n params: Record<string, unknown>,\n content: Record<string, unknown>,\n callback: HandlerCallback | undefined,\n): Promise<ActionResult> {\n const access = await requireTaskAgentAccess(runtime, message, \"interact\");\n if (!access.allowed) {\n if (callback) await callback({ text: access.reason });\n return failureResult(\"TASKS:control\", \"FORBIDDEN\", access.reason, {\n reason: \"access_denied\",\n });\n }\n\n const coordinator = getCoordinator(runtime);\n if (!coordinator) {\n if (callback) await callback({ text: \"Coordinator is not available.\" });\n return failureResult(\n \"TASKS:control\",\n \"SERVICE_UNAVAILABLE\",\n \"Coordinator is not available.\",\n { reason: \"coordinator_unavailable\" },\n );\n }\n\n const text = typeof content.text === \"string\" ? content.text : \"\";\n const topLevelAction = textValue(params.action) ?? textValue(content.action);\n const normalizedTopLevelAction = topLevelAction?.toLowerCase().replace(/-/g, \"_\");\n const legacyControlAction =\n topLevelAction && normalizedTopLevelAction !== \"control\"\n ? topLevelAction\n : undefined;\n const action = inferControlAction(\n text,\n textValue(params.controlAction) ??\n textValue(content.controlAction) ??\n legacyControlAction,\n );\n\n if (!action) {\n const msg =\n \"No task-control action was specified. Use pause, stop, resume, continue, archive, or reopen.\";\n if (callback) await callback({ text: msg });\n return failureResult(\"TASKS:control\", \"INVALID_OPERATION\", msg, {\n reason: \"invalid_operation\",\n });\n }\n\n const thread = await resolveTaskThreadTarget({\n coordinator,\n message,\n state,\n options: params,\n includeArchived: action === \"reopen\" || action === \"archive\",\n });\n if (!thread) {\n const msg = \"I could not find a matching task thread.\";\n if (callback) await callback({ text: msg });\n return failureResult(\"TASKS:control\", \"THREAD_NOT_FOUND\", msg, {\n reason: \"thread_not_found\",\n action,\n });\n }\n\n const note =\n textValue(params.note) ??\n textValue(content.note) ??\n (text.length > 0 ? text : undefined);\n const instruction =\n textValue(params.instruction) ??\n textValue(content.instruction) ??\n (action === \"continue\" || action === \"resume\" ? text : undefined);\n const requestedAgentType =\n textValue(params.agentType) ?? textValue(content.agentType);\n\n let responseText = \"\";\n let data: Record<string, unknown> = {\n actionName: \"TASKS:control\",\n threadId: thread.id,\n action,\n };\n\n if (action === \"pause\") {\n const result = await coordinator.pauseTaskThread(thread.id, note);\n responseText = `Paused \"${thread.title}\" and preserved the thread for follow-up discussion.`;\n data = { ...data, ...result };\n } else if (action === \"stop\") {\n const result = await coordinator.stopTaskThread(thread.id, note);\n responseText = `Stopped \"${thread.title}\" and kept the thread history intact.`;\n data = { ...data, ...result };\n } else if (action === \"archive\") {\n await coordinator.archiveTaskThread(thread.id);\n responseText = `Archived \"${thread.title}\".`;\n } else if (action === \"reopen\") {\n await coordinator.reopenTaskThread(thread.id);\n responseText = `Reopened \"${thread.title}\".`;\n } else if (action === \"continue\") {\n const nextInstruction =\n instruction?.trim() || `Continue the task \"${thread.title}\".`;\n const result = await coordinator.continueTaskThread(\n thread.id,\n nextInstruction,\n requestedAgentType,\n );\n responseText = result.reusedSession\n ? `Sent follow-up instructions to \"${thread.title}\" on the existing task session.`\n : `Resumed \"${thread.title}\" on a new task session.`;\n data = { ...data, ...result };\n } else {\n const result = await coordinator.resumeTaskThread(\n thread.id,\n instruction?.trim() || undefined,\n requestedAgentType,\n );\n responseText = result.reusedSession\n ? `Resumed \"${thread.title}\" on the current task session.`\n : `Resumed \"${thread.title}\" on a new task session.`;\n data = { ...data, ...result };\n }\n\n if (callback) await callback({ text: responseText });\n return {\n success: true,\n text: responseText,\n data: data as ActionResult[\"data\"],\n };\n}\n\n// ── op: share (TASK_SHARE) ──────────────────────────────────────────────\n\nfunction artifactTypeForTarget(type: string): string {\n if (type === \"preview_url\" || type === \"artifact_uri\") return \"share_link\";\n if (type === \"artifact_path\") return \"share_path\";\n return \"workspace\";\n}\n\nasync function runShare(\n runtime: IAgentRuntime,\n message: Memory,\n state: State | undefined,\n params: Record<string, unknown>,\n _content: Record<string, unknown>,\n callback: HandlerCallback | undefined,\n): Promise<ActionResult> {\n const access = await requireTaskAgentAccess(runtime, message, \"interact\");\n if (!access.allowed) {\n if (callback) await callback({ text: access.reason });\n return { success: false, error: \"FORBIDDEN\", text: access.reason };\n }\n\n const coordinator = getCoordinator(runtime);\n if (!coordinator) {\n if (callback) await callback({ text: \"Coordinator is not available.\" });\n return { success: false, error: \"SERVICE_UNAVAILABLE\" };\n }\n\n const thread = await resolveTaskThreadTarget({\n coordinator,\n message,\n state,\n options: params,\n includeArchived: true,\n });\n if (!thread) {\n if (callback)\n await callback({ text: \"I could not find a task thread to share.\" });\n return { success: false, error: \"THREAD_NOT_FOUND\" };\n }\n\n const discovery = await discoverTaskShareOptions(coordinator, thread.id);\n if (!discovery || discovery.targets.length === 0) {\n const fallback = `I found the task thread \"${thread.title}\", but I did not find a preview URL or shareable artifact yet.`;\n if (callback) await callback({ text: fallback });\n return {\n success: false,\n error: \"NO_SHARE_TARGET\",\n text: fallback,\n data: {\n threadId: thread.id,\n shareCapabilities: discovery?.shareCapabilities ?? [],\n },\n };\n }\n\n const detail = await coordinator.getTaskThread(thread.id);\n const existingKeys = new Set(\n (detail?.artifacts ?? []).map(\n (artifact) =>\n artifact.uri?.trim() ||\n artifact.path?.trim() ||\n `${artifact.artifactType}:${artifact.title}`,\n ),\n );\n for (const target of discovery.targets) {\n const key = target.value.trim();\n if (!key || existingKeys.has(key)) continue;\n await coordinator.taskRegistry.recordArtifact({\n threadId: thread.id,\n artifactType: artifactTypeForTarget(target.type),\n title: target.label,\n ...(target.type === \"artifact_path\" || target.type === \"workspace\"\n ? { path: target.value }\n : { uri: target.value }),\n metadata: {\n source: target.source,\n remoteAccessible: target.remoteAccessible,\n discoveredVia: \"tasks-share-action\",\n },\n });\n existingKeys.add(key);\n }\n\n const preferred = discovery.preferredTarget;\n const lines = [\n preferred\n ? `Best available view for \"${thread.title}\": ${preferred.value}`\n : `I found share options for \"${thread.title}\".`,\n ...discovery.targets\n .slice(0, 5)\n .map(\n (target) =>\n `- ${target.label}: ${target.value}${target.remoteAccessible ? \" (remote-ready)\" : \"\"}`,\n ),\n discovery.shareCapabilities.length > 0\n ? `Environment share capabilities: ${discovery.shareCapabilities.join(\", \")}`\n : \"No explicit remote-share capability is configured, so local artifact paths and preview URLs are the only confirmed options right now.\",\n ].filter(Boolean);\n const responseText = lines.join(\"\\n\");\n\n if (callback) await callback({ text: responseText });\n return {\n success: true,\n text: responseText,\n data: {\n threadId: thread.id,\n preferredTarget: preferred,\n shareCapabilities: discovery.shareCapabilities,\n targetCount: discovery.targets.length,\n },\n };\n}\n\n// ── op: provision_workspace (CREATE_WORKSPACE) ─────────────────────────\n\nasync function runProvisionWorkspace(\n runtime: IAgentRuntime,\n message: Memory,\n state: State | undefined,\n _params: Record<string, unknown>,\n _content: Record<string, unknown>,\n callback: HandlerCallback | undefined,\n): Promise<ActionResult> {\n const access = await requireTaskAgentAccess(runtime, message, \"create\");\n if (!access.allowed) {\n if (callback) await callback({ text: access.reason });\n return { success: false, error: \"FORBIDDEN\", text: access.reason };\n }\n\n const workspaceService = getCodingWorkspaceService(runtime);\n if (!workspaceService) {\n if (callback)\n await callback({ text: \"Workspace Service is not available.\" });\n return { success: false, error: \"SERVICE_UNAVAILABLE\" };\n }\n\n const content = message.content as {\n text?: string;\n repo?: string;\n baseBranch?: string;\n useWorktree?: boolean;\n parentWorkspaceId?: string;\n };\n\n let repo = content.repo;\n if (!repo && content.text) {\n const urlMatch = content.text.match(\n /https?:\\/\\/(?:github\\.com|gitlab\\.com|bitbucket\\.org)\\/[\\w.-]+\\/[\\w.-]+(?:\\.git)?/i,\n );\n if (urlMatch) {\n repo = urlMatch[0];\n }\n }\n\n if (!repo && !content.useWorktree) {\n if (callback)\n await callback({\n text: \"Please specify a repository URL or use worktree mode with a parent workspace.\",\n });\n return { success: false, error: \"MISSING_REPO\" };\n }\n\n if (repo) {\n const ALLOWED_DOMAINS =\n /^https?:\\/\\/(github\\.com|gitlab\\.com|bitbucket\\.org)\\//i;\n if (!ALLOWED_DOMAINS.test(repo)) {\n if (callback)\n await callback({\n text: \"Repository URL must be from github.com, gitlab.com, or bitbucket.org.\",\n });\n return { success: false, error: \"INVALID_REPO_DOMAIN\" };\n }\n }\n\n let parentWorkspaceId = content.parentWorkspaceId;\n if (content.useWorktree && !parentWorkspaceId) {\n if (state?.codingWorkspace) {\n parentWorkspaceId = (state.codingWorkspace as { id: string }).id;\n } else {\n if (callback)\n await callback({\n text: \"Worktree mode requires a parent workspace. Clone a repo first or specify parentWorkspaceId.\",\n });\n return { success: false, error: \"MISSING_PARENT\" };\n }\n }\n\n try {\n const workspace: WorkspaceResult = await Promise.race([\n workspaceService.provisionWorkspace({\n repo: repo ?? \"\",\n baseBranch: content.baseBranch,\n useWorktree: content.useWorktree,\n parentWorkspaceId,\n }),\n new Promise<never>((_, reject) =>\n setTimeout(\n () => reject(new Error(\"Workspace provisioning timeout\")),\n PROVISION_WORKSPACE_TIMEOUT_MS,\n ),\n ),\n ]);\n\n if (state) {\n state.codingWorkspace = {\n id: workspace.id,\n path: workspace.path.slice(0, WORKSPACE_PATH_MAX_CHARS),\n branch: workspace.branch,\n isWorktree: workspace.isWorktree,\n };\n }\n\n if (callback)\n await callback({\n text:\n `Created workspace at ${workspace.path.slice(0, WORKSPACE_PATH_MAX_CHARS)}\\n` +\n `Branch: ${workspace.branch}\\n` +\n `Type: ${workspace.isWorktree ? \"worktree\" : \"clone\"}`,\n });\n\n return {\n success: true,\n text: `Created workspace ${workspace.id}`,\n data: {\n workspaceId: workspace.id,\n path: workspace.path.slice(0, WORKSPACE_PATH_MAX_CHARS),\n branch: workspace.branch,\n isWorktree: workspace.isWorktree,\n },\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n if (callback)\n await callback({\n text: `Failed to provision workspace: ${errorMessage}`,\n });\n return { success: false, error: errorMessage };\n }\n}\n\n// ── op: submit_workspace (SUBMIT_WORKSPACE) ────────────────────────────\n\nasync function runSubmitWorkspace(\n runtime: IAgentRuntime,\n message: Memory,\n state: State | undefined,\n _params: Record<string, unknown>,\n _content: Record<string, unknown>,\n callback: HandlerCallback | undefined,\n): Promise<ActionResult> {\n const access = await requireTaskAgentAccess(runtime, message, \"interact\");\n if (!access.allowed) {\n if (callback) await callback({ text: access.reason });\n return { success: false, error: \"FORBIDDEN\", text: access.reason };\n }\n\n const workspaceService = getCodingWorkspaceService(runtime);\n if (!workspaceService) {\n if (callback)\n await callback({ text: \"Workspace Service is not available.\" });\n return { success: false, error: \"SERVICE_UNAVAILABLE\" };\n }\n\n const content = message.content as {\n workspaceId?: string;\n commitMessage?: string;\n prTitle?: string;\n prBody?: string;\n baseBranch?: string;\n draft?: boolean;\n skipPR?: boolean;\n };\n\n let workspaceId = content.workspaceId;\n if (!workspaceId && state?.codingWorkspace) {\n workspaceId = (state.codingWorkspace as { id: string }).id;\n }\n\n if (!workspaceId) {\n const workspaces = workspaceService.listWorkspaces();\n if (workspaces.length === 0) {\n if (callback)\n await callback({\n text: \"No workspaces available. Provision a workspace first.\",\n });\n return { success: false, error: \"NO_WORKSPACE\" };\n }\n workspaceId = workspaces[workspaces.length - 1].id;\n }\n\n const workspace = workspaceService.getWorkspace(workspaceId);\n if (!workspace) {\n if (callback)\n await callback({ text: `Workspace ${workspaceId} not found.` });\n return { success: false, error: \"WORKSPACE_NOT_FOUND\" };\n }\n\n try {\n const status = await workspaceService.getStatus(workspaceId);\n\n if (status.clean && status.staged.length === 0) {\n if (callback)\n await callback({ text: \"No changes to commit in this workspace.\" });\n return {\n success: true,\n text: \"No changes to commit\",\n data: { workspaceId, status },\n };\n }\n\n const commitMessage =\n content.commitMessage ??\n `feat: automated changes from task agent\\n\\nGenerated by Eliza task-agent plugin.`;\n\n const commitHash = await workspaceService.commit(workspaceId, {\n message: commitMessage,\n all: true,\n });\n\n await workspaceService.push(workspaceId, { setUpstream: true });\n\n let prInfo = null;\n if (!content.skipPR) {\n const prTitle = content.prTitle ?? `[Eliza] ${workspace.branch}`;\n const prBody =\n content.prBody ??\n `## Summary\\n\\nAutomated changes generated by Eliza task agent.\\n\\n` +\n `**Branch:** ${workspace.branch}\\n` +\n `**Commit:** ${commitHash}\\n\\n` +\n `---\\n*Generated by @elizaos/plugin-agent-orchestrator*`;\n\n prInfo = await workspaceService.createPR(workspaceId, {\n title: prTitle,\n body: prBody,\n base: content.baseBranch,\n draft: content.draft,\n });\n }\n\n if (callback) {\n if (prInfo) {\n await callback({\n text:\n `Workspace finalized!\\n` +\n `Commit: ${commitHash.slice(0, 8)}\\n` +\n `PR #${prInfo.number}: ${prInfo.url}`,\n });\n } else {\n await callback({\n text:\n `Workspace changes committed and pushed.\\n` +\n `Commit: ${commitHash.slice(0, 8)}`,\n });\n }\n }\n\n return {\n success: true,\n text: prInfo\n ? `Created PR #${prInfo.number}`\n : \"Changes committed and pushed\",\n data: {\n workspaceId,\n commitHash,\n pr: prInfo ? { number: prInfo.number, url: prInfo.url } : undefined,\n },\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n if (callback)\n await callback({ text: `Failed to finalize workspace: ${errorMessage}` });\n return { success: false, error: \"FINALIZE_FAILED\" };\n }\n}\n\n// ── op: manage_issues (MANAGE_ISSUES) ──────────────────────────────────\n\nfunction formatGitHubAuthPrompt(\n prompt: Parameters<AuthPromptCallback>[0],\n): string {\n return (\n `I need GitHub access to manage issues. Please authorize me:\\n\\n` +\n `Go to: ${prompt.verificationUri}\\n` +\n `Enter code: **${prompt.userCode}**\\n\\n` +\n `This code expires in ${Math.floor(prompt.expiresIn / 60)} minutes. ` +\n `I'll wait for you to complete authorization...`\n );\n}\n\nfunction extractBulkItems(\n text: string,\n): Array<{ title: string; body?: string }> {\n if (!text) return [];\n\n const numberedPattern =\n /(?:^|\\s)(\\d+)[).:-]\\s*(.+?)(?=(?:\\s+\\d+[).:-]\\s)|$)/gs;\n const items: Array<{ title: string; body?: string }> = [];\n\n for (const match of text.matchAll(numberedPattern)) {\n const raw = match[2].trim();\n if (raw.length > 0) {\n items.push({ title: raw });\n }\n }\n\n if (items.length >= 2) return items;\n\n const bulletPattern = /(?:^|\\n)\\s*[-*•]\\s+(.+)/g;\n const bulletItems: Array<{ title: string; body?: string }> = [];\n for (const match of text.matchAll(bulletPattern)) {\n const raw = match[1].trim();\n if (raw.length > 0) {\n bulletItems.push({ title: raw });\n }\n }\n\n if (bulletItems.length >= 2) return bulletItems;\n\n return [];\n}\n\nfunction inferIssueAction(text: string): string {\n const lower = text.toLowerCase();\n\n if (/\\b(create|open|file|submit|make|add)\\b.*\\bissue/.test(lower))\n return \"create\";\n if (/\\bissue.*\\b(create|open|file|submit|make)\\b/.test(lower))\n return \"create\";\n if (/\\b(close|resolve)\\b.*\\bissue/.test(lower)) return \"close\";\n if (/\\bissue.*\\b(close|resolve)\\b/.test(lower)) return \"close\";\n if (/\\b(reopen|re-open)\\b.*\\bissue/.test(lower)) return \"reopen\";\n if (/\\b(comment|reply)\\b.*\\bissue/.test(lower)) return \"comment\";\n if (/\\bissue.*\\b(comment|reply)\\b/.test(lower)) return \"comment\";\n if (/\\b(update|edit|modify)\\b.*\\bissue/.test(lower)) return \"update\";\n if (/\\bissue.*\\b(update|edit|modify)\\b/.test(lower)) return \"update\";\n if (/\\b(label|tag)\\b.*\\bissue/.test(lower)) return \"add_labels\";\n if (/\\bget\\b.*\\bissue\\s*#?\\d/.test(lower)) return \"get\";\n if (/\\bissue\\s*#?\\d/.test(lower) && !/\\b(list|show|all)\\b/.test(lower))\n return \"get\";\n if (/\\b(list|show|check|what are)\\b.*\\bissue/.test(lower)) return \"list\";\n\n return \"list\";\n}\n\nfunction parseLabels(input: unknown): string[] {\n if (!input) return [];\n if (Array.isArray(input)) return input.map(String);\n if (typeof input === \"string\")\n return input\n .split(\",\")\n .map((s) => s.trim())\n .filter(Boolean);\n return [];\n}\n\nasync function handleIssueAction(\n service: CodingWorkspaceService,\n repo: string,\n action: string,\n params: Record<string, unknown>,\n originalText: string,\n callback?: HandlerCallback,\n): Promise<ActionResult | undefined> {\n try {\n switch (action.toLowerCase()) {\n case \"create\": {\n const title = params.title as string;\n const body = params.body as string | undefined;\n\n if (!title) {\n const items = extractBulkItems(\n (params.text as string) ?? originalText,\n );\n if (items.length > 0) {\n const labels = parseLabels(params.labels);\n const created = [];\n for (const item of items.slice(0, ISSUE_RESULT_LIMIT)) {\n const issue = await service.createIssue(repo, {\n title: item.title,\n body: item.body ?? \"\",\n labels: labels.length > 0 ? labels : undefined,\n });\n created.push(issue);\n }\n if (callback) {\n const summary = created\n .map((i) => `#${i.number}: ${i.title}\\n ${i.url}`)\n .join(\"\\n\");\n await callback({\n text: `Created ${created.length} issues:\\n${summary}`,\n });\n }\n return { success: true, data: { issues: created } };\n }\n\n if (callback)\n await callback({ text: \"Issue title is required for create.\" });\n return { success: false, error: \"MISSING_TITLE\" };\n }\n\n const labels = parseLabels(params.labels);\n const issue = await service.createIssue(repo, {\n title,\n body: body ?? \"\",\n labels: labels.length > 0 ? labels : undefined,\n });\n if (callback)\n await callback({\n text: `Created issue #${issue.number}: ${issue.title}\\n${issue.url}`,\n });\n return { success: true, data: { issue } };\n }\n\n case \"list\": {\n const stateFilter = (params.state as string) ?? \"open\";\n const labels = parseLabels(params.labels);\n const issues = (\n await service.listIssues(repo, {\n state: stateFilter as \"open\" | \"closed\" | \"all\",\n labels: labels.length > 0 ? labels : undefined,\n })\n ).slice(0, ISSUE_RESULT_LIMIT);\n if (callback) {\n if (issues.length === 0) {\n await callback({\n text: `No ${stateFilter} issues found in ${repo}.`,\n });\n } else {\n const summary = issues\n .map(\n (i) =>\n `#${i.number} [${i.state}] ${i.title}${i.labels.length > 0 ? ` (${i.labels.join(\", \")})` : \"\"}`,\n )\n .join(\"\\n\");\n await callback({ text: `Issues in ${repo}:\\n${summary}` });\n }\n }\n return { success: true, data: { issues } };\n }\n\n case \"get\": {\n const issueNumber = Number(params.issueNumber);\n if (!issueNumber) {\n if (callback) await callback({ text: \"Issue number is required.\" });\n return { success: false, error: \"MISSING_ISSUE_NUMBER\" };\n }\n const issue = await service.getIssue(repo, issueNumber);\n if (callback)\n await callback({\n text: `Issue #${issue.number}: ${issue.title} [${issue.state}]\\n\\n${issue.body.slice(0, ISSUE_BODY_MAX_CHARS)}\\n\\nLabels: ${issue.labels.join(\", \") || \"none\"}\\n${issue.url}`,\n });\n return { success: true, data: { issue } };\n }\n\n case \"update\": {\n const issueNumber = Number(params.issueNumber);\n if (!issueNumber) {\n if (callback) await callback({ text: \"Issue number is required.\" });\n return { success: false, error: \"MISSING_ISSUE_NUMBER\" };\n }\n const labels = parseLabels(params.labels);\n const issue = await service.updateIssue(repo, issueNumber, {\n title: params.title as string | undefined,\n body: params.body as string | undefined,\n labels: labels.length > 0 ? labels : undefined,\n });\n if (callback)\n await callback({\n text: `Updated issue #${issue.number}: ${issue.title}`,\n });\n return { success: true, data: { issue } };\n }\n\n case \"comment\": {\n const issueNumber = Number(params.issueNumber);\n const body = params.body as string;\n if (!issueNumber || !body) {\n if (callback)\n await callback({\n text: \"Issue number and comment body are required.\",\n });\n return { success: false, error: \"MISSING_PARAMS\" };\n }\n const comment = await service.addComment(repo, issueNumber, body);\n if (callback)\n await callback({\n text: `Added comment to issue #${issueNumber}: ${comment.url}`,\n });\n return { success: true, data: { comment } };\n }\n\n case \"close\": {\n const issueNumber = Number(params.issueNumber);\n if (!issueNumber) {\n if (callback) await callback({ text: \"Issue number is required.\" });\n return { success: false, error: \"MISSING_ISSUE_NUMBER\" };\n }\n const issue = await service.closeIssue(repo, issueNumber);\n if (callback)\n await callback({\n text: `Closed issue #${issue.number}: ${issue.title}`,\n });\n return { success: true, data: { issue } };\n }\n\n case \"reopen\": {\n const issueNumber = Number(params.issueNumber);\n if (!issueNumber) {\n if (callback) await callback({ text: \"Issue number is required.\" });\n return { success: false, error: \"MISSING_ISSUE_NUMBER\" };\n }\n const issue = await service.reopenIssue(repo, issueNumber);\n if (callback)\n await callback({\n text: `Reopened issue #${issue.number}: ${issue.title}`,\n });\n return { success: true, data: { issue } };\n }\n\n case \"add_labels\": {\n const issueNumber = Number(params.issueNumber);\n const labels = parseLabels(params.labels);\n if (!issueNumber || labels.length === 0) {\n if (callback)\n await callback({ text: \"Issue number and labels are required.\" });\n return { success: false, error: \"MISSING_PARAMS\" };\n }\n await service.addLabels(repo, issueNumber, labels);\n if (callback)\n await callback({\n text: `Added labels [${labels.join(\", \")}] to issue #${issueNumber}`,\n });\n return { success: true };\n }\n\n default:\n if (callback)\n await callback({\n text: `Unknown issue action: ${action}. Use: create, list, get, update, comment, close, reopen, add_labels`,\n });\n return { success: false, error: \"UNKNOWN_OPERATION\" };\n }\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n if (callback)\n await callback({ text: `Issue operation failed: ${errorMessage}` });\n return { success: false, error: errorMessage };\n }\n}\n\nasync function runManageIssues(\n runtime: IAgentRuntime,\n message: Memory,\n _state: State | undefined,\n params: Record<string, unknown>,\n content: Record<string, unknown>,\n callback: HandlerCallback | undefined,\n): Promise<ActionResult> {\n const access = await requireTaskAgentAccess(runtime, message, \"interact\");\n if (!access.allowed) {\n if (callback) await callback({ text: access.reason });\n return { success: false, error: \"FORBIDDEN\", text: access.reason };\n }\n\n const workspaceService = getCodingWorkspaceService(runtime);\n if (!workspaceService) {\n if (callback)\n await callback({ text: \"Workspace Service is not available.\" });\n return { success: false, error: \"SERVICE_UNAVAILABLE\" };\n }\n\n workspaceService.setAuthPromptCallback(\n (prompt: Parameters<AuthPromptCallback>[0]) => {\n const delivered =\n getCoordinator(runtime)?.sendChatMessage(\n formatGitHubAuthPrompt(prompt),\n \"github-auth\",\n ) === true;\n if (!delivered) {\n coreLogger.warn(\n \"[TASKS:manage_issues] GitHub OAuth prompt requires immediate delivery, but the coordinator chat bridge is not wired\",\n );\n }\n return delivered;\n },\n );\n\n const text = ((content.text as string) ?? \"\").slice(0, ISSUE_BODY_MAX_CHARS);\n\n const topLevelAction = textValue(params.action) ?? textValue(content.action);\n const normalizedTopLevelAction = topLevelAction?.toLowerCase().replace(/-/g, \"_\");\n const legacyIssueAction =\n topLevelAction && normalizedTopLevelAction !== \"manage_issues\"\n ? topLevelAction\n : undefined;\n const action =\n (params.issueAction as string) ??\n (content.issueAction as string) ??\n legacyIssueAction ??\n inferIssueAction(text);\n const repo = (params.repo as string) ?? (content.repo as string);\n\n if (!repo) {\n const urlMatch = text?.match(\n /(?:https?:\\/\\/github\\.com\\/)?([a-zA-Z0-9_.-]+\\/[a-zA-Z0-9_.-]+)/,\n );\n if (!urlMatch) {\n if (callback)\n await callback({\n text: \"Please specify a repository (e.g., owner/repo or a GitHub URL).\",\n });\n return { success: false, error: \"MISSING_REPO\" };\n }\n return (\n (await handleIssueAction(\n workspaceService,\n urlMatch[1],\n action,\n { ...content, ...params },\n text,\n callback,\n )) ?? { success: false, error: \"UNKNOWN_OPERATION\" }\n );\n }\n\n return (\n (await handleIssueAction(\n workspaceService,\n repo,\n action,\n { ...content, ...params },\n text,\n callback,\n )) ?? { success: false, error: \"UNKNOWN_OPERATION\" }\n );\n}\n\n// ── op: archive / reopen (ARCHIVE_CODING_TASK / REOPEN_CODING_TASK) ────\n\nasync function runArchive(\n runtime: IAgentRuntime,\n _message: Memory,\n _state: State | undefined,\n params: Record<string, unknown>,\n content: Record<string, unknown>,\n callback: HandlerCallback | undefined,\n): Promise<ActionResult> {\n const coordinator = getCoordinator(runtime);\n if (!coordinator) {\n const msg = \"Coordinator is not available.\";\n await callbackText(callback, msg);\n return { success: false, error: \"SERVICE_UNAVAILABLE\", text: msg };\n }\n\n const taskId =\n pickString(params, content, \"taskId\") ??\n pickString(params, content, \"threadId\");\n if (!taskId) {\n const msg = \"taskId is required.\";\n await callbackText(callback, msg);\n return {\n success: false,\n text: msg,\n values: { error: \"MISSING_TASK_ID\" },\n };\n }\n\n try {\n await coordinator.archiveTaskThread(taskId);\n const msg = `Archived coding task ${taskId}.`;\n await callbackText(callback, msg);\n return {\n success: true,\n text: msg,\n values: { taskId, archived: true },\n data: { actionName: \"TASKS:archive\", taskId },\n };\n } catch (err) {\n const errMsg = err instanceof Error ? err.message : String(err);\n coreLogger.warn(`[TASKS:archive] failed: ${errMsg}`);\n const out = `Failed to archive coding task ${taskId}: ${errMsg}`;\n await callbackText(callback, out);\n return { success: false, text: out, error: errMsg };\n }\n}\n\nasync function runReopen(\n runtime: IAgentRuntime,\n _message: Memory,\n _state: State | undefined,\n params: Record<string, unknown>,\n content: Record<string, unknown>,\n callback: HandlerCallback | undefined,\n): Promise<ActionResult> {\n const coordinator = getCoordinator(runtime);\n if (!coordinator) {\n const msg = \"Coordinator is not available.\";\n await callbackText(callback, msg);\n return { success: false, error: \"SERVICE_UNAVAILABLE\", text: msg };\n }\n\n const taskId =\n pickString(params, content, \"taskId\") ??\n pickString(params, content, \"threadId\");\n if (!taskId) {\n const msg = \"taskId is required.\";\n await callbackText(callback, msg);\n return {\n success: false,\n text: msg,\n values: { error: \"MISSING_TASK_ID\" },\n };\n }\n\n try {\n await coordinator.reopenTaskThread(taskId);\n const msg = `Reopened coding task ${taskId}.`;\n await callbackText(callback, msg);\n return {\n success: true,\n text: msg,\n values: { taskId, reopened: true },\n data: { actionName: \"TASKS:reopen\", taskId },\n };\n } catch (err) {\n const errMsg = err instanceof Error ? err.message : String(err);\n coreLogger.warn(`[TASKS:reopen] failed: ${errMsg}`);\n const out = `Failed to reopen coding task ${taskId}: ${errMsg}`;\n await callbackText(callback, out);\n return { success: false, text: out, error: errMsg };\n }\n}\n\n// ── parent action ──────────────────────────────────────────────────────\n\nexport const tasksAction: Action & { suppressPostActionContinuation: true } = {\n name: \"TASKS\",\n contexts: [\"tasks\", \"code\", \"automation\", \"agent_internal\", \"connectors\"],\n roleGate: { minRole: \"USER\" },\n similes: [\n // create\n \"CREATE_AGENT_TASK\",\n \"CREATE_TASK\",\n \"START_CODING_TASK\",\n \"LAUNCH_CODING_TASK\",\n \"RUN_CODING_TASK\",\n \"START_AGENT_TASK\",\n \"SPAWN_AND_PROVISION\",\n \"CODE_THIS\",\n \"LAUNCH_TASK\",\n \"CREATE_SUBTASK\",\n // spawn_agent\n \"SPAWN_AGENT\",\n \"SPAWN_CODING_AGENT\",\n \"START_CODING_AGENT\",\n \"LAUNCH_CODING_AGENT\",\n \"CREATE_CODING_AGENT\",\n \"SPAWN_CODER\",\n \"RUN_CODING_AGENT\",\n \"SPAWN_SUB_AGENT\",\n \"START_TASK_AGENT\",\n \"CREATE_AGENT\",\n // send\n \"SEND_TO_AGENT\",\n \"SEND_TO_CODING_AGENT\",\n \"MESSAGE_CODING_AGENT\",\n \"INPUT_TO_AGENT\",\n \"RESPOND_TO_AGENT\",\n \"TELL_CODING_AGENT\",\n \"MESSAGE_AGENT\",\n \"TELL_TASK_AGENT\",\n // stop_agent\n \"STOP_AGENT\",\n \"STOP_CODING_AGENT\",\n \"KILL_CODING_AGENT\",\n \"TERMINATE_AGENT\",\n \"END_CODING_SESSION\",\n \"CANCEL_AGENT\",\n \"CANCEL_TASK_AGENT\",\n \"STOP_SUB_AGENT\",\n // list_agents\n \"LIST_AGENTS\",\n \"LIST_CODING_AGENTS\",\n \"SHOW_CODING_AGENTS\",\n \"GET_ACTIVE_AGENTS\",\n \"LIST_SESSIONS\",\n \"SHOW_CODING_SESSIONS\",\n \"SHOW_TASK_AGENTS\",\n \"LIST_SUB_AGENTS\",\n \"SHOW_TASK_STATUS\",\n // cancel\n \"CANCEL_TASK\",\n \"STOP_TASK\",\n \"ABORT_TASK\",\n \"KILL_TASK\",\n \"STOP_SUBTASK\",\n // history\n \"TASK_HISTORY\",\n \"LIST_TASK_HISTORY\",\n \"GET_TASK_HISTORY\",\n \"SHOW_TASKS\",\n \"COUNT_TASKS\",\n \"TASK_STATUS_HISTORY\",\n // control\n \"TASK_CONTROL\",\n \"CONTROL_TASK\",\n \"PAUSE_TASK\",\n \"RESUME_TASK\",\n \"CONTINUE_TASK\",\n \"ARCHIVE_TASK\",\n \"REOPEN_TASK\",\n // share\n \"TASK_SHARE\",\n \"SHARE_TASK_RESULT\",\n \"SHOW_TASK_ARTIFACT\",\n \"VIEW_TASK_OUTPUT\",\n \"CAN_I_SEE_IT\",\n \"PULL_IT_UP\",\n // provision_workspace\n \"CREATE_WORKSPACE\",\n \"PROVISION_WORKSPACE\",\n \"CLONE_REPO\",\n \"SETUP_WORKSPACE\",\n \"PREPARE_WORKSPACE\",\n // submit_workspace\n \"SUBMIT_WORKSPACE\",\n \"FINALIZE_WORKSPACE\",\n \"COMMIT_AND_PR\",\n \"CREATE_PR\",\n \"SUBMIT_CHANGES\",\n \"FINISH_WORKSPACE\",\n // manage_issues\n \"MANAGE_ISSUES\",\n \"CREATE_ISSUE\",\n \"LIST_ISSUES\",\n \"CLOSE_ISSUE\",\n \"COMMENT_ISSUE\",\n \"UPDATE_ISSUE\",\n \"GET_ISSUE\",\n // archive / reopen\n \"ARCHIVE_CODING_TASK\",\n \"CLOSE_CODING_TASK\",\n \"ARCHIVE_TASK_THREAD\",\n \"REOPEN_CODING_TASK\",\n \"UNARCHIVE_CODING_TASK\",\n \"RESUME_CODING_TASK\",\n ],\n description:\n \"Single planner-visible surface for the orchestrator's task-agent and workspace lifecycle. \" +\n \"Pick `action` to dispatch: create / spawn_agent / send / stop_agent / list_agents / cancel / history / control / share / provision_workspace / submit_workspace / manage_issues / archive / reopen. \" +\n \"Use `control` with controlAction=pause|resume|stop|continue|archive|reopen for task-thread state transitions, and `manage_issues` with issueAction=create|list|get|update|comment|close|reopen|add_labels for GitHub issues.\",\n descriptionCompressed:\n \"tasks: action=create|spawn_agent|send|stop_agent|list_agents|cancel|history|control|share|provision_workspace|submit_workspace|manage_issues|archive|reopen\",\n suppressPostActionContinuation: true,\n parameters: [\n {\n name: \"action\",\n description:\n \"Task operation: create, spawn_agent, send, stop_agent, list_agents, cancel, history, control, share, provision_workspace, submit_workspace, manage_issues, archive, reopen.\",\n required: false,\n schema: { type: \"string\" as const, enum: [...SUPPORTED_OPS] },\n },\n // create / spawn_agent\n {\n name: \"task\",\n description: \"Task prompt for create / spawn_agent / send (as new task).\",\n required: false,\n schema: { type: \"string\" as const },\n },\n {\n name: \"agentType\",\n description:\n \"Agent type (codex, claude, etc.) for create / spawn_agent / control.resume.\",\n required: false,\n schema: { type: \"string\" as const },\n },\n {\n name: \"agents\",\n description: \"Pipe-delimited multi-agent task list for action=create.\",\n required: false,\n schema: { type: \"string\" as const },\n },\n {\n name: \"repo\",\n description:\n \"Repository URL/slug for action=create / action=manage_issues / action=provision_workspace.\",\n required: false,\n schema: { type: \"string\" as const },\n },\n {\n name: \"workdir\",\n description: \"Working directory for action=create / action=spawn_agent.\",\n required: false,\n schema: { type: \"string\" as const },\n },\n {\n name: \"memoryContent\",\n description: \"Additional memory/context for action=create / action=spawn_agent.\",\n required: false,\n schema: { type: \"string\" as const },\n },\n {\n name: \"label\",\n description: \"Task label for action=create / action=spawn_agent / action=send.\",\n required: false,\n schema: { type: \"string\" as const },\n },\n {\n name: \"approvalPreset\",\n description: \"Approval preset for action=create / action=spawn_agent.\",\n required: false,\n schema: {\n type: \"string\" as const,\n enum: [\"readonly\", \"standard\", \"permissive\", \"autonomous\"],\n },\n },\n {\n name: \"keepAliveAfterComplete\",\n description: \"Keep session alive after completion for action=spawn_agent.\",\n required: false,\n schema: { type: \"boolean\" as const },\n },\n // send\n {\n name: \"input\",\n description: \"Text input to send to a running session for action=send.\",\n required: false,\n schema: { type: \"string\" as const },\n },\n {\n name: \"keys\",\n description: \"Key sequence to send for action=send.\",\n required: false,\n schema: { type: \"string\" as const },\n },\n // session/thread targeting\n {\n name: \"sessionId\",\n description:\n \"Target session id for action=send / action=stop_agent / action=cancel / action=control / action=share.\",\n required: false,\n schema: { type: \"string\" as const },\n },\n {\n name: \"threadId\",\n description:\n \"Target task-thread id for action=cancel / action=control / action=share / action=archive / action=reopen.\",\n required: false,\n schema: { type: \"string\" as const },\n },\n {\n name: \"taskId\",\n description: \"Alias for threadId; preferred for action=archive / action=reopen.\",\n required: false,\n schema: { type: \"string\" as const },\n },\n {\n name: \"all\",\n description: \"Apply to all sessions for action=stop_agent / action=cancel.\",\n required: false,\n schema: { type: \"boolean\" as const },\n },\n {\n name: \"search\",\n description:\n \"Free-text search for thread/task lookup in op=cancel / op=control / op=history / op=share.\",\n required: false,\n schema: { type: \"string\" as const },\n },\n {\n name: \"reason\",\n description: \"Cancellation reason for op=cancel.\",\n required: false,\n schema: { type: \"string\" as const },\n },\n // history\n {\n name: \"metric\",\n description:\n \"History query mode for op=history: list (default), count, or detail.\",\n required: false,\n schema: { type: \"string\" as const, enum: [\"list\", \"count\", \"detail\"] },\n },\n {\n name: \"window\",\n description: \"Relative window for op=history.\",\n required: false,\n schema: {\n type: \"string\" as const,\n enum: [\"active\", \"today\", \"yesterday\", \"last_7_days\", \"last_30_days\"],\n },\n },\n {\n name: \"statuses\",\n description: \"Status filter list for action=history.\",\n required: false,\n schema: { type: \"array\" as const, items: { type: \"string\" as const } },\n },\n {\n name: \"limit\",\n description: \"Result limit for action=history.\",\n required: false,\n schema: { type: \"number\" as const },\n },\n {\n name: \"includeArchived\",\n description: \"Include archived threads in action=history.\",\n required: false,\n schema: { type: \"boolean\" as const },\n },\n // control\n {\n name: \"controlAction\",\n description:\n \"Child action for action=control: pause | resume | stop | continue | archive | reopen. Legacy action=<control verb> is still accepted when top-level action is supplied as op/subaction.\",\n required: false,\n schema: { type: \"string\" as const },\n },\n {\n name: \"issueAction\",\n description:\n \"Child action for action=manage_issues: create | list | get | update | comment | close | reopen | add_labels.\",\n required: false,\n schema: { type: \"string\" as const },\n },\n {\n name: \"note\",\n description: \"Optional note for action=control with controlAction=pause|stop.\",\n required: false,\n schema: { type: \"string\" as const },\n },\n {\n name: \"instruction\",\n description:\n \"Follow-up instruction for action=control with controlAction=resume|continue.\",\n required: false,\n schema: { type: \"string\" as const },\n },\n // workspace\n {\n name: \"baseBranch\",\n description:\n \"Base branch for action=provision_workspace / action=submit_workspace.\",\n required: false,\n schema: { type: \"string\" as const },\n },\n {\n name: \"useWorktree\",\n description: \"Use worktree mode for op=provision_workspace.\",\n required: false,\n schema: { type: \"boolean\" as const },\n },\n {\n name: \"parentWorkspaceId\",\n description:\n \"Parent workspace id for op=provision_workspace worktree mode.\",\n required: false,\n schema: { type: \"string\" as const },\n },\n {\n name: \"workspaceId\",\n description: \"Workspace id for op=submit_workspace.\",\n required: false,\n schema: { type: \"string\" as const },\n },\n {\n name: \"commitMessage\",\n description: \"Commit message for op=submit_workspace.\",\n required: false,\n schema: { type: \"string\" as const },\n },\n {\n name: \"prTitle\",\n description: \"PR title for op=submit_workspace.\",\n required: false,\n schema: { type: \"string\" as const },\n },\n {\n name: \"prBody\",\n description: \"PR body for op=submit_workspace.\",\n required: false,\n schema: { type: \"string\" as const },\n },\n {\n name: \"draft\",\n description: \"Create draft PR for op=submit_workspace.\",\n required: false,\n schema: { type: \"boolean\" as const },\n },\n {\n name: \"skipPR\",\n description: \"Skip PR creation for action=submit_workspace.\",\n required: false,\n schema: { type: \"boolean\" as const },\n },\n // manage_issues\n {\n name: \"title\",\n description:\n \"Issue title for action=manage_issues with issueAction=create|update.\",\n required: false,\n schema: { type: \"string\" as const },\n },\n {\n name: \"body\",\n description:\n \"Issue body for action=manage_issues with issueAction=create|update|comment.\",\n required: false,\n schema: { type: \"string\" as const },\n },\n {\n name: \"issueNumber\",\n description:\n \"Issue number for action=manage_issues with issueAction=get|update|comment|close|reopen|add_labels.\",\n required: false,\n schema: { type: \"number\" as const },\n },\n {\n name: \"labels\",\n description:\n \"Labels (csv string or array) for action=manage_issues with issueAction=create|update|add_labels|list.\",\n required: false,\n schema: { type: \"string\" as const },\n },\n {\n name: \"state\",\n description:\n \"State filter (open|closed|all) for action=manage_issues with issueAction=list.\",\n required: false,\n schema: { type: \"string\" as const },\n },\n // misc\n {\n name: \"validator\",\n description: \"Optional verifier for op=create.\",\n required: false,\n schema: { type: \"object\" as const },\n },\n {\n name: \"maxRetries\",\n description: \"Verifier retry count for op=create.\",\n required: false,\n schema: { type: \"integer\" as const, minimum: 0 },\n },\n {\n name: \"onVerificationFail\",\n description: \"Verifier failure behavior for op=create.\",\n required: false,\n schema: {\n type: \"string\" as const,\n enum: [\"retry\", \"escalate\"],\n },\n },\n {\n name: \"metadata\",\n description: \"Additional metadata for op=create.\",\n required: false,\n schema: { type: \"object\" as const },\n },\n ],\n validate: async (runtime, message) => {\n // Always allow when ACP service is available — op switch handles dispatch.\n if (!getAcpService(runtime) && !getCoordinator(runtime)) return false;\n if (\n hasExplicitPayload(message, [\n \"op\",\n \"task\",\n \"repo\",\n \"workdir\",\n \"agents\",\n \"agentType\",\n \"sessionId\",\n \"threadId\",\n \"taskId\",\n ])\n )\n return true;\n const text = messageText(message);\n if (looksLikePersonalLifeOpsTask(text)) return false;\n return looksLikeTaskAgentRequest(text);\n },\n handler: async (\n runtime: IAgentRuntime,\n message: Memory,\n state?: State,\n options?: HandlerOptions,\n callback?: HandlerCallback,\n ): Promise<ActionResult | undefined> => {\n const params = paramsRecord(options as HandlerOptionsLike | undefined);\n const content = contentRecord(message);\n const op = readOp(params, content) ?? \"create\";\n\n switch (op) {\n case \"create\":\n return runCreate(runtime, message, state, params, content, callback);\n case \"spawn_agent\":\n return runSpawnAgent(\n runtime,\n message,\n state,\n params,\n content,\n callback,\n );\n case \"send\":\n return runSend(runtime, message, state, params, content, callback);\n case \"stop_agent\":\n return runStopAgent(runtime, message, state, params, content, callback);\n case \"list_agents\":\n return runListAgents(\n runtime,\n message,\n state,\n params,\n content,\n callback,\n );\n case \"cancel\":\n return runCancel(runtime, message, state, params, content, callback);\n case \"history\":\n return runHistory(runtime, message, state, params, content, callback);\n case \"control\":\n return runControl(runtime, message, state, params, content, callback);\n case \"share\":\n return runShare(runtime, message, state, params, content, callback);\n case \"provision_workspace\":\n return runProvisionWorkspace(\n runtime,\n message,\n state,\n params,\n content,\n callback,\n );\n case \"submit_workspace\":\n return runSubmitWorkspace(\n runtime,\n message,\n state,\n params,\n content,\n callback,\n );\n case \"manage_issues\":\n return runManageIssues(\n runtime,\n message,\n state,\n params,\n content,\n callback,\n );\n case \"archive\":\n return runArchive(runtime, message, state, params, content, callback);\n case \"reopen\":\n return runReopen(runtime, message, state, params, content, callback);\n default:\n return errorResult(\"UNKNOWN\", `Unknown TASKS op: ${String(op)}`);\n }\n },\n\n examples: [\n [\n {\n name: \"{{name1}}\",\n content: {\n text: \"Spawn a coding agent to refactor the auth module.\",\n source: \"chat\",\n },\n },\n {\n name: \"{{agentName}}\",\n content: {\n text: \"Creating the task and dispatching a coding sub-agent.\",\n actions: [\"TASKS\"],\n thought:\n \"User asked to delegate a coding job; TASKS subaction=create with kind=coding routes to the orchestrator's spawn path.\",\n },\n },\n ],\n [\n {\n name: \"{{name1}}\",\n content: {\n text: \"What's the status of my running tasks?\",\n source: \"chat\",\n },\n },\n {\n name: \"{{agentName}}\",\n content: {\n text: \"Listing active tasks.\",\n actions: [\"TASKS\"],\n thought:\n \"Status check maps to TASKS subaction=list filtering for in_progress / queued tasks.\",\n },\n },\n ],\n [\n {\n name: \"{{name1}}\",\n content: {\n text: \"Stop the migration task; I'll come back to it later.\",\n source: \"chat\",\n },\n },\n {\n name: \"{{agentName}}\",\n content: {\n text: \"Pausing the task.\",\n actions: [\"TASKS\"],\n thought:\n \"Halt-and-keep-state maps to TASKS subaction=pause; archive/reopen are for fully resolved tasks.\",\n },\n },\n ],\n [\n {\n name: \"{{name1}}\",\n content: {\n text: \"Show me the worktree for task TASK-12.\",\n source: \"chat\",\n },\n },\n {\n name: \"{{agentName}}\",\n content: {\n text: \"Opening the worktree.\",\n actions: [\"TASKS\"],\n thought:\n \"Worktree inspection maps to TASKS subaction=worktree with the explicit task id.\",\n },\n },\n ],\n ],\n};\n\n// Operation-specific handles resolve to the consolidated TASKS action.\nexport const createTaskAction = tasksAction;\nexport const startCodingTaskAction = tasksAction;\nexport const spawnAgentAction = tasksAction;\nexport const spawnTaskAgentAction = tasksAction;\nexport const sendToAgentAction = tasksAction;\nexport const sendToTaskAgentAction = tasksAction;\nexport const stopAgentAction = tasksAction;\nexport const stopTaskAgentAction = tasksAction;\nexport const listAgentsAction = tasksAction;\nexport const listTaskAgentsAction = tasksAction;\nexport const cancelTaskAction = tasksAction;\nexport const taskHistoryAction = tasksAction;\nexport const taskControlAction = tasksAction;\nexport const taskShareAction = tasksAction;\nexport const provisionWorkspaceAction = tasksAction;\nexport const finalizeWorkspaceAction = tasksAction;\nexport const manageIssuesAction = tasksAction;\nexport const archiveCodingTaskAction = tasksAction;\nexport const reopenCodingTaskAction = tasksAction;\n",
|
|
58
|
+
"import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\nimport type { IAgentRuntime, Memory } from \"@elizaos/core\";\n\ntype RoleName = \"OWNER\" | \"ADMIN\" | \"USER\" | \"GUEST\";\ntype TaskAgentAbility = \"create\" | \"interact\";\ntype ConnectorPolicy = Partial<Record<TaskAgentAbility, RoleName>>;\ntype TaskAgentPolicyConfig = {\n default?: RoleName | ConnectorPolicy;\n connectors?: Record<string, RoleName | ConnectorPolicy>;\n};\n\nconst ROLE_RANK: Record<RoleName, number> = {\n GUEST: 0,\n USER: 1,\n ADMIN: 2,\n OWNER: 3,\n};\n\nconst DEFAULT_POLICY: TaskAgentPolicyConfig = {\n default: \"GUEST\",\n connectors: {\n discord: {\n create: \"ADMIN\",\n interact: \"ADMIN\",\n },\n },\n};\n\ntype RoleCheckResult = {\n role: RoleName;\n isAdmin: boolean;\n isOwner: boolean;\n};\n\nconst LOCAL_ROLES_MODULE_CANDIDATES = [\n path.resolve(process.cwd(), \"packages/plugin-roles/src/index.ts\"),\n path.resolve(process.cwd(), \"packages/plugin-roles/dist/index.js\"),\n path.resolve(process.cwd(), \"packages/agent/src/runtime/roles/src/index.ts\"),\n];\n\nfunction normalizeRole(value: unknown): RoleName {\n const upper = typeof value === \"string\" ? value.trim().toUpperCase() : \"\";\n switch (upper) {\n case \"OWNER\":\n case \"ADMIN\":\n case \"USER\":\n return upper;\n default:\n return \"GUEST\";\n }\n}\n\nfunction normalizeConnectorPolicy(\n value: RoleName | ConnectorPolicy | undefined,\n): ConnectorPolicy {\n if (!value) return {};\n if (typeof value === \"string\") {\n const role = normalizeRole(value);\n return {\n create: role,\n interact: role,\n };\n }\n return {\n ...(value.create ? { create: normalizeRole(value.create) } : {}),\n ...(value.interact ? { interact: normalizeRole(value.interact) } : {}),\n };\n}\n\nfunction parseTaskAgentPolicy(runtime: IAgentRuntime): TaskAgentPolicyConfig {\n if (typeof runtime.getSetting !== \"function\") {\n return DEFAULT_POLICY;\n }\n\n const configured =\n runtime.getSetting(\"TASK_AGENT_ROLE_POLICY\") ??\n runtime.getSetting(\"TASK_AGENT_CONNECTOR_ROLE_POLICY\");\n\n if (!configured) {\n return DEFAULT_POLICY;\n }\n\n let parsed: unknown = configured;\n if (typeof configured === \"string\") {\n try {\n parsed = JSON.parse(configured);\n } catch {\n return DEFAULT_POLICY;\n }\n }\n\n if (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n return DEFAULT_POLICY;\n }\n\n const record = parsed as Record<string, unknown>;\n const connectors =\n record.connectors &&\n typeof record.connectors === \"object\" &&\n !Array.isArray(record.connectors)\n ? Object.fromEntries(\n Object.entries(record.connectors as Record<string, unknown>).map(\n ([connector, value]) => [\n connector,\n normalizeConnectorPolicy(value as RoleName | ConnectorPolicy),\n ],\n ),\n )\n : DEFAULT_POLICY.connectors;\n\n return {\n default: normalizeConnectorPolicy(\n (record.default ?? DEFAULT_POLICY.default) as RoleName | ConnectorPolicy,\n ),\n connectors,\n };\n}\n\nfunction getConnectorFromBridgeMetadata(message: Memory): string | null {\n const metadata = (message.content as Record<string, unknown> | undefined)\n ?.metadata;\n if (!metadata || typeof metadata !== \"object\") return null;\n const bridgeSender = (metadata as Record<string, unknown>).bridgeSender;\n if (!bridgeSender || typeof bridgeSender !== \"object\") return null;\n const liveMetadata = (bridgeSender as Record<string, unknown>).metadata;\n if (!liveMetadata || typeof liveMetadata !== \"object\") return null;\n\n for (const [connector, value] of Object.entries(\n liveMetadata as Record<string, unknown>,\n )) {\n if (value && typeof value === \"object\") {\n return connector;\n }\n }\n return null;\n}\n\nasync function resolveConnectorSource(\n runtime: IAgentRuntime,\n message: Memory,\n): Promise<string | null> {\n const content = message.content as Record<string, unknown> | undefined;\n const directSource =\n typeof content?.source === \"string\" && content.source !== \"client_chat\"\n ? content.source\n : null;\n if (directSource) return directSource;\n\n const bridgeSource = getConnectorFromBridgeMetadata(message);\n if (bridgeSource) return bridgeSource;\n\n try {\n const room = await runtime.getRoom(message.roomId);\n if (typeof room?.source === \"string\" && room.source.trim().length > 0) {\n return room.source;\n }\n } catch {\n // Ignore room lookup failures and fall through to null.\n }\n\n return null;\n}\n\nasync function resolveSenderRole(\n runtime: IAgentRuntime,\n message: Memory,\n): Promise<RoleCheckResult | null> {\n if (process.env.ELIZA_SKIP_LOCAL_PLUGIN_ROLES !== \"1\") {\n for (const candidate of LOCAL_ROLES_MODULE_CANDIDATES) {\n if (!fs.existsSync(candidate)) {\n continue;\n }\n\n try {\n const localRolesModule = (await import(\n pathToFileURL(candidate).href\n )) as {\n checkSenderRole?: (\n runtime: IAgentRuntime,\n message: Memory,\n ) => Promise<RoleCheckResult | null>;\n };\n if (typeof localRolesModule.checkSenderRole === \"function\") {\n return await localRolesModule.checkSenderRole(runtime, message);\n }\n } catch {\n // fall through to the installed package import below\n }\n }\n }\n\n try {\n const rolesModule = (await import(\"@elizaos/core\")) as {\n checkSenderRole?: (\n runtime: IAgentRuntime,\n message: Memory,\n ) => Promise<RoleCheckResult | null>;\n };\n if (typeof rolesModule.checkSenderRole === \"function\") {\n return await rolesModule.checkSenderRole(runtime, message);\n }\n } catch {\n // Package not available in standalone tests.\n }\n return null;\n}\n\nexport async function requireTaskAgentAccess(\n runtime: IAgentRuntime,\n message: Memory,\n ability: TaskAgentAbility,\n): Promise<\n | {\n allowed: true;\n connector: string | null;\n requiredRole: RoleName;\n actualRole: RoleName;\n }\n | {\n allowed: false;\n connector: string | null;\n requiredRole: RoleName;\n actualRole: RoleName;\n reason: string;\n }\n> {\n const messageEntityId =\n typeof message.entityId === \"string\" && message.entityId.length > 0\n ? message.entityId\n : null;\n const runtimeAgentId =\n typeof runtime.agentId === \"string\" && runtime.agentId.length > 0\n ? runtime.agentId\n : null;\n\n if (messageEntityId && runtimeAgentId && messageEntityId === runtimeAgentId) {\n return {\n allowed: true,\n connector: null,\n requiredRole: \"GUEST\",\n actualRole: \"OWNER\",\n };\n }\n\n const connector = await resolveConnectorSource(runtime, message);\n const policy = parseTaskAgentPolicy(runtime);\n const connectorPolicy = connector\n ? normalizeConnectorPolicy(policy.connectors?.[connector])\n : {};\n const defaultPolicy = normalizeConnectorPolicy(\n policy.default as RoleName | ConnectorPolicy,\n );\n const requiredRole =\n connectorPolicy[ability] ?? defaultPolicy[ability] ?? \"GUEST\";\n\n if (requiredRole === \"GUEST\") {\n return {\n allowed: true,\n connector,\n requiredRole,\n actualRole: \"GUEST\",\n };\n }\n\n const roleCheck = await resolveSenderRole(runtime, message);\n if (!roleCheck) {\n return {\n allowed: false,\n connector,\n requiredRole,\n actualRole: \"GUEST\",\n reason:\n connector === \"discord\"\n ? \"Task-agent access in Discord requires a verified OWNER or ADMIN role.\"\n : \"Task-agent access requires a verified role, but role context is unavailable.\",\n };\n }\n\n const actualRole = normalizeRole(roleCheck.role);\n if (ROLE_RANK[actualRole] < ROLE_RANK[requiredRole]) {\n return {\n allowed: false,\n connector,\n requiredRole,\n actualRole,\n reason:\n connector === \"discord\"\n ? `Task-agent access in Discord requires ${requiredRole} or higher. Current role: ${actualRole}.`\n : `Task-agent access requires ${requiredRole} or higher. Current role: ${actualRole}.`,\n };\n }\n\n return {\n allowed: true,\n connector,\n requiredRole,\n actualRole,\n };\n}\n",
|
|
59
|
+
"import type {\n ActionResult,\n HandlerCallback,\n IAgentRuntime,\n Memory,\n State,\n} from \"@elizaos/core\";\nimport type {\n AcpJsonRpcMessage,\n ApprovalPreset,\n AvailableAgentInfo,\n PromptResult,\n SessionEventName,\n SessionInfo,\n SpawnOptions,\n SpawnResult,\n} from \"../services/types.js\";\n\nexport interface AcpActionService {\n defaultApprovalPreset?: ApprovalPreset;\n agentSelectionStrategy?: string;\n spawnSession(opts: SpawnOptions): Promise<SpawnResult>;\n sendPrompt?(\n sessionId: string,\n text: string,\n opts?: { timeoutMs?: number; model?: string },\n ): Promise<PromptResult>;\n sendToSession(sessionId: string, input: string): Promise<PromptResult>;\n sendKeysToSession(sessionId: string, keys?: string): Promise<void>;\n stopSession(sessionId: string, force?: boolean): Promise<void>;\n cancelSession?(sessionId: string): Promise<void>;\n listSessions(): SessionInfo[] | Promise<SessionInfo[]>;\n getSession(\n sessionId: string,\n ): SessionInfo | undefined | Promise<SessionInfo | null | undefined>;\n resolveAgentType?(\n selection?: Record<string, unknown>,\n ): Promise<string> | string;\n checkAvailableAgents?(types?: string[]): Promise<AvailableAgentInfo[]>;\n getAvailableAgents?(): Promise<AvailableAgentInfo[]>;\n onSessionEvent?(\n handler: (\n sessionId: string,\n event: SessionEventName,\n data: unknown,\n ) => void,\n ): () => void;\n onAcpEvent?(\n handler: (event: AcpJsonRpcMessage, sessionId?: string) => void,\n ): () => void;\n emitSessionEvent?(\n sessionId: string,\n event: SessionEventName,\n data: unknown,\n ): void;\n}\n\nexport type HandlerOptionsLike =\n | { parameters?: Record<string, unknown> }\n | Record<string, unknown>;\n\nexport function getAcpService(\n runtime: IAgentRuntime,\n): AcpActionService | undefined {\n return (runtime.getService?.(\"ACP_SERVICE\") ??\n runtime.getService?.(\"ACP_SUBPROCESS_SERVICE\") ??\n runtime.getService?.(\"PTY_SERVICE\") ??\n undefined) as AcpActionService | undefined;\n}\n\nexport function logger(runtime: IAgentRuntime) {\n return runtime.logger ?? {};\n}\n\nexport function contentRecord(message: Memory): Record<string, unknown> {\n return message.content && typeof message.content === \"object\"\n ? (message.content as Record<string, unknown>)\n : {};\n}\n\nexport function paramsRecord(\n options?: HandlerOptionsLike,\n): Record<string, unknown> {\n const maybeParams =\n options && \"parameters\" in options ? options.parameters : undefined;\n return maybeParams && typeof maybeParams === \"object\"\n ? (maybeParams as Record<string, unknown>)\n : {};\n}\n\nexport function pickString(\n params: Record<string, unknown>,\n content: Record<string, unknown>,\n name: string,\n): string | undefined {\n const value = params[name] ?? content[name];\n return typeof value === \"string\" && value.trim().length > 0\n ? value.trim()\n : undefined;\n}\n\nexport function pickBoolean(\n params: Record<string, unknown>,\n content: Record<string, unknown>,\n name: string,\n): boolean | undefined {\n const value = params[name] ?? content[name];\n return typeof value === \"boolean\" ? value : undefined;\n}\n\nexport function pickNumber(\n params: Record<string, unknown>,\n content: Record<string, unknown>,\n name: string,\n): number | undefined {\n const value = params[name] ?? content[name];\n return typeof value === \"number\" && Number.isFinite(value)\n ? value\n : undefined;\n}\n\nexport function messageText(message: Memory): string {\n if (typeof message.content === \"string\") return message.content;\n const content = contentRecord(message);\n return typeof content.text === \"string\" ? content.text : \"\";\n}\n\nexport function hasExplicitPayload(message: Memory, fields: string[]): boolean {\n const content = contentRecord(message);\n return fields.some((field) => typeof content[field] === \"string\");\n}\n\nexport function looksLikeTaskAgentRequest(text: string): boolean {\n if (!text.trim()) return true;\n return /\\b(code|debug|fix|implement|investigate|research|summari[sz]e|write|plan|delegate|subagent|agent|repo|test|build|refactor|analy[sz]e|document|automate|script|issue|pr|pull request)\\b/i.test(\n text,\n );\n}\n\nexport function shortId(id: string): string {\n return id.slice(0, 8).toLowerCase();\n}\n\nexport function labelFor(\n session: Pick<SessionInfo, \"id\" | \"name\" | \"metadata\">,\n): string {\n return typeof session.metadata?.label === \"string\"\n ? session.metadata.label\n : (session.name ?? shortId(session.id));\n}\n\nexport function newestSession(\n sessions: SessionInfo[],\n): SessionInfo | undefined {\n return sessions\n .slice()\n .sort(\n (a, b) =>\n new Date(b.lastActivityAt).getTime() -\n new Date(a.lastActivityAt).getTime(),\n )[0];\n}\n\nexport async function listSessionsWithin(\n service: AcpActionService,\n timeoutMs = 2000,\n): Promise<SessionInfo[]> {\n return Promise.race([\n Promise.resolve(service.listSessions()),\n new Promise<SessionInfo[]>((resolve) =>\n setTimeout(() => resolve([]), timeoutMs),\n ),\n ]);\n}\n\nexport async function validateHasSessions(\n runtime: IAgentRuntime,\n): Promise<boolean> {\n const service = getAcpService(runtime);\n if (!service) return false;\n try {\n const sessions = await listSessionsWithin(service, 2000);\n return sessions.length > 0;\n } catch {\n return false;\n }\n}\n\nexport async function callbackText(\n callback: HandlerCallback | undefined,\n text: string,\n): Promise<void> {\n if (callback) await callback({ text });\n}\n\nexport function errorResult(error: string, text?: string): ActionResult {\n return { success: false, error, ...(text ? { text } : {}) };\n}\n\nexport async function resolveSession(\n service: AcpActionService,\n sessionId: string | undefined,\n state?: State,\n): Promise<{\n session?: SessionInfo;\n missingId?: string;\n sessions: SessionInfo[];\n}> {\n const stateSession = (\n state as { codingSession?: { id?: string } } | undefined\n )?.codingSession?.id;\n const targetId = sessionId ?? stateSession;\n if (targetId) {\n const found = await Promise.resolve(service.getSession(targetId));\n return {\n session: found ?? undefined,\n missingId: found ? undefined : targetId,\n sessions: [],\n };\n }\n const sessions = await Promise.resolve(service.listSessions());\n return { session: newestSession(sessions), sessions };\n}\n\nexport function setCurrentSession(\n state: State | undefined,\n session: SpawnResult | SessionInfo,\n): void {\n if (state) (state as { codingSession?: unknown }).codingSession = session;\n}\n\nexport function setCurrentSessions(\n state: State | undefined,\n sessions: SpawnResult[],\n): void {\n if (state) (state as { codingSessions?: unknown }).codingSessions = sessions;\n}\n\nexport function emitSessionEvent(\n service: AcpActionService,\n sessionId: string,\n event: SessionEventName,\n data: unknown,\n): void {\n service.emitSessionEvent?.(sessionId, event, data);\n}\n\nexport function parseApproval(\n value: string | undefined,\n): ApprovalPreset | undefined {\n if (\n value === \"readonly\" ||\n value === \"standard\" ||\n value === \"permissive\" ||\n value === \"autonomous\"\n )\n return value;\n return undefined;\n}\n\nexport function isAuthError(error: unknown): boolean {\n const text = error instanceof Error ? error.message : String(error);\n return /auth|login|credential|unauthorized|forbidden|permission/i.test(text);\n}\n\nexport function failureMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nexport function getTimeoutMs(\n params: Record<string, unknown>,\n content: Record<string, unknown>,\n): number | undefined {\n return (\n pickNumber(params, content, \"timeout_ms\") ??\n pickNumber(params, content, \"timeoutMs\")\n );\n}\n",
|
|
60
|
+
"import type { Memory, State } from \"@elizaos/core\";\nimport type { SwarmCoordinator } from \"../services/swarm-coordinator.js\";\nimport type {\n ListTaskThreadsOptions,\n TaskThreadSummary,\n} from \"../services/task-registry.js\";\n\ntype MessageFields = {\n roomId?: string;\n userId?: string;\n content?: Record<string, unknown>;\n};\n\nfunction stringValue(value: unknown): string | undefined {\n return typeof value === \"string\" && value.trim().length > 0\n ? value.trim()\n : undefined;\n}\n\nfunction inferSearchText(text: string): string | undefined {\n const quoted =\n text.match(/\"([^\"]{3,120})\"/)?.[1] ?? text.match(/'([^']{3,120})'/)?.[1];\n if (quoted) return quoted.trim();\n\n const topical =\n text.match(/\\bworking on\\s+(.+?)(?:[?.!,]|$)/i)?.[1] ??\n text.match(/\\bfor\\s+(.+?)(?:[?.!,]|$)/i)?.[1] ??\n text.match(/\\bon\\s+(.+?)(?:[?.!,]|$)/i)?.[1];\n return topical?.trim();\n}\n\nfunction buildScopedListOptions(\n message: Memory,\n includeArchived: boolean,\n): ListTaskThreadsOptions {\n const messageLike = message as MessageFields;\n return {\n includeArchived,\n roomId: stringValue(messageLike.roomId),\n ownerUserId: stringValue(messageLike.userId),\n limit: 10,\n };\n}\n\nasync function threadBySession(\n coordinator: SwarmCoordinator,\n sessionId: string,\n): Promise<TaskThreadSummary | null> {\n const threadId =\n await coordinator.taskRegistry.findThreadIdBySessionId(sessionId);\n if (!threadId) return null;\n const detail = await coordinator.getTaskThread(threadId);\n return detail;\n}\n\nexport async function resolveTaskThreadTarget(params: {\n coordinator: SwarmCoordinator;\n message: Memory;\n state?: State;\n options?: Record<string, unknown>;\n includeArchived?: boolean;\n}): Promise<TaskThreadSummary | null> {\n const {\n coordinator,\n message,\n state,\n options,\n includeArchived = true,\n } = params;\n const content = (message.content ?? {}) as Record<string, unknown>;\n\n const explicitThreadId =\n stringValue(options?.threadId) ?? stringValue(content.threadId);\n if (explicitThreadId) {\n return coordinator.getTaskThread(explicitThreadId);\n }\n\n const codingSession =\n state && typeof state === \"object\"\n ? ((state as Record<string, unknown>).codingSession as\n | Record<string, unknown>\n | undefined)\n : undefined;\n const explicitSessionId =\n stringValue(options?.sessionId) ??\n stringValue(content.sessionId) ??\n stringValue(codingSession?.id);\n if (explicitSessionId) {\n const bySession = await threadBySession(coordinator, explicitSessionId);\n if (bySession) return bySession;\n }\n\n const search =\n stringValue(options?.search) ??\n stringValue(content.search) ??\n inferSearchText(typeof content.text === \"string\" ? content.text : \"\");\n if (search) {\n const matches = await coordinator.listTaskThreads({\n ...buildScopedListOptions(message, includeArchived),\n search,\n });\n if (matches.length > 0) return matches[0];\n }\n\n const scoped = await coordinator.listTaskThreads(\n buildScopedListOptions(message, includeArchived),\n );\n if (scoped.length > 0) return scoped[0];\n\n const recent = await coordinator.listTaskThreads({\n includeArchived,\n limit: 10,\n });\n return recent[0] ?? null;\n}\n",
|
|
61
|
+
"/**\n * Provider that injects plain text task-agent action examples into the prompt context.\n *\n * ElizaOS core only shows exampleCalls from its static action-docs registry,\n * which doesn't include custom plugin actions. This provider bridges the gap\n * by formatting our task-agent action examples in the same compact plain-text\n * style the model sees for core actions.\n *\n * @module providers/action-examples\n */\n\nimport type { IAgentRuntime, Memory, Provider, State } from \"@elizaos/core\";\nimport { getPtyService } from \"../services/pty-service.js\";\nimport {\n formatTaskAgentFrameworkLine,\n getTaskAgentFrameworkState,\n looksLikeTaskAgentRequest,\n TASK_AGENT_FRAMEWORK_LABELS,\n} from \"../services/task-agent-frameworks.js\";\n\nconst MAX_FRAMEWORK_LINES = 12;\nconst MAX_FRAMEWORK_DATA = 12;\n\nexport const codingAgentExamplesProvider: Provider = {\n name: \"CODING_AGENT_EXAMPLES\",\n description:\n \"Plain text examples showing how to use ACPX task-agent actions, framework availability, and subscription-aware defaults\",\n descriptionCompressed:\n \"ACPX task-agent action examples, framework availability, subscription defaults.\",\n position: -1,\n contexts: [\"code\", \"tasks\", \"agent_internal\"],\n contextGate: { anyOf: [\"code\", \"tasks\", \"agent_internal\"] },\n cacheStable: true,\n cacheScope: \"agent\",\n\n get: async (runtime: IAgentRuntime, message: Memory, _state: State) => {\n try {\n const userText =\n (typeof message.content === \"string\"\n ? message.content\n : message.content?.text) ?? \"\";\n const ptyService = getPtyService(runtime) ?? undefined;\n const frameworkState = await getTaskAgentFrameworkState(\n runtime,\n ptyService,\n );\n const frameworks = frameworkState.frameworks.slice(0, MAX_FRAMEWORK_DATA);\n const frameworkLines = frameworks\n .slice(0, MAX_FRAMEWORK_LINES)\n .map(formatTaskAgentFrameworkLine);\n\n const compactText = [\n \"task_agent_action_examples:\",\n \" useWhen: work is more complicated than a simple direct reply\",\n \" execution: asynchronous open-ended workers\",\n \" capabilities: code, debug, research, write, analyze, plan, document, automate\",\n ` recommendedDefault: ${TASK_AGENT_FRAMEWORK_LABELS[frameworkState.preferred.id]}`,\n ` recommendedReason: ${frameworkState.preferred.reason}`,\n ...(frameworkState.configuredSubscriptionProvider\n ? [\n ` configuredSubscriptionProvider: ${frameworkState.configuredSubscriptionProvider}`,\n ]\n : []),\n `frameworks[${frameworkLines.length}]:`,\n ...frameworkLines,\n \"canonicalActions:\",\n \" create: CREATE_AGENT_TASK\",\n \" directSpawn: SPAWN_AGENT\",\n \" sendInput: SEND_TO_AGENT\",\n \" status: provider.active_workspace_context\",\n \" cancel: STOP_AGENT\",\n \" history: TASK_HISTORY\",\n \" control: TASK_CONTROL\",\n \" share: TASK_SHARE\",\n \" workspace: PROVISION_WORKSPACE or FINALIZE_WORKSPACE\",\n ].join(\"\\n\");\n\n if (!looksLikeTaskAgentRequest(userText)) {\n return {\n data: {\n preferredTaskAgent: frameworkState.preferred.id,\n frameworks,\n },\n values: { taskAgentExamples: compactText },\n text: compactText,\n };\n }\n\n const detailedText = [\n compactText,\n \"\",\n \"examples[5]{user,actions,params}:\",\n \" Investigate why production login returns 401s in https://github.com/acme/app and fix it,REPLY|CREATE_AGENT_TASK,repo=https://github.com/acme/app; task=Investigate login 401s implement fix run tests summarize root cause\",\n \" Research browser automation options compare them and draft a recommendation doc,REPLY|CREATE_AGENT_TASK,agents=Research Playwright tradeoffs | Compare Stagehand Playwright browser-use | Draft recommendation memo\",\n \" Tell the running sub-agent to accept that prompt and continue,REPLY|SEND_TO_AGENT,input=Yes accept it and continue\",\n \" What are you working on right now?,TASK_HISTORY,metric=list; window=active\",\n \" Can I see it?,TASK_SHARE,none\",\n \"guidance:\",\n \" preferCreateAgentTask: use ACPX CREATE_AGENT_TASK for open-ended multi-step async work\",\n \" repoContext: include repo or workspace when user references real project or prior workspace\",\n \" parallelism: use multiple agents only for separable subtasks\",\n \" statusQuestions: use provider.active_workspace_context or TASK_HISTORY\",\n \" controlRequests: use TASK_CONTROL\",\n \" shareRequests: use TASK_SHARE\",\n ].join(\"\\n\");\n\n return {\n data: {\n preferredTaskAgent: frameworkState.preferred.id,\n frameworks,\n },\n values: { taskAgentExamples: detailedText },\n text: detailedText,\n };\n } catch {\n return { text: \"\", values: {}, data: {} };\n }\n },\n};\n\nexport const taskAgentExamplesProvider = codingAgentExamplesProvider;\n",
|
|
62
|
+
"import type { IAgentRuntime, Memory, Provider, State } from \"@elizaos/core\";\nimport { getAcpService } from \"../actions/common.js\";\nimport type { SessionInfo } from \"../services/types.js\";\n\nconst TERMINAL_STATUSES = new Set([\n \"stopped\",\n \"completed\",\n \"error\",\n \"errored\",\n \"cancelled\",\n]);\n\n// Transient statuses that bucket together as \"active\" for the planner-visible\n// view. We do NOT distinguish ready vs busy vs tool_running vs running vs\n// authenticating because that distinction would invalidate the cached\n// provider segment on every tool call. The planner only needs to know:\n// \"is this session active and addressable, or is it blocked-and-waiting\".\nconst ACTIVE_STATUS_BUCKET = new Set([\n \"ready\",\n \"running\",\n \"busy\",\n \"tool_running\",\n \"authenticating\",\n]);\n\nfunction bucketStatus(status: string): string {\n if (ACTIVE_STATUS_BUCKET.has(status)) return \"active\";\n if (status === \"blocked\") return \"blocked\";\n return status;\n}\n\nconst PROVIDER_NAME = \"ACTIVE_SUB_AGENTS\";\n\n/**\n * Stable view of active ACPX sub-agent sessions, sorted by sessionId so the\n * provider text is deterministic across turns. Only sessions that carry\n * origin metadata (i.e. were spawned by CREATE_TASK with a roomId/userId\n * to route back to) are included — these are the sessions the SubAgentRouter\n * will post messages from.\n *\n * Cache strategy: text contains structural state only (id, label, agentType,\n * status, workdir-tail). Live message content is delivered via the synthetic\n * Memory the router posts, NOT through this provider, so prefix cache hits\n * stay high turn-over-turn.\n */\nexport const activeSubAgentsProvider: Provider = {\n name: PROVIDER_NAME,\n description:\n \"Active ACPX sub-agent sessions the main agent can reply to via SEND_TO_AGENT or terminate via STOP_AGENT.\",\n dynamic: true,\n position: 0,\n relevanceKeywords: [\n \"sub-agent\",\n \"sub agent\",\n \"subagent\",\n \"task agent\",\n \"coding agent\",\n \"acpx\",\n ],\n get: async (runtime: IAgentRuntime, _message: Memory, _state: State) => {\n const service = getAcpService(runtime);\n if (!service || typeof service.listSessions !== \"function\") {\n return emptyResult();\n }\n const all = await Promise.resolve(service.listSessions()).catch(\n () => [] as SessionInfo[],\n );\n const routed = (Array.isArray(all) ? all : [])\n .filter(hasOrigin)\n .filter((s) => !TERMINAL_STATUSES.has(s.status));\n if (routed.length === 0) return emptyResult();\n\n routed.sort((a, b) => a.id.localeCompare(b.id));\n\n const lines = [\n \"## Active sub-agent sessions\",\n \"Each line is a live sub-agent. Reply to one with SEND_TO_AGENT { sessionId, text }; terminate with STOP_AGENT { sessionId }. Replying to the user uses the standard REPLY action; you may do both in one turn.\",\n ];\n for (const session of routed) {\n lines.push(formatLine(session));\n }\n const text = lines.join(\"\\n\");\n\n return {\n text,\n values: { activeSubAgents: text },\n data: {\n sessions: routed.map((s) => ({\n sessionId: s.id,\n label: labelOf(s),\n agentType: s.agentType,\n status: s.status,\n workdirTail: workdirTail(s.workdir),\n originRoomId: (s.metadata as Record<string, unknown> | undefined)\n ?.roomId,\n originUserId: (s.metadata as Record<string, unknown> | undefined)\n ?.userId,\n })),\n },\n };\n },\n};\n\nfunction emptyResult() {\n return {\n text: \"\",\n values: { activeSubAgents: \"\" },\n data: { sessions: [] },\n };\n}\n\nfunction hasOrigin(session: SessionInfo): boolean {\n const meta = session.metadata as Record<string, unknown> | undefined;\n if (!meta) return false;\n const roomId = meta.roomId;\n return typeof roomId === \"string\" && roomId.length > 0;\n}\n\nfunction formatLine(session: SessionInfo): string {\n const label = labelOf(session);\n const tail = workdirTail(session.workdir);\n const bucket = bucketStatus(session.status);\n return `- [${label}] sessionId=${session.id} agentType=${session.agentType} status=${bucket} workdir=…${tail}`;\n}\n\nfunction labelOf(session: SessionInfo): string {\n const meta = session.metadata as Record<string, unknown> | undefined;\n if (meta && typeof meta.label === \"string\" && meta.label.trim()) {\n return meta.label;\n }\n return session.name || session.id;\n}\n\nfunction workdirTail(workdir: string): string {\n if (!workdir) return \"\";\n const parts = workdir.split(\"/\").filter(Boolean);\n return parts.slice(-2).join(\"/\");\n}\n",
|
|
63
|
+
"import type { IAgentRuntime, Memory, Provider, State } from \"@elizaos/core\";\nimport {\n getAcpService,\n labelFor,\n listSessionsWithin,\n shortId,\n} from \"../actions/common.js\";\n\nexport const availableAgentsProvider: Provider = {\n name: \"AVAILABLE_AGENTS\",\n description:\n \"Live status of available acpx task-agent adapters and active sessions.\",\n dynamic: true,\n position: 1,\n relevanceKeywords: [\"agent\", \"task\", \"coding\", \"session\", \"acp\"],\n get: async (runtime: IAgentRuntime, _message: Memory, _state: State) => {\n const service = getAcpService(runtime);\n if (!service) {\n const text =\n \"# acpx task agents\\n@elizaos/plugin-agent-orchestrator task-agent service is not available.\";\n return {\n text,\n values: { availableAgents: text },\n data: { agents: [], activeSessions: [], serviceAvailable: false },\n };\n }\n\n const [agents, sessions] = await Promise.all([\n service.checkAvailableAgents?.() ??\n service.getAvailableAgents?.() ??\n Promise.resolve([]),\n listSessionsWithin(service, 2000),\n ]);\n\n const lines = [\"# acpx task agents\"];\n if (agents.length > 0) {\n lines.push(\"\", \"## Available adapters\");\n for (const agent of agents) {\n const auth = agent.auth?.status ? `, auth: ${agent.auth.status}` : \"\";\n lines.push(\n `- ${agent.agentType ?? agent.adapter}: ${agent.installed ? \"installed\" : \"not installed\"}${auth}`,\n );\n }\n } else {\n lines.push(\n \"No adapter inventory available. Defaulting to acpx runtime selection.\",\n );\n }\n\n if (sessions.length > 0) {\n lines.push(\"\", `## Active sessions (${sessions.length})`);\n for (const session of sessions) {\n lines.push(\n `- ${labelFor(session)} [${shortId(session.id)}] ${session.agentType} ${session.status} in ${session.workdir}`,\n );\n }\n } else {\n lines.push(\"\", \"No active task-agent sessions.\");\n }\n\n const text = lines.join(\"\\n\");\n return {\n text,\n values: { availableAgents: text },\n data: {\n agents,\n activeSessions: sessions.map((session) => ({\n id: session.id,\n label: labelFor(session),\n agentType: session.agentType,\n status: session.status,\n workdir: session.workdir,\n })),\n serviceAvailable: true,\n },\n };\n },\n};\n\nexport const acpAvailableAgentsProvider = availableAgentsProvider;\n",
|
|
64
|
+
"import { type ChildProcessWithoutNullStreams, spawn } from \"node:child_process\";\nimport { randomUUID } from \"node:crypto\";\nimport { mkdir } from \"node:fs/promises\";\nimport { tmpdir } from \"node:os\";\nimport { join, resolve } from \"node:path\";\nimport type { IAgentRuntime } from \"@elizaos/core\";\nimport {\n AcpSessionStore,\n InMemorySessionStore,\n type SessionStoreBackend,\n} from \"./session-store.js\";\nimport type {\n AcpEventCallback,\n AcpJsonRpcMessage,\n AcpToolCall,\n AgentType,\n ApprovalPreset,\n AvailableAgentInfo,\n PromptResult,\n SendOptions,\n SessionEventCallback,\n SessionEventName,\n SessionInfo,\n SessionStore,\n SpawnOptions,\n SpawnResult,\n} from \"./types.js\";\n\ntype RuntimeLike = IAgentRuntime & {\n logger?: Partial<\n Record<\n \"debug\" | \"info\" | \"warn\" | \"error\",\n (message: string, data?: unknown) => void\n >\n >;\n services?: Map<string, unknown[]>;\n databaseAdapter?: unknown;\n getSetting?: (key: string) => string | undefined | null;\n};\ntype RuntimeLogger = NonNullable<RuntimeLike[\"logger\"]>;\ntype ProcessRecord = {\n proc: ChildProcessWithoutNullStreams;\n stderr: string;\n stdoutBuffer: string;\n killedByService: boolean;\n cancelled: boolean;\n exited: boolean;\n killTimer?: ReturnType<typeof setTimeout>;\n};\n\ntype RunOptions = {\n sessionId?: string;\n sessionName?: string;\n agentType: AgentType;\n workdir: string;\n args: string[];\n env?: Record<string, string | undefined>;\n promptPreview?: string;\n promptLength?: number;\n timeoutMs?: number;\n activeForSession?: boolean;\n};\n\ntype RunResult = {\n code: number | null;\n signal: NodeJS.Signals | null;\n stderr: string;\n finalText: string;\n stopReason?: string;\n cancelled?: boolean;\n durationMs: number;\n};\n\nconst STDERR_CAP_BYTES = 64 * 1024;\nconst KILL_GRACE_MS = 5_000;\nconst DEFAULT_WORKDIR_ROOT = join(tmpdir(), \"eliza-acp\");\nconst DEFAULT_AGENTS = [\"codex\", \"claude\", \"gemini\", \"aider\", \"pi\"];\nconst DENY_ENV_PATTERNS = [\n /DISCORD.*TOKEN/i,\n /TELEGRAM.*TOKEN/i,\n /SLACK.*TOKEN/i,\n /BOT.*TOKEN/i,\n /MILADY_VAULT_PASSPHRASE/i,\n];\n\nexport class AcpService {\n static serviceType = \"ACP_SUBPROCESS_SERVICE\";\n\n capabilityDescription =\n \"Manages asynchronous ACPX task-agent sessions for open-ended background work\";\n\n readonly defaultApprovalPreset: ApprovalPreset;\n readonly agentSelectionStrategy: string;\n\n private readonly runtime: RuntimeLike;\n private readonly logger: RuntimeLogger;\n private readonly store: SessionStore;\n private readonly cliPath: string;\n private readonly defaultAgent: AgentType;\n private readonly maxSessions: number;\n private readonly sessionTimeoutMs?: number;\n private readonly sessionCallbacks: SessionEventCallback[] = [];\n private readonly acpCallbacks: AcpEventCallback[] = [];\n private readonly activeProcesses = new Map<string, ProcessRecord>();\n private readonly outputBuffers = new Map<string, string[]>();\n private started = false;\n\n constructor(runtime: IAgentRuntime, opts: { store?: SessionStore } = {}) {\n this.runtime = runtime as RuntimeLike;\n this.logger = (this.runtime.logger ?? {}) as RuntimeLogger;\n this.store = opts.store ?? new InMemorySessionStore();\n this.cliPath = this.setting(\"ELIZA_ACP_CLI\") ?? \"acpx\";\n this.defaultAgent = this.setting(\"ELIZA_ACP_DEFAULT_AGENT\") ?? \"codex\";\n this.defaultApprovalPreset = normalizeApprovalPreset(\n boolSetting(this.setting(\"ACPX_APPROVE_ALL\")) === true\n ? \"approve-all\"\n : this.setting(\"ELIZA_ACP_DEFAULT_APPROVAL\"),\n );\n this.agentSelectionStrategy =\n this.setting(\"ELIZA_ACP_AGENT_SELECTION_STRATEGY\") ?? \"fixed\";\n this.maxSessions =\n parsePositiveInt(this.setting(\"ELIZA_ACP_MAX_SESSIONS\")) ?? 8;\n this.sessionTimeoutMs = parsePositiveInt(\n this.setting(\"ACPX_DEFAULT_TIMEOUT_MS\") ??\n this.setting(\"ELIZA_ACP_PROMPT_TIMEOUT_MS\"),\n );\n }\n\n static async start(runtime: IAgentRuntime): Promise<AcpService> {\n const service = new AcpService(runtime, {\n store: createDefaultSessionStore(runtime as RuntimeLike),\n });\n await service.start();\n return service;\n }\n\n async start(): Promise<void> {\n this.started = true;\n this.log(\"debug\", \"AcpService initialized\", {\n cliPath: this.cliPath,\n defaultAgent: this.defaultAgent,\n defaultApprovalPreset: this.defaultApprovalPreset,\n });\n }\n\n async stop(): Promise<void> {\n const stops = Array.from(this.activeProcesses.keys()).map((sessionId) =>\n this.stopTrackedProcess(sessionId),\n );\n await Promise.allSettled(stops);\n this.started = false;\n }\n\n async spawnSession(opts: SpawnOptions): Promise<SpawnResult> {\n this.ensureStarted();\n const id = randomUUID();\n const name = opts.name?.trim() || id;\n const agentType = opts.agentType ?? this.defaultAgent;\n const approvalPreset = opts.approvalPreset ?? this.defaultApprovalPreset;\n const workdir = resolve(\n opts.workdir ??\n this.setting(\"ELIZA_ACP_WORKSPACE_ROOT\") ??\n this.setting(\"ACPX_DEFAULT_CWD\") ??\n DEFAULT_WORKDIR_ROOT,\n );\n await mkdir(workdir, { recursive: true });\n await this.enforceSessionLimit();\n\n const now = new Date();\n const session: SessionInfo = {\n id,\n name,\n agentType,\n workdir,\n status: \"running\",\n approvalPreset,\n createdAt: now,\n lastActivityAt: now,\n metadata: opts.metadata,\n };\n await this.store.create(session);\n\n const args = this.baseArgs({\n workdir,\n approvalPreset,\n timeoutMs: opts.timeoutMs,\n model: opts.model,\n });\n args.push(agentType, \"sessions\", \"new\", \"--name\", name);\n const result = await this.runAcpx({\n sessionId: id,\n sessionName: name,\n agentType,\n workdir,\n args,\n env: this.buildEnv(\n opts.env,\n opts.customCredentials,\n opts.model,\n agentType,\n ),\n });\n\n if (result.code !== 0) {\n const message = this.classifyExitError(result.code, result.stderr);\n await this.store.updateStatus(id, \"errored\", message);\n this.emitSessionEvent(id, \"error\", {\n message,\n exitCode: result.code,\n stderr: result.stderr,\n });\n throw new Error(message);\n }\n\n const readyPatch: Partial<SessionInfo> = {\n status: \"ready\",\n pid: undefined,\n lastActivityAt: new Date(),\n };\n await this.store.update(id, readyPatch);\n this.emitSessionEvent(id, \"ready\", {\n sessionId: id,\n name,\n agentType,\n workdir,\n });\n\n if (opts.initialTask?.trim()) {\n void this.sendPrompt(id, opts.initialTask, {\n timeoutMs: opts.timeoutMs,\n model: opts.model,\n }).catch((err: unknown) => {\n this.log(\"error\", \"initial prompt failed\", {\n sessionId: id,\n agentType,\n promptLength: opts.initialTask?.length ?? 0,\n promptPreview: preview(opts.initialTask ?? \"\"),\n error: errorMessage(err),\n });\n });\n }\n\n const updated = await this.store.get(id);\n const sessionSnapshot: SessionInfo = { ...session, status: \"ready\" };\n return toSpawnResult(updated ?? sessionSnapshot);\n }\n\n async sendPrompt(\n sessionId: string,\n text: string,\n opts: SendOptions = {},\n ): Promise<PromptResult> {\n this.ensureStarted();\n const session = await this.requireSession(sessionId);\n const startedAt = Date.now();\n await this.store.updateStatus(sessionId, \"busy\");\n const args = this.baseArgs({\n workdir: session.workdir,\n approvalPreset: session.approvalPreset,\n timeoutMs: opts.timeoutMs ?? this.sessionTimeoutMs,\n model: opts.model,\n });\n args.push(\n session.agentType,\n \"prompt\",\n \"-s\",\n session.name ?? session.id,\n text,\n );\n\n const result = await this.runAcpx({\n sessionId,\n sessionName: session.name ?? session.id,\n agentType: session.agentType,\n workdir: session.workdir,\n args,\n env: this.buildEnv(opts.env, undefined, opts.model, session.agentType),\n promptPreview: preview(text),\n promptLength: text.length,\n timeoutMs: opts.timeoutMs,\n activeForSession: true,\n });\n\n const stopReason =\n result.stopReason ??\n (result.cancelled\n ? \"cancelled\"\n : result.code === 0\n ? \"end_turn\"\n : \"error\");\n const promptResult: PromptResult = {\n sessionId,\n response: result.finalText,\n finalText: result.finalText,\n stopReason,\n durationMs: result.durationMs || Date.now() - startedAt,\n exitCode: result.code,\n signal: result.signal,\n ...(result.code !== 0 && !result.cancelled\n ? { error: this.classifyExitError(result.code, result.stderr) }\n : {}),\n };\n\n if (result.cancelled || stopReason === \"cancelled\") {\n await this.store.updateStatus(sessionId, \"cancelled\");\n return promptResult;\n }\n\n if (result.code === 0 && stopReason !== \"error\") {\n await this.store.update(sessionId, {\n status: \"ready\",\n lastActivityAt: new Date(),\n });\n return promptResult;\n }\n\n const message =\n promptResult.error ?? `acpx prompt failed with stopReason ${stopReason}`;\n await this.store.updateStatus(sessionId, \"errored\", message);\n this.emitSessionEvent(sessionId, \"error\", {\n message,\n stopReason,\n failureKind: isAuthText(result.stderr) ? \"auth\" : undefined,\n });\n return promptResult;\n }\n\n async cancelSession(sessionId: string): Promise<void> {\n const session = await this.requireSession(sessionId);\n const active = this.activeProcesses.get(sessionId);\n if (active) {\n active.cancelled = true;\n this.terminateProcess(sessionId, active);\n } else {\n const args = [\n session.agentType,\n \"cancel\",\n \"-s\",\n session.name ?? session.id,\n ];\n await this.runAcpx({\n sessionId,\n agentType: session.agentType,\n workdir: session.workdir,\n args,\n });\n }\n await this.store.updateStatus(sessionId, \"cancelled\");\n }\n\n async closeSession(sessionId: string): Promise<void> {\n const session = await this.requireSession(sessionId);\n await this.stopTrackedProcess(sessionId);\n const args = [\n \"--format\",\n \"json\",\n \"--cwd\",\n session.workdir,\n session.agentType,\n \"sessions\",\n \"close\",\n session.name ?? session.id,\n ];\n await this.runAcpx({\n sessionId,\n agentType: session.agentType,\n workdir: session.workdir,\n args,\n });\n await this.store.updateStatus(sessionId, \"stopped\");\n this.emitSessionEvent(sessionId, \"stopped\", {\n sessionId,\n response: this.lastOutput(sessionId),\n });\n }\n\n async deleteSession(sessionId: string): Promise<void> {\n await this.closeSession(sessionId).catch((err: unknown) => {\n this.log(\"warn\", \"deleteSession close failed\", {\n sessionId,\n error: errorMessage(err),\n });\n });\n await this.store.delete(sessionId);\n this.outputBuffers.delete(sessionId);\n }\n\n async listSessions(): Promise<SessionInfo[]> {\n return this.store.list();\n }\n\n async getSession(sessionId: string): Promise<SessionInfo | undefined> {\n const session = await this.store.get(sessionId);\n return session ?? undefined;\n }\n\n onSessionEvent(handler: SessionEventCallback): () => void {\n this.sessionCallbacks.push(handler);\n return () => {\n const index = this.sessionCallbacks.indexOf(handler);\n if (index >= 0) this.sessionCallbacks.splice(index, 1);\n };\n }\n\n onAcpEvent(handler: AcpEventCallback): () => void {\n this.acpCallbacks.push(handler);\n return () => {\n const index = this.acpCallbacks.indexOf(handler);\n if (index >= 0) this.acpCallbacks.splice(index, 1);\n };\n }\n\n async reattachSession(sessionId: string): Promise<SpawnResult> {\n const session = await this.requireSession(sessionId);\n if (session.pid && isPidAlive(session.pid)) {\n await this.store.updateStatus(sessionId, \"ready\");\n return toSpawnResult({ ...session, status: \"ready\" });\n }\n const respawn = await this.spawnSession({\n name: session.name ?? session.id,\n agentType: session.agentType,\n workdir: session.workdir,\n approvalPreset: session.approvalPreset,\n metadata: { ...session.metadata, reattachedFrom: session.id },\n });\n await this.store.update(sessionId, {\n status: \"stopped\",\n lastActivityAt: new Date(),\n });\n this.emitSessionEvent(respawn.sessionId, \"reconnected\", {\n previousSessionId: sessionId,\n });\n return respawn;\n }\n\n async getAvailableAgents(): Promise<AvailableAgentInfo[]> {\n return DEFAULT_AGENTS.map((agentType) => ({\n adapter: agentType,\n agentType,\n installed: true,\n auth: { status: \"unknown\" },\n }));\n }\n\n async checkAvailableAgents(types?: string[]): Promise<AvailableAgentInfo[]> {\n const available = await this.getAvailableAgents();\n return types?.length\n ? available.filter((a) => types.includes(String(a.agentType)))\n : available;\n }\n\n async resolveAgentType(): Promise<string> {\n return String(this.defaultAgent);\n }\n\n async sendToSession(sessionId: string, input: string): Promise<PromptResult> {\n return this.sendPrompt(sessionId, input);\n }\n\n async sendKeysToSession(sessionId: string): Promise<void> {\n await this.requireSession(sessionId);\n throw new Error(\"ACP sessions do not support raw key input.\");\n }\n\n async stopSession(sessionId: string): Promise<void> {\n await this.closeSession(sessionId);\n }\n\n subscribeToOutput(\n sessionId: string,\n callback: (data: string) => void,\n ): () => void {\n for (const line of this.outputBuffers.get(sessionId) ?? []) callback(line);\n return () => undefined;\n }\n\n async getSessionOutput(sessionId: string, lines = 200): Promise<string> {\n return (this.outputBuffers.get(sessionId) ?? []).slice(-lines).join(\"\");\n }\n\n private baseArgs(opts: {\n workdir: string;\n approvalPreset: ApprovalPreset;\n timeoutMs?: number;\n model?: string;\n }): string[] {\n const format = this.setting(\"ACPX_FORMAT\") ?? \"json\";\n const args = [\n \"--format\",\n format,\n \"--cwd\",\n opts.workdir,\n ...approvalArgs(opts.approvalPreset),\n ];\n if (boolSetting(this.setting(\"ACPX_NO_TERMINAL\")) !== false)\n args.push(\"--no-terminal\");\n const timeoutMs = opts.timeoutMs ?? this.sessionTimeoutMs;\n if (timeoutMs && timeoutMs > 0)\n args.push(\"--timeout\", String(timeoutMs / 1000));\n if (opts.model) args.push(\"--model\", opts.model);\n return args;\n }\n\n private runAcpx(opts: RunOptions): Promise<RunResult> {\n const startedAt = Date.now();\n let finalText = \"\";\n let stopReason: string | undefined;\n return new Promise((resolveRun) => {\n const proc = spawn(this.cliPath, opts.args, {\n cwd: opts.workdir,\n env: this.buildEnv(opts.env),\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n });\n const record: ProcessRecord = {\n proc,\n stderr: \"\",\n stdoutBuffer: \"\",\n killedByService: false,\n cancelled: false,\n exited: false,\n };\n if (opts.activeForSession && opts.sessionId)\n this.activeProcesses.set(opts.sessionId, record);\n\n proc.stdout.on(\"data\", (chunk: Buffer) => {\n record.stdoutBuffer += chunk.toString(\"utf8\");\n let newlineIndex = record.stdoutBuffer.indexOf(\"\\n\");\n while (newlineIndex >= 0) {\n const line = record.stdoutBuffer.slice(0, newlineIndex).trim();\n record.stdoutBuffer = record.stdoutBuffer.slice(newlineIndex + 1);\n if (line) {\n const parsed = this.parseNdjson(line, opts.sessionId);\n if (parsed) {\n const handled = this.handleAcpEvent(\n parsed,\n opts.sessionId,\n finalText,\n startedAt,\n );\n finalText = handled.finalText;\n stopReason = handled.stopReason ?? stopReason;\n }\n }\n newlineIndex = record.stdoutBuffer.indexOf(\"\\n\");\n }\n });\n\n proc.stderr.on(\"data\", (chunk: Buffer) => {\n record.stderr = capStderr(record.stderr + chunk.toString(\"utf8\"));\n });\n\n proc.on(\"error\", (err: NodeJS.ErrnoException) => {\n record.stderr = capStderr(record.stderr + errorMessage(err));\n if (err.code === \"ENOENT\") {\n const message = `acpx CLI not found at ${this.cliPath}. Set ELIZA_ACP_CLI or npm install -g acpx@latest.`;\n record.stderr = capStderr(`${record.stderr}\\n${message}`);\n if (opts.sessionId)\n this.emitSessionEvent(opts.sessionId, \"error\", {\n message,\n failureKind: \"not_found\",\n });\n }\n });\n\n proc.on(\"close\", (code, signal) => {\n record.exited = true;\n if (record.stdoutBuffer.trim()) {\n const parsed = this.parseNdjson(\n record.stdoutBuffer.trim(),\n opts.sessionId,\n );\n if (parsed) {\n const handled = this.handleAcpEvent(\n parsed,\n opts.sessionId,\n finalText,\n startedAt,\n );\n finalText = handled.finalText;\n stopReason = handled.stopReason ?? stopReason;\n }\n }\n if (\n opts.sessionId &&\n this.activeProcesses.get(opts.sessionId) === record\n ) {\n this.activeProcesses.delete(opts.sessionId);\n }\n if (record.killTimer) clearTimeout(record.killTimer);\n if (\n opts.sessionId &&\n !record.cancelled &&\n code !== 0 &&\n isAuthText(record.stderr)\n ) {\n this.emitSessionEvent(opts.sessionId, \"error\", {\n message: this.classifyExitError(code, record.stderr),\n failureKind: \"auth\",\n });\n }\n if (opts.sessionId && opts.activeForSession) {\n const event = record.cancelled ? \"cancelled\" : \"stopped\";\n this.emitSessionEvent(opts.sessionId, event, {\n sessionId: opts.sessionId,\n response: finalText,\n exitCode: code,\n signal,\n });\n }\n resolveRun({\n code,\n signal,\n stderr: record.stderr,\n finalText,\n stopReason: record.cancelled ? \"cancelled\" : stopReason,\n cancelled: record.cancelled,\n durationMs: Date.now() - startedAt,\n });\n });\n\n if (opts.timeoutMs && opts.timeoutMs > 0) {\n setTimeout(() => {\n if (!proc.killed) this.terminateProcess(opts.sessionId ?? \"\", record);\n }, opts.timeoutMs).unref?.();\n }\n });\n }\n\n private parseNdjson(\n line: string,\n sessionId?: string,\n ): AcpJsonRpcMessage | null {\n try {\n return JSON.parse(line) as AcpJsonRpcMessage;\n } catch {\n this.log(\"warn\", \"malformed acpx NDJSON line ignored\", {\n sessionId,\n line: line.slice(0, 200),\n });\n return null;\n }\n }\n\n private handleAcpEvent(\n event: AcpJsonRpcMessage,\n localSessionId: string | undefined,\n currentFinalText: string,\n startedAt: number,\n ): { finalText: string; stopReason?: string } {\n const protocolSessionId = extractSessionId(event);\n const sessionId = localSessionId ?? protocolSessionId;\n if (\n localSessionId &&\n protocolSessionId &&\n protocolSessionId !== localSessionId\n ) {\n void this.store\n .update(localSessionId, { acpxSessionId: protocolSessionId })\n .catch(() => undefined);\n }\n for (const callback of this.acpCallbacks) callback(event, sessionId);\n const method = typeof event.method === \"string\" ? event.method : undefined;\n const params = asRecord(event.params);\n const result = asRecord(event.result);\n let finalText = currentFinalText;\n let stopReason: string | undefined;\n\n // Real ACP wraps session/update payload under params.update.{sessionUpdate,...}\n // Some adapters put fields at params.* directly. Look in both places.\n const updateBlock = asRecord(params?.update) ?? params;\n const sessionUpdate = updateBlock?.sessionUpdate ?? params?.sessionUpdate;\n\n if (\n sessionId &&\n (method === \"session_started\" || sessionUpdate === \"session_started\")\n ) {\n this.emitSessionEvent(sessionId, \"ready\", { event });\n }\n\n if (sessionId && method === \"permission/request\") {\n const description = stringifyMaybe(\n params?.description ?? params?.message ?? \"permission required\",\n );\n this.emitSessionEvent(sessionId, \"blocked\", {\n message: description,\n request: params,\n });\n if (isAuthText(description))\n this.emitSessionEvent(sessionId, \"login_required\", {\n message: description,\n request: params,\n });\n void this.store.updateStatus(sessionId, \"blocked\").catch(() => undefined);\n }\n\n if (sessionId && method === \"session/update\") {\n // agent_message_chunk: content.text streams\n const content = asRecord(updateBlock?.content);\n if (\n sessionUpdate === \"agent_message_chunk\" &&\n content?.type === \"text\" &&\n typeof content.text === \"string\"\n ) {\n finalText += content.text;\n this.appendOutput(sessionId, content.text);\n this.emitSessionEvent(sessionId, \"message\", { text: content.text });\n }\n // Some adapters put text directly at content level.\n else if (\n !sessionUpdate &&\n content?.type === \"text\" &&\n typeof content.text === \"string\"\n ) {\n finalText += content.text;\n this.appendOutput(sessionId, content.text);\n this.emitSessionEvent(sessionId, \"message\", { text: content.text });\n }\n // tool_call: emit tool_running while in_progress; ignore in_progress -> failed/completed transitions don't need re-emit\n if (\n sessionUpdate === \"tool_call\" ||\n sessionUpdate === \"tool_call_update\"\n ) {\n const status = stringifyMaybe(updateBlock?.status);\n const toolCall: AcpToolCall = {\n id: stringifyMaybe(updateBlock?.toolCallId ?? updateBlock?.id) ?? \"\",\n title: stringifyMaybe(updateBlock?.title) ?? \"\",\n status: (status as AcpToolCall[\"status\"]) ?? \"running\",\n output: stringifyMaybe(updateBlock?.rawOutput),\n };\n if (status === \"in_progress\" || status === \"running\") {\n this.emitSessionEvent(sessionId, \"tool_running\", { toolCall });\n void this.store\n .updateStatus(sessionId, \"tool_running\")\n .catch(() => undefined);\n }\n }\n // usage_update is informational; we don't currently surface it but could log\n // available_commands_update is metadata; ignore for now\n }\n\n if (sessionId && result && typeof result.stopReason === \"string\") {\n stopReason = result.stopReason;\n if (stopReason === \"end_turn\") {\n this.emitSessionEvent(sessionId, \"task_complete\", {\n response: finalText,\n durationMs: Date.now() - startedAt,\n stopReason,\n });\n } else if (stopReason === \"error\") {\n this.emitSessionEvent(sessionId, \"error\", {\n message: \"acpx prompt ended with stopReason error\",\n stopReason,\n });\n }\n }\n\n if (sessionId && event.error && typeof event.error === \"object\") {\n const message = errorMessage(\n (event.error as { message?: unknown }).message ?? event.error,\n );\n this.emitSessionEvent(sessionId, \"error\", { message });\n }\n\n return { finalText, stopReason };\n }\n\n emitSessionEvent(\n sessionId: string,\n event: SessionEventName,\n data: unknown,\n ): void {\n for (const callback of [...this.sessionCallbacks]) {\n try {\n callback(sessionId, event, data);\n } catch (err) {\n this.log(\"warn\", \"session event callback failed\", {\n sessionId,\n event,\n error: errorMessage(err),\n });\n }\n }\n }\n\n private async requireSession(sessionId: string): Promise<SessionInfo> {\n const session = await this.store.get(sessionId);\n if (!session) throw new Error(`acpx session not found: ${sessionId}`);\n return session;\n }\n\n private async enforceSessionLimit(): Promise<void> {\n const sessions = await this.store.list();\n const active = sessions.filter(\n (s) =>\n ![\"stopped\", \"errored\", \"completed\", \"cancelled\"].includes(s.status),\n );\n if (active.length >= this.maxSessions)\n throw new Error(`acpx max session limit reached (${this.maxSessions})`);\n }\n\n private async stopTrackedProcess(sessionId: string): Promise<void> {\n const active = this.activeProcesses.get(sessionId);\n if (!active) return;\n this.terminateProcess(sessionId, active);\n await new Promise<void>((resolveStop) =>\n active.proc.once(\"close\", () => resolveStop()),\n );\n }\n\n private terminateProcess(_sessionId: string, record: ProcessRecord): void {\n record.killedByService = true;\n if (!record.exited) record.proc.kill(\"SIGTERM\");\n record.killTimer = setTimeout(() => {\n if (!record.exited) record.proc.kill(\"SIGKILL\");\n }, KILL_GRACE_MS);\n }\n\n private buildEnv(\n extra?: Record<string, string | undefined>,\n customCredentials?: Record<string, string | undefined>,\n model?: string,\n agentType?: AgentType,\n ): NodeJS.ProcessEnv {\n const env: NodeJS.ProcessEnv = {};\n for (const [key, value] of Object.entries(process.env)) {\n if (typeof value !== \"string\") continue;\n if (DENY_ENV_PATTERNS.some((pattern) => pattern.test(key))) continue;\n if (shouldForwardEnv(key)) env[key] = value;\n }\n for (const [key, value] of Object.entries(customCredentials ?? {})) {\n if (typeof value === \"string\") env[key] = value;\n }\n for (const [key, value] of Object.entries(extra ?? {})) {\n if (typeof value === \"string\") env[key] = value;\n }\n if (model) {\n env.OPENAI_MODEL = model;\n if (agentType === \"claude\") env.ANTHROPIC_MODEL = model;\n if (agentType === \"gemini\") env.GEMINI_MODEL = model;\n }\n return env;\n }\n\n private classifyExitError(code: number | null, stderr: string): string {\n if (code === 1 && isAuthText(stderr))\n return \"acpx auth failed. Re-authenticate the selected agent or set ACPX_AUTH_* credentials.\";\n if (code === 4)\n return \"acpx session was not found. This is likely an internal session bookkeeping error.\";\n if (code === 5) return \"acpx permission denied.\";\n if (code === 3) return \"acpx prompt timed out.\";\n if (stderr.trim()) return stderr.trim().slice(0, 500);\n return `acpx subprocess exited with code ${code ?? \"unknown\"}`;\n }\n\n private lastOutput(sessionId: string): string {\n return (this.outputBuffers.get(sessionId) ?? []).join(\"\");\n }\n\n private appendOutput(sessionId: string, text: string): void {\n const buffer = this.outputBuffers.get(sessionId) ?? [];\n buffer.push(text);\n if (buffer.length > 2_000) buffer.splice(0, buffer.length - 2_000);\n this.outputBuffers.set(sessionId, buffer);\n }\n\n private setting(key: string): string | undefined {\n const fromRuntime = this.runtime.getSetting?.(key);\n if (typeof fromRuntime === \"string\" && fromRuntime.length > 0)\n return fromRuntime;\n const fromEnv = process.env[key];\n return fromEnv && fromEnv.length > 0 ? fromEnv : undefined;\n }\n\n private ensureStarted(): void {\n if (!this.started) throw new Error(\"AcpService not started\");\n }\n\n private log(\n level: \"debug\" | \"info\" | \"warn\" | \"error\",\n message: string,\n data?: unknown,\n ): void {\n const loggerFn = this.logger[level] as\n | ((message: string, data?: unknown) => void)\n | undefined;\n loggerFn?.call(this.logger, `[AcpService] ${message}`, data);\n }\n}\n\nfunction approvalArgs(preset: ApprovalPreset): string[] {\n switch (preset) {\n case \"autonomous\":\n case \"permissive\":\n return [\"--approve-all\"];\n case \"readonly\":\n return [\"--deny-all\"];\n default:\n return [\"--approve-reads\", \"--non-interactive-permissions\", \"deny\"];\n }\n}\n\nfunction normalizeApprovalPreset(value: string | undefined): ApprovalPreset {\n const normalized = value?.trim().toLowerCase();\n if (\n normalized === \"readonly\" ||\n normalized === \"read-only\" ||\n normalized === \"deny-all\"\n )\n return \"readonly\";\n if (\n normalized === \"standard\" ||\n normalized === \"auto\" ||\n normalized === \"default\"\n )\n return \"standard\";\n if (\n normalized === \"permissive\" ||\n normalized === \"approve-all\" ||\n normalized === \"full-access\"\n )\n return \"permissive\";\n if (normalized === \"autonomous\") return \"autonomous\";\n return \"autonomous\";\n}\n\nfunction shouldForwardEnv(key: string): boolean {\n return (\n key === \"PATH\" ||\n key === \"HOME\" ||\n key === \"USER\" ||\n key === \"LANG\" ||\n key === \"LC_ALL\" ||\n key === \"LC_CTYPE\" ||\n key === \"TZ\" ||\n key === \"TERM\" ||\n key.startsWith(\"ACPX_AUTH_\") ||\n key.startsWith(\"ELIZA_\") ||\n key.startsWith(\"MILADY_\") ||\n [\n \"OPENAI_API_KEY\",\n \"ANTHROPIC_API_KEY\",\n \"GOOGLE_API_KEY\",\n \"GOOGLE_GENERATIVE_AI_API_KEY\",\n \"OPENAI_MODEL\",\n \"ANTHROPIC_MODEL\",\n \"GEMINI_MODEL\",\n \"CODEX_HOME\",\n ].includes(key)\n );\n}\n\nfunction extractSessionId(event: AcpJsonRpcMessage): string | undefined {\n const params = asRecord(event.params);\n const result = asRecord(event.result);\n const candidates = [\n params?.sessionId,\n params?.session_id,\n result?.sessionId,\n result?.acpxSessionId,\n (event as Record<string, unknown>).sessionId,\n ];\n return candidates.find(\n (candidate): candidate is string =>\n typeof candidate === \"string\" && candidate.length > 0,\n );\n}\n\nfunction asRecord(value: unknown): Record<string, unknown> | undefined {\n return value && typeof value === \"object\"\n ? (value as Record<string, unknown>)\n : undefined;\n}\n\nfunction stringifyMaybe(value: unknown): string {\n return typeof value === \"string\" ? value : JSON.stringify(value ?? \"\");\n}\n\nfunction isAuthText(text: string): boolean {\n return /authenticate|unauthorized|\\b401\\b|login|required auth|api key|invalid_grant/i.test(\n text,\n );\n}\n\nfunction capStderr(text: string): string {\n if (Buffer.byteLength(text, \"utf8\") <= STDERR_CAP_BYTES) return text;\n return text.slice(-STDERR_CAP_BYTES);\n}\n\nfunction preview(text: string): string {\n return text.replace(/\\s+/g, \" \").slice(0, 80);\n}\n\nfunction errorMessage(err: unknown): string {\n if (err instanceof Error) return err.message;\n if (typeof err === \"string\") return err;\n return JSON.stringify(err);\n}\n\nfunction parsePositiveInt(value: string | undefined): number | undefined {\n if (!value) return undefined;\n const parsed = Number.parseInt(value, 10);\n return Number.isFinite(parsed) && parsed > 0 ? parsed : undefined;\n}\n\nfunction boolSetting(value: string | undefined): boolean | undefined {\n if (value === undefined) return undefined;\n const normalized = value.trim().toLowerCase();\n if ([\"1\", \"true\", \"yes\", \"on\"].includes(normalized)) return true;\n if ([\"0\", \"false\", \"no\", \"off\"].includes(normalized)) return false;\n return undefined;\n}\n\nfunction createDefaultSessionStore(runtime: RuntimeLike): SessionStore {\n const runtimeForStore = {\n databaseAdapter: runtime.databaseAdapter,\n logger: runtime.logger,\n getSetting: (key: string) => {\n const value = runtime.getSetting?.(key);\n return typeof value === \"string\" ? value : undefined;\n },\n };\n return new AcpSessionStore({\n runtime: runtimeForStore,\n backend: parseSessionStoreBackend(\n runtimeForStore.getSetting(\"ELIZA_ACP_SESSION_STORE_BACKEND\") ??\n process.env.ELIZA_ACP_SESSION_STORE_BACKEND,\n ),\n });\n}\n\nfunction parseSessionStoreBackend(\n value: string | undefined | null,\n): SessionStoreBackend | undefined {\n const normalized = value?.trim().toLowerCase();\n if (\n normalized === \"runtime-db\" ||\n normalized === \"file\" ||\n normalized === \"memory\"\n ) {\n return normalized;\n }\n return undefined;\n}\n\nfunction isPidAlive(pid: number): boolean {\n try {\n process.kill(pid, 0);\n return true;\n } catch {\n return false;\n }\n}\n\nfunction toSpawnResult(session: SessionInfo): SpawnResult {\n return {\n sessionId: session.id,\n id: session.id,\n name: session.name ?? session.id,\n agentType: session.agentType,\n workdir: session.workdir,\n status: session.status,\n acpxRecordId: session.acpxRecordId,\n acpxSessionId: session.acpxSessionId,\n agentSessionId: session.agentSessionId,\n pid: session.pid,\n authReady: session.status !== \"errored\",\n metadata: session.metadata,\n };\n}\n",
|
|
65
|
+
"import { constants } from \"node:fs\";\nimport {\n access,\n mkdir,\n open,\n readFile,\n rename,\n rm,\n writeFile,\n} from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport type {\n SessionFilter,\n SessionInfo,\n SessionStatus,\n SessionStore,\n SessionStoreRuntime,\n} from \"./types.js\";\n\nexport type SessionStoreBackend = \"runtime-db\" | \"file\" | \"memory\";\n\ntype Logger = NonNullable<SessionStoreRuntime[\"logger\"]>;\n\ntype SqlDatabaseAdapter = {\n query?: (sql: string, params?: unknown[]) => Promise<unknown> | unknown;\n execute?: (sql: string, params?: unknown[]) => Promise<unknown> | unknown;\n run?: (sql: string, params?: unknown[]) => Promise<unknown> | unknown;\n all?: (sql: string, params?: unknown[]) => Promise<unknown[]> | unknown[];\n get?: (sql: string, params?: unknown[]) => Promise<unknown> | unknown;\n select?: (sql: string, params?: unknown[]) => Promise<unknown[]> | unknown[];\n};\n\ntype StoredSession = Omit<SessionInfo, \"createdAt\" | \"lastActivityAt\"> & {\n createdAt: string;\n lastActivityAt: string;\n};\n\nconst SESSION_TABLE_SQL = `CREATE TABLE IF NOT EXISTS acp_sessions (\n id TEXT PRIMARY KEY,\n name TEXT,\n agent_type TEXT NOT NULL,\n workdir TEXT NOT NULL,\n status TEXT NOT NULL,\n acpx_record_id TEXT,\n acpx_session_id TEXT,\n agent_session_id TEXT,\n pid INTEGER,\n approval_preset TEXT NOT NULL,\n created_at TEXT NOT NULL,\n last_activity_at TEXT NOT NULL,\n last_error TEXT,\n metadata TEXT\n)`;\n\nconst SESSION_INDEX_SQL = [\n \"CREATE INDEX IF NOT EXISTS idx_acp_sessions_scope ON acp_sessions(workdir, agent_type, name)\",\n \"CREATE INDEX IF NOT EXISTS idx_acp_sessions_status ON acp_sessions(status)\",\n \"CREATE INDEX IF NOT EXISTS idx_acp_sessions_acpx_record_id ON acp_sessions(acpx_record_id)\",\n];\n\nfunction cloneSession(session: SessionInfo): SessionInfo {\n return {\n ...session,\n createdAt: new Date(session.createdAt),\n lastActivityAt: new Date(session.lastActivityAt),\n metadata: session.metadata ? { ...session.metadata } : undefined,\n };\n}\n\nfunction toStoredSession(session: SessionInfo): StoredSession {\n return {\n ...session,\n createdAt: session.createdAt.toISOString(),\n lastActivityAt: session.lastActivityAt.toISOString(),\n metadata: session.metadata ? { ...session.metadata } : undefined,\n };\n}\n\nfunction fromStoredSession(session: StoredSession): SessionInfo {\n return {\n ...session,\n createdAt: new Date(session.createdAt),\n lastActivityAt: new Date(session.lastActivityAt),\n metadata: session.metadata ? { ...session.metadata } : undefined,\n };\n}\n\nfunction matchesFilter(session: SessionInfo, filter?: SessionFilter): boolean {\n if (!filter) return true;\n if (filter.status !== undefined && session.status !== filter.status)\n return false;\n if (\n filter.statuses !== undefined &&\n !filter.statuses.includes(session.status)\n )\n return false;\n if (filter.workdir !== undefined && session.workdir !== filter.workdir)\n return false;\n if (filter.agentType !== undefined && session.agentType !== filter.agentType)\n return false;\n if (filter.name !== undefined && session.name !== filter.name) return false;\n if (\n filter.acpxRecordId !== undefined &&\n session.acpxRecordId !== filter.acpxRecordId\n )\n return false;\n return true;\n}\n\nfunction defaultStateFile(): string {\n return join(homedir(), \".eliza\", \"plugin-acp\", \"sessions.json\");\n}\n\nfunction resolveStateFile(\n runtime?: SessionStoreRuntime,\n stateFile?: string,\n): string {\n if (stateFile) return stateFile;\n const configured =\n process.env.ELIZA_ACP_STATE_DIR ??\n runtime?.getSetting?.(\"ELIZA_ACP_STATE_DIR\");\n return configured ? join(configured, \"sessions.json\") : defaultStateFile();\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\nfunction isSqlDatabaseAdapter(value: unknown): value is SqlDatabaseAdapter {\n if (!isRecord(value)) return false;\n return [\"query\", \"execute\", \"run\", \"all\", \"get\", \"select\"].some(\n (method) => typeof value[method] === \"function\",\n );\n}\n\nfunction normalizeRows(result: unknown): unknown[] {\n if (Array.isArray(result)) return result;\n if (!isRecord(result)) return [];\n for (const key of [\"rows\", \"results\", \"data\", \"values\"]) {\n const value = result[key];\n if (Array.isArray(value)) return value;\n }\n return [];\n}\n\nfunction rowToSession(row: unknown): SessionInfo {\n if (!isRecord(row)) throw new Error(\"Invalid session row\");\n return {\n id: String(row.id),\n name:\n row.name === null || row.name === undefined\n ? undefined\n : String(row.name),\n agentType: String(row.agent_type),\n workdir: String(row.workdir),\n status: String(row.status),\n acpxRecordId:\n row.acpx_record_id === null || row.acpx_record_id === undefined\n ? undefined\n : String(row.acpx_record_id),\n acpxSessionId:\n row.acpx_session_id === null || row.acpx_session_id === undefined\n ? undefined\n : String(row.acpx_session_id),\n agentSessionId:\n row.agent_session_id === null || row.agent_session_id === undefined\n ? undefined\n : String(row.agent_session_id),\n pid:\n row.pid === null || row.pid === undefined ? undefined : Number(row.pid),\n approvalPreset: String(\n row.approval_preset,\n ) as SessionInfo[\"approvalPreset\"],\n createdAt: new Date(String(row.created_at)),\n lastActivityAt: new Date(String(row.last_activity_at)),\n lastError:\n row.last_error === null || row.last_error === undefined\n ? undefined\n : String(row.last_error),\n metadata:\n typeof row.metadata === \"string\" && row.metadata.length > 0\n ? JSON.parse(row.metadata)\n : undefined,\n };\n}\n\nfunction sessionToParams(session: SessionInfo): unknown[] {\n return [\n session.id,\n session.name ?? null,\n session.agentType,\n session.workdir,\n session.status,\n session.acpxRecordId ?? null,\n session.acpxSessionId ?? null,\n session.agentSessionId ?? null,\n session.pid ?? null,\n session.approvalPreset,\n session.createdAt.toISOString(),\n session.lastActivityAt.toISOString(),\n session.lastError ?? null,\n session.metadata ? JSON.stringify(session.metadata) : null,\n ];\n}\n\nclass WriteQueue {\n private tail = Promise.resolve();\n\n enqueue<T>(operation: () => Promise<T>): Promise<T> {\n const run = this.tail.then(operation, operation);\n this.tail = run.then(\n () => undefined,\n () => undefined,\n );\n return run;\n }\n}\n\nexport class InMemorySessionStore implements SessionStore {\n protected readonly sessions = new Map<string, SessionInfo>();\n protected readonly writes = new WriteQueue();\n\n async create(session: SessionInfo): Promise<void> {\n await this.writes.enqueue(async () => {\n this.sessions.set(session.id, cloneSession(session));\n await this.afterWrite();\n });\n }\n\n async get(id: string): Promise<SessionInfo | null> {\n return this.getSync(id);\n }\n\n getSync(id: string): SessionInfo | null {\n const session = this.sessions.get(id);\n return session ? cloneSession(session) : null;\n }\n\n async getByAcpxRecordId(recordId: string): Promise<SessionInfo | null> {\n for (const session of this.sessions.values()) {\n if (session.acpxRecordId === recordId) return cloneSession(session);\n }\n return null;\n }\n\n async findByScope(opts: {\n workdir: string;\n agentType: string;\n name?: string;\n }): Promise<SessionInfo | null> {\n for (const session of this.sessions.values()) {\n if (\n session.workdir === opts.workdir &&\n session.agentType === opts.agentType &&\n session.name === opts.name\n ) {\n return cloneSession(session);\n }\n }\n return null;\n }\n\n async list(filter?: SessionFilter): Promise<SessionInfo[]> {\n return this.listSync(filter);\n }\n\n listSync(filter?: SessionFilter): SessionInfo[] {\n return [...this.sessions.values()]\n .filter((session) => matchesFilter(session, filter))\n .map(cloneSession);\n }\n\n async update(id: string, patch: Partial<SessionInfo>): Promise<void> {\n await this.writes.enqueue(async () => {\n const current = this.sessions.get(id);\n if (!current) return;\n const next: SessionInfo = {\n ...current,\n ...patch,\n lastActivityAt: patch.lastActivityAt\n ? new Date(patch.lastActivityAt)\n : new Date(),\n createdAt: patch.createdAt\n ? new Date(patch.createdAt)\n : current.createdAt,\n metadata: patch.metadata\n ? { ...patch.metadata }\n : current.metadata\n ? { ...current.metadata }\n : undefined,\n };\n this.sessions.set(id, next);\n await this.afterWrite();\n });\n }\n\n async updateStatus(\n id: string,\n status: SessionStatus,\n error?: string,\n ): Promise<void> {\n const patch: Partial<SessionInfo> = { status };\n if (status === \"errored\") patch.lastError = error;\n await this.update(id, patch);\n }\n\n async delete(id: string): Promise<void> {\n await this.writes.enqueue(async () => {\n this.sessions.delete(id);\n await this.afterWrite();\n });\n }\n\n async sweepStale(maxAgeMs: number): Promise<string[]> {\n return this.writes.enqueue(async () => {\n const now = Date.now();\n const staleIds = [...this.sessions.values()]\n .filter(\n (session) =>\n (session.status === \"stopped\" || session.status === \"errored\") &&\n now - session.lastActivityAt.getTime() > maxAgeMs,\n )\n .map((session) => session.id);\n for (const id of staleIds) this.sessions.delete(id);\n if (staleIds.length > 0) await this.afterWrite();\n return staleIds;\n });\n }\n\n protected async afterWrite(): Promise<void> {\n // Implemented by durable subclasses.\n }\n}\n\nexport class FileSessionStore extends InMemorySessionStore {\n private readonly lockFile: string;\n private loaded = false;\n\n constructor(\n private readonly filePath = resolveStateFile(),\n private readonly logger?: Logger,\n ) {\n super();\n this.lockFile = `${filePath}.lock`;\n }\n\n async create(session: SessionInfo): Promise<void> {\n await this.load();\n await super.create(session);\n }\n\n async get(id: string): Promise<SessionInfo | null> {\n await this.load();\n return super.get(id);\n }\n\n async getByAcpxRecordId(recordId: string): Promise<SessionInfo | null> {\n await this.load();\n return super.getByAcpxRecordId(recordId);\n }\n\n async findByScope(opts: {\n workdir: string;\n agentType: string;\n name?: string;\n }): Promise<SessionInfo | null> {\n await this.load();\n return super.findByScope(opts);\n }\n\n async list(filter?: SessionFilter): Promise<SessionInfo[]> {\n await this.load();\n return super.list(filter);\n }\n\n async update(id: string, patch: Partial<SessionInfo>): Promise<void> {\n await this.load();\n await super.update(id, patch);\n }\n\n async delete(id: string): Promise<void> {\n await this.load();\n await super.delete(id);\n }\n\n async sweepStale(maxAgeMs: number): Promise<string[]> {\n await this.load();\n return super.sweepStale(maxAgeMs);\n }\n\n protected override async afterWrite(): Promise<void> {\n await this.withLock(async () => {\n await mkdir(dirname(this.filePath), { recursive: true });\n const tempPath = `${this.filePath}.${process.pid}.${Date.now()}.tmp`;\n const payload = JSON.stringify(\n [...this.sessions.values()].map(toStoredSession),\n null,\n 2,\n );\n await writeFile(tempPath, `${payload}\\n`, \"utf8\");\n await rename(tempPath, this.filePath);\n });\n }\n\n private async load(): Promise<void> {\n if (this.loaded) return;\n await this.writes.enqueue(async () => {\n if (this.loaded) return;\n try {\n const contents = await readFile(this.filePath, \"utf8\");\n const parsed = JSON.parse(contents) as unknown;\n if (!Array.isArray(parsed))\n throw new Error(\"Session store JSON must be an array\");\n this.sessions.clear();\n for (const raw of parsed) {\n if (!isRecord(raw)) continue;\n this.sessions.set(\n String(raw.id),\n fromStoredSession(raw as StoredSession),\n );\n }\n } catch (error) {\n const code =\n isRecord(error) && typeof error.code === \"string\"\n ? error.code\n : undefined;\n if (code !== \"ENOENT\") {\n this.logger?.warn?.(\n \"acpx SessionStore JSON could not be read; starting with an empty store\",\n error,\n );\n }\n this.sessions.clear();\n }\n this.loaded = true;\n });\n }\n\n private async withLock<T>(operation: () => Promise<T>): Promise<T> {\n await mkdir(dirname(this.lockFile), { recursive: true });\n const deadline = Date.now() + 5_000;\n let handle: Awaited<ReturnType<typeof open>> | undefined;\n while (!handle) {\n try {\n handle = await open(this.lockFile, \"wx\");\n } catch (error) {\n const code =\n isRecord(error) && typeof error.code === \"string\"\n ? error.code\n : undefined;\n if (code !== \"EEXIST\" || Date.now() > deadline) throw error;\n await new Promise((resolve) => setTimeout(resolve, 25));\n }\n }\n try {\n return await operation();\n } finally {\n await handle.close();\n await rm(this.lockFile, { force: true });\n }\n }\n}\n\nexport class RuntimeDbSessionStore implements SessionStore {\n private readonly writes = new WriteQueue();\n private initPromise: Promise<void> | undefined;\n\n constructor(\n private readonly adapter: SqlDatabaseAdapter,\n private readonly logger?: Logger,\n ) {\n void this.logger;\n }\n\n async create(session: SessionInfo): Promise<void> {\n await this.writes.enqueue(async () => {\n await this.ensureInitialized();\n await this.upsert(session);\n });\n }\n\n async get(id: string): Promise<SessionInfo | null> {\n await this.ensureInitialized();\n return this.getOne(\"SELECT * FROM acp_sessions WHERE id = ?\", [id]);\n }\n\n async getByAcpxRecordId(recordId: string): Promise<SessionInfo | null> {\n await this.ensureInitialized();\n return this.getOne(\"SELECT * FROM acp_sessions WHERE acpx_record_id = ?\", [\n recordId,\n ]);\n }\n\n async findByScope(opts: {\n workdir: string;\n agentType: string;\n name?: string;\n }): Promise<SessionInfo | null> {\n await this.ensureInitialized();\n if (opts.name === undefined) {\n return this.getOne(\n \"SELECT * FROM acp_sessions WHERE workdir = ? AND agent_type = ? AND name IS NULL ORDER BY created_at DESC LIMIT 1\",\n [opts.workdir, opts.agentType],\n );\n }\n return this.getOne(\n \"SELECT * FROM acp_sessions WHERE workdir = ? AND agent_type = ? AND name = ? ORDER BY created_at DESC LIMIT 1\",\n [opts.workdir, opts.agentType, opts.name],\n );\n }\n\n async list(filter?: SessionFilter): Promise<SessionInfo[]> {\n await this.ensureInitialized();\n const sessions = (await this.getMany(\"SELECT * FROM acp_sessions\", [])).map(\n cloneSession,\n );\n return sessions.filter((session) => matchesFilter(session, filter));\n }\n\n async update(id: string, patch: Partial<SessionInfo>): Promise<void> {\n await this.writes.enqueue(async () => {\n await this.ensureInitialized();\n const current = await this.getOne(\n \"SELECT * FROM acp_sessions WHERE id = ?\",\n [id],\n );\n if (!current) return;\n await this.upsert({\n ...current,\n ...patch,\n createdAt: patch.createdAt\n ? new Date(patch.createdAt)\n : current.createdAt,\n lastActivityAt: patch.lastActivityAt\n ? new Date(patch.lastActivityAt)\n : new Date(),\n metadata: patch.metadata ? { ...patch.metadata } : current.metadata,\n });\n });\n }\n\n async updateStatus(\n id: string,\n status: SessionStatus,\n error?: string,\n ): Promise<void> {\n const patch: Partial<SessionInfo> = { status };\n if (status === \"errored\") patch.lastError = error;\n await this.update(id, patch);\n }\n\n async delete(id: string): Promise<void> {\n await this.writes.enqueue(async () => {\n await this.ensureInitialized();\n await this.execute(\"DELETE FROM acp_sessions WHERE id = ?\", [id]);\n });\n }\n\n async sweepStale(maxAgeMs: number): Promise<string[]> {\n return this.writes.enqueue(async () => {\n await this.ensureInitialized();\n const cutoff = new Date(Date.now() - maxAgeMs).toISOString();\n const stale = await this.getMany(\n \"SELECT * FROM acp_sessions WHERE (status = ? OR status = ?) AND last_activity_at < ?\",\n [\"stopped\", \"errored\", cutoff],\n );\n for (const session of stale) {\n await this.execute(\"DELETE FROM acp_sessions WHERE id = ?\", [\n session.id,\n ]);\n }\n return stale.map((session) => session.id);\n });\n }\n\n private async ensureInitialized(): Promise<void> {\n this.initPromise ??= (async () => {\n await this.execute(SESSION_TABLE_SQL);\n for (const sql of SESSION_INDEX_SQL) await this.execute(sql);\n })();\n await this.initPromise;\n }\n\n private async upsert(session: SessionInfo): Promise<void> {\n await this.execute(\n `INSERT OR REPLACE INTO acp_sessions (\n id, name, agent_type, workdir, status, acpx_record_id, acpx_session_id, agent_session_id,\n pid, approval_preset, created_at, last_activity_at, last_error, metadata\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n sessionToParams(session),\n );\n }\n\n private async execute(sql: string, params: unknown[] = []): Promise<unknown> {\n const fn = this.adapter.execute ?? this.adapter.run ?? this.adapter.query;\n if (!fn)\n throw new Error(\n \"Runtime database adapter does not expose execute, run, or query\",\n );\n return fn.call(this.adapter, sql, params);\n }\n\n private async getMany(\n sql: string,\n params: unknown[],\n ): Promise<SessionInfo[]> {\n const fn = this.adapter.all ?? this.adapter.select ?? this.adapter.query;\n if (!fn)\n throw new Error(\n \"Runtime database adapter does not expose all, select, or query\",\n );\n const rows = normalizeRows(await fn.call(this.adapter, sql, params));\n return rows.map(rowToSession);\n }\n\n private async getOne(\n sql: string,\n params: unknown[],\n ): Promise<SessionInfo | null> {\n if (this.adapter.get) {\n const row = await this.adapter.get.call(this.adapter, sql, params);\n return row ? rowToSession(row) : null;\n }\n const [row] = await this.getMany(sql, params);\n return row ?? null;\n }\n}\n\nexport interface AcpSessionStoreOptions {\n runtime?: SessionStoreRuntime;\n stateFile?: string;\n backend?: SessionStoreBackend;\n}\n\nexport class AcpSessionStore implements SessionStore {\n readonly backend: SessionStoreBackend;\n private readonly delegate: SessionStore;\n\n constructor(options: AcpSessionStoreOptions = {}) {\n const adapter = options.runtime?.databaseAdapter;\n const logger = options.runtime?.logger;\n if (\n (options.backend === undefined || options.backend === \"runtime-db\") &&\n isSqlDatabaseAdapter(adapter)\n ) {\n this.backend = \"runtime-db\";\n this.delegate = new RuntimeDbSessionStore(adapter, logger);\n return;\n }\n\n if (options.backend === \"memory\") {\n this.backend = \"memory\";\n this.delegate = new InMemorySessionStore();\n logger?.warn?.(\n \"acpx SessionStore is using in-memory storage; sessions will not persist across restarts\",\n );\n return;\n }\n\n const filePath = resolveStateFile(options.runtime, options.stateFile);\n try {\n access(dirname(filePath), constants.W_OK).catch(() => undefined);\n this.backend = \"file\";\n this.delegate = new FileSessionStore(filePath, logger);\n } catch (error) {\n this.backend = \"memory\";\n this.delegate = new InMemorySessionStore();\n logger?.warn?.(\n \"acpx SessionStore could not initialize file storage; sessions will not persist across restarts\",\n error,\n );\n }\n }\n\n create(session: SessionInfo): Promise<void> {\n return this.delegate.create(session);\n }\n\n get(id: string): Promise<SessionInfo | null> {\n return this.delegate.get(id);\n }\n\n getByAcpxRecordId(recordId: string): Promise<SessionInfo | null> {\n return this.delegate.getByAcpxRecordId(recordId);\n }\n\n findByScope(opts: {\n workdir: string;\n agentType: string;\n name?: string;\n }): Promise<SessionInfo | null> {\n return this.delegate.findByScope(opts);\n }\n\n list(filter?: SessionFilter): Promise<SessionInfo[]> {\n return this.delegate.list(filter);\n }\n\n update(id: string, patch: Partial<SessionInfo>): Promise<void> {\n return this.delegate.update(id, patch);\n }\n\n updateStatus(\n id: string,\n status: SessionStatus,\n error?: string,\n ): Promise<void> {\n return this.delegate.updateStatus(id, status, error);\n }\n\n delete(id: string): Promise<void> {\n return this.delegate.delete(id);\n }\n\n sweepStale(maxAgeMs: number): Promise<string[]> {\n return this.delegate.sweepStale(maxAgeMs);\n }\n}\n\nexport type {\n SessionFilter,\n SessionInfo,\n SessionStatus,\n SessionStore,\n} from \"./types.js\";\n",
|
|
66
|
+
"import { createHash, randomUUID } from \"node:crypto\";\nimport type { IAgentRuntime, Memory, UUID } from \"@elizaos/core\";\nimport type { AcpService } from \"./acp-service.js\";\nimport type { SessionEventName, SessionInfo } from \"./types.js\";\n\nconst ACPX_ROUTER_SOURCE = \"sub_agent\";\nconst SUB_AGENT_ENTITY_NAMESPACE = \"acpx:sub-agent\";\nconst DEFAULT_ROUND_TRIP_CAP = 32;\n\n/**\n * SubAgentRouter takes terminal-significant ACPX session events\n * (`task_complete`, `error`, `blocked`) and posts them as synthetic inbound\n * messages into the runtime so the main agent's normal action layer can\n * decide whether to:\n * - REPLY to the user,\n * - SEND_TO_AGENT to push the sub-agent further,\n * - or both.\n *\n * Routing keys are read from `session.metadata` populated by TASKS op=create\n * at spawn time: `roomId`, `worldId`, `userId`, `messageId`, `source`, `label`.\n *\n * Streaming chunks (`agent_message_chunk`, `tool_running`) are intentionally\n * NOT injected — they would refire the planner constantly and burn cache.\n * The provider is the channel for live status; this router is the channel for\n * boundary events that warrant a decision.\n */\nexport class SubAgentRouter {\n static serviceType = \"ACPX_SUB_AGENT_ROUTER\";\n static dependencies = [\"ACP_SUBPROCESS_SERVICE\"];\n\n capabilityDescription =\n \"Routes ACPX sub-agent terminal events back into the runtime as inbound messages so the main agent decides reply-to-user vs reply-to-agent vs both.\";\n\n private readonly runtime: IAgentRuntime;\n private acp: AcpService | null = null;\n private unsubscribe: (() => void) | undefined;\n private readonly delivered = new Set<string>();\n private readonly roundTripCounts = new Map<string, number>();\n private readonly capExceededSessions = new Set<string>();\n private started = false;\n private roundTripCap = DEFAULT_ROUND_TRIP_CAP;\n\n constructor(runtime: IAgentRuntime) {\n this.runtime = runtime;\n }\n\n static async start(runtime: IAgentRuntime): Promise<SubAgentRouter> {\n const router = new SubAgentRouter(runtime);\n await router.start();\n return router;\n }\n\n async start(): Promise<void> {\n if (this.started) return;\n this.started = true;\n const disabled = readSetting(\n this.runtime,\n \"ACPX_SUB_AGENT_ROUTER_DISABLED\",\n );\n if (disabled === \"1\" || disabled === \"true\") {\n this.log(\"info\", \"router disabled via ACPX_SUB_AGENT_ROUTER_DISABLED\");\n return;\n }\n const capRaw = readSetting(this.runtime, \"ACPX_SUB_AGENT_ROUND_TRIP_CAP\");\n const parsed = capRaw ? Number.parseInt(capRaw, 10) : NaN;\n if (Number.isFinite(parsed) && parsed > 0) this.roundTripCap = parsed;\n const acp = this.runtime.getService(\n \"ACP_SUBPROCESS_SERVICE\",\n ) as AcpService | null;\n if (!acp || typeof acp.onSessionEvent !== \"function\") {\n this.log(\"debug\", \"AcpService unavailable; router idle\");\n return;\n }\n this.acp = acp;\n this.unsubscribe = acp.onSessionEvent((sid, event, data) => {\n this.handleEvent(sid, event, data).catch((err) => {\n this.log(\"error\", \"router event failed\", {\n sessionId: sid,\n event,\n error: err instanceof Error ? err.message : String(err),\n });\n });\n });\n this.log(\"info\", \"router bound to AcpService\");\n }\n\n async stop(): Promise<void> {\n this.unsubscribe?.();\n this.unsubscribe = undefined;\n this.acp = null;\n this.started = false;\n this.delivered.clear();\n this.roundTripCounts.clear();\n this.capExceededSessions.clear();\n }\n\n private async handleEvent(\n sessionId: string,\n event: SessionEventName,\n data: unknown,\n ): Promise<void> {\n if (!shouldInject(event)) return;\n const acp = this.acp;\n if (!acp) return;\n const session = await acp.getSession(sessionId);\n if (!session) return;\n\n const dedupKey = computeDedupKey(sessionId, event, session, data);\n if (this.delivered.has(dedupKey)) return;\n this.delivered.add(dedupKey);\n pruneDelivered(this.delivered, 256);\n\n const origin = readOrigin(session);\n if (!origin) {\n this.log(\n \"debug\",\n \"session has no origin metadata; skipping router post\",\n {\n sessionId,\n event,\n },\n );\n return;\n }\n\n const nextCount = (this.roundTripCounts.get(sessionId) ?? 0) + 1;\n this.roundTripCounts.set(sessionId, nextCount);\n const capExceeded = nextCount > this.roundTripCap;\n if (capExceeded) {\n if (this.capExceededSessions.has(sessionId)) {\n this.log(\"debug\", \"round-trip cap already surfaced; suppressing\", {\n sessionId,\n event,\n count: nextCount,\n });\n return;\n }\n this.capExceededSessions.add(sessionId);\n this.log(\"warn\", \"sub-agent round-trip cap exceeded; force-stopping\", {\n sessionId,\n count: nextCount,\n cap: this.roundTripCap,\n });\n await acp.stopSession(sessionId).catch((err) =>\n this.log(\"warn\", \"force-stop after cap failed\", {\n sessionId,\n error: err instanceof Error ? err.message : String(err),\n }),\n );\n }\n\n const subAgentEntityId = deriveUuidFromString(\n `${this.runtime.agentId}:${SUB_AGENT_ENTITY_NAMESPACE}:${sessionId}`,\n );\n const text = capExceeded\n ? `[sub-agent: ${origin.label} (${session.agentType}) — round-trip cap exceeded]\\nThis session reached ${nextCount} round-trips (cap=${this.roundTripCap}) and was force-stopped to prevent a runaway loop. Decide whether to spawn a fresh session, escalate to the user, or drop the task.`\n : composeNarration(event, origin.label, session, data);\n const memory: Memory = {\n id: randomUUID() as UUID,\n entityId: subAgentEntityId,\n agentId: this.runtime.agentId,\n roomId: origin.roomId,\n ...(origin.worldId ? { worldId: origin.worldId } : {}),\n content: {\n text,\n source: ACPX_ROUTER_SOURCE,\n ...(origin.parentMessageId\n ? { inReplyTo: origin.parentMessageId }\n : {}),\n metadata: {\n subAgent: true,\n subAgentSessionId: sessionId,\n subAgentLabel: origin.label,\n subAgentEvent: capExceeded ? \"round_trip_cap_exceeded\" : event,\n subAgentStatus: capExceeded ? \"stopped\" : session.status,\n subAgentAgentType: session.agentType,\n subAgentRoundTrip: nextCount,\n subAgentRoundTripCap: this.roundTripCap,\n ...(capExceeded ? { subAgentCapExceeded: true } : {}),\n ...(origin.userId ? { originUserId: origin.userId } : {}),\n ...(origin.parentMessageId\n ? { originMessageId: origin.parentMessageId }\n : {}),\n ...(origin.source ? { originSource: origin.source } : {}),\n },\n },\n createdAt: Date.now(),\n };\n\n await this.runtime.createMemory(memory, \"messages\").catch((err) => {\n this.log(\"warn\", \"createMemory for sub-agent post failed\", {\n sessionId,\n event,\n error: err instanceof Error ? err.message : String(err),\n });\n });\n\n if (this.runtime.messageService?.handleMessage) {\n await this.runtime.messageService\n .handleMessage(this.runtime, memory, undefined)\n .catch((err) => {\n this.log(\"error\", \"handleMessage for sub-agent post failed\", {\n sessionId,\n event,\n error: err instanceof Error ? err.message : String(err),\n });\n });\n } else {\n this.log(\n \"warn\",\n \"runtime.messageService unavailable; falling back to MESSAGE_RECEIVED emit\",\n {\n sessionId,\n event,\n },\n );\n const emit = this.runtime.emitEvent.bind(this.runtime) as (\n name: string,\n payload: { source: string; message: Memory; runtime: IAgentRuntime },\n ) => Promise<void>;\n await emit(\"MESSAGE_RECEIVED\", {\n runtime: this.runtime,\n message: memory,\n source: ACPX_ROUTER_SOURCE,\n });\n }\n }\n\n private log(\n level: \"debug\" | \"info\" | \"warn\" | \"error\",\n msg: string,\n data?: unknown,\n ): void {\n const logger = this.runtime.logger;\n const fn = logger?.[level];\n if (typeof fn === \"function\") {\n fn.call(\n logger,\n { src: \"acpx:sub-agent-router\", ...(data as object) },\n msg,\n );\n }\n }\n}\n\nfunction shouldInject(event: SessionEventName): boolean {\n return event === \"task_complete\" || event === \"error\" || event === \"blocked\";\n}\n\ninterface OriginInfo {\n roomId: UUID;\n worldId?: UUID;\n userId?: UUID;\n parentMessageId?: UUID;\n label: string;\n source?: string;\n}\n\nfunction readOrigin(session: SessionInfo): OriginInfo | null {\n const meta = session.metadata as Record<string, unknown> | undefined;\n if (!meta) return null;\n const roomId = pickUuid(meta.roomId);\n if (!roomId) return null;\n return {\n roomId,\n worldId: pickUuid(meta.worldId),\n userId: pickUuid(meta.userId),\n parentMessageId: pickUuid(meta.messageId),\n label: pickLabel(meta) ?? session.name ?? session.id,\n source: typeof meta.source === \"string\" ? meta.source : undefined,\n };\n}\n\nfunction pickUuid(v: unknown): UUID | undefined {\n if (typeof v !== \"string\") return undefined;\n if (\n !/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(v)\n )\n return undefined;\n return v as UUID;\n}\n\nfunction pickLabel(meta: Record<string, unknown>): string | undefined {\n if (typeof meta.label === \"string\" && meta.label.trim()) return meta.label;\n return undefined;\n}\n\nfunction pickPayloadString(data: unknown, key: string): string | undefined {\n if (!data || typeof data !== \"object\") return undefined;\n const v = (data as Record<string, unknown>)[key];\n if (typeof v !== \"string\" || !v.trim()) return undefined;\n return v;\n}\n\nfunction composeNarration(\n event: SessionEventName,\n label: string,\n session: SessionInfo,\n data: unknown,\n): string {\n const header = `[sub-agent: ${label} (${session.agentType}) — ${event}]`;\n if (event === \"error\") {\n const message =\n pickPayloadString(data, \"message\") ?? \"sub-agent reported an error\";\n return `${header}\\n${message}`;\n }\n if (event === \"blocked\") {\n const message =\n pickPayloadString(data, \"message\") ??\n pickPayloadString(data, \"prompt\") ??\n \"sub-agent is blocked and waiting for input\";\n return `${header}\\n${message}`;\n }\n const response =\n pickPayloadString(data, \"response\") ??\n pickPayloadString(data, \"finalText\") ??\n \"sub-agent reports task complete (no captured output).\";\n return `${header}\\n${response}`;\n}\n\nfunction computeDedupKey(\n sessionId: string,\n event: SessionEventName,\n session: SessionInfo,\n data: unknown,\n): string {\n const fingerprint =\n pickPayloadString(data, \"response\") ??\n pickPayloadString(data, \"finalText\") ??\n pickPayloadString(data, \"message\") ??\n \"\";\n return `${sessionId}|${event}|${session.status}|${shortHash(fingerprint)}`;\n}\n\nfunction shortHash(input: string): string {\n let h = 0;\n for (let i = 0; i < input.length; i++) {\n h = (h * 31 + input.charCodeAt(i)) | 0;\n }\n return h.toString(36);\n}\n\nfunction pruneDelivered(set: Set<string>, max: number): void {\n if (set.size <= max) return;\n const it = set.values();\n for (let i = 0; i < set.size - max; i++) {\n const next = it.next();\n if (next.done) break;\n set.delete(next.value);\n }\n}\n\nfunction readSetting(runtime: IAgentRuntime, key: string): string | undefined {\n const get = (runtime as { getSetting?: (k: string) => string | undefined })\n .getSetting;\n if (typeof get === \"function\") {\n const v = get.call(runtime, key);\n if (typeof v === \"string\" && v.length > 0) return v;\n }\n const env = process.env[key];\n return typeof env === \"string\" && env.length > 0 ? env : undefined;\n}\n\n/**\n * Deterministic UUIDv5-like derivation from a string. Same input → same\n * UUID. Local replacement for `createUniqueUuid` from @elizaos/core so\n * this service stays type-only on core (no runtime dist dependency).\n */\nfunction deriveUuidFromString(input: string): UUID {\n const digest = createHash(\"sha1\").update(input).digest(\"hex\");\n const bytes = digest.slice(0, 32).split(\"\");\n // Set version (5) and variant bits per RFC 4122.\n bytes[12] = \"5\";\n bytes[16] = ((parseInt(bytes[16] ?? \"0\", 16) & 0x3) | 0x8).toString(16);\n const hex = bytes.join(\"\");\n return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20, 32)}` as UUID;\n}\n",
|
|
67
|
+
"export * from \"./src/index.js\";\n\nimport _defaultExport from \"./src/index.js\";\nexport default _defaultExport;\n"
|
|
68
|
+
],
|
|
69
|
+
"mappings": "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",
|
|
70
|
+
"debugId": "1C52A8B599733DBF64756E2164756E21",
|
|
71
|
+
"names": []
|
|
72
|
+
}
|