@elizaos/agent 2.0.0-alpha.144 → 2.0.0-alpha.151
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/apps/app-lifeops/src/actions/inbox-digest.d.ts +2 -0
- package/apps/app-lifeops/src/actions/inbox-digest.d.ts.map +1 -0
- package/apps/app-lifeops/src/actions/inbox-digest.js +1 -0
- package/apps/app-lifeops/src/actions/inbox-respond.d.ts +2 -0
- package/apps/app-lifeops/src/actions/inbox-respond.d.ts.map +1 -0
- package/apps/app-lifeops/src/actions/inbox-respond.js +1 -0
- package/apps/app-lifeops/src/actions/inbox-triage.d.ts +2 -0
- package/apps/app-lifeops/src/actions/inbox-triage.d.ts.map +1 -0
- package/apps/app-lifeops/src/actions/inbox-triage.js +1 -0
- package/apps/app-lifeops/src/actions/inbox.d.ts +3 -0
- package/apps/app-lifeops/src/actions/inbox.d.ts.map +1 -0
- package/apps/app-lifeops/src/actions/inbox.js +856 -0
- package/apps/app-lifeops/src/actions/update-owner-profile.d.ts +3 -0
- package/apps/app-lifeops/src/actions/update-owner-profile.d.ts.map +1 -0
- package/apps/app-lifeops/src/actions/update-owner-profile.js +131 -0
- package/apps/app-lifeops/src/inbox/channel-deep-links.d.ts.map +1 -0
- package/apps/app-lifeops/src/inbox/config.d.ts.map +1 -0
- package/{packages/agent → apps/app-lifeops}/src/inbox/config.js +1 -1
- package/apps/app-lifeops/src/inbox/message-fetcher.d.ts.map +1 -0
- package/apps/app-lifeops/src/inbox/reflection.d.ts.map +1 -0
- package/apps/app-lifeops/src/inbox/repository.d.ts.map +1 -0
- package/apps/app-lifeops/src/inbox/triage-classifier.d.ts.map +1 -0
- package/apps/app-lifeops/src/inbox/types.d.ts.map +1 -0
- package/apps/app-lifeops/src/lifeops/index.d.ts +25 -0
- package/apps/app-lifeops/src/lifeops/index.d.ts.map +1 -0
- package/apps/app-lifeops/src/lifeops/index.js +24 -0
- package/apps/app-lifeops/src/lifeops/screen-context.d.ts +52 -0
- package/apps/app-lifeops/src/lifeops/screen-context.d.ts.map +1 -0
- package/apps/app-lifeops/src/lifeops/screen-context.js +332 -0
- package/apps/app-lifeops/src/plugin.d.ts +3 -0
- package/apps/app-lifeops/src/plugin.d.ts.map +1 -1
- package/apps/app-lifeops/src/plugin.js +16 -3
- package/apps/app-lifeops/src/providers/inbox-triage.d.ts +3 -0
- package/apps/app-lifeops/src/providers/inbox-triage.d.ts.map +1 -0
- package/apps/app-lifeops/src/providers/inbox-triage.js +89 -0
- package/package.json +6 -4
- package/packages/agent/src/actions/calendar.d.ts +1 -18
- package/packages/agent/src/actions/calendar.d.ts.map +1 -1
- package/packages/agent/src/actions/calendar.js +1 -3143
- package/packages/agent/src/actions/check-balance.d.ts +17 -0
- package/packages/agent/src/actions/check-balance.d.ts.map +1 -0
- package/packages/agent/src/actions/check-balance.js +167 -0
- package/packages/agent/src/actions/connector-resolver.d.ts +75 -0
- package/packages/agent/src/actions/connector-resolver.d.ts.map +1 -0
- package/packages/agent/src/actions/connector-resolver.js +245 -0
- package/packages/agent/src/actions/context-signal-lexicon.d.ts +1 -1
- package/packages/agent/src/actions/context-signal-lexicon.d.ts.map +1 -1
- package/packages/agent/src/actions/context-signal-lexicon.js +6 -0
- package/packages/agent/src/actions/eject-plugin.d.ts +3 -0
- package/packages/agent/src/actions/eject-plugin.d.ts.map +1 -0
- package/packages/agent/src/actions/eject-plugin.js +48 -0
- package/packages/agent/src/actions/execute-trade.d.ts +17 -0
- package/packages/agent/src/actions/execute-trade.d.ts.map +1 -0
- package/packages/agent/src/actions/execute-trade.js +299 -0
- package/packages/agent/src/actions/get-self-status.d.ts +13 -0
- package/packages/agent/src/actions/get-self-status.d.ts.map +1 -0
- package/packages/agent/src/actions/get-self-status.js +66 -0
- package/packages/agent/src/actions/gmail.d.ts +1 -32
- package/packages/agent/src/actions/gmail.d.ts.map +1 -1
- package/packages/agent/src/actions/gmail.js +1 -1734
- package/packages/agent/src/actions/inbox-digest.d.ts +1 -1
- package/packages/agent/src/actions/inbox-digest.d.ts.map +1 -1
- package/packages/agent/src/actions/inbox-digest.js +1 -1
- package/packages/agent/src/actions/inbox-respond.d.ts +1 -1
- package/packages/agent/src/actions/inbox-respond.d.ts.map +1 -1
- package/packages/agent/src/actions/inbox-respond.js +1 -1
- package/packages/agent/src/actions/inbox-triage.d.ts +1 -1
- package/packages/agent/src/actions/inbox-triage.d.ts.map +1 -1
- package/packages/agent/src/actions/inbox-triage.js +1 -1
- package/packages/agent/src/actions/inbox.d.ts +1 -2
- package/packages/agent/src/actions/inbox.d.ts.map +1 -1
- package/packages/agent/src/actions/inbox.js +1 -856
- package/packages/agent/src/actions/index.d.ts +13 -0
- package/packages/agent/src/actions/index.d.ts.map +1 -1
- package/packages/agent/src/actions/index.js +13 -0
- package/packages/agent/src/actions/install-plugin.d.ts +3 -0
- package/packages/agent/src/actions/install-plugin.d.ts.map +1 -0
- package/packages/agent/src/actions/install-plugin.js +65 -0
- package/packages/agent/src/actions/life-goal-extractor.d.ts +1 -68
- package/packages/agent/src/actions/life-goal-extractor.d.ts.map +1 -1
- package/packages/agent/src/actions/life-goal-extractor.js +1 -354
- package/packages/agent/src/actions/life-param-extractor.d.ts +1 -77
- package/packages/agent/src/actions/life-param-extractor.d.ts.map +1 -1
- package/packages/agent/src/actions/life-param-extractor.js +1 -423
- package/packages/agent/src/actions/life-recent-context.d.ts +1 -8
- package/packages/agent/src/actions/life-recent-context.d.ts.map +1 -1
- package/packages/agent/src/actions/life-recent-context.js +1 -84
- package/packages/agent/src/actions/life-update-extractor.d.ts +1 -26
- package/packages/agent/src/actions/life-update-extractor.d.ts.map +1 -1
- package/packages/agent/src/actions/life-update-extractor.js +1 -195
- package/packages/agent/src/actions/life.d.ts +1 -8
- package/packages/agent/src/actions/life.d.ts.map +1 -1
- package/packages/agent/src/actions/life.extractor.d.ts +1 -17
- package/packages/agent/src/actions/life.extractor.d.ts.map +1 -1
- package/packages/agent/src/actions/life.extractor.js +1 -264
- package/packages/agent/src/actions/life.js +1 -3379
- package/packages/agent/src/actions/lifeops-extraction-config.d.ts +1 -15
- package/packages/agent/src/actions/lifeops-extraction-config.d.ts.map +1 -1
- package/packages/agent/src/actions/lifeops-extraction-config.js +1 -25
- package/packages/agent/src/actions/lifeops-google-helpers.d.ts +1 -61
- package/packages/agent/src/actions/lifeops-google-helpers.d.ts.map +1 -1
- package/packages/agent/src/actions/lifeops-google-helpers.js +1 -607
- package/packages/agent/src/actions/list-ejected.d.ts +3 -0
- package/packages/agent/src/actions/list-ejected.d.ts.map +1 -0
- package/packages/agent/src/actions/list-ejected.js +35 -0
- package/packages/agent/src/actions/log-level.d.ts +3 -0
- package/packages/agent/src/actions/log-level.d.ts.map +1 -0
- package/packages/agent/src/actions/log-level.js +125 -0
- package/packages/agent/src/actions/manage-tasks.d.ts.map +1 -1
- package/packages/agent/src/actions/manage-tasks.js +51 -15
- package/packages/agent/src/actions/media.d.ts +21 -0
- package/packages/agent/src/actions/media.d.ts.map +1 -0
- package/packages/agent/src/actions/media.js +384 -0
- package/packages/agent/src/actions/read-messages.d.ts +14 -0
- package/packages/agent/src/actions/read-messages.d.ts.map +1 -0
- package/packages/agent/src/actions/read-messages.js +228 -0
- package/packages/agent/src/actions/reinject-plugin.d.ts +3 -0
- package/packages/agent/src/actions/reinject-plugin.d.ts.map +1 -0
- package/packages/agent/src/actions/reinject-plugin.js +47 -0
- package/packages/agent/src/actions/send-message.d.ts +0 -7
- package/packages/agent/src/actions/send-message.d.ts.map +1 -1
- package/packages/agent/src/actions/send-message.js +170 -49
- package/packages/agent/src/actions/sync-plugin.d.ts +3 -0
- package/packages/agent/src/actions/sync-plugin.d.ts.map +1 -0
- package/packages/agent/src/actions/sync-plugin.js +47 -0
- package/packages/agent/src/actions/timezone-normalization.d.ts +1 -2
- package/packages/agent/src/actions/timezone-normalization.d.ts.map +1 -1
- package/packages/agent/src/actions/timezone-normalization.js +1 -107
- package/packages/agent/src/actions/transfer-token.d.ts +17 -0
- package/packages/agent/src/actions/transfer-token.d.ts.map +1 -0
- package/packages/agent/src/actions/transfer-token.js +470 -0
- package/packages/agent/src/actions/update-owner-profile.d.ts +1 -2
- package/packages/agent/src/actions/update-owner-profile.d.ts.map +1 -1
- package/packages/agent/src/actions/update-owner-profile.js +1 -131
- package/packages/agent/src/actions/wallet-action-shared.d.ts +15 -0
- package/packages/agent/src/actions/wallet-action-shared.d.ts.map +1 -0
- package/packages/agent/src/actions/wallet-action-shared.js +24 -0
- package/packages/agent/src/api/agent-admin-routes.d.ts.map +1 -1
- package/packages/agent/src/api/agent-admin-routes.js +1 -1
- package/packages/agent/src/api/binance-skill-helpers.d.ts.map +1 -1
- package/packages/agent/src/api/binance-skill-helpers.js +8 -3
- package/packages/agent/src/api/chat-routes.d.ts.map +1 -1
- package/packages/agent/src/api/chat-routes.js +20 -5
- package/packages/agent/src/api/coding-agents-auth-sanitize.d.ts +1 -22
- package/packages/agent/src/api/coding-agents-auth-sanitize.d.ts.map +1 -1
- package/packages/agent/src/api/coding-agents-auth-sanitize.js +1 -39
- package/packages/agent/src/api/coding-agents-preflight-normalize.d.ts +1 -28
- package/packages/agent/src/api/coding-agents-preflight-normalize.d.ts.map +1 -1
- package/packages/agent/src/api/coding-agents-preflight-normalize.js +1 -45
- package/packages/agent/src/api/coordinator-types.d.ts +1 -46
- package/packages/agent/src/api/coordinator-types.d.ts.map +1 -1
- package/packages/agent/src/api/coordinator-types.js +1 -1
- package/packages/agent/src/api/coordinator-wiring.d.ts +1 -45
- package/packages/agent/src/api/coordinator-wiring.d.ts.map +1 -1
- package/packages/agent/src/api/coordinator-wiring.js +1 -108
- package/packages/agent/src/api/index.d.ts +1 -1
- package/packages/agent/src/api/index.d.ts.map +1 -1
- package/packages/agent/src/api/index.js +1 -1
- package/packages/agent/src/api/lifeops-browser-packaging.d.ts +1 -15
- package/packages/agent/src/api/lifeops-browser-packaging.d.ts.map +1 -1
- package/packages/agent/src/api/lifeops-browser-packaging.js +1 -305
- package/packages/agent/src/api/lifeops-routes.d.ts +1 -19
- package/packages/agent/src/api/lifeops-routes.d.ts.map +1 -1
- package/packages/agent/src/api/lifeops-routes.js +1 -1173
- package/packages/agent/src/api/server.d.ts.map +1 -1
- package/packages/agent/src/api/server.js +6 -6
- package/packages/agent/src/api/task-agent-message-routing.d.ts +1 -9
- package/packages/agent/src/api/task-agent-message-routing.d.ts.map +1 -1
- package/packages/agent/src/api/task-agent-message-routing.js +1 -62
- package/packages/agent/src/api/website-blocker-routes.d.ts +1 -6
- package/packages/agent/src/api/website-blocker-routes.d.ts.map +1 -1
- package/packages/agent/src/api/website-blocker-routes.js +1 -174
- package/packages/agent/src/config/types.agent-defaults.d.ts +1 -1
- package/packages/agent/src/config/types.agent-defaults.d.ts.map +1 -1
- package/packages/agent/src/evals/coordinator-eval-client.d.ts +1 -38
- package/packages/agent/src/evals/coordinator-eval-client.d.ts.map +1 -1
- package/packages/agent/src/evals/coordinator-eval-client.js +1 -138
- package/packages/agent/src/evals/coordinator-live-runner.d.ts +1 -56
- package/packages/agent/src/evals/coordinator-live-runner.d.ts.map +1 -1
- package/packages/agent/src/evals/coordinator-live-runner.js +1 -546
- package/packages/agent/src/evals/coordinator-preflight.d.ts +1 -31
- package/packages/agent/src/evals/coordinator-preflight.d.ts.map +1 -1
- package/packages/agent/src/evals/coordinator-preflight.js +1 -296
- package/packages/agent/src/evals/coordinator-scenarios.d.ts +1 -23
- package/packages/agent/src/evals/coordinator-scenarios.d.ts.map +1 -1
- package/packages/agent/src/evals/coordinator-scenarios.js +1 -1141
- package/packages/agent/src/lifeops/app-state.d.ts +1 -10
- package/packages/agent/src/lifeops/app-state.d.ts.map +1 -1
- package/packages/agent/src/lifeops/app-state.js +1 -32
- package/packages/agent/src/lifeops/apple-reminders.d.ts +1 -57
- package/packages/agent/src/lifeops/apple-reminders.d.ts.map +1 -1
- package/packages/agent/src/lifeops/apple-reminders.js +1 -325
- package/packages/agent/src/lifeops/defaults.d.ts +1 -23
- package/packages/agent/src/lifeops/defaults.d.ts.map +1 -1
- package/packages/agent/src/lifeops/defaults.js +1 -205
- package/packages/agent/src/lifeops/engine.d.ts +1 -7
- package/packages/agent/src/lifeops/engine.d.ts.map +1 -1
- package/packages/agent/src/lifeops/engine.js +1 -389
- package/packages/agent/src/lifeops/goal-grounding.d.ts +1 -53
- package/packages/agent/src/lifeops/goal-grounding.d.ts.map +1 -1
- package/packages/agent/src/lifeops/goal-grounding.js +1 -147
- package/packages/agent/src/lifeops/goal-semantic-evaluator.d.ts +1 -11
- package/packages/agent/src/lifeops/goal-semantic-evaluator.d.ts.map +1 -1
- package/packages/agent/src/lifeops/goal-semantic-evaluator.js +1 -154
- package/packages/agent/src/lifeops/google-api-error.d.ts +1 -6
- package/packages/agent/src/lifeops/google-api-error.d.ts.map +1 -1
- package/packages/agent/src/lifeops/google-api-error.js +1 -35
- package/packages/agent/src/lifeops/google-calendar.d.ts +1 -52
- package/packages/agent/src/lifeops/google-calendar.d.ts.map +1 -1
- package/packages/agent/src/lifeops/google-calendar.js +1 -268
- package/packages/agent/src/lifeops/google-connector-gateway.d.ts +1 -18
- package/packages/agent/src/lifeops/google-connector-gateway.d.ts.map +1 -1
- package/packages/agent/src/lifeops/google-connector-gateway.js +1 -65
- package/packages/agent/src/lifeops/google-fetch.d.ts +1 -10
- package/packages/agent/src/lifeops/google-fetch.d.ts.map +1 -1
- package/packages/agent/src/lifeops/google-fetch.js +1 -85
- package/packages/agent/src/lifeops/google-gmail.d.ts +1 -53
- package/packages/agent/src/lifeops/google-gmail.d.ts.map +1 -1
- package/packages/agent/src/lifeops/google-gmail.js +1 -471
- package/packages/agent/src/lifeops/google-managed-client.d.ts +1 -126
- package/packages/agent/src/lifeops/google-managed-client.d.ts.map +1 -1
- package/packages/agent/src/lifeops/google-managed-client.js +1 -294
- package/packages/agent/src/lifeops/google-oauth.d.ts +1 -60
- package/packages/agent/src/lifeops/google-oauth.d.ts.map +1 -1
- package/packages/agent/src/lifeops/google-oauth.js +1 -494
- package/packages/agent/src/lifeops/google-scopes.d.ts +1 -12
- package/packages/agent/src/lifeops/google-scopes.d.ts.map +1 -1
- package/packages/agent/src/lifeops/google-scopes.js +1 -96
- package/packages/agent/src/lifeops/index.d.ts +1 -2
- package/packages/agent/src/lifeops/index.d.ts.map +1 -1
- package/packages/agent/src/lifeops/index.js +1 -2
- package/packages/agent/src/lifeops/owner-profile.d.ts +1 -14
- package/packages/agent/src/lifeops/owner-profile.d.ts.map +1 -1
- package/packages/agent/src/lifeops/owner-profile.js +1 -194
- package/packages/agent/src/lifeops/repository.d.ts +1 -208
- package/packages/agent/src/lifeops/repository.d.ts.map +1 -1
- package/packages/agent/src/lifeops/repository.js +1 -3187
- package/packages/agent/src/lifeops/runtime.d.ts +1 -13
- package/packages/agent/src/lifeops/runtime.d.ts.map +1 -1
- package/packages/agent/src/lifeops/runtime.js +1 -120
- package/packages/agent/src/lifeops/screen-context.d.ts +1 -51
- package/packages/agent/src/lifeops/screen-context.d.ts.map +1 -1
- package/packages/agent/src/lifeops/screen-context.js +1 -332
- package/packages/agent/src/lifeops/seed-routines.d.ts +1 -19
- package/packages/agent/src/lifeops/seed-routines.d.ts.map +1 -1
- package/packages/agent/src/lifeops/seed-routines.js +1 -111
- package/packages/agent/src/lifeops/service.d.ts +1 -274
- package/packages/agent/src/lifeops/service.d.ts.map +1 -1
- package/packages/agent/src/lifeops/service.js +1 -9260
- package/packages/agent/src/lifeops/sql.d.ts +1 -30
- package/packages/agent/src/lifeops/sql.d.ts.map +1 -1
- package/packages/agent/src/lifeops/sql.js +1 -247
- package/packages/agent/src/lifeops/time.d.ts +1 -16
- package/packages/agent/src/lifeops/time.d.ts.map +1 -1
- package/packages/agent/src/lifeops/time.js +1 -132
- package/packages/agent/src/lifeops/twilio.d.ts +1 -24
- package/packages/agent/src/lifeops/twilio.d.ts.map +1 -1
- package/packages/agent/src/lifeops/twilio.js +1 -157
- package/packages/agent/src/lifeops/x-poster.d.ts +1 -18
- package/packages/agent/src/lifeops/x-poster.d.ts.map +1 -1
- package/packages/agent/src/lifeops/x-poster.js +1 -148
- package/packages/agent/src/providers/inbox-triage.d.ts +1 -2
- package/packages/agent/src/providers/inbox-triage.d.ts.map +1 -1
- package/packages/agent/src/providers/inbox-triage.js +1 -89
- package/packages/agent/src/providers/index.d.ts +4 -1
- package/packages/agent/src/providers/index.d.ts.map +1 -1
- package/packages/agent/src/providers/index.js +4 -1
- package/packages/agent/src/providers/lifeops.d.ts +1 -2
- package/packages/agent/src/providers/lifeops.d.ts.map +1 -1
- package/packages/agent/src/providers/lifeops.js +1 -157
- package/packages/agent/src/providers/local-models.d.ts +118 -0
- package/packages/agent/src/providers/local-models.d.ts.map +1 -0
- package/packages/agent/src/providers/local-models.js +427 -0
- package/packages/agent/src/providers/media-provider.d.ts +192 -0
- package/packages/agent/src/providers/media-provider.d.ts.map +1 -0
- package/packages/agent/src/providers/media-provider.js +1088 -0
- package/packages/agent/src/providers/self-status.d.ts +4 -0
- package/packages/agent/src/providers/self-status.d.ts.map +1 -0
- package/packages/agent/src/providers/self-status.js +12 -0
- package/packages/agent/src/providers/tasks.d.ts.map +1 -1
- package/packages/agent/src/providers/tasks.js +7 -7
- package/packages/agent/src/runtime/core-plugins.js +1 -1
- package/packages/agent/src/runtime/eliza-plugin.d.ts.map +1 -1
- package/packages/agent/src/runtime/eliza-plugin.js +1 -7
- package/packages/agent/src/runtime/eliza.js +2 -2
- package/packages/agent/src/runtime/plugin-collector.js +3 -3
- package/packages/agent/src/runtime/plugin-lifecycle.d.ts.map +1 -1
- package/packages/agent/src/runtime/plugin-lifecycle.js +3 -13
- package/packages/agent/src/runtime/trajectory-internals.d.ts.map +1 -1
- package/packages/agent/src/runtime/trajectory-internals.js +1 -3
- package/packages/agent/src/services/built-in-app-routes/hyperscape.d.ts.map +1 -1
- package/packages/agent/src/services/coding-task-executor.d.ts +3 -3
- package/packages/agent/src/services/coding-task-executor.js +3 -3
- package/packages/shared/src/awareness/index.d.ts +2 -0
- package/packages/shared/src/awareness/index.d.ts.map +1 -0
- package/packages/shared/src/awareness/index.js +1 -0
- package/packages/shared/src/awareness/registry.d.ts +27 -0
- package/packages/shared/src/awareness/registry.d.ts.map +1 -0
- package/packages/shared/src/awareness/registry.js +161 -0
- package/packages/shared/src/i18n/generated/validation-keyword-data.d.ts +24 -0
- package/packages/shared/src/i18n/generated/validation-keyword-data.d.ts.map +1 -1
- package/packages/shared/src/i18n/generated/validation-keyword-data.js +24 -0
- package/packages/shared/src/runtime-env.d.ts.map +1 -1
- package/packages/shared/src/runtime-env.js +5 -1
- package/packages/typescript/src/generated/action-docs.d.ts +135 -0
- package/packages/typescript/src/generated/action-docs.d.ts.map +1 -1
- package/packages/typescript/src/generated/action-docs.js +237 -0
- package/packages/typescript/src/i18n/generated/validation-keyword-data.d.ts +24 -0
- package/packages/typescript/src/i18n/generated/validation-keyword-data.d.ts.map +1 -1
- package/packages/typescript/src/i18n/generated/validation-keyword-data.js +24 -0
- package/packages/typescript/src/index.node.d.ts +2 -2
- package/packages/typescript/src/index.node.d.ts.map +1 -1
- package/packages/typescript/src/index.node.js +4 -3
- package/packages/typescript/src/plugin-lifecycle.d.ts.map +1 -1
- package/packages/typescript/src/plugin-lifecycle.js +42 -3
- package/packages/typescript/src/services/message.d.ts.map +1 -1
- package/packages/typescript/src/services/message.js +32 -0
- package/apps/app-training/src/core/cli.d.ts +0 -11
- package/apps/app-training/src/core/cli.d.ts.map +0 -1
- package/apps/app-training/src/core/cli.js +0 -302
- package/apps/app-training/src/core/context-audit.d.ts +0 -51
- package/apps/app-training/src/core/context-audit.d.ts.map +0 -1
- package/apps/app-training/src/core/context-audit.js +0 -141
- package/apps/app-training/src/core/context-catalog.d.ts +0 -47
- package/apps/app-training/src/core/context-catalog.d.ts.map +0 -1
- package/apps/app-training/src/core/context-catalog.js +0 -259
- package/apps/app-training/src/core/context-types.d.ts +0 -3
- package/apps/app-training/src/core/context-types.d.ts.map +0 -1
- package/apps/app-training/src/core/context-types.js +0 -11
- package/apps/app-training/src/core/dataset-generator.d.ts +0 -135
- package/apps/app-training/src/core/dataset-generator.d.ts.map +0 -1
- package/apps/app-training/src/core/dataset-generator.js +0 -703
- package/apps/app-training/src/core/replay-validator.d.ts +0 -96
- package/apps/app-training/src/core/replay-validator.d.ts.map +0 -1
- package/apps/app-training/src/core/replay-validator.js +0 -265
- package/apps/app-training/src/core/roleplay-executor.d.ts +0 -123
- package/apps/app-training/src/core/roleplay-executor.d.ts.map +0 -1
- package/apps/app-training/src/core/roleplay-executor.js +0 -645
- package/apps/app-training/src/core/roleplay-trajectories.d.ts +0 -54
- package/apps/app-training/src/core/roleplay-trajectories.d.ts.map +0 -1
- package/apps/app-training/src/core/roleplay-trajectories.js +0 -73
- package/apps/app-training/src/core/scenario-blueprints.d.ts +0 -62
- package/apps/app-training/src/core/scenario-blueprints.d.ts.map +0 -1
- package/apps/app-training/src/core/scenario-blueprints.js +0 -790
- package/apps/app-training/src/core/trajectory-task-datasets.d.ts +0 -38
- package/apps/app-training/src/core/trajectory-task-datasets.d.ts.map +0 -1
- package/apps/app-training/src/core/trajectory-task-datasets.js +0 -281
- package/apps/app-training/src/core/vertex-tuning.d.ts +0 -139
- package/apps/app-training/src/core/vertex-tuning.d.ts.map +0 -1
- package/apps/app-training/src/core/vertex-tuning.js +0 -234
- package/packages/agent/src/inbox/channel-deep-links.d.ts.map +0 -1
- package/packages/agent/src/inbox/config.d.ts.map +0 -1
- package/packages/agent/src/inbox/message-fetcher.d.ts.map +0 -1
- package/packages/agent/src/inbox/reflection.d.ts.map +0 -1
- package/packages/agent/src/inbox/repository.d.ts.map +0 -1
- package/packages/agent/src/inbox/triage-classifier.d.ts.map +0 -1
- package/packages/agent/src/inbox/types.d.ts.map +0 -1
- package/packages/agent/src/training/cli.d.ts +0 -2
- package/packages/agent/src/training/cli.d.ts.map +0 -1
- package/packages/agent/src/training/cli.js +0 -2
- package/packages/agent/src/training/context-audit.d.ts +0 -2
- package/packages/agent/src/training/context-audit.d.ts.map +0 -1
- package/packages/agent/src/training/context-audit.js +0 -2
- package/packages/agent/src/training/context-catalog.d.ts +0 -2
- package/packages/agent/src/training/context-catalog.d.ts.map +0 -1
- package/packages/agent/src/training/context-catalog.js +0 -2
- package/packages/agent/src/training/context-types.d.ts +0 -2
- package/packages/agent/src/training/context-types.d.ts.map +0 -1
- package/packages/agent/src/training/context-types.js +0 -2
- package/packages/agent/src/training/dataset-generator.d.ts +0 -2
- package/packages/agent/src/training/dataset-generator.d.ts.map +0 -1
- package/packages/agent/src/training/dataset-generator.js +0 -2
- package/packages/agent/src/training/replay-validator.d.ts +0 -2
- package/packages/agent/src/training/replay-validator.d.ts.map +0 -1
- package/packages/agent/src/training/replay-validator.js +0 -2
- package/packages/agent/src/training/roleplay-executor.d.ts +0 -2
- package/packages/agent/src/training/roleplay-executor.d.ts.map +0 -1
- package/packages/agent/src/training/roleplay-executor.js +0 -2
- package/packages/agent/src/training/roleplay-trajectories.d.ts +0 -2
- package/packages/agent/src/training/roleplay-trajectories.d.ts.map +0 -1
- package/packages/agent/src/training/roleplay-trajectories.js +0 -2
- package/packages/agent/src/training/scenario-blueprints.d.ts +0 -2
- package/packages/agent/src/training/scenario-blueprints.d.ts.map +0 -1
- package/packages/agent/src/training/scenario-blueprints.js +0 -2
- package/packages/agent/src/training/trajectory-task-datasets.d.ts +0 -2
- package/packages/agent/src/training/trajectory-task-datasets.d.ts.map +0 -1
- package/packages/agent/src/training/trajectory-task-datasets.js +0 -2
- package/packages/agent/src/training/vertex-tuning.d.ts +0 -2
- package/packages/agent/src/training/vertex-tuning.d.ts.map +0 -1
- package/packages/agent/src/training/vertex-tuning.js +0 -2
- package/packages/typescript/src/features/orchestrator/actions/coding-task-handlers.d.ts +0 -41
- package/packages/typescript/src/features/orchestrator/actions/coding-task-handlers.d.ts.map +0 -1
- package/packages/typescript/src/features/orchestrator/actions/coding-task-handlers.js +0 -443
- package/packages/typescript/src/features/orchestrator/actions/coding-task-helpers.d.ts +0 -34
- package/packages/typescript/src/features/orchestrator/actions/coding-task-helpers.d.ts.map +0 -1
- package/packages/typescript/src/features/orchestrator/actions/coding-task-helpers.js +0 -171
- package/packages/typescript/src/features/orchestrator/actions/eval-metadata.d.ts +0 -11
- package/packages/typescript/src/features/orchestrator/actions/eval-metadata.d.ts.map +0 -1
- package/packages/typescript/src/features/orchestrator/actions/eval-metadata.js +0 -55
- package/packages/typescript/src/features/orchestrator/actions/finalize-workspace.d.ts +0 -11
- package/packages/typescript/src/features/orchestrator/actions/finalize-workspace.d.ts.map +0 -1
- package/packages/typescript/src/features/orchestrator/actions/finalize-workspace.js +0 -214
- package/packages/typescript/src/features/orchestrator/actions/list-agents.d.ts +0 -13
- package/packages/typescript/src/features/orchestrator/actions/list-agents.d.ts.map +0 -1
- package/packages/typescript/src/features/orchestrator/actions/list-agents.js +0 -174
- package/packages/typescript/src/features/orchestrator/actions/manage-issues.d.ts +0 -11
- package/packages/typescript/src/features/orchestrator/actions/manage-issues.d.ts.map +0 -1
- package/packages/typescript/src/features/orchestrator/actions/manage-issues.js +0 -428
- package/packages/typescript/src/features/orchestrator/actions/provision-workspace.d.ts +0 -11
- package/packages/typescript/src/features/orchestrator/actions/provision-workspace.d.ts.map +0 -1
- package/packages/typescript/src/features/orchestrator/actions/provision-workspace.js +0 -189
- package/packages/typescript/src/features/orchestrator/actions/send-to-agent.d.ts +0 -12
- package/packages/typescript/src/features/orchestrator/actions/send-to-agent.d.ts.map +0 -1
- package/packages/typescript/src/features/orchestrator/actions/send-to-agent.js +0 -265
- package/packages/typescript/src/features/orchestrator/actions/spawn-agent.d.ts +0 -12
- package/packages/typescript/src/features/orchestrator/actions/spawn-agent.d.ts.map +0 -1
- package/packages/typescript/src/features/orchestrator/actions/spawn-agent.js +0 -356
- package/packages/typescript/src/features/orchestrator/actions/start-coding-task.d.ts +0 -22
- package/packages/typescript/src/features/orchestrator/actions/start-coding-task.d.ts.map +0 -1
- package/packages/typescript/src/features/orchestrator/actions/start-coding-task.js +0 -270
- package/packages/typescript/src/features/orchestrator/actions/stop-agent.d.ts +0 -12
- package/packages/typescript/src/features/orchestrator/actions/stop-agent.d.ts.map +0 -1
- package/packages/typescript/src/features/orchestrator/actions/stop-agent.js +0 -192
- package/packages/typescript/src/features/orchestrator/actions/task-control.d.ts +0 -3
- package/packages/typescript/src/features/orchestrator/actions/task-control.d.ts.map +0 -1
- package/packages/typescript/src/features/orchestrator/actions/task-control.js +0 -217
- package/packages/typescript/src/features/orchestrator/actions/task-history.d.ts +0 -3
- package/packages/typescript/src/features/orchestrator/actions/task-history.d.ts.map +0 -1
- package/packages/typescript/src/features/orchestrator/actions/task-history.js +0 -323
- package/packages/typescript/src/features/orchestrator/actions/task-share.d.ts +0 -3
- package/packages/typescript/src/features/orchestrator/actions/task-share.d.ts.map +0 -1
- package/packages/typescript/src/features/orchestrator/actions/task-share.js +0 -168
- package/packages/typescript/src/features/orchestrator/actions/task-thread-target.d.ts +0 -11
- package/packages/typescript/src/features/orchestrator/actions/task-thread-target.d.ts.map +0 -1
- package/packages/typescript/src/features/orchestrator/actions/task-thread-target.js +0 -68
- package/packages/typescript/src/features/orchestrator/api/agent-routes.d.ts +0 -18
- package/packages/typescript/src/features/orchestrator/api/agent-routes.d.ts.map +0 -1
- package/packages/typescript/src/features/orchestrator/api/agent-routes.js +0 -654
- package/packages/typescript/src/features/orchestrator/api/coordinator-routes.d.ts +0 -22
- package/packages/typescript/src/features/orchestrator/api/coordinator-routes.d.ts.map +0 -1
- package/packages/typescript/src/features/orchestrator/api/coordinator-routes.js +0 -403
- package/packages/typescript/src/features/orchestrator/api/hook-routes.d.ts +0 -18
- package/packages/typescript/src/features/orchestrator/api/hook-routes.d.ts.map +0 -1
- package/packages/typescript/src/features/orchestrator/api/hook-routes.js +0 -164
- package/packages/typescript/src/features/orchestrator/api/issue-routes.d.ts +0 -17
- package/packages/typescript/src/features/orchestrator/api/issue-routes.d.ts.map +0 -1
- package/packages/typescript/src/features/orchestrator/api/issue-routes.js +0 -132
- package/packages/typescript/src/features/orchestrator/api/routes.d.ts +0 -37
- package/packages/typescript/src/features/orchestrator/api/routes.d.ts.map +0 -1
- package/packages/typescript/src/features/orchestrator/api/routes.js +0 -96
- package/packages/typescript/src/features/orchestrator/api/workspace-routes.d.ts +0 -17
- package/packages/typescript/src/features/orchestrator/api/workspace-routes.d.ts.map +0 -1
- package/packages/typescript/src/features/orchestrator/api/workspace-routes.js +0 -149
- package/packages/typescript/src/features/orchestrator/base-plugin.d.ts +0 -19
- package/packages/typescript/src/features/orchestrator/base-plugin.d.ts.map +0 -1
- package/packages/typescript/src/features/orchestrator/base-plugin.js +0 -75
- package/packages/typescript/src/features/orchestrator/claude-jsonl-completion-watcher.d.ts +0 -101
- package/packages/typescript/src/features/orchestrator/claude-jsonl-completion-watcher.d.ts.map +0 -1
- package/packages/typescript/src/features/orchestrator/claude-jsonl-completion-watcher.js +0 -310
- package/packages/typescript/src/features/orchestrator/index.d.ts +0 -33
- package/packages/typescript/src/features/orchestrator/index.d.ts.map +0 -1
- package/packages/typescript/src/features/orchestrator/index.js +0 -30
- package/packages/typescript/src/features/orchestrator/patch-agent-orchestrator-plugin.d.ts +0 -15
- package/packages/typescript/src/features/orchestrator/patch-agent-orchestrator-plugin.d.ts.map +0 -1
- package/packages/typescript/src/features/orchestrator/patch-agent-orchestrator-plugin.js +0 -1449
- package/packages/typescript/src/features/orchestrator/providers/action-examples.d.ts +0 -14
- package/packages/typescript/src/features/orchestrator/providers/action-examples.d.ts.map +0 -1
- package/packages/typescript/src/features/orchestrator/providers/action-examples.js +0 -151
- package/packages/typescript/src/features/orchestrator/providers/active-workspace-context.d.ts +0 -13
- package/packages/typescript/src/features/orchestrator/providers/active-workspace-context.d.ts.map +0 -1
- package/packages/typescript/src/features/orchestrator/providers/active-workspace-context.js +0 -142
- package/packages/typescript/src/features/orchestrator/services/agent-credentials.d.ts +0 -6
- package/packages/typescript/src/features/orchestrator/services/agent-credentials.d.ts.map +0 -1
- package/packages/typescript/src/features/orchestrator/services/agent-credentials.js +0 -91
- package/packages/typescript/src/features/orchestrator/services/agent-metrics.d.ts +0 -30
- package/packages/typescript/src/features/orchestrator/services/agent-metrics.d.ts.map +0 -1
- package/packages/typescript/src/features/orchestrator/services/agent-metrics.js +0 -54
- package/packages/typescript/src/features/orchestrator/services/agent-selection.d.ts +0 -53
- package/packages/typescript/src/features/orchestrator/services/agent-selection.d.ts.map +0 -1
- package/packages/typescript/src/features/orchestrator/services/agent-selection.js +0 -70
- package/packages/typescript/src/features/orchestrator/services/ansi-utils.d.ts +0 -61
- package/packages/typescript/src/features/orchestrator/services/ansi-utils.d.ts.map +0 -1
- package/packages/typescript/src/features/orchestrator/services/ansi-utils.js +0 -252
- package/packages/typescript/src/features/orchestrator/services/config-env.d.ts +0 -13
- package/packages/typescript/src/features/orchestrator/services/config-env.d.ts.map +0 -1
- package/packages/typescript/src/features/orchestrator/services/config-env.js +0 -37
- package/packages/typescript/src/features/orchestrator/services/coordinator-event-normalizer.d.ts +0 -50
- package/packages/typescript/src/features/orchestrator/services/coordinator-event-normalizer.d.ts.map +0 -1
- package/packages/typescript/src/features/orchestrator/services/coordinator-event-normalizer.js +0 -184
- package/packages/typescript/src/features/orchestrator/services/debug-capture.d.ts +0 -38
- package/packages/typescript/src/features/orchestrator/services/debug-capture.d.ts.map +0 -1
- package/packages/typescript/src/features/orchestrator/services/debug-capture.js +0 -113
- package/packages/typescript/src/features/orchestrator/services/pty-auto-response.d.ts +0 -30
- package/packages/typescript/src/features/orchestrator/services/pty-auto-response.d.ts.map +0 -1
- package/packages/typescript/src/features/orchestrator/services/pty-auto-response.js +0 -146
- package/packages/typescript/src/features/orchestrator/services/pty-init.d.ts +0 -54
- package/packages/typescript/src/features/orchestrator/services/pty-init.d.ts.map +0 -1
- package/packages/typescript/src/features/orchestrator/services/pty-init.js +0 -315
- package/packages/typescript/src/features/orchestrator/services/pty-service.d.ts +0 -175
- package/packages/typescript/src/features/orchestrator/services/pty-service.d.ts.map +0 -1
- package/packages/typescript/src/features/orchestrator/services/pty-service.js +0 -1469
- package/packages/typescript/src/features/orchestrator/services/pty-session-io.d.ts +0 -49
- package/packages/typescript/src/features/orchestrator/services/pty-session-io.d.ts.map +0 -1
- package/packages/typescript/src/features/orchestrator/services/pty-session-io.js +0 -180
- package/packages/typescript/src/features/orchestrator/services/pty-spawn.d.ts +0 -53
- package/packages/typescript/src/features/orchestrator/services/pty-spawn.d.ts.map +0 -1
- package/packages/typescript/src/features/orchestrator/services/pty-spawn.js +0 -280
- package/packages/typescript/src/features/orchestrator/services/pty-types.d.ts +0 -80
- package/packages/typescript/src/features/orchestrator/services/pty-types.d.ts.map +0 -1
- package/packages/typescript/src/features/orchestrator/services/pty-types.js +0 -51
- package/packages/typescript/src/features/orchestrator/services/repo-input.d.ts +0 -16
- package/packages/typescript/src/features/orchestrator/services/repo-input.d.ts.map +0 -1
- package/packages/typescript/src/features/orchestrator/services/repo-input.js +0 -88
- package/packages/typescript/src/features/orchestrator/services/stall-classifier.d.ts +0 -69
- package/packages/typescript/src/features/orchestrator/services/stall-classifier.d.ts.map +0 -1
- package/packages/typescript/src/features/orchestrator/services/stall-classifier.js +0 -446
- package/packages/typescript/src/features/orchestrator/services/swarm-coordinator-prompts.d.ts +0 -97
- package/packages/typescript/src/features/orchestrator/services/swarm-coordinator-prompts.d.ts.map +0 -1
- package/packages/typescript/src/features/orchestrator/services/swarm-coordinator-prompts.js +0 -342
- package/packages/typescript/src/features/orchestrator/services/swarm-coordinator.d.ts +0 -421
- package/packages/typescript/src/features/orchestrator/services/swarm-coordinator.d.ts.map +0 -1
- package/packages/typescript/src/features/orchestrator/services/swarm-coordinator.js +0 -2356
- package/packages/typescript/src/features/orchestrator/services/swarm-decision-loop.d.ts +0 -52
- package/packages/typescript/src/features/orchestrator/services/swarm-decision-loop.d.ts.map +0 -1
- package/packages/typescript/src/features/orchestrator/services/swarm-decision-loop.js +0 -1538
- package/packages/typescript/src/features/orchestrator/services/swarm-event-triage.d.ts +0 -49
- package/packages/typescript/src/features/orchestrator/services/swarm-event-triage.d.ts.map +0 -1
- package/packages/typescript/src/features/orchestrator/services/swarm-event-triage.js +0 -171
- package/packages/typescript/src/features/orchestrator/services/swarm-history.d.ts +0 -27
- package/packages/typescript/src/features/orchestrator/services/swarm-history.d.ts.map +0 -1
- package/packages/typescript/src/features/orchestrator/services/swarm-history.js +0 -148
- package/packages/typescript/src/features/orchestrator/services/swarm-idle-watchdog.d.ts +0 -22
- package/packages/typescript/src/features/orchestrator/services/swarm-idle-watchdog.d.ts.map +0 -1
- package/packages/typescript/src/features/orchestrator/services/swarm-idle-watchdog.js +0 -265
- package/packages/typescript/src/features/orchestrator/services/task-acceptance.d.ts +0 -8
- package/packages/typescript/src/features/orchestrator/services/task-acceptance.d.ts.map +0 -1
- package/packages/typescript/src/features/orchestrator/services/task-acceptance.js +0 -114
- package/packages/typescript/src/features/orchestrator/services/task-agent-auth.d.ts +0 -68
- package/packages/typescript/src/features/orchestrator/services/task-agent-auth.d.ts.map +0 -1
- package/packages/typescript/src/features/orchestrator/services/task-agent-auth.js +0 -559
- package/packages/typescript/src/features/orchestrator/services/task-agent-frameworks.d.ts +0 -82
- package/packages/typescript/src/features/orchestrator/services/task-agent-frameworks.d.ts.map +0 -1
- package/packages/typescript/src/features/orchestrator/services/task-agent-frameworks.js +0 -738
- package/packages/typescript/src/features/orchestrator/services/task-kind.d.ts +0 -3
- package/packages/typescript/src/features/orchestrator/services/task-kind.d.ts.map +0 -1
- package/packages/typescript/src/features/orchestrator/services/task-kind.js +0 -40
- package/packages/typescript/src/features/orchestrator/services/task-policy.d.ts +0 -17
- package/packages/typescript/src/features/orchestrator/services/task-policy.d.ts.map +0 -1
- package/packages/typescript/src/features/orchestrator/services/task-policy.js +0 -226
- package/packages/typescript/src/features/orchestrator/services/task-registry.d.ts +0 -550
- package/packages/typescript/src/features/orchestrator/services/task-registry.d.ts.map +0 -1
- package/packages/typescript/src/features/orchestrator/services/task-registry.js +0 -2182
- package/packages/typescript/src/features/orchestrator/services/task-share.d.ts +0 -18
- package/packages/typescript/src/features/orchestrator/services/task-share.d.ts.map +0 -1
- package/packages/typescript/src/features/orchestrator/services/task-share.js +0 -159
- package/packages/typescript/src/features/orchestrator/services/task-validation.d.ts +0 -69
- package/packages/typescript/src/features/orchestrator/services/task-validation.d.ts.map +0 -1
- package/packages/typescript/src/features/orchestrator/services/task-validation.js +0 -587
- package/packages/typescript/src/features/orchestrator/services/task-verifier-runner.d.ts +0 -5
- package/packages/typescript/src/features/orchestrator/services/task-verifier-runner.d.ts.map +0 -1
- package/packages/typescript/src/features/orchestrator/services/task-verifier-runner.js +0 -372
- package/packages/typescript/src/features/orchestrator/services/trajectory-context.d.ts +0 -73
- package/packages/typescript/src/features/orchestrator/services/trajectory-context.d.ts.map +0 -1
- package/packages/typescript/src/features/orchestrator/services/trajectory-context.js +0 -64
- package/packages/typescript/src/features/orchestrator/services/trajectory-feedback.d.ts +0 -53
- package/packages/typescript/src/features/orchestrator/services/trajectory-feedback.d.ts.map +0 -1
- package/packages/typescript/src/features/orchestrator/services/trajectory-feedback.js +0 -260
- package/packages/typescript/src/features/orchestrator/services/workspace-git-ops.d.ts +0 -28
- package/packages/typescript/src/features/orchestrator/services/workspace-git-ops.d.ts.map +0 -1
- package/packages/typescript/src/features/orchestrator/services/workspace-git-ops.js +0 -105
- package/packages/typescript/src/features/orchestrator/services/workspace-github.d.ts +0 -58
- package/packages/typescript/src/features/orchestrator/services/workspace-github.d.ts.map +0 -1
- package/packages/typescript/src/features/orchestrator/services/workspace-github.js +0 -139
- package/packages/typescript/src/features/orchestrator/services/workspace-lifecycle.d.ts +0 -18
- package/packages/typescript/src/features/orchestrator/services/workspace-lifecycle.d.ts.map +0 -1
- package/packages/typescript/src/features/orchestrator/services/workspace-lifecycle.js +0 -86
- package/packages/typescript/src/features/orchestrator/services/workspace-service.d.ts +0 -118
- package/packages/typescript/src/features/orchestrator/services/workspace-service.d.ts.map +0 -1
- package/packages/typescript/src/features/orchestrator/services/workspace-service.js +0 -533
- package/packages/typescript/src/features/orchestrator/services/workspace-types.d.ts +0 -81
- package/packages/typescript/src/features/orchestrator/services/workspace-types.d.ts.map +0 -1
- package/packages/typescript/src/features/orchestrator/services/workspace-types.js +0 -8
- package/packages/typescript/src/features/orchestrator/task-progress-streamer.d.ts +0 -38
- package/packages/typescript/src/features/orchestrator/task-progress-streamer.d.ts.map +0 -1
- package/packages/typescript/src/features/orchestrator/task-progress-streamer.js +0 -293
- /package/{packages/agent → apps/app-lifeops}/src/inbox/channel-deep-links.d.ts +0 -0
- /package/{packages/agent → apps/app-lifeops}/src/inbox/channel-deep-links.js +0 -0
- /package/{packages/agent → apps/app-lifeops}/src/inbox/config.d.ts +0 -0
- /package/{packages/agent → apps/app-lifeops}/src/inbox/message-fetcher.d.ts +0 -0
- /package/{packages/agent → apps/app-lifeops}/src/inbox/message-fetcher.js +0 -0
- /package/{packages/agent → apps/app-lifeops}/src/inbox/reflection.d.ts +0 -0
- /package/{packages/agent → apps/app-lifeops}/src/inbox/reflection.js +0 -0
- /package/{packages/agent → apps/app-lifeops}/src/inbox/repository.d.ts +0 -0
- /package/{packages/agent → apps/app-lifeops}/src/inbox/repository.js +0 -0
- /package/{packages/agent → apps/app-lifeops}/src/inbox/triage-classifier.d.ts +0 -0
- /package/{packages/agent → apps/app-lifeops}/src/inbox/triage-classifier.js +0 -0
- /package/{packages/agent → apps/app-lifeops}/src/inbox/types.d.ts +0 -0
- /package/{packages/agent → apps/app-lifeops}/src/inbox/types.js +0 -0
|
@@ -1,1469 +0,0 @@
|
|
|
1
|
-
/** @module services/pty-service */
|
|
2
|
-
import { appendFile, mkdir, readFile, writeFile } from "node:fs/promises";
|
|
3
|
-
import { dirname, join } from "node:path";
|
|
4
|
-
import { logger } from "@elizaos/core";
|
|
5
|
-
import { checkAdapters, createAdapter, generateApprovalConfig, } from "coding-agent-adapters";
|
|
6
|
-
import { PTYConsoleBridge } from "pty-console";
|
|
7
|
-
import { AgentMetricsTracker } from "./agent-metrics.js";
|
|
8
|
-
import { captureTaskResponse, cleanForChat, extractCompletionSummary, peekTaskResponse, } from "./ansi-utils.js";
|
|
9
|
-
import { readConfigEnvKey } from "./config-env.js";
|
|
10
|
-
import { normalizeCoordinatorEvent, } from "./coordinator-event-normalizer.js";
|
|
11
|
-
import { captureFeed, captureLifecycle, captureSessionOpen, isDebugCaptureEnabled, } from "./debug-capture.js";
|
|
12
|
-
import { handleGeminiAuth as handleGeminiAuthFlow, pushDefaultRules as pushDefaultAutoResponseRules, } from "./pty-auto-response.js";
|
|
13
|
-
import { initializePTYManager } from "./pty-init.js";
|
|
14
|
-
import { getSessionOutput as getSessionOutputIO, sendKeysToSession as sendKeysToSessionIO, sendToSession as sendToSessionIO, stopSession as stopSessionIO, subscribeToOutput as subscribeToOutputIO, } from "./pty-session-io.js";
|
|
15
|
-
import { buildSpawnConfig, setupDeferredTaskDelivery, setupOutputBuffer, } from "./pty-spawn.js";
|
|
16
|
-
import { isPiAgentType, toPiCommand } from "./pty-types.js";
|
|
17
|
-
import { classifyAndDecideForCoordinator, classifyStallOutput, } from "./stall-classifier.js";
|
|
18
|
-
import { SwarmCoordinator } from "./swarm-coordinator.js";
|
|
19
|
-
import { POST_SEND_COOLDOWN_MS } from "./swarm-decision-loop.js";
|
|
20
|
-
import { assistTaskAgentBrowserLogin, augmentTaskAgentPreflightResults, getTaskAgentLoginHint, launchTaskAgentAuthFlow, probeTaskAgentAuth, } from "./task-agent-auth.js";
|
|
21
|
-
import { buildTaskAgentTaskProfile, clearTaskAgentFrameworkStateCache, getTaskAgentFrameworkState, } from "./task-agent-frameworks.js";
|
|
22
|
-
/**
|
|
23
|
-
* Grace period after `task_complete` before auto-stopping a PTY session.
|
|
24
|
-
* Short enough that stale subagents don't linger (and trigger spurious
|
|
25
|
-
* stall classifications that fire phantom heartbeats in downstream
|
|
26
|
-
* streamers), long enough that any backgrounded processes spawned by
|
|
27
|
-
* the agent can detach from the PTY parent before it exits.
|
|
28
|
-
*
|
|
29
|
-
* Previously 5000 ms in our nubs/full-working-state fork branch
|
|
30
|
-
* (commit 66a9a74); upstream alpha removed the auto-stop entirely in a
|
|
31
|
-
* later refactor which caused subagents to sit around for minutes after
|
|
32
|
-
* finishing their turn.
|
|
33
|
-
*/
|
|
34
|
-
const TASK_COMPLETE_STOP_DELAY_MS = 5_000;
|
|
35
|
-
/**
|
|
36
|
-
* Portable safety floor injected into every spawned coding-agent's memory
|
|
37
|
-
* file. Locks the agent to its allocated workspace dir so it never wanders
|
|
38
|
-
* into $HOME or /tmp regardless of caller-supplied memoryContent. Deployment-
|
|
39
|
-
* specific conventions (hosting, URLs, etc.) belong in caller memoryContent.
|
|
40
|
-
*/
|
|
41
|
-
function buildWorkspaceLockMemory(workdir) {
|
|
42
|
-
return `# Workspace
|
|
43
|
-
|
|
44
|
-
Your 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.`;
|
|
45
|
-
}
|
|
46
|
-
function prependWorkspaceLockToTask(task, workspaceLock) {
|
|
47
|
-
if (!task?.trim()) {
|
|
48
|
-
return undefined;
|
|
49
|
-
}
|
|
50
|
-
return `${workspaceLock}\n\n---\n\n${task}`;
|
|
51
|
-
}
|
|
52
|
-
// Re-export for backward compatibility
|
|
53
|
-
export { normalizeAgentType } from "./pty-types.js";
|
|
54
|
-
/**
|
|
55
|
-
* Retrieve the SwarmCoordinator from the PTYService registered on the runtime.
|
|
56
|
-
* Returns undefined if PTYService or coordinator is not available.
|
|
57
|
-
*/
|
|
58
|
-
export function getCoordinator(runtime) {
|
|
59
|
-
const ptyService = runtime.getService("PTY_SERVICE");
|
|
60
|
-
return ptyService?.coordinator ?? undefined;
|
|
61
|
-
}
|
|
62
|
-
export class PTYService {
|
|
63
|
-
static serviceType = "PTY_SERVICE";
|
|
64
|
-
capabilityDescription = "Manages asynchronous PTY task-agent sessions for open-ended background work";
|
|
65
|
-
runtime;
|
|
66
|
-
manager = null;
|
|
67
|
-
usingBunWorker = false;
|
|
68
|
-
serviceConfig;
|
|
69
|
-
sessionNames = new Map();
|
|
70
|
-
sessionMetadata = new Map();
|
|
71
|
-
sessionWorkdirs = new Map();
|
|
72
|
-
eventCallbacks = [];
|
|
73
|
-
normalizedEventCallbacks = [];
|
|
74
|
-
outputUnsubscribers = new Map();
|
|
75
|
-
transcriptUnsubscribers = new Map();
|
|
76
|
-
sessionOutputBuffers = new Map();
|
|
77
|
-
completionReconcileTimers = new Map();
|
|
78
|
-
completionSignalSince = new Map();
|
|
79
|
-
terminalSessionStates = new Map();
|
|
80
|
-
adapterCache = new Map();
|
|
81
|
-
/** Tracks the buffer index when a task was sent, so we can capture the response on completion */
|
|
82
|
-
taskResponseMarkers = new Map();
|
|
83
|
-
/** Captures "Task completion trace" log entries from worker stderr (rolling, capped at 200) */
|
|
84
|
-
traceEntries = [];
|
|
85
|
-
static MAX_TRACE_ENTRIES = 200;
|
|
86
|
-
/** Lightweight per-agent-type metrics for observability */
|
|
87
|
-
metricsTracker = new AgentMetricsTracker();
|
|
88
|
-
/** Active provider auth helper processes keyed by agent type. */
|
|
89
|
-
activeAuthFlows = new Map();
|
|
90
|
-
/** Background auth-recovery watchers keyed by blocked session id. */
|
|
91
|
-
authRecoveryTimers = new Map();
|
|
92
|
-
/** Console bridge for terminal output streaming and buffered hydration */
|
|
93
|
-
consoleBridge = null;
|
|
94
|
-
/** Swarm coordinator instance (if active). Accessed via getCoordinator(runtime). */
|
|
95
|
-
coordinator = null;
|
|
96
|
-
constructor(runtime, config = {}) {
|
|
97
|
-
this.runtime = runtime;
|
|
98
|
-
this.serviceConfig = {
|
|
99
|
-
maxLogLines: config.maxLogLines ?? 1000,
|
|
100
|
-
debug: config.debug ?? false,
|
|
101
|
-
registerCodingAdapters: config.registerCodingAdapters ?? true,
|
|
102
|
-
maxConcurrentSessions: config.maxConcurrentSessions ?? 8,
|
|
103
|
-
defaultApprovalPreset: config.defaultApprovalPreset ?? "autonomous",
|
|
104
|
-
};
|
|
105
|
-
}
|
|
106
|
-
static async start(runtime) {
|
|
107
|
-
const config = runtime.getSetting("PTY_SERVICE_CONFIG");
|
|
108
|
-
const service = new PTYService(runtime, config ?? {});
|
|
109
|
-
await service.initialize();
|
|
110
|
-
// Wire the SwarmCoordinator — done here instead of plugin init()
|
|
111
|
-
// because ElizaOS calls Service.start() reliably but may not call
|
|
112
|
-
// plugin.init() depending on the registration path.
|
|
113
|
-
// Guard: the framework may call start() more than once — skip if
|
|
114
|
-
// a coordinator is already registered on this runtime.
|
|
115
|
-
const servicesMap = runtime.services;
|
|
116
|
-
const existing = servicesMap?.get?.("SWARM_COORDINATOR");
|
|
117
|
-
if (existing && existing.length > 0) {
|
|
118
|
-
service.coordinator = existing[0];
|
|
119
|
-
logger.info("[PTYService] SwarmCoordinator already registered, skipping duplicate start");
|
|
120
|
-
}
|
|
121
|
-
else {
|
|
122
|
-
try {
|
|
123
|
-
const coordinator = new SwarmCoordinator(runtime);
|
|
124
|
-
await coordinator.start(service);
|
|
125
|
-
service.coordinator = coordinator;
|
|
126
|
-
// Register the coordinator as a discoverable runtime service so
|
|
127
|
-
// server.ts can find it via runtime.getService("SWARM_COORDINATOR")
|
|
128
|
-
// without a hard import from this plugin package.
|
|
129
|
-
// We bypass registerService() (which would call start() again) and
|
|
130
|
-
// write directly to the services map that getService() reads from.
|
|
131
|
-
servicesMap?.set?.("SWARM_COORDINATOR", [
|
|
132
|
-
coordinator,
|
|
133
|
-
]);
|
|
134
|
-
logger.info("[PTYService] SwarmCoordinator wired and started");
|
|
135
|
-
}
|
|
136
|
-
catch (err) {
|
|
137
|
-
logger.error(`[PTYService] Failed to wire SwarmCoordinator: ${err}`);
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
return service;
|
|
141
|
-
}
|
|
142
|
-
static async stopRuntime(runtime) {
|
|
143
|
-
const service = runtime.getService("PTY_SERVICE");
|
|
144
|
-
if (service) {
|
|
145
|
-
await service.stop();
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
async initialize() {
|
|
149
|
-
const result = await initializePTYManager({
|
|
150
|
-
serviceConfig: this.serviceConfig,
|
|
151
|
-
classifyStall: (id, out) => this.classifyStall(id, out),
|
|
152
|
-
emitEvent: (id, event, data) => this.emitEvent(id, event, data),
|
|
153
|
-
handleGeminiAuth: (id) => this.handleGeminiAuth(id),
|
|
154
|
-
sessionOutputBuffers: this.sessionOutputBuffers,
|
|
155
|
-
taskResponseMarkers: this.taskResponseMarkers,
|
|
156
|
-
metricsTracker: this.metricsTracker,
|
|
157
|
-
traceEntries: this.traceEntries,
|
|
158
|
-
maxTraceEntries: PTYService.MAX_TRACE_ENTRIES,
|
|
159
|
-
log: (msg) => this.log(msg),
|
|
160
|
-
handleWorkerExit: (info) => this.handleWorkerExit(info),
|
|
161
|
-
hasActiveTask: (sessionId) => {
|
|
162
|
-
const coordinator = this.coordinator;
|
|
163
|
-
if (!coordinator)
|
|
164
|
-
return false;
|
|
165
|
-
const taskCtx = coordinator.getTaskContext(sessionId);
|
|
166
|
-
// tool_running counts as active for PTY purposes — the task is
|
|
167
|
-
// still alive, just executing a tool. matches the same expansion
|
|
168
|
-
// applied to handleTurnComplete and drainPendingTurnComplete so
|
|
169
|
-
// tool-heavy scratch tasks aren't treated as inactive mid-run.
|
|
170
|
-
return (taskCtx?.status === "active" || taskCtx?.status === "tool_running");
|
|
171
|
-
},
|
|
172
|
-
hasTaskActivity: (sessionId) => {
|
|
173
|
-
const coordinator = this.coordinator;
|
|
174
|
-
if (!coordinator)
|
|
175
|
-
return false;
|
|
176
|
-
const taskCtx = coordinator.getTaskContext(sessionId);
|
|
177
|
-
if (!taskCtx)
|
|
178
|
-
return false;
|
|
179
|
-
// Task has activity if the initial task was delivered (agent started
|
|
180
|
-
// working) OR coordinator made decisions. The taskDelivered flag
|
|
181
|
-
// covers agents that finish without hitting any blocking prompts.
|
|
182
|
-
return taskCtx.taskDelivered || taskCtx.decisions.length > 0;
|
|
183
|
-
},
|
|
184
|
-
markTaskDelivered: (sessionId) => {
|
|
185
|
-
const coordinator = this.coordinator;
|
|
186
|
-
if (!coordinator)
|
|
187
|
-
return;
|
|
188
|
-
void coordinator.setTaskDelivered(sessionId);
|
|
189
|
-
},
|
|
190
|
-
});
|
|
191
|
-
this.manager = result.manager;
|
|
192
|
-
this.usingBunWorker = result.usingBunWorker;
|
|
193
|
-
// Wire console bridge for terminal output streaming / hydration
|
|
194
|
-
try {
|
|
195
|
-
this.consoleBridge = new PTYConsoleBridge(this.manager, {
|
|
196
|
-
maxBufferedCharsPerSession: 100_000,
|
|
197
|
-
});
|
|
198
|
-
this.log("PTYConsoleBridge wired");
|
|
199
|
-
}
|
|
200
|
-
catch (err) {
|
|
201
|
-
this.log(`Failed to wire PTYConsoleBridge: ${err}`);
|
|
202
|
-
}
|
|
203
|
-
this.log("PTYService initialized");
|
|
204
|
-
}
|
|
205
|
-
async stop() {
|
|
206
|
-
// Stop the coordinator if one was wired to this service
|
|
207
|
-
if (this.coordinator) {
|
|
208
|
-
await this.coordinator.stop();
|
|
209
|
-
// Remove from runtime services map
|
|
210
|
-
this.runtime.services.delete("SWARM_COORDINATOR");
|
|
211
|
-
this.coordinator = null;
|
|
212
|
-
}
|
|
213
|
-
if (this.consoleBridge) {
|
|
214
|
-
this.consoleBridge.close();
|
|
215
|
-
this.consoleBridge = null;
|
|
216
|
-
}
|
|
217
|
-
for (const unsubscribe of this.outputUnsubscribers.values()) {
|
|
218
|
-
unsubscribe();
|
|
219
|
-
}
|
|
220
|
-
this.outputUnsubscribers.clear();
|
|
221
|
-
for (const unsubscribe of this.transcriptUnsubscribers.values()) {
|
|
222
|
-
unsubscribe();
|
|
223
|
-
}
|
|
224
|
-
this.transcriptUnsubscribers.clear();
|
|
225
|
-
for (const timer of this.completionReconcileTimers.values()) {
|
|
226
|
-
clearInterval(timer);
|
|
227
|
-
}
|
|
228
|
-
this.completionReconcileTimers.clear();
|
|
229
|
-
this.completionSignalSince.clear();
|
|
230
|
-
for (const timer of this.authRecoveryTimers.values()) {
|
|
231
|
-
clearInterval(timer);
|
|
232
|
-
}
|
|
233
|
-
this.authRecoveryTimers.clear();
|
|
234
|
-
for (const flow of this.activeAuthFlows.values()) {
|
|
235
|
-
try {
|
|
236
|
-
flow.stop();
|
|
237
|
-
}
|
|
238
|
-
catch {
|
|
239
|
-
// Ignore auth-helper cleanup failures on shutdown.
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
this.activeAuthFlows.clear();
|
|
243
|
-
if (this.manager) {
|
|
244
|
-
await this.manager.shutdown();
|
|
245
|
-
this.manager = null;
|
|
246
|
-
}
|
|
247
|
-
this.sessionMetadata.clear();
|
|
248
|
-
this.sessionNames.clear();
|
|
249
|
-
this.sessionWorkdirs.clear();
|
|
250
|
-
this.sessionOutputBuffers.clear();
|
|
251
|
-
this.log("PTYService shutdown complete");
|
|
252
|
-
}
|
|
253
|
-
generateSessionId() {
|
|
254
|
-
return `pty-${Date.now()}-${crypto.randomUUID().slice(0, 8)}`;
|
|
255
|
-
}
|
|
256
|
-
/** Build a SessionIOContext from current instance state. */
|
|
257
|
-
ioContext() {
|
|
258
|
-
return {
|
|
259
|
-
manager: this.manager,
|
|
260
|
-
usingBunWorker: this.usingBunWorker,
|
|
261
|
-
sessionOutputBuffers: this.sessionOutputBuffers,
|
|
262
|
-
taskResponseMarkers: this.taskResponseMarkers,
|
|
263
|
-
outputUnsubscribers: this.outputUnsubscribers,
|
|
264
|
-
};
|
|
265
|
-
}
|
|
266
|
-
/**
|
|
267
|
-
* Spawn a new PTY session for a coding agent
|
|
268
|
-
*/
|
|
269
|
-
async spawnSession(options) {
|
|
270
|
-
if (!this.manager) {
|
|
271
|
-
throw new Error("PTYService not initialized");
|
|
272
|
-
}
|
|
273
|
-
const piRequested = isPiAgentType(options.agentType);
|
|
274
|
-
const resolvedAgentType = piRequested
|
|
275
|
-
? "shell"
|
|
276
|
-
: options.agentType;
|
|
277
|
-
const effectiveApprovalPreset = options.approvalPreset ??
|
|
278
|
-
(resolvedAgentType !== "shell" ? this.defaultApprovalPreset : undefined);
|
|
279
|
-
const maxSessions = this.serviceConfig.maxConcurrentSessions ?? 8;
|
|
280
|
-
const activeSessions = (await this.listSessions()).length;
|
|
281
|
-
if (activeSessions >= maxSessions) {
|
|
282
|
-
throw new Error(`Concurrent session limit reached (${maxSessions})`);
|
|
283
|
-
}
|
|
284
|
-
const sessionId = this.generateSessionId();
|
|
285
|
-
const workdir = options.workdir ?? process.cwd();
|
|
286
|
-
const workspaceLock = buildWorkspaceLockMemory(workdir);
|
|
287
|
-
const shouldWriteMemoryFile = resolvedAgentType !== "shell" && Boolean(options.memoryContent?.trim());
|
|
288
|
-
const effectiveInitialTask = shouldWriteMemoryFile
|
|
289
|
-
? options.initialTask
|
|
290
|
-
: prependWorkspaceLockToTask(options.initialTask, workspaceLock);
|
|
291
|
-
const resolvedInitialTask = piRequested
|
|
292
|
-
? toPiCommand(effectiveInitialTask)
|
|
293
|
-
: effectiveInitialTask;
|
|
294
|
-
// Store workdir for later retrieval
|
|
295
|
-
this.sessionWorkdirs.set(sessionId, workdir);
|
|
296
|
-
// Write memory content before spawning so the agent reads it on startup.
|
|
297
|
-
// Always prepend the workspace lock so the spawned agent stays inside its
|
|
298
|
-
// allocated workdir even when the caller passes nothing or unrelated rules.
|
|
299
|
-
if (shouldWriteMemoryFile) {
|
|
300
|
-
const fullMemory = options.memoryContent
|
|
301
|
-
? `${workspaceLock}\n\n---\n\n${options.memoryContent}`
|
|
302
|
-
: workspaceLock;
|
|
303
|
-
try {
|
|
304
|
-
const writtenPath = await this.writeMemoryFile(resolvedAgentType, workdir, fullMemory);
|
|
305
|
-
this.log(`Wrote memory file for ${resolvedAgentType}: ${writtenPath}`);
|
|
306
|
-
}
|
|
307
|
-
catch (err) {
|
|
308
|
-
this.log(`Failed to write memory file for ${resolvedAgentType}: ${err}`);
|
|
309
|
-
}
|
|
310
|
-
}
|
|
311
|
-
// Write approval config files to workspace before spawn
|
|
312
|
-
if (effectiveApprovalPreset && resolvedAgentType !== "shell") {
|
|
313
|
-
try {
|
|
314
|
-
const written = await this.getAdapter(resolvedAgentType).writeApprovalConfig(workdir, {
|
|
315
|
-
name: options.name,
|
|
316
|
-
type: resolvedAgentType,
|
|
317
|
-
workdir,
|
|
318
|
-
adapterConfig: { approvalPreset: effectiveApprovalPreset },
|
|
319
|
-
});
|
|
320
|
-
this.log(`Wrote approval config (${effectiveApprovalPreset}) for ${resolvedAgentType}: ${written.join(", ")}`);
|
|
321
|
-
}
|
|
322
|
-
catch (err) {
|
|
323
|
-
this.log(`Failed to write approval config: ${err}`);
|
|
324
|
-
}
|
|
325
|
-
}
|
|
326
|
-
// Inject agent-specific settings and HTTP hooks
|
|
327
|
-
const hookUrl = `http://localhost:${this.runtime.getSetting("SERVER_PORT") ?? "2138"}/api/coding-agents/hooks`;
|
|
328
|
-
if (resolvedAgentType === "claude") {
|
|
329
|
-
try {
|
|
330
|
-
const settingsPath = join(workdir, ".claude", "settings.json");
|
|
331
|
-
let settings = {};
|
|
332
|
-
try {
|
|
333
|
-
settings = JSON.parse(await readFile(settingsPath, "utf-8"));
|
|
334
|
-
}
|
|
335
|
-
catch {
|
|
336
|
-
// File may not exist yet
|
|
337
|
-
}
|
|
338
|
-
const permissions = settings.permissions ?? {};
|
|
339
|
-
permissions.allowedDirectories = [workdir];
|
|
340
|
-
settings.permissions = permissions;
|
|
341
|
-
// Inject HTTP hooks for deterministic state detection.
|
|
342
|
-
// Merge with existing hooks to preserve workspace-owned hook entries.
|
|
343
|
-
const adapter = this.getAdapter("claude");
|
|
344
|
-
const hookProtocol = adapter.getHookTelemetryProtocol({
|
|
345
|
-
httpUrl: hookUrl,
|
|
346
|
-
sessionId,
|
|
347
|
-
});
|
|
348
|
-
if (hookProtocol) {
|
|
349
|
-
const existingHooks = (settings.hooks ?? {});
|
|
350
|
-
settings.hooks = { ...existingHooks, ...hookProtocol.settingsHooks };
|
|
351
|
-
this.log(`Injecting HTTP hooks for session ${sessionId}`);
|
|
352
|
-
}
|
|
353
|
-
await mkdir(dirname(settingsPath), { recursive: true });
|
|
354
|
-
await writeFile(settingsPath, JSON.stringify(settings, null, 2), "utf-8");
|
|
355
|
-
this.log(`Wrote allowedDirectories [${workdir}] to ${settingsPath}`);
|
|
356
|
-
}
|
|
357
|
-
catch (err) {
|
|
358
|
-
this.log(`Failed to write Claude settings: ${err}`);
|
|
359
|
-
}
|
|
360
|
-
}
|
|
361
|
-
if (resolvedAgentType === "gemini") {
|
|
362
|
-
try {
|
|
363
|
-
const settingsPath = join(workdir, ".gemini", "settings.json");
|
|
364
|
-
let settings = {};
|
|
365
|
-
try {
|
|
366
|
-
settings = JSON.parse(await readFile(settingsPath, "utf-8"));
|
|
367
|
-
}
|
|
368
|
-
catch {
|
|
369
|
-
// File may not exist yet
|
|
370
|
-
}
|
|
371
|
-
// Inject command hooks that curl the orchestrator endpoint.
|
|
372
|
-
// Merge with existing hooks to preserve workspace-owned hook entries.
|
|
373
|
-
const adapter = this.getAdapter("gemini");
|
|
374
|
-
const hookProtocol = adapter.getHookTelemetryProtocol({
|
|
375
|
-
httpUrl: hookUrl,
|
|
376
|
-
sessionId,
|
|
377
|
-
});
|
|
378
|
-
if (hookProtocol) {
|
|
379
|
-
const existingHooks = (settings.hooks ?? {});
|
|
380
|
-
settings.hooks = { ...existingHooks, ...hookProtocol.settingsHooks };
|
|
381
|
-
this.log(`Injecting Gemini CLI hooks for session ${sessionId}`);
|
|
382
|
-
}
|
|
383
|
-
await mkdir(dirname(settingsPath), { recursive: true });
|
|
384
|
-
await writeFile(settingsPath, JSON.stringify(settings, null, 2), "utf-8");
|
|
385
|
-
}
|
|
386
|
-
catch (err) {
|
|
387
|
-
this.log(`Failed to write Gemini settings: ${err}`);
|
|
388
|
-
}
|
|
389
|
-
}
|
|
390
|
-
// Ensure injected config/memory files are gitignored so agents don't
|
|
391
|
-
// commit them. Appends to existing .gitignore if present.
|
|
392
|
-
if (resolvedAgentType !== "shell" && workdir !== process.cwd()) {
|
|
393
|
-
await this.ensureOrchestratorGitignore(workdir);
|
|
394
|
-
}
|
|
395
|
-
const spawnConfig = buildSpawnConfig(sessionId, {
|
|
396
|
-
...options,
|
|
397
|
-
agentType: resolvedAgentType,
|
|
398
|
-
initialTask: resolvedInitialTask,
|
|
399
|
-
approvalPreset: effectiveApprovalPreset,
|
|
400
|
-
}, workdir);
|
|
401
|
-
const session = await this.manager.spawn(spawnConfig);
|
|
402
|
-
this.terminalSessionStates.delete(session.id);
|
|
403
|
-
this.sessionNames.set(session.id, options.name);
|
|
404
|
-
// Store metadata separately (always include agentType for stall classification)
|
|
405
|
-
this.sessionMetadata.set(session.id, {
|
|
406
|
-
...options.metadata,
|
|
407
|
-
requestedType: options.metadata?.requestedType ?? options.agentType,
|
|
408
|
-
agentType: resolvedAgentType,
|
|
409
|
-
coordinatorManaged: !!options.skipAdapterAutoResponse,
|
|
410
|
-
});
|
|
411
|
-
// Build spawn context for delegating to extracted spawn modules
|
|
412
|
-
const ctx = {
|
|
413
|
-
manager: this.manager,
|
|
414
|
-
usingBunWorker: this.usingBunWorker,
|
|
415
|
-
serviceConfig: this.serviceConfig,
|
|
416
|
-
sessionMetadata: this.sessionMetadata,
|
|
417
|
-
sessionWorkdirs: this.sessionWorkdirs,
|
|
418
|
-
sessionOutputBuffers: this.sessionOutputBuffers,
|
|
419
|
-
outputUnsubscribers: this.outputUnsubscribers,
|
|
420
|
-
taskResponseMarkers: this.taskResponseMarkers,
|
|
421
|
-
getAdapter: (t) => this.getAdapter(t),
|
|
422
|
-
sendToSession: (id, input) => this.sendToSession(id, input),
|
|
423
|
-
sendKeysToSession: (id, keys) => this.sendKeysToSession(id, keys),
|
|
424
|
-
writeRawToSession: async (id, data) => {
|
|
425
|
-
if (!this.manager)
|
|
426
|
-
return;
|
|
427
|
-
if (this.usingBunWorker) {
|
|
428
|
-
await this.manager.writeRaw(id, data);
|
|
429
|
-
return;
|
|
430
|
-
}
|
|
431
|
-
const ptySession = this.manager.getSession(id);
|
|
432
|
-
ptySession?.writeRaw(data);
|
|
433
|
-
},
|
|
434
|
-
pushDefaultRules: (id, type) => this.pushDefaultRules(id, type),
|
|
435
|
-
toSessionInfo: (s, w) => this.toSessionInfo(s, w),
|
|
436
|
-
log: (msg) => this.log(msg),
|
|
437
|
-
markTaskDelivered: (sessionId) => {
|
|
438
|
-
const coordinator = this.coordinator;
|
|
439
|
-
if (!coordinator)
|
|
440
|
-
return;
|
|
441
|
-
void coordinator.setTaskDelivered(sessionId);
|
|
442
|
-
},
|
|
443
|
-
};
|
|
444
|
-
// Buffer output for Bun worker path (no logs() method available)
|
|
445
|
-
if (this.usingBunWorker) {
|
|
446
|
-
setupOutputBuffer(ctx, session.id);
|
|
447
|
-
}
|
|
448
|
-
// Debug capture: open a capture session and wire stdout feed.
|
|
449
|
-
// Capture files persist after the agent is killed for offline analysis.
|
|
450
|
-
if (isDebugCaptureEnabled()) {
|
|
451
|
-
captureSessionOpen(session.id, resolvedAgentType).catch(() => { });
|
|
452
|
-
if (this.usingBunWorker) {
|
|
453
|
-
this.manager.onSessionData(session.id, (data) => {
|
|
454
|
-
captureFeed(session.id, data, "stdout");
|
|
455
|
-
});
|
|
456
|
-
}
|
|
457
|
-
else {
|
|
458
|
-
const ptySession = this.manager.getSession(session.id);
|
|
459
|
-
if (ptySession) {
|
|
460
|
-
ptySession.on("output", (data) => {
|
|
461
|
-
captureFeed(session.id, data, "stdout");
|
|
462
|
-
});
|
|
463
|
-
}
|
|
464
|
-
}
|
|
465
|
-
}
|
|
466
|
-
this.wireTranscriptCapture(session.id);
|
|
467
|
-
// Defer initial task until session is ready.
|
|
468
|
-
// IMPORTANT: Set up the listener BEFORE pushDefaultRules (which has a 1500ms sleep),
|
|
469
|
-
// otherwise session_ready fires during pushDefaultRules and the listener misses it.
|
|
470
|
-
if (resolvedInitialTask) {
|
|
471
|
-
setupDeferredTaskDelivery(ctx, session, resolvedInitialTask, resolvedAgentType);
|
|
472
|
-
}
|
|
473
|
-
await this.pushDefaultRules(session.id, resolvedAgentType);
|
|
474
|
-
this.metricsTracker.get(resolvedAgentType).spawned++;
|
|
475
|
-
this.log(`Spawned session ${session.id} (${resolvedAgentType})`);
|
|
476
|
-
return this.toSessionInfo(session, workdir);
|
|
477
|
-
}
|
|
478
|
-
autoResponseContext() {
|
|
479
|
-
return {
|
|
480
|
-
manager: this.manager,
|
|
481
|
-
usingBunWorker: this.usingBunWorker,
|
|
482
|
-
runtime: this.runtime,
|
|
483
|
-
log: (msg) => this.log(msg),
|
|
484
|
-
};
|
|
485
|
-
}
|
|
486
|
-
async pushDefaultRules(sessionId, agentType) {
|
|
487
|
-
if (!this.manager)
|
|
488
|
-
return;
|
|
489
|
-
await pushDefaultAutoResponseRules(this.autoResponseContext(), sessionId, agentType);
|
|
490
|
-
}
|
|
491
|
-
async handleGeminiAuth(sessionId) {
|
|
492
|
-
await handleGeminiAuthFlow(this.autoResponseContext(), sessionId, (id, keys) => this.sendKeysToSession(id, keys));
|
|
493
|
-
}
|
|
494
|
-
async sendToSession(sessionId, input) {
|
|
495
|
-
if (!this.manager)
|
|
496
|
-
throw new Error("PTYService not initialized");
|
|
497
|
-
captureFeed(sessionId, input, "stdin");
|
|
498
|
-
void this.persistTranscript(sessionId, "stdin", input);
|
|
499
|
-
const metadata = this.sessionMetadata.get(sessionId);
|
|
500
|
-
if (metadata) {
|
|
501
|
-
metadata.lastSentInput = input;
|
|
502
|
-
}
|
|
503
|
-
const message = await sendToSessionIO(this.ioContext(), sessionId, input);
|
|
504
|
-
this.scheduleCompletionReconcile(sessionId);
|
|
505
|
-
return message;
|
|
506
|
-
}
|
|
507
|
-
async sendKeysToSession(sessionId, keys) {
|
|
508
|
-
if (!this.manager)
|
|
509
|
-
throw new Error("PTYService not initialized");
|
|
510
|
-
const content = Array.isArray(keys) ? keys.join(",") : keys;
|
|
511
|
-
void this.persistTranscript(sessionId, "keys", content);
|
|
512
|
-
return sendKeysToSessionIO(this.ioContext(), sessionId, keys);
|
|
513
|
-
}
|
|
514
|
-
async stopSession(sessionId, force = false) {
|
|
515
|
-
if (!this.manager)
|
|
516
|
-
throw new Error("PTYService not initialized");
|
|
517
|
-
captureLifecycle(sessionId, "session_stopped", force ? "force" : undefined);
|
|
518
|
-
try {
|
|
519
|
-
return await stopSessionIO(this.ioContext(), sessionId, this.sessionMetadata, this.sessionWorkdirs, (msg) => this.log(msg), force);
|
|
520
|
-
}
|
|
521
|
-
finally {
|
|
522
|
-
this.clearCompletionReconcile(sessionId);
|
|
523
|
-
const authRecoveryTimer = this.authRecoveryTimers.get(sessionId);
|
|
524
|
-
if (authRecoveryTimer) {
|
|
525
|
-
clearInterval(authRecoveryTimer);
|
|
526
|
-
this.authRecoveryTimers.delete(sessionId);
|
|
527
|
-
}
|
|
528
|
-
this.clearTranscriptCapture(sessionId);
|
|
529
|
-
}
|
|
530
|
-
}
|
|
531
|
-
/** Default approval preset — runtime env var takes precedence over config. */
|
|
532
|
-
get defaultApprovalPreset() {
|
|
533
|
-
const fromEnv = this.runtime.getSetting("PARALLAX_DEFAULT_APPROVAL_PRESET");
|
|
534
|
-
if (fromEnv &&
|
|
535
|
-
["readonly", "standard", "permissive", "autonomous"].includes(fromEnv)) {
|
|
536
|
-
return fromEnv;
|
|
537
|
-
}
|
|
538
|
-
return this.serviceConfig.defaultApprovalPreset ?? "autonomous";
|
|
539
|
-
}
|
|
540
|
-
/** Agent selection strategy — env var takes precedence. */
|
|
541
|
-
get agentSelectionStrategy() {
|
|
542
|
-
const fromEnv = this.runtime.getSetting("PARALLAX_AGENT_SELECTION_STRATEGY");
|
|
543
|
-
if (fromEnv && (fromEnv === "fixed" || fromEnv === "ranked")) {
|
|
544
|
-
return fromEnv;
|
|
545
|
-
}
|
|
546
|
-
return "fixed";
|
|
547
|
-
}
|
|
548
|
-
/**
|
|
549
|
-
* Default agent type when strategy is "fixed".
|
|
550
|
-
* Precedence: config file (`eliza.json` env section, written by the UI)
|
|
551
|
-
* > runtime/env setting > "claude" fallback.
|
|
552
|
-
*/
|
|
553
|
-
get defaultAgentType() {
|
|
554
|
-
return this.explicitDefaultAgentType ?? "claude";
|
|
555
|
-
}
|
|
556
|
-
get explicitDefaultAgentType() {
|
|
557
|
-
const fromConfig = readConfigEnvKey("PARALLAX_DEFAULT_AGENT_TYPE");
|
|
558
|
-
const fromRuntimeOrEnv = fromConfig ||
|
|
559
|
-
this.runtime.getSetting("PARALLAX_DEFAULT_AGENT_TYPE");
|
|
560
|
-
if (fromRuntimeOrEnv &&
|
|
561
|
-
["claude", "gemini", "codex", "aider"].includes(fromRuntimeOrEnv.toLowerCase())) {
|
|
562
|
-
return fromRuntimeOrEnv.toLowerCase();
|
|
563
|
-
}
|
|
564
|
-
return null;
|
|
565
|
-
}
|
|
566
|
-
/**
|
|
567
|
-
* Resolve which agent type to use when the caller didn't specify one.
|
|
568
|
-
*
|
|
569
|
-
* When the caller explicitly configured a fixed default agent type, fixed
|
|
570
|
-
* mode returns that pinned framework. Otherwise the resolver scores the
|
|
571
|
-
* available frameworks from task shape, auth/install state, and recent
|
|
572
|
-
* metrics so dynamic routing still works on unconfigured installs.
|
|
573
|
-
*/
|
|
574
|
-
async resolveAgentType(selection) {
|
|
575
|
-
if (this.agentSelectionStrategy === "fixed" &&
|
|
576
|
-
this.explicitDefaultAgentType) {
|
|
577
|
-
return this.explicitDefaultAgentType;
|
|
578
|
-
}
|
|
579
|
-
const frameworkState = await this.getFrameworkState(selection);
|
|
580
|
-
return frameworkState.preferred.id;
|
|
581
|
-
}
|
|
582
|
-
async getFrameworkState(selection) {
|
|
583
|
-
const profile = selection
|
|
584
|
-
? buildTaskAgentTaskProfile(selection)
|
|
585
|
-
: undefined;
|
|
586
|
-
return getTaskAgentFrameworkState(this.runtime, {
|
|
587
|
-
checkAvailableAgents: (types) => this.checkAvailableAgents(types),
|
|
588
|
-
getAgentMetrics: () => this.metricsTracker.getAll(),
|
|
589
|
-
}, profile
|
|
590
|
-
? {
|
|
591
|
-
task: selection?.task,
|
|
592
|
-
repo: selection?.repo,
|
|
593
|
-
workdir: selection?.workdir,
|
|
594
|
-
threadKind: profile.kind,
|
|
595
|
-
subtaskCount: profile.subtaskCount,
|
|
596
|
-
acceptanceCriteria: selection?.acceptanceCriteria,
|
|
597
|
-
}
|
|
598
|
-
: selection);
|
|
599
|
-
}
|
|
600
|
-
getSession(sessionId) {
|
|
601
|
-
if (!this.manager)
|
|
602
|
-
return undefined;
|
|
603
|
-
const session = this.manager.get(sessionId);
|
|
604
|
-
if (!session)
|
|
605
|
-
return this.toTerminalSessionInfo(sessionId);
|
|
606
|
-
return this.toSessionInfo(session, this.sessionWorkdirs.get(sessionId));
|
|
607
|
-
}
|
|
608
|
-
async listSessions(filter) {
|
|
609
|
-
if (!this.manager)
|
|
610
|
-
return [];
|
|
611
|
-
const sessions = this.usingBunWorker
|
|
612
|
-
? await this.manager.list()
|
|
613
|
-
: this.manager.list(filter);
|
|
614
|
-
const liveSessions = sessions.map((session) => {
|
|
615
|
-
const cached = this.manager?.get(session.id);
|
|
616
|
-
return this.toSessionInfo(cached ?? session, this.sessionWorkdirs.get(session.id));
|
|
617
|
-
});
|
|
618
|
-
const terminalSessions = Array.from(this.terminalSessionStates.keys())
|
|
619
|
-
.filter((sessionId) => !sessions.some((session) => session.id === sessionId))
|
|
620
|
-
.map((sessionId) => this.toTerminalSessionInfo(sessionId))
|
|
621
|
-
.filter((session) => session !== undefined);
|
|
622
|
-
return [...liveSessions, ...terminalSessions];
|
|
623
|
-
}
|
|
624
|
-
subscribeToOutput(sessionId, callback) {
|
|
625
|
-
if (!this.manager)
|
|
626
|
-
throw new Error("PTYService not initialized");
|
|
627
|
-
return subscribeToOutputIO(this.ioContext(), sessionId, callback);
|
|
628
|
-
}
|
|
629
|
-
async getSessionOutput(sessionId, lines) {
|
|
630
|
-
if (!this.manager)
|
|
631
|
-
throw new Error("PTYService not initialized");
|
|
632
|
-
return getSessionOutputIO(this.ioContext(), sessionId, lines);
|
|
633
|
-
}
|
|
634
|
-
/**
|
|
635
|
-
* Whether the adapter currently classifies the session as actively
|
|
636
|
-
* processing work (e.g. Codex's "esc to interrupt" status row).
|
|
637
|
-
*
|
|
638
|
-
* The swarm idle watchdog consults this before assuming a session is
|
|
639
|
-
* idle based on output byte diffs, which are fooled by TUIs that
|
|
640
|
-
* redraw the same status row in place via cursor positioning.
|
|
641
|
-
*
|
|
642
|
-
* Returns `false` for unknown sessions or adapters that don't
|
|
643
|
-
* implement `detectLoading`. For Bun-compat mode this round-trips to
|
|
644
|
-
* the worker; for in-process mode it reads the session directly.
|
|
645
|
-
*/
|
|
646
|
-
async isSessionLoading(sessionId) {
|
|
647
|
-
if (!this.manager)
|
|
648
|
-
return false;
|
|
649
|
-
if (this.usingBunWorker) {
|
|
650
|
-
return (this.manager.isSessionLoading?.(sessionId) ?? false);
|
|
651
|
-
}
|
|
652
|
-
return (this.manager.isSessionLoading?.(sessionId) ?? false);
|
|
653
|
-
}
|
|
654
|
-
clearTranscriptCapture(sessionId) {
|
|
655
|
-
const unsubscribe = this.transcriptUnsubscribers.get(sessionId);
|
|
656
|
-
if (unsubscribe) {
|
|
657
|
-
try {
|
|
658
|
-
unsubscribe();
|
|
659
|
-
}
|
|
660
|
-
catch {
|
|
661
|
-
// Ignore cleanup failures on dead sessions.
|
|
662
|
-
}
|
|
663
|
-
}
|
|
664
|
-
this.transcriptUnsubscribers.delete(sessionId);
|
|
665
|
-
}
|
|
666
|
-
async resolveTaskThreadId(sessionId) {
|
|
667
|
-
const liveThreadId = this.coordinator?.getTaskContext(sessionId)?.threadId;
|
|
668
|
-
if (liveThreadId)
|
|
669
|
-
return liveThreadId;
|
|
670
|
-
const metadataThreadId = this.sessionMetadata.get(sessionId)?.threadId;
|
|
671
|
-
if (typeof metadataThreadId === "string" && metadataThreadId.trim()) {
|
|
672
|
-
return metadataThreadId;
|
|
673
|
-
}
|
|
674
|
-
return ((await this.coordinator?.taskRegistry.findThreadIdBySessionId(sessionId)) ?? null);
|
|
675
|
-
}
|
|
676
|
-
async persistTranscript(sessionId, direction, content) {
|
|
677
|
-
if (!content || !this.coordinator)
|
|
678
|
-
return;
|
|
679
|
-
const threadId = await this.resolveTaskThreadId(sessionId);
|
|
680
|
-
if (!threadId)
|
|
681
|
-
return;
|
|
682
|
-
await this.coordinator.taskRegistry.recordTranscript({
|
|
683
|
-
threadId,
|
|
684
|
-
sessionId,
|
|
685
|
-
direction,
|
|
686
|
-
content,
|
|
687
|
-
});
|
|
688
|
-
}
|
|
689
|
-
wireTranscriptCapture(sessionId) {
|
|
690
|
-
if (!this.manager)
|
|
691
|
-
return;
|
|
692
|
-
this.clearTranscriptCapture(sessionId);
|
|
693
|
-
if (this.usingBunWorker) {
|
|
694
|
-
const unsubscribe = this.manager.onSessionData(sessionId, (data) => {
|
|
695
|
-
void this.persistTranscript(sessionId, "stdout", data);
|
|
696
|
-
});
|
|
697
|
-
this.transcriptUnsubscribers.set(sessionId, unsubscribe);
|
|
698
|
-
return;
|
|
699
|
-
}
|
|
700
|
-
const ptySession = this.manager.getSession(sessionId);
|
|
701
|
-
if (!ptySession ||
|
|
702
|
-
typeof ptySession.on !== "function" ||
|
|
703
|
-
typeof ptySession.off !== "function") {
|
|
704
|
-
return;
|
|
705
|
-
}
|
|
706
|
-
const onOutput = (data) => {
|
|
707
|
-
void this.persistTranscript(sessionId, "stdout", data);
|
|
708
|
-
};
|
|
709
|
-
ptySession.on("output", onOutput);
|
|
710
|
-
this.transcriptUnsubscribers.set(sessionId, () => {
|
|
711
|
-
ptySession.off("output", onOutput);
|
|
712
|
-
});
|
|
713
|
-
}
|
|
714
|
-
isSessionBlocked(sessionId) {
|
|
715
|
-
const session = this.getSession(sessionId);
|
|
716
|
-
return session?.status === "authenticating";
|
|
717
|
-
}
|
|
718
|
-
/**
|
|
719
|
-
* Find a PTY session ID by its working directory.
|
|
720
|
-
* Used by the HTTP hooks endpoint to correlate Claude's cwd with our session.
|
|
721
|
-
*/
|
|
722
|
-
findSessionIdByCwd(cwd) {
|
|
723
|
-
for (const [sessionId, workdir] of this.sessionWorkdirs) {
|
|
724
|
-
if (workdir === cwd)
|
|
725
|
-
return sessionId;
|
|
726
|
-
}
|
|
727
|
-
return undefined;
|
|
728
|
-
}
|
|
729
|
-
/**
|
|
730
|
-
* Handle an incoming hook event from Claude Code's HTTP hooks.
|
|
731
|
-
* Translates hook events into PTY service events.
|
|
732
|
-
*/
|
|
733
|
-
handleHookEvent(sessionId, event, data) {
|
|
734
|
-
// Log high-frequency events (tool_running, permission) at debug level;
|
|
735
|
-
// completion events at info level.
|
|
736
|
-
const summary = event === "tool_running"
|
|
737
|
-
? `tool=${data.toolName ?? "?"}`
|
|
738
|
-
: event === "permission_approved"
|
|
739
|
-
? `tool=${data.tool ?? "?"}`
|
|
740
|
-
: JSON.stringify(data);
|
|
741
|
-
if (event === "tool_running" || event === "permission_approved") {
|
|
742
|
-
logger.debug(`[PTYService] Hook event for ${sessionId}: ${event} ${summary}`);
|
|
743
|
-
}
|
|
744
|
-
else {
|
|
745
|
-
this.log(`Hook event for ${sessionId}: ${event} ${summary}`);
|
|
746
|
-
}
|
|
747
|
-
// Forward hook event to the underlying PTY session so it can reset its
|
|
748
|
-
// stall timer and update internal status. Without this, the stall detector
|
|
749
|
-
// runs independently of hooks and can falsely escalate hook-managed sessions.
|
|
750
|
-
if (this.manager && this.usingBunWorker) {
|
|
751
|
-
this.manager
|
|
752
|
-
.notifyHookEvent(sessionId, event)
|
|
753
|
-
.catch((err) => logger.debug(`[PTYService] Failed to forward hook event to session: ${err}`));
|
|
754
|
-
}
|
|
755
|
-
switch (event) {
|
|
756
|
-
case "tool_running":
|
|
757
|
-
this.emitEvent(sessionId, "tool_running", { ...data, source: "hook" });
|
|
758
|
-
break;
|
|
759
|
-
case "task_complete":
|
|
760
|
-
this.emitEvent(sessionId, "task_complete", { ...data, source: "hook" });
|
|
761
|
-
// Auto-stop the PTY after a short grace period. Without this,
|
|
762
|
-
// subagents sit around firing stall classifications that then
|
|
763
|
-
// trigger phantom heartbeats in downstream streamers minutes
|
|
764
|
-
// after the user already got their answer. The grace period
|
|
765
|
-
// lets any backgrounded processes detach from the PTY parent
|
|
766
|
-
// before it exits.
|
|
767
|
-
setTimeout(() => {
|
|
768
|
-
this.stopSession(sessionId).catch(() => { });
|
|
769
|
-
}, TASK_COMPLETE_STOP_DELAY_MS);
|
|
770
|
-
break;
|
|
771
|
-
case "permission_approved":
|
|
772
|
-
// Permission was auto-approved via PermissionRequest hook.
|
|
773
|
-
// No PTY event needed — the hook response already allowed it.
|
|
774
|
-
break;
|
|
775
|
-
case "notification":
|
|
776
|
-
this.emitEvent(sessionId, "message", { ...data, source: "hook" });
|
|
777
|
-
break;
|
|
778
|
-
case "session_end":
|
|
779
|
-
// CLI session is ending — treat as a stopped event so the coordinator
|
|
780
|
-
// and frontend see the session transition to terminal state.
|
|
781
|
-
this.emitEvent(sessionId, "stopped", {
|
|
782
|
-
...data,
|
|
783
|
-
reason: "session_end",
|
|
784
|
-
source: "hook",
|
|
785
|
-
});
|
|
786
|
-
break;
|
|
787
|
-
default:
|
|
788
|
-
break;
|
|
789
|
-
}
|
|
790
|
-
}
|
|
791
|
-
async checkAvailableAgents(types) {
|
|
792
|
-
const agentTypes = types ?? ["claude", "gemini", "codex", "aider"];
|
|
793
|
-
const results = await checkAdapters(agentTypes);
|
|
794
|
-
return await augmentTaskAgentPreflightResults(results, {
|
|
795
|
-
runtime: this.runtime,
|
|
796
|
-
});
|
|
797
|
-
}
|
|
798
|
-
async getAgentAuthStatus(agentType) {
|
|
799
|
-
return await probeTaskAgentAuth(agentType, { runtime: this.runtime });
|
|
800
|
-
}
|
|
801
|
-
async triggerAgentAuth(agentType) {
|
|
802
|
-
const existing = this.activeAuthFlows.get(agentType);
|
|
803
|
-
if (existing) {
|
|
804
|
-
return existing.snapshot();
|
|
805
|
-
}
|
|
806
|
-
clearTaskAgentFrameworkStateCache();
|
|
807
|
-
const currentStatus = await this.getAgentAuthStatus(agentType);
|
|
808
|
-
if (currentStatus.status === "authenticated") {
|
|
809
|
-
return {
|
|
810
|
-
launched: true,
|
|
811
|
-
instructions: `${agentType} is already authenticated.`,
|
|
812
|
-
};
|
|
813
|
-
}
|
|
814
|
-
const launched = await launchTaskAgentAuthFlow(agentType, {
|
|
815
|
-
runtime: this.runtime,
|
|
816
|
-
});
|
|
817
|
-
if (!launched.handle) {
|
|
818
|
-
return launched.result;
|
|
819
|
-
}
|
|
820
|
-
this.activeAuthFlows.set(agentType, launched.handle);
|
|
821
|
-
void launched.handle.completion.finally(() => {
|
|
822
|
-
const active = this.activeAuthFlows.get(agentType);
|
|
823
|
-
if (active === launched.handle) {
|
|
824
|
-
this.activeAuthFlows.delete(agentType);
|
|
825
|
-
}
|
|
826
|
-
clearTaskAgentFrameworkStateCache();
|
|
827
|
-
});
|
|
828
|
-
let result = launched.result;
|
|
829
|
-
if (result.url) {
|
|
830
|
-
const browserAssist = await assistTaskAgentBrowserLogin(agentType, result.url, { runtime: this.runtime });
|
|
831
|
-
result = {
|
|
832
|
-
...result,
|
|
833
|
-
browserOpened: browserAssist.opened,
|
|
834
|
-
browserClicked: browserAssist.clicked,
|
|
835
|
-
browserDetail: browserAssist.detail,
|
|
836
|
-
};
|
|
837
|
-
}
|
|
838
|
-
return result;
|
|
839
|
-
}
|
|
840
|
-
async startSessionAuthRecovery(sessionId, agentType, login) {
|
|
841
|
-
clearTaskAgentFrameworkStateCache();
|
|
842
|
-
const status = await this.getAgentAuthStatus(agentType);
|
|
843
|
-
if (status.status === "authenticated") {
|
|
844
|
-
const resumed = await this.resumeSessionAfterRecoveredAuth(sessionId, agentType);
|
|
845
|
-
if (resumed) {
|
|
846
|
-
return {
|
|
847
|
-
launched: true,
|
|
848
|
-
instructions: `${agentType} authentication is already valid. Eliza resumed the blocked session.`,
|
|
849
|
-
recoveryStarted: true,
|
|
850
|
-
status: "recovered",
|
|
851
|
-
recoveryTarget: "same_session",
|
|
852
|
-
};
|
|
853
|
-
}
|
|
854
|
-
const replacement = await this.coordinator?.resumeTaskAfterProviderAuth?.(sessionId, `${agentType} authentication was refreshed`);
|
|
855
|
-
if (replacement) {
|
|
856
|
-
return {
|
|
857
|
-
launched: true,
|
|
858
|
-
instructions: `${agentType} authentication is already valid. Eliza restarted the task on a fresh session.`,
|
|
859
|
-
recoveryStarted: true,
|
|
860
|
-
status: "recovered",
|
|
861
|
-
recoveryTarget: "replacement_session",
|
|
862
|
-
replacementSessionId: replacement.replacementSessionId,
|
|
863
|
-
replacementFramework: replacement.replacementFramework,
|
|
864
|
-
};
|
|
865
|
-
}
|
|
866
|
-
return {
|
|
867
|
-
launched: false,
|
|
868
|
-
instructions: `${agentType} authentication is valid, but Eliza could not resume the task automatically.`,
|
|
869
|
-
recoveryStarted: false,
|
|
870
|
-
status: "failed",
|
|
871
|
-
};
|
|
872
|
-
}
|
|
873
|
-
let launch = {
|
|
874
|
-
launched: false,
|
|
875
|
-
instructions: login.instructions?.trim() ||
|
|
876
|
-
getTaskAgentLoginHint(agentType) ||
|
|
877
|
-
`Authentication is required for ${agentType}.`,
|
|
878
|
-
...(login.url ? { url: login.url } : {}),
|
|
879
|
-
...(login.deviceCode ? { deviceCode: login.deviceCode } : {}),
|
|
880
|
-
};
|
|
881
|
-
if (!launch.url && !launch.deviceCode) {
|
|
882
|
-
launch = await this.triggerAgentAuth(agentType);
|
|
883
|
-
}
|
|
884
|
-
else if (launch.url) {
|
|
885
|
-
const browserAssist = await assistTaskAgentBrowserLogin(agentType, launch.url, { runtime: this.runtime });
|
|
886
|
-
launch = {
|
|
887
|
-
...launch,
|
|
888
|
-
launched: true,
|
|
889
|
-
browserOpened: browserAssist.opened,
|
|
890
|
-
browserClicked: browserAssist.clicked,
|
|
891
|
-
browserDetail: browserAssist.detail,
|
|
892
|
-
};
|
|
893
|
-
}
|
|
894
|
-
this.monitorSessionAuthRecovery(sessionId, agentType);
|
|
895
|
-
return {
|
|
896
|
-
...launch,
|
|
897
|
-
recoveryStarted: true,
|
|
898
|
-
status: launch.launched ? "recovering" : "failed",
|
|
899
|
-
};
|
|
900
|
-
}
|
|
901
|
-
monitorSessionAuthRecovery(sessionId, agentType) {
|
|
902
|
-
const existing = this.authRecoveryTimers.get(sessionId);
|
|
903
|
-
if (existing)
|
|
904
|
-
return;
|
|
905
|
-
const startedAt = Date.now();
|
|
906
|
-
const timer = setInterval(() => {
|
|
907
|
-
void (async () => {
|
|
908
|
-
const session = this.getSession(sessionId);
|
|
909
|
-
if (!session ||
|
|
910
|
-
session.status === "stopped" ||
|
|
911
|
-
session.status === "error") {
|
|
912
|
-
clearInterval(timer);
|
|
913
|
-
this.authRecoveryTimers.delete(sessionId);
|
|
914
|
-
return;
|
|
915
|
-
}
|
|
916
|
-
const auth = await this.getAgentAuthStatus(agentType);
|
|
917
|
-
if (auth.status === "authenticated") {
|
|
918
|
-
clearInterval(timer);
|
|
919
|
-
this.authRecoveryTimers.delete(sessionId);
|
|
920
|
-
clearTaskAgentFrameworkStateCache();
|
|
921
|
-
const resumed = await this.resumeSessionAfterRecoveredAuth(sessionId, agentType);
|
|
922
|
-
if (resumed) {
|
|
923
|
-
await this.coordinator?.markTaskResumedAfterProviderAuth?.(sessionId);
|
|
924
|
-
return;
|
|
925
|
-
}
|
|
926
|
-
await this.coordinator?.resumeTaskAfterProviderAuth?.(sessionId, `${agentType} authentication was refreshed`);
|
|
927
|
-
return;
|
|
928
|
-
}
|
|
929
|
-
if (Date.now() - startedAt > 5 * 60_000) {
|
|
930
|
-
clearInterval(timer);
|
|
931
|
-
this.authRecoveryTimers.delete(sessionId);
|
|
932
|
-
}
|
|
933
|
-
})().catch((error) => {
|
|
934
|
-
this.log(`Auth recovery watcher failed for ${sessionId}: ${error}`);
|
|
935
|
-
clearInterval(timer);
|
|
936
|
-
this.authRecoveryTimers.delete(sessionId);
|
|
937
|
-
});
|
|
938
|
-
}, 2_500);
|
|
939
|
-
this.authRecoveryTimers.set(sessionId, timer);
|
|
940
|
-
}
|
|
941
|
-
async resumeSessionAfterRecoveredAuth(sessionId, agentType) {
|
|
942
|
-
const session = this.getSession(sessionId);
|
|
943
|
-
if (!session)
|
|
944
|
-
return false;
|
|
945
|
-
if (session.status === "ready" || session.status === "busy") {
|
|
946
|
-
return true;
|
|
947
|
-
}
|
|
948
|
-
try {
|
|
949
|
-
await this.sendKeysToSession(sessionId, "enter");
|
|
950
|
-
await new Promise((resolve) => setTimeout(resolve, 250));
|
|
951
|
-
await this.sendKeysToSession(sessionId, "enter");
|
|
952
|
-
}
|
|
953
|
-
catch (error) {
|
|
954
|
-
this.log(`Failed to nudge ${agentType} session ${sessionId} after auth recovery: ${error}`);
|
|
955
|
-
return false;
|
|
956
|
-
}
|
|
957
|
-
const deadline = Date.now() + 8_000;
|
|
958
|
-
while (Date.now() < deadline) {
|
|
959
|
-
const current = this.getSession(sessionId);
|
|
960
|
-
if (!current)
|
|
961
|
-
return false;
|
|
962
|
-
if (current.status === "ready" || current.status === "busy") {
|
|
963
|
-
return true;
|
|
964
|
-
}
|
|
965
|
-
if (current.status === "stopped" || current.status === "error") {
|
|
966
|
-
return false;
|
|
967
|
-
}
|
|
968
|
-
await new Promise((resolve) => setTimeout(resolve, 400));
|
|
969
|
-
}
|
|
970
|
-
return false;
|
|
971
|
-
}
|
|
972
|
-
getSupportedAgentTypes() {
|
|
973
|
-
return ["shell", "claude", "gemini", "codex", "aider", "pi"];
|
|
974
|
-
}
|
|
975
|
-
async classifyStall(sessionId, recentOutput) {
|
|
976
|
-
const meta = this.sessionMetadata.get(sessionId);
|
|
977
|
-
const agentType = meta?.agentType ?? "unknown";
|
|
978
|
-
// For coordinator-managed sessions in autonomous mode: use combined
|
|
979
|
-
// classify+decide in a single LLM call. The suggestedResponse is kept
|
|
980
|
-
// intact so pty-manager auto-responds, and the coordinator receives
|
|
981
|
-
// autoResponded: true — skipping the second LLM call in handleBlocked().
|
|
982
|
-
if (meta?.coordinatorManaged &&
|
|
983
|
-
this.coordinator?.getSupervisionLevel() === "autonomous") {
|
|
984
|
-
const taskCtx = this.coordinator.getTaskContext(sessionId);
|
|
985
|
-
if (taskCtx) {
|
|
986
|
-
// Suppress stall classification during the post-send cooldown.
|
|
987
|
-
// The agent is processing coordinator input — the output buffer
|
|
988
|
-
// still contains the previous response, so classifying now would
|
|
989
|
-
// produce a stale "task_complete" that triggers cascading follow-ups.
|
|
990
|
-
if (taskCtx.lastInputSentAt) {
|
|
991
|
-
const elapsed = Date.now() - taskCtx.lastInputSentAt;
|
|
992
|
-
if (elapsed < POST_SEND_COOLDOWN_MS) {
|
|
993
|
-
this.log(`Suppressing stall classification for ${sessionId} — ` +
|
|
994
|
-
`${Math.round(elapsed / 1000)}s since coordinator sent input`);
|
|
995
|
-
return null;
|
|
996
|
-
}
|
|
997
|
-
}
|
|
998
|
-
return classifyAndDecideForCoordinator({
|
|
999
|
-
sessionId,
|
|
1000
|
-
recentOutput,
|
|
1001
|
-
agentType,
|
|
1002
|
-
buffers: this.sessionOutputBuffers,
|
|
1003
|
-
traceEntries: this.traceEntries,
|
|
1004
|
-
runtime: this.runtime,
|
|
1005
|
-
manager: this.manager,
|
|
1006
|
-
metricsTracker: this.metricsTracker,
|
|
1007
|
-
debugSnapshots: this.serviceConfig.debug === true,
|
|
1008
|
-
lastSentInput: typeof meta?.lastSentInput === "string"
|
|
1009
|
-
? meta.lastSentInput
|
|
1010
|
-
: undefined,
|
|
1011
|
-
log: (msg) => this.log(msg),
|
|
1012
|
-
taskContext: {
|
|
1013
|
-
sessionId: taskCtx.sessionId,
|
|
1014
|
-
agentType: taskCtx.agentType,
|
|
1015
|
-
label: taskCtx.label,
|
|
1016
|
-
originalTask: taskCtx.originalTask,
|
|
1017
|
-
workdir: taskCtx.workdir,
|
|
1018
|
-
repo: taskCtx.repo,
|
|
1019
|
-
},
|
|
1020
|
-
decisionHistory: taskCtx.decisions
|
|
1021
|
-
.filter((d) => d.decision !== "auto_resolved")
|
|
1022
|
-
.slice(-5)
|
|
1023
|
-
.map((d) => ({
|
|
1024
|
-
event: d.event,
|
|
1025
|
-
promptText: d.promptText,
|
|
1026
|
-
action: d.decision,
|
|
1027
|
-
response: d.response,
|
|
1028
|
-
reasoning: d.reasoning,
|
|
1029
|
-
})),
|
|
1030
|
-
});
|
|
1031
|
-
}
|
|
1032
|
-
}
|
|
1033
|
-
const classification = await classifyStallOutput({
|
|
1034
|
-
sessionId,
|
|
1035
|
-
recentOutput,
|
|
1036
|
-
agentType,
|
|
1037
|
-
buffers: this.sessionOutputBuffers,
|
|
1038
|
-
traceEntries: this.traceEntries,
|
|
1039
|
-
runtime: this.runtime,
|
|
1040
|
-
manager: this.manager,
|
|
1041
|
-
metricsTracker: this.metricsTracker,
|
|
1042
|
-
debugSnapshots: this.serviceConfig.debug === true,
|
|
1043
|
-
lastSentInput: typeof meta?.lastSentInput === "string"
|
|
1044
|
-
? meta.lastSentInput
|
|
1045
|
-
: undefined,
|
|
1046
|
-
log: (msg) => this.log(msg),
|
|
1047
|
-
});
|
|
1048
|
-
// When the SwarmCoordinator manages this session (non-autonomous mode),
|
|
1049
|
-
// strip suggestedResponse so the PTY worker doesn't auto-respond.
|
|
1050
|
-
// The coordinator's LLM decision loop will handle blocked prompts instead.
|
|
1051
|
-
if (classification &&
|
|
1052
|
-
meta?.coordinatorManaged &&
|
|
1053
|
-
classification.suggestedResponse) {
|
|
1054
|
-
this.log(`Suppressing stall auto-response for coordinator-managed session ${sessionId} ` +
|
|
1055
|
-
`(would have sent: "${classification.suggestedResponse}")`);
|
|
1056
|
-
classification.suggestedResponse = undefined;
|
|
1057
|
-
}
|
|
1058
|
-
return classification;
|
|
1059
|
-
}
|
|
1060
|
-
// ─── Workspace Files ───
|
|
1061
|
-
getAdapter(agentType) {
|
|
1062
|
-
let adapter = this.adapterCache.get(agentType);
|
|
1063
|
-
if (!adapter) {
|
|
1064
|
-
adapter = createAdapter(agentType);
|
|
1065
|
-
this.adapterCache.set(agentType, adapter);
|
|
1066
|
-
}
|
|
1067
|
-
return adapter;
|
|
1068
|
-
}
|
|
1069
|
-
getWorkspaceFiles(agentType) {
|
|
1070
|
-
return this.getAdapter(agentType).getWorkspaceFiles();
|
|
1071
|
-
}
|
|
1072
|
-
getMemoryFilePath(agentType) {
|
|
1073
|
-
return this.getAdapter(agentType).memoryFilePath;
|
|
1074
|
-
}
|
|
1075
|
-
getApprovalConfig(agentType, preset) {
|
|
1076
|
-
return generateApprovalConfig(agentType, preset);
|
|
1077
|
-
}
|
|
1078
|
-
async writeMemoryFile(agentType, workspacePath, content, options) {
|
|
1079
|
-
return this.getAdapter(agentType).writeMemoryFile(workspacePath, content, options);
|
|
1080
|
-
}
|
|
1081
|
-
// ─── Gitignore for Orchestrator Files ───
|
|
1082
|
-
/** Marker comment used to detect orchestrator-managed gitignore entries. */
|
|
1083
|
-
static GITIGNORE_MARKER = "# orchestrator-injected (do not commit agent config/memory files)";
|
|
1084
|
-
/** Per-path lock to serialize concurrent gitignore updates for the same workdir. */
|
|
1085
|
-
static gitignoreLocks = new Map();
|
|
1086
|
-
/**
|
|
1087
|
-
* Ensure that orchestrator-injected files (CLAUDE.md, .claude/, GEMINI.md, etc.)
|
|
1088
|
-
* are listed in the workspace .gitignore so agents don't commit them.
|
|
1089
|
-
* Appends to an existing .gitignore or creates one. Idempotent — skips if
|
|
1090
|
-
* the marker comment is already present. Serialized per-path to prevent
|
|
1091
|
-
* duplicate entries from concurrent spawns.
|
|
1092
|
-
*/
|
|
1093
|
-
async ensureOrchestratorGitignore(workdir) {
|
|
1094
|
-
const gitignorePath = join(workdir, ".gitignore");
|
|
1095
|
-
// Serialize per-path: wait for any in-flight update to the same file.
|
|
1096
|
-
const existing_lock = PTYService.gitignoreLocks.get(gitignorePath);
|
|
1097
|
-
if (existing_lock)
|
|
1098
|
-
await existing_lock;
|
|
1099
|
-
const task = this.doEnsureGitignore(gitignorePath, workdir);
|
|
1100
|
-
PTYService.gitignoreLocks.set(gitignorePath, task);
|
|
1101
|
-
try {
|
|
1102
|
-
await task;
|
|
1103
|
-
}
|
|
1104
|
-
finally {
|
|
1105
|
-
// Only delete if we're still the current holder
|
|
1106
|
-
if (PTYService.gitignoreLocks.get(gitignorePath) === task) {
|
|
1107
|
-
PTYService.gitignoreLocks.delete(gitignorePath);
|
|
1108
|
-
}
|
|
1109
|
-
}
|
|
1110
|
-
}
|
|
1111
|
-
async doEnsureGitignore(gitignorePath, workdir) {
|
|
1112
|
-
let existing = "";
|
|
1113
|
-
try {
|
|
1114
|
-
existing = await readFile(gitignorePath, "utf-8");
|
|
1115
|
-
}
|
|
1116
|
-
catch {
|
|
1117
|
-
// No .gitignore yet — we'll create one
|
|
1118
|
-
}
|
|
1119
|
-
// Idempotent: skip if we already added our entries
|
|
1120
|
-
if (existing.includes(PTYService.GITIGNORE_MARKER))
|
|
1121
|
-
return;
|
|
1122
|
-
// Include all common patterns so multi-agent swarms with mixed types are covered.
|
|
1123
|
-
const entries = [
|
|
1124
|
-
"",
|
|
1125
|
-
PTYService.GITIGNORE_MARKER,
|
|
1126
|
-
"CLAUDE.md",
|
|
1127
|
-
".claude/",
|
|
1128
|
-
"GEMINI.md",
|
|
1129
|
-
".gemini/",
|
|
1130
|
-
".aider*",
|
|
1131
|
-
];
|
|
1132
|
-
try {
|
|
1133
|
-
if (existing.length === 0) {
|
|
1134
|
-
// No .gitignore yet — create with just our entries
|
|
1135
|
-
await writeFile(gitignorePath, `${entries.join("\n")}\n`, "utf-8");
|
|
1136
|
-
}
|
|
1137
|
-
else {
|
|
1138
|
-
// Append-only to avoid clobbering concurrent edits
|
|
1139
|
-
const separator = existing.endsWith("\n") ? "" : "\n";
|
|
1140
|
-
await appendFile(gitignorePath, `${separator + entries.join("\n")}\n`, "utf-8");
|
|
1141
|
-
}
|
|
1142
|
-
}
|
|
1143
|
-
catch (err) {
|
|
1144
|
-
this.log(`Failed to update .gitignore in ${workdir}: ${err}`);
|
|
1145
|
-
}
|
|
1146
|
-
}
|
|
1147
|
-
// ─── Event & Adapter Registration ───
|
|
1148
|
-
onSessionEvent(callback) {
|
|
1149
|
-
this.eventCallbacks.push(callback);
|
|
1150
|
-
return () => {
|
|
1151
|
-
const idx = this.eventCallbacks.indexOf(callback);
|
|
1152
|
-
if (idx !== -1)
|
|
1153
|
-
this.eventCallbacks.splice(idx, 1);
|
|
1154
|
-
};
|
|
1155
|
-
}
|
|
1156
|
-
onNormalizedSessionEvent(callback) {
|
|
1157
|
-
this.normalizedEventCallbacks.push(callback);
|
|
1158
|
-
return () => {
|
|
1159
|
-
const idx = this.normalizedEventCallbacks.indexOf(callback);
|
|
1160
|
-
if (idx !== -1)
|
|
1161
|
-
this.normalizedEventCallbacks.splice(idx, 1);
|
|
1162
|
-
};
|
|
1163
|
-
}
|
|
1164
|
-
registerAdapter(adapter) {
|
|
1165
|
-
if (!this.manager) {
|
|
1166
|
-
throw new Error("PTYService not initialized");
|
|
1167
|
-
}
|
|
1168
|
-
if (this.usingBunWorker) {
|
|
1169
|
-
this.log("registerAdapter not available with Bun worker - adapters must be in the worker");
|
|
1170
|
-
return;
|
|
1171
|
-
}
|
|
1172
|
-
this.manager.registerAdapter(adapter);
|
|
1173
|
-
this.log(`Registered adapter`);
|
|
1174
|
-
}
|
|
1175
|
-
toSessionInfo(session, workdir) {
|
|
1176
|
-
const metadata = this.sessionMetadata.get(session.id);
|
|
1177
|
-
const requestedType = typeof metadata?.requestedType === "string"
|
|
1178
|
-
? metadata.requestedType
|
|
1179
|
-
: undefined;
|
|
1180
|
-
const displayAgentType = session.type === "shell" && isPiAgentType(requestedType)
|
|
1181
|
-
? "pi"
|
|
1182
|
-
: session.type;
|
|
1183
|
-
return {
|
|
1184
|
-
id: session.id,
|
|
1185
|
-
name: session.name,
|
|
1186
|
-
agentType: displayAgentType,
|
|
1187
|
-
workdir: workdir ?? process.cwd(),
|
|
1188
|
-
status: session.status,
|
|
1189
|
-
createdAt: session.startedAt ? new Date(session.startedAt) : new Date(),
|
|
1190
|
-
lastActivityAt: session.lastActivityAt
|
|
1191
|
-
? new Date(session.lastActivityAt)
|
|
1192
|
-
: new Date(),
|
|
1193
|
-
metadata,
|
|
1194
|
-
};
|
|
1195
|
-
}
|
|
1196
|
-
toTerminalSessionInfo(sessionId) {
|
|
1197
|
-
const terminal = this.terminalSessionStates.get(sessionId);
|
|
1198
|
-
if (!terminal)
|
|
1199
|
-
return undefined;
|
|
1200
|
-
const metadata = this.sessionMetadata.get(sessionId);
|
|
1201
|
-
const requestedType = typeof metadata?.requestedType === "string"
|
|
1202
|
-
? metadata.requestedType
|
|
1203
|
-
: undefined;
|
|
1204
|
-
const storedAgentType = typeof metadata?.agentType === "string" ? metadata.agentType : "unknown";
|
|
1205
|
-
const displayAgentType = storedAgentType === "shell" && isPiAgentType(requestedType)
|
|
1206
|
-
? "pi"
|
|
1207
|
-
: storedAgentType;
|
|
1208
|
-
return {
|
|
1209
|
-
id: sessionId,
|
|
1210
|
-
name: this.sessionNames.get(sessionId) ?? sessionId,
|
|
1211
|
-
agentType: displayAgentType,
|
|
1212
|
-
workdir: this.sessionWorkdirs.get(sessionId) ?? process.cwd(),
|
|
1213
|
-
status: terminal.status,
|
|
1214
|
-
createdAt: terminal.createdAt,
|
|
1215
|
-
lastActivityAt: terminal.lastActivityAt,
|
|
1216
|
-
metadata,
|
|
1217
|
-
};
|
|
1218
|
-
}
|
|
1219
|
-
emitEvent(sessionId, event, data) {
|
|
1220
|
-
if (event === "blocked" &&
|
|
1221
|
-
this.shouldSuppressBlockedEvent(sessionId, data)) {
|
|
1222
|
-
return;
|
|
1223
|
-
}
|
|
1224
|
-
if (event === "ready" ||
|
|
1225
|
-
event === "task_complete" ||
|
|
1226
|
-
event === "stopped" ||
|
|
1227
|
-
event === "error") {
|
|
1228
|
-
this.clearCompletionReconcile(sessionId);
|
|
1229
|
-
}
|
|
1230
|
-
if (event === "stopped" || event === "error") {
|
|
1231
|
-
const authRecoveryTimer = this.authRecoveryTimers.get(sessionId);
|
|
1232
|
-
if (authRecoveryTimer) {
|
|
1233
|
-
clearInterval(authRecoveryTimer);
|
|
1234
|
-
this.authRecoveryTimers.delete(sessionId);
|
|
1235
|
-
}
|
|
1236
|
-
const liveSession = this.manager?.get(sessionId);
|
|
1237
|
-
const createdAt = liveSession?.startedAt instanceof Date
|
|
1238
|
-
? liveSession.startedAt
|
|
1239
|
-
: liveSession?.startedAt
|
|
1240
|
-
? new Date(liveSession.startedAt)
|
|
1241
|
-
: new Date();
|
|
1242
|
-
const lastActivityAt = liveSession?.lastActivityAt instanceof Date
|
|
1243
|
-
? liveSession.lastActivityAt
|
|
1244
|
-
: liveSession?.lastActivityAt
|
|
1245
|
-
? new Date(liveSession.lastActivityAt)
|
|
1246
|
-
: new Date();
|
|
1247
|
-
const reason = event === "stopped"
|
|
1248
|
-
? data?.reason
|
|
1249
|
-
: data?.message;
|
|
1250
|
-
this.terminalSessionStates.set(sessionId, {
|
|
1251
|
-
status: event,
|
|
1252
|
-
createdAt,
|
|
1253
|
-
lastActivityAt,
|
|
1254
|
-
reason,
|
|
1255
|
-
});
|
|
1256
|
-
}
|
|
1257
|
-
for (const callback of this.eventCallbacks) {
|
|
1258
|
-
try {
|
|
1259
|
-
callback(sessionId, event, data);
|
|
1260
|
-
}
|
|
1261
|
-
catch (err) {
|
|
1262
|
-
this.log(`Event callback error: ${err}`);
|
|
1263
|
-
}
|
|
1264
|
-
}
|
|
1265
|
-
const normalized = normalizeCoordinatorEvent(sessionId, event, data);
|
|
1266
|
-
if (!normalized)
|
|
1267
|
-
return;
|
|
1268
|
-
for (const callback of this.normalizedEventCallbacks) {
|
|
1269
|
-
try {
|
|
1270
|
-
callback(normalized);
|
|
1271
|
-
}
|
|
1272
|
-
catch (err) {
|
|
1273
|
-
this.log(`Normalized event callback error: ${err}`);
|
|
1274
|
-
}
|
|
1275
|
-
}
|
|
1276
|
-
}
|
|
1277
|
-
// ─── Metrics ───
|
|
1278
|
-
getAgentMetrics() {
|
|
1279
|
-
return this.metricsTracker.getAll();
|
|
1280
|
-
}
|
|
1281
|
-
log(message) {
|
|
1282
|
-
logger.debug(`[PTYService] ${message}`);
|
|
1283
|
-
}
|
|
1284
|
-
handleWorkerExit(info) {
|
|
1285
|
-
const trackedSessionIds = new Set([
|
|
1286
|
-
...this.sessionMetadata.keys(),
|
|
1287
|
-
...this.sessionWorkdirs.keys(),
|
|
1288
|
-
]);
|
|
1289
|
-
if (trackedSessionIds.size === 0) {
|
|
1290
|
-
return;
|
|
1291
|
-
}
|
|
1292
|
-
const reason = info.signal
|
|
1293
|
-
? `PTY worker exited unexpectedly (signal ${info.signal})`
|
|
1294
|
-
: `PTY worker exited unexpectedly (code ${info.code ?? "unknown"})`;
|
|
1295
|
-
for (const sessionId of trackedSessionIds) {
|
|
1296
|
-
const terminalState = this.terminalSessionStates.get(sessionId);
|
|
1297
|
-
if (terminalState?.status === "stopped" ||
|
|
1298
|
-
terminalState?.status === "error") {
|
|
1299
|
-
continue;
|
|
1300
|
-
}
|
|
1301
|
-
this.emitEvent(sessionId, "error", {
|
|
1302
|
-
message: reason,
|
|
1303
|
-
workerExit: info,
|
|
1304
|
-
source: "pty_manager",
|
|
1305
|
-
});
|
|
1306
|
-
}
|
|
1307
|
-
}
|
|
1308
|
-
clearCompletionReconcile(sessionId) {
|
|
1309
|
-
const timer = this.completionReconcileTimers.get(sessionId);
|
|
1310
|
-
if (timer) {
|
|
1311
|
-
clearInterval(timer);
|
|
1312
|
-
this.completionReconcileTimers.delete(sessionId);
|
|
1313
|
-
}
|
|
1314
|
-
this.completionSignalSince.delete(sessionId);
|
|
1315
|
-
}
|
|
1316
|
-
scheduleCompletionReconcile(sessionId) {
|
|
1317
|
-
this.clearCompletionReconcile(sessionId);
|
|
1318
|
-
const timer = setInterval(() => {
|
|
1319
|
-
void this.reconcileBusySessionFromOutput(sessionId);
|
|
1320
|
-
}, 1000);
|
|
1321
|
-
this.completionReconcileTimers.set(sessionId, timer);
|
|
1322
|
-
void this.reconcileBusySessionFromOutput(sessionId);
|
|
1323
|
-
}
|
|
1324
|
-
isAdapterBackedAgentType(value) {
|
|
1325
|
-
return (value === "claude" ||
|
|
1326
|
-
value === "gemini" ||
|
|
1327
|
-
value === "codex" ||
|
|
1328
|
-
value === "aider" ||
|
|
1329
|
-
value === "hermes");
|
|
1330
|
-
}
|
|
1331
|
-
shouldSuppressBlockedEvent(sessionId, data) {
|
|
1332
|
-
const payload = data;
|
|
1333
|
-
if (payload?.source !== "pty_manager") {
|
|
1334
|
-
return false;
|
|
1335
|
-
}
|
|
1336
|
-
const promptInfo = payload.promptInfo &&
|
|
1337
|
-
typeof payload.promptInfo === "object" &&
|
|
1338
|
-
!Array.isArray(payload.promptInfo)
|
|
1339
|
-
? payload.promptInfo
|
|
1340
|
-
: undefined;
|
|
1341
|
-
if (!promptInfo) {
|
|
1342
|
-
return false;
|
|
1343
|
-
}
|
|
1344
|
-
const promptType = typeof promptInfo.type === "string" ? promptInfo.type.toLowerCase() : "";
|
|
1345
|
-
if (promptType && promptType !== "unknown") {
|
|
1346
|
-
return false;
|
|
1347
|
-
}
|
|
1348
|
-
const promptText = typeof promptInfo.prompt === "string"
|
|
1349
|
-
? cleanForChat(promptInfo.prompt)
|
|
1350
|
-
: "";
|
|
1351
|
-
if (!promptText) {
|
|
1352
|
-
return false;
|
|
1353
|
-
}
|
|
1354
|
-
const compactPrompt = promptText.replace(/\s+/g, " ").trim();
|
|
1355
|
-
const hasWorkspacePath = /(\/private\/|\/var\/folders\/)/.test(compactPrompt);
|
|
1356
|
-
const looksLikeWorkingStatus = /working \(\d+s .*esc to interrupt\)/i.test(compactPrompt) ||
|
|
1357
|
-
/messages to be submitted after next tool call/i.test(compactPrompt) ||
|
|
1358
|
-
/find and fix a bug in @filename/i.test(compactPrompt) ||
|
|
1359
|
-
/use \/skills to list available skills/i.test(compactPrompt);
|
|
1360
|
-
const looksLikeSpinnerTail = /\b\d+% left\b/i.test(compactPrompt) && hasWorkspacePath;
|
|
1361
|
-
const looksLikeSpinnerFragments = hasWorkspacePath &&
|
|
1362
|
-
/(?:\bW Wo\b|• Wor|• Work|Worki|Workin|Working)/i.test(compactPrompt);
|
|
1363
|
-
if (!looksLikeWorkingStatus &&
|
|
1364
|
-
!looksLikeSpinnerTail &&
|
|
1365
|
-
!looksLikeSpinnerFragments) {
|
|
1366
|
-
return false;
|
|
1367
|
-
}
|
|
1368
|
-
this.log(`Suppressing false blocked prompt noise for ${sessionId}: ${compactPrompt.slice(0, 160)}`);
|
|
1369
|
-
return true;
|
|
1370
|
-
}
|
|
1371
|
-
responseLooksMeaningful(response, rawOutput) {
|
|
1372
|
-
if (extractCompletionSummary(rawOutput).trim().length > 0) {
|
|
1373
|
-
return true;
|
|
1374
|
-
}
|
|
1375
|
-
const cleaned = response.trim();
|
|
1376
|
-
if (!cleaned)
|
|
1377
|
-
return false;
|
|
1378
|
-
const substantiveLines = cleaned
|
|
1379
|
-
.split("\n")
|
|
1380
|
-
.map((line) => line.trim())
|
|
1381
|
-
.filter((line) => line.length > 0)
|
|
1382
|
-
.filter((line) => !line.startsWith("› ") &&
|
|
1383
|
-
!/^Work(?:i|in|ing)?(?:\s+\d+)?$/i.test(line) &&
|
|
1384
|
-
!/^\d+% left\b/i.test(line) &&
|
|
1385
|
-
!/context left/i.test(line) &&
|
|
1386
|
-
!/esc to interrupt/i.test(line) &&
|
|
1387
|
-
!/Use \/skills/i.test(line) &&
|
|
1388
|
-
!/Messages to be submitted after next tool call/i.test(line));
|
|
1389
|
-
if (substantiveLines.some((line) => /\b(Added|Created|Creating|Updated|Wrote|Deleted|Renamed|Verified|Completed|Finished|Saved|Ran|LIVE_)\b/i.test(line))) {
|
|
1390
|
-
return true;
|
|
1391
|
-
}
|
|
1392
|
-
return false;
|
|
1393
|
-
}
|
|
1394
|
-
async reconcileBusySessionFromOutput(sessionId) {
|
|
1395
|
-
if (!this.manager) {
|
|
1396
|
-
this.clearCompletionReconcile(sessionId);
|
|
1397
|
-
return;
|
|
1398
|
-
}
|
|
1399
|
-
const liveSession = this.manager.get(sessionId);
|
|
1400
|
-
if (!liveSession) {
|
|
1401
|
-
this.clearCompletionReconcile(sessionId);
|
|
1402
|
-
return;
|
|
1403
|
-
}
|
|
1404
|
-
if (liveSession.status !== "busy") {
|
|
1405
|
-
this.clearCompletionReconcile(sessionId);
|
|
1406
|
-
return;
|
|
1407
|
-
}
|
|
1408
|
-
const agentType = this.sessionMetadata.get(sessionId)?.agentType;
|
|
1409
|
-
if (!this.isAdapterBackedAgentType(agentType)) {
|
|
1410
|
-
this.clearCompletionReconcile(sessionId);
|
|
1411
|
-
return;
|
|
1412
|
-
}
|
|
1413
|
-
const adapter = this.getAdapter(agentType);
|
|
1414
|
-
const rawOutput = await this.getSessionOutput(sessionId);
|
|
1415
|
-
if (!rawOutput.trim()) {
|
|
1416
|
-
this.completionSignalSince.delete(sessionId);
|
|
1417
|
-
return;
|
|
1418
|
-
}
|
|
1419
|
-
if (adapter.detectLoading?.(rawOutput)) {
|
|
1420
|
-
this.completionSignalSince.delete(sessionId);
|
|
1421
|
-
return;
|
|
1422
|
-
}
|
|
1423
|
-
if (adapter.detectLogin(rawOutput).required) {
|
|
1424
|
-
this.completionSignalSince.delete(sessionId);
|
|
1425
|
-
return;
|
|
1426
|
-
}
|
|
1427
|
-
if (adapter.detectBlockingPrompt(rawOutput).detected) {
|
|
1428
|
-
this.completionSignalSince.delete(sessionId);
|
|
1429
|
-
return;
|
|
1430
|
-
}
|
|
1431
|
-
const completionSignal = adapter.detectTaskComplete
|
|
1432
|
-
? adapter.detectTaskComplete(rawOutput)
|
|
1433
|
-
: adapter.detectReady(rawOutput);
|
|
1434
|
-
if (!completionSignal) {
|
|
1435
|
-
this.completionSignalSince.delete(sessionId);
|
|
1436
|
-
return;
|
|
1437
|
-
}
|
|
1438
|
-
const previewResponse = this.taskResponseMarkers.has(sessionId)
|
|
1439
|
-
? peekTaskResponse(sessionId, this.sessionOutputBuffers, this.taskResponseMarkers)
|
|
1440
|
-
: cleanForChat(rawOutput);
|
|
1441
|
-
if (!this.responseLooksMeaningful(previewResponse, rawOutput)) {
|
|
1442
|
-
this.completionSignalSince.delete(sessionId);
|
|
1443
|
-
return;
|
|
1444
|
-
}
|
|
1445
|
-
const firstSeenAt = this.completionSignalSince.get(sessionId);
|
|
1446
|
-
if (firstSeenAt === undefined) {
|
|
1447
|
-
this.completionSignalSince.set(sessionId, Date.now());
|
|
1448
|
-
return;
|
|
1449
|
-
}
|
|
1450
|
-
if (Date.now() - firstSeenAt < 2500) {
|
|
1451
|
-
return;
|
|
1452
|
-
}
|
|
1453
|
-
const response = this.taskResponseMarkers.has(sessionId)
|
|
1454
|
-
? captureTaskResponse(sessionId, this.sessionOutputBuffers, this.taskResponseMarkers)
|
|
1455
|
-
: previewResponse;
|
|
1456
|
-
const durationMs = liveSession.startedAt
|
|
1457
|
-
? Date.now() - new Date(liveSession.startedAt).getTime()
|
|
1458
|
-
: 0;
|
|
1459
|
-
liveSession.status = "ready";
|
|
1460
|
-
liveSession.lastActivityAt = new Date();
|
|
1461
|
-
this.metricsTracker.recordCompletion(agentType, "output-reconcile", durationMs);
|
|
1462
|
-
this.log(`Reconciled ${sessionId} from busy to task_complete using stable adapter output`);
|
|
1463
|
-
this.emitEvent(sessionId, "task_complete", {
|
|
1464
|
-
session: liveSession,
|
|
1465
|
-
response,
|
|
1466
|
-
source: "output_reconcile",
|
|
1467
|
-
});
|
|
1468
|
-
}
|
|
1469
|
-
}
|