crewly 1.20.194 → 1.20.195
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/config/roles/auditor/prompt.md +2 -2
- package/config/roles/orchestrator/fragments/communication.md +1 -1
- package/config/roles/orchestrator/prompt.md +15 -505
- package/config/skills/agent/computer-use/SKILL.md +6 -0
- package/config/skills/agent/core/experiment-card/SKILL.md +10 -5
- package/config/skills/agent/core/experiment-card/execute.sh +5 -3
- package/config/skills/agent/core/experiment-card/execute.test.sh +6 -0
- package/config/skills/agent/desktop-app-control/execute.sh +5 -2
- package/config/skills/orchestrator/send-message/execute.sh +19 -2
- package/config/skills/orchestrator/send-message/execute.test.sh +80 -0
- package/config/skills/registry.json +6 -5
- package/config/skills/team-leader/signal-digest/SKILL.md +110 -0
- package/config/skills/team-leader/signal-digest/execute.sh +173 -0
- package/config/skills/team-leader/signal-digest/execute.test.sh +123 -0
- package/config/skills/team-leader/signal-digest/signal-digest.config.example.json +23 -0
- package/config/skills/team-leader/signal-digest/signal_digest.py +572 -0
- package/config/skills/team-leader/signal-digest/signal_digest.test.py +319 -0
- package/dist/backend/backend/src/constants.d.ts +133 -0
- package/dist/backend/backend/src/constants.d.ts.map +1 -1
- package/dist/backend/backend/src/constants.js +135 -2
- package/dist/backend/backend/src/constants.js.map +1 -1
- package/dist/backend/backend/src/controllers/chat/chat.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/chat/chat.controller.js +6 -0
- package/dist/backend/backend/src/controllers/chat/chat.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/chat-v2/chat-v2.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/chat-v2/chat-v2.controller.js +3 -1
- package/dist/backend/backend/src/controllers/chat-v2/chat-v2.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/marketplace/marketplace.routes.d.ts +1 -0
- package/dist/backend/backend/src/controllers/marketplace/marketplace.routes.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/marketplace/marketplace.routes.js +1 -0
- package/dist/backend/backend/src/controllers/marketplace/marketplace.routes.js.map +1 -1
- package/dist/backend/backend/src/controllers/monitoring/terminal.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/monitoring/terminal.controller.js +5 -2
- package/dist/backend/backend/src/controllers/monitoring/terminal.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/request/request.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/request/request.controller.js +5 -1
- package/dist/backend/backend/src/controllers/request/request.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/settings/settings.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/settings/settings.controller.js +18 -2
- package/dist/backend/backend/src/controllers/settings/settings.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/signal-digest/signal-digest.controller.d.ts +26 -0
- package/dist/backend/backend/src/controllers/signal-digest/signal-digest.controller.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/signal-digest/signal-digest.controller.js +100 -0
- package/dist/backend/backend/src/controllers/signal-digest/signal-digest.controller.js.map +1 -0
- package/dist/backend/backend/src/controllers/trace/trace.controller.d.ts +47 -0
- package/dist/backend/backend/src/controllers/trace/trace.controller.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/trace/trace.controller.js +169 -0
- package/dist/backend/backend/src/controllers/trace/trace.controller.js.map +1 -0
- package/dist/backend/backend/src/index.d.ts.map +1 -1
- package/dist/backend/backend/src/index.js +29 -19
- package/dist/backend/backend/src/index.js.map +1 -1
- package/dist/backend/backend/src/routes/api.routes.d.ts.map +1 -1
- package/dist/backend/backend/src/routes/api.routes.js +11 -0
- package/dist/backend/backend/src/routes/api.routes.js.map +1 -1
- package/dist/backend/backend/src/services/agent/agent-registration.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/agent/agent-registration.service.js +6 -1
- package/dist/backend/backend/src/services/agent/agent-registration.service.js.map +1 -1
- package/dist/backend/backend/src/services/agent/oauth-relogin-monitor.service.d.ts +1 -1
- package/dist/backend/backend/src/services/agent/oauth-relogin-monitor.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/agent/runtime-session-recovery.d.ts +4 -2
- package/dist/backend/backend/src/services/agent/runtime-session-recovery.d.ts.map +1 -1
- package/dist/backend/backend/src/services/agent/runtime-session-recovery.js +22 -6
- package/dist/backend/backend/src/services/agent/runtime-session-recovery.js.map +1 -1
- package/dist/backend/backend/src/services/ai/prompt-modules/communication.module.js +2 -2
- package/dist/backend/backend/src/services/ai/prompt-modules/communication.module.js.map +1 -1
- package/dist/backend/backend/src/services/backup/backup-archive.service.d.ts +6 -0
- package/dist/backend/backend/src/services/backup/backup-archive.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/backup/backup-archive.service.js +7 -1
- package/dist/backend/backend/src/services/backup/backup-archive.service.js.map +1 -1
- package/dist/backend/backend/src/services/boot/boot-announce.service.d.ts +1 -1
- package/dist/backend/backend/src/services/boot/boot-announce.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/chat/chat.service.d.ts +78 -2
- package/dist/backend/backend/src/services/chat/chat.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/chat/chat.service.js +210 -26
- package/dist/backend/backend/src/services/chat/chat.service.js.map +1 -1
- package/dist/backend/backend/src/services/chat-v2/chat-v2.service.d.ts +4 -3
- package/dist/backend/backend/src/services/chat-v2/chat-v2.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/chat-v2/chat-v2.service.js +7 -4
- package/dist/backend/backend/src/services/chat-v2/chat-v2.service.js.map +1 -1
- package/dist/backend/backend/src/services/decisions/decision-store.d.ts.map +1 -1
- package/dist/backend/backend/src/services/decisions/decision-store.js +5 -1
- package/dist/backend/backend/src/services/decisions/decision-store.js.map +1 -1
- package/dist/backend/backend/src/services/decisions/decision.wiring.d.ts +10 -1
- package/dist/backend/backend/src/services/decisions/decision.wiring.d.ts.map +1 -1
- package/dist/backend/backend/src/services/decisions/decision.wiring.js +20 -9
- package/dist/backend/backend/src/services/decisions/decision.wiring.js.map +1 -1
- package/dist/backend/backend/src/services/experiments/experiment-verdict.d.ts +1 -1
- package/dist/backend/backend/src/services/experiments/experiment-verdict.js +2 -2
- package/dist/backend/backend/src/services/experiments/experiment-verdict.js.map +1 -1
- package/dist/backend/backend/src/services/experiments/experiment.service.d.ts +52 -3
- package/dist/backend/backend/src/services/experiments/experiment.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/experiments/experiment.service.js +178 -24
- package/dist/backend/backend/src/services/experiments/experiment.service.js.map +1 -1
- package/dist/backend/backend/src/services/experiments/experiment.wiring.d.ts +20 -5
- package/dist/backend/backend/src/services/experiments/experiment.wiring.d.ts.map +1 -1
- package/dist/backend/backend/src/services/experiments/experiment.wiring.js +27 -7
- package/dist/backend/backend/src/services/experiments/experiment.wiring.js.map +1 -1
- package/dist/backend/backend/src/services/experiments/seo-ops-metric.fetcher.d.ts +7 -0
- package/dist/backend/backend/src/services/experiments/seo-ops-metric.fetcher.d.ts.map +1 -1
- package/dist/backend/backend/src/services/experiments/seo-ops-metric.fetcher.js +21 -1
- package/dist/backend/backend/src/services/experiments/seo-ops-metric.fetcher.js.map +1 -1
- package/dist/backend/backend/src/services/messaging/owner-message-watchdog.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/messaging/owner-message-watchdog.service.js +7 -0
- package/dist/backend/backend/src/services/messaging/owner-message-watchdog.service.js.map +1 -1
- package/dist/backend/backend/src/services/monitoring/token-usage.service.d.ts +7 -0
- package/dist/backend/backend/src/services/monitoring/token-usage.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/monitoring/token-usage.service.js +4 -0
- package/dist/backend/backend/src/services/monitoring/token-usage.service.js.map +1 -1
- package/dist/backend/backend/src/services/orc/orc-status-router.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/orc/orc-status-router.service.js +10 -2
- package/dist/backend/backend/src/services/orc/orc-status-router.service.js.map +1 -1
- package/dist/backend/backend/src/services/orc/reply-destination.wiring.d.ts.map +1 -1
- package/dist/backend/backend/src/services/orc/reply-destination.wiring.js +16 -0
- package/dist/backend/backend/src/services/orc/reply-destination.wiring.js.map +1 -1
- package/dist/backend/backend/src/services/project-tickets/project-ticket.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/project-tickets/project-ticket.service.js +2 -0
- package/dist/backend/backend/src/services/project-tickets/project-ticket.service.js.map +1 -1
- package/dist/backend/backend/src/services/reconciler/reconciler.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/reconciler/reconciler.service.js +15 -0
- package/dist/backend/backend/src/services/reconciler/reconciler.service.js.map +1 -1
- package/dist/backend/backend/src/services/session/session-handoff.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/session/session-handoff.service.js +8 -5
- package/dist/backend/backend/src/services/session/session-handoff.service.js.map +1 -1
- package/dist/backend/backend/src/services/signal-digest/signal-digest-card.d.ts +75 -0
- package/dist/backend/backend/src/services/signal-digest/signal-digest-card.d.ts.map +1 -0
- package/dist/backend/backend/src/services/signal-digest/signal-digest-card.js +187 -0
- package/dist/backend/backend/src/services/signal-digest/signal-digest-card.js.map +1 -0
- package/dist/backend/backend/src/services/signal-digest/signal-digest-contract.d.ts +86 -0
- package/dist/backend/backend/src/services/signal-digest/signal-digest-contract.d.ts.map +1 -0
- package/dist/backend/backend/src/services/signal-digest/signal-digest-contract.js +307 -0
- package/dist/backend/backend/src/services/signal-digest/signal-digest-contract.js.map +1 -0
- package/dist/backend/backend/src/services/signal-digest/signal-digest-store.d.ts +85 -0
- package/dist/backend/backend/src/services/signal-digest/signal-digest-store.d.ts.map +1 -0
- package/dist/backend/backend/src/services/signal-digest/signal-digest-store.js +185 -0
- package/dist/backend/backend/src/services/signal-digest/signal-digest-store.js.map +1 -0
- package/dist/backend/backend/src/services/signal-digest/signal-digest.service.d.ts +272 -0
- package/dist/backend/backend/src/services/signal-digest/signal-digest.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/signal-digest/signal-digest.service.js +570 -0
- package/dist/backend/backend/src/services/signal-digest/signal-digest.service.js.map +1 -0
- package/dist/backend/backend/src/services/signal-digest/signal-digest.wiring.d.ts +51 -0
- package/dist/backend/backend/src/services/signal-digest/signal-digest.wiring.d.ts.map +1 -0
- package/dist/backend/backend/src/services/signal-digest/signal-digest.wiring.js +116 -0
- package/dist/backend/backend/src/services/signal-digest/signal-digest.wiring.js.map +1 -0
- package/dist/backend/backend/src/services/slack/notify-reconciliation.service.d.ts +5 -1
- package/dist/backend/backend/src/services/slack/notify-reconciliation.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/slack/notify-reconciliation.service.js +6 -2
- package/dist/backend/backend/src/services/slack/notify-reconciliation.service.js.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.d.ts +2 -1
- package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.d.ts.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.js +3 -2
- package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.js.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-relogin-dm.service.d.ts +1 -1
- package/dist/backend/backend/src/services/slack/slack-relogin-dm.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/slack/slack.service.d.ts +25 -1
- package/dist/backend/backend/src/services/slack/slack.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/slack/slack.service.js +44 -7
- package/dist/backend/backend/src/services/slack/slack.service.js.map +1 -1
- package/dist/backend/backend/src/services/system/auto-update.service.d.ts +2 -2
- package/dist/backend/backend/src/services/system/auto-update.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/task-pool/pool-storage.d.ts.map +1 -1
- package/dist/backend/backend/src/services/task-pool/pool-storage.js +4 -0
- package/dist/backend/backend/src/services/task-pool/pool-storage.js.map +1 -1
- package/dist/backend/backend/src/services/task-pool/task-pool.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/task-pool/task-pool.service.js +2 -0
- package/dist/backend/backend/src/services/task-pool/task-pool.service.js.map +1 -1
- package/dist/backend/backend/src/services/trace/trace-context.service.d.ts +195 -0
- package/dist/backend/backend/src/services/trace/trace-context.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/trace/trace-context.service.js +432 -0
- package/dist/backend/backend/src/services/trace/trace-context.service.js.map +1 -0
- package/dist/backend/backend/src/services/trace/trace-http.middleware.d.ts +42 -0
- package/dist/backend/backend/src/services/trace/trace-http.middleware.d.ts.map +1 -0
- package/dist/backend/backend/src/services/trace/trace-http.middleware.js +146 -0
- package/dist/backend/backend/src/services/trace/trace-http.middleware.js.map +1 -0
- package/dist/backend/backend/src/services/trace/trace-markers.d.ts +93 -0
- package/dist/backend/backend/src/services/trace/trace-markers.d.ts.map +1 -0
- package/dist/backend/backend/src/services/trace/trace-markers.js +162 -0
- package/dist/backend/backend/src/services/trace/trace-markers.js.map +1 -0
- package/dist/backend/backend/src/services/trace/trace-recorder.d.ts +290 -0
- package/dist/backend/backend/src/services/trace/trace-recorder.d.ts.map +1 -0
- package/dist/backend/backend/src/services/trace/trace-recorder.js +669 -0
- package/dist/backend/backend/src/services/trace/trace-recorder.js.map +1 -0
- package/dist/backend/backend/src/services/trace/trace-store.d.ts +269 -0
- package/dist/backend/backend/src/services/trace/trace-store.d.ts.map +1 -0
- package/dist/backend/backend/src/services/trace/trace-store.js +602 -0
- package/dist/backend/backend/src/services/trace/trace-store.js.map +1 -0
- package/dist/backend/backend/src/services/trace/trace.types.d.ts +118 -0
- package/dist/backend/backend/src/services/trace/trace.types.d.ts.map +1 -0
- package/dist/backend/backend/src/services/trace/trace.types.js +85 -0
- package/dist/backend/backend/src/services/trace/trace.types.js.map +1 -0
- package/dist/backend/backend/src/services/v3/owner-receipt/owner-receipt.boot.d.ts +1 -1
- package/dist/backend/backend/src/services/v3/owner-receipt/owner-receipt.boot.d.ts.map +1 -1
- package/dist/backend/backend/src/services/v3/request.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/v3/request.service.js +4 -0
- package/dist/backend/backend/src/services/v3/request.service.js.map +1 -1
- package/dist/backend/backend/src/services/v3/workitem-dispatch.subscriber.d.ts.map +1 -1
- package/dist/backend/backend/src/services/v3/workitem-dispatch.subscriber.js +22 -2
- package/dist/backend/backend/src/services/v3/workitem-dispatch.subscriber.js.map +1 -1
- package/dist/backend/backend/src/services/worktree/worktree-janitor.service.d.ts +3 -0
- package/dist/backend/backend/src/services/worktree/worktree-janitor.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/worktree/worktree-janitor.service.js +7 -0
- package/dist/backend/backend/src/services/worktree/worktree-janitor.service.js.map +1 -1
- package/dist/backend/backend/src/types/experiment.types.d.ts +8 -6
- package/dist/backend/backend/src/types/experiment.types.d.ts.map +1 -1
- package/dist/backend/backend/src/types/experiment.types.js.map +1 -1
- package/dist/backend/backend/src/types/signal-digest.types.d.ts +185 -0
- package/dist/backend/backend/src/types/signal-digest.types.d.ts.map +1 -0
- package/dist/backend/backend/src/types/signal-digest.types.js +21 -0
- package/dist/backend/backend/src/types/signal-digest.types.js.map +1 -0
- package/dist/backend/backend/src/types/v2/request.types.d.ts +4 -0
- package/dist/backend/backend/src/types/v2/request.types.d.ts.map +1 -1
- package/dist/backend/backend/src/types/v2/request.types.js.map +1 -1
- package/dist/backend/backend/src/types/v2/work-item.types.d.ts +4 -0
- package/dist/backend/backend/src/types/v2/work-item.types.d.ts.map +1 -1
- package/dist/backend/backend/src/types/v2/work-item.types.js +1 -0
- package/dist/backend/backend/src/types/v2/work-item.types.js.map +1 -1
- package/dist/backend/backend/src/utils/security.d.ts +2 -0
- package/dist/backend/backend/src/utils/security.d.ts.map +1 -1
- package/dist/backend/backend/src/utils/security.js +3 -1
- package/dist/backend/backend/src/utils/security.js.map +1 -1
- package/dist/backend/backend/src/websocket/chat.gateway.d.ts +9 -0
- package/dist/backend/backend/src/websocket/chat.gateway.d.ts.map +1 -1
- package/dist/backend/backend/src/websocket/chat.gateway.js +26 -0
- package/dist/backend/backend/src/websocket/chat.gateway.js.map +1 -1
- package/dist/backend/build-info.json +2 -2
- package/dist/cli/backend/src/constants.d.ts +133 -0
- package/dist/cli/backend/src/constants.d.ts.map +1 -1
- package/dist/cli/backend/src/constants.js +135 -2
- package/dist/cli/backend/src/constants.js.map +1 -1
- package/dist/cli/backend/src/services/agent/agent-registration.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/agent/agent-registration.service.js +6 -1
- package/dist/cli/backend/src/services/agent/agent-registration.service.js.map +1 -1
- package/dist/cli/backend/src/services/agent/oauth-relogin-monitor.service.d.ts +1 -1
- package/dist/cli/backend/src/services/agent/oauth-relogin-monitor.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/agent/runtime-session-recovery.d.ts +4 -2
- package/dist/cli/backend/src/services/agent/runtime-session-recovery.d.ts.map +1 -1
- package/dist/cli/backend/src/services/agent/runtime-session-recovery.js +22 -6
- package/dist/cli/backend/src/services/agent/runtime-session-recovery.js.map +1 -1
- package/dist/cli/backend/src/services/ai/prompt-modules/communication.module.js +2 -2
- package/dist/cli/backend/src/services/ai/prompt-modules/communication.module.js.map +1 -1
- package/dist/cli/backend/src/services/backup/backup-archive.service.d.ts +6 -0
- package/dist/cli/backend/src/services/backup/backup-archive.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/backup/backup-archive.service.js +7 -1
- package/dist/cli/backend/src/services/backup/backup-archive.service.js.map +1 -1
- package/dist/cli/backend/src/services/chat/chat.service.d.ts +185 -0
- package/dist/cli/backend/src/services/chat/chat.service.d.ts.map +1 -0
- package/dist/cli/backend/src/services/chat/chat.service.js +558 -0
- package/dist/cli/backend/src/services/chat/chat.service.js.map +1 -0
- package/dist/cli/backend/src/services/chat-v2/chat-v2.service.d.ts +4 -3
- package/dist/cli/backend/src/services/chat-v2/chat-v2.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/chat-v2/chat-v2.service.js +7 -4
- package/dist/cli/backend/src/services/chat-v2/chat-v2.service.js.map +1 -1
- package/dist/cli/backend/src/services/decisions/decision-store.d.ts.map +1 -1
- package/dist/cli/backend/src/services/decisions/decision-store.js +5 -1
- package/dist/cli/backend/src/services/decisions/decision-store.js.map +1 -1
- package/dist/cli/backend/src/services/messaging/owner-message-watchdog.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/messaging/owner-message-watchdog.service.js +7 -0
- package/dist/cli/backend/src/services/messaging/owner-message-watchdog.service.js.map +1 -1
- package/dist/cli/backend/src/services/monitoring/token-usage.service.d.ts +7 -0
- package/dist/cli/backend/src/services/monitoring/token-usage.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/monitoring/token-usage.service.js +4 -0
- package/dist/cli/backend/src/services/monitoring/token-usage.service.js.map +1 -1
- package/dist/cli/backend/src/services/project-tickets/project-ticket.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/project-tickets/project-ticket.service.js +2 -0
- package/dist/cli/backend/src/services/project-tickets/project-ticket.service.js.map +1 -1
- package/dist/cli/backend/src/services/session/session-handoff.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/session/session-handoff.service.js +8 -5
- package/dist/cli/backend/src/services/session/session-handoff.service.js.map +1 -1
- package/dist/cli/backend/src/services/slack/slack-orchestrator-bridge.d.ts +2 -1
- package/dist/cli/backend/src/services/slack/slack-orchestrator-bridge.d.ts.map +1 -1
- package/dist/cli/backend/src/services/slack/slack-orchestrator-bridge.js +3 -2
- package/dist/cli/backend/src/services/slack/slack-orchestrator-bridge.js.map +1 -1
- package/dist/cli/backend/src/services/slack/slack.service.d.ts +25 -1
- package/dist/cli/backend/src/services/slack/slack.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/slack/slack.service.js +44 -7
- package/dist/cli/backend/src/services/slack/slack.service.js.map +1 -1
- package/dist/cli/backend/src/services/task-pool/pool-storage.d.ts.map +1 -1
- package/dist/cli/backend/src/services/task-pool/pool-storage.js +4 -0
- package/dist/cli/backend/src/services/task-pool/pool-storage.js.map +1 -1
- package/dist/cli/backend/src/services/task-pool/task-pool.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/task-pool/task-pool.service.js +2 -0
- package/dist/cli/backend/src/services/task-pool/task-pool.service.js.map +1 -1
- package/dist/cli/backend/src/services/trace/trace-context.service.d.ts +195 -0
- package/dist/cli/backend/src/services/trace/trace-context.service.d.ts.map +1 -0
- package/dist/cli/backend/src/services/trace/trace-context.service.js +432 -0
- package/dist/cli/backend/src/services/trace/trace-context.service.js.map +1 -0
- package/dist/cli/backend/src/services/trace/trace-markers.d.ts +93 -0
- package/dist/cli/backend/src/services/trace/trace-markers.d.ts.map +1 -0
- package/dist/cli/backend/src/services/trace/trace-markers.js +162 -0
- package/dist/cli/backend/src/services/trace/trace-markers.js.map +1 -0
- package/dist/cli/backend/src/services/trace/trace-recorder.d.ts +290 -0
- package/dist/cli/backend/src/services/trace/trace-recorder.d.ts.map +1 -0
- package/dist/cli/backend/src/services/trace/trace-recorder.js +669 -0
- package/dist/cli/backend/src/services/trace/trace-recorder.js.map +1 -0
- package/dist/cli/backend/src/services/trace/trace-store.d.ts +269 -0
- package/dist/cli/backend/src/services/trace/trace-store.d.ts.map +1 -0
- package/dist/cli/backend/src/services/trace/trace-store.js +602 -0
- package/dist/cli/backend/src/services/trace/trace-store.js.map +1 -0
- package/dist/cli/backend/src/services/trace/trace.types.d.ts +118 -0
- package/dist/cli/backend/src/services/trace/trace.types.d.ts.map +1 -0
- package/dist/cli/backend/src/services/trace/trace.types.js +85 -0
- package/dist/cli/backend/src/services/trace/trace.types.js.map +1 -0
- package/dist/cli/backend/src/services/v3/request.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/v3/request.service.js +4 -0
- package/dist/cli/backend/src/services/v3/request.service.js.map +1 -1
- package/dist/cli/backend/src/types/v2/request.types.d.ts +4 -0
- package/dist/cli/backend/src/types/v2/request.types.d.ts.map +1 -1
- package/dist/cli/backend/src/types/v2/request.types.js.map +1 -1
- package/dist/cli/backend/src/types/v2/work-item.types.d.ts +4 -0
- package/dist/cli/backend/src/types/v2/work-item.types.d.ts.map +1 -1
- package/dist/cli/backend/src/types/v2/work-item.types.js +1 -0
- package/dist/cli/backend/src/types/v2/work-item.types.js.map +1 -1
- package/dist/cli/backend/src/utils/security.d.ts +196 -0
- package/dist/cli/backend/src/utils/security.d.ts.map +1 -0
- package/dist/cli/backend/src/utils/security.js +538 -0
- package/dist/cli/backend/src/utils/security.js.map +1 -0
- package/dist/cli/backend/src/websocket/chat.gateway.d.ts +9 -0
- package/dist/cli/backend/src/websocket/chat.gateway.d.ts.map +1 -1
- package/dist/cli/backend/src/websocket/chat.gateway.js +26 -0
- package/dist/cli/backend/src/websocket/chat.gateway.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,669 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Run trace hooks: the one-line calls the rest of the backend makes to start
|
|
3
|
+
* traces, carry them onto entities, and record what happened.
|
|
4
|
+
*
|
|
5
|
+
* Every function here is fire-and-forget: it catches its own errors and never
|
|
6
|
+
* throws, so a trace problem can never break a turn, a delivery or a request.
|
|
7
|
+
*
|
|
8
|
+
* specs/2026-10-03-run-traces.md
|
|
9
|
+
*
|
|
10
|
+
* @module services/trace/trace-recorder
|
|
11
|
+
*/
|
|
12
|
+
import { readProjectTicketLink } from '../../types/project-ticket.types.js';
|
|
13
|
+
import { formatTicketNumber } from '../../types/v2/ticket.types.js';
|
|
14
|
+
import { getTraceContext } from './trace-context.service.js';
|
|
15
|
+
import { appendTraceMarker, formatTraceMarker } from './trace-markers.js';
|
|
16
|
+
import { TERMINAL_INPUT_MAX_LENGTH } from '../../utils/security.js';
|
|
17
|
+
import { isTraceId } from './trace.types.js';
|
|
18
|
+
/**
|
|
19
|
+
* Run a hook, swallowing any error.
|
|
20
|
+
*
|
|
21
|
+
* @param fn - The hook body
|
|
22
|
+
* @param fallback - Value on error
|
|
23
|
+
* @returns The hook's value, or the fallback
|
|
24
|
+
*/
|
|
25
|
+
function safely(fn, fallback) {
|
|
26
|
+
try {
|
|
27
|
+
return fn();
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
return fallback;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* A trace id that is well-formed and known to the store.
|
|
35
|
+
*
|
|
36
|
+
* @param id - Candidate
|
|
37
|
+
* @returns The id, or null
|
|
38
|
+
*/
|
|
39
|
+
function known(id) {
|
|
40
|
+
return id && isTraceId(id) && getTraceContext().store.has(id) ? id : null;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Actor for an agent session (the orchestrator included).
|
|
44
|
+
*
|
|
45
|
+
* @param session - Session name
|
|
46
|
+
* @returns Agent actor, or system when unknown
|
|
47
|
+
*/
|
|
48
|
+
function agentActor(session) {
|
|
49
|
+
return session ? { kind: 'agent', session } : { kind: 'system' };
|
|
50
|
+
}
|
|
51
|
+
// ---------------------------------------------------------------------------
|
|
52
|
+
// Turn context
|
|
53
|
+
// ---------------------------------------------------------------------------
|
|
54
|
+
/**
|
|
55
|
+
* The trace a session's turn is on (no pending root is materialised).
|
|
56
|
+
*
|
|
57
|
+
* @param session - Agent session
|
|
58
|
+
* @returns Trace id, or null
|
|
59
|
+
*/
|
|
60
|
+
export function currentTraceOf(session) {
|
|
61
|
+
return safely(() => getTraceContext().currentTrace(session), null);
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* The trace a session's turn is on; a waiting owner message becomes a root now
|
|
65
|
+
* because the turn is starting work.
|
|
66
|
+
*
|
|
67
|
+
* @param session - Agent session
|
|
68
|
+
* @returns Trace id, or null
|
|
69
|
+
*/
|
|
70
|
+
export function ensureTraceForSession(session) {
|
|
71
|
+
return safely(() => getTraceContext().ensureTraceForSession(session), null);
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* A message was written into an agent turn (PTY or in-process).
|
|
75
|
+
*
|
|
76
|
+
* @param session - Agent session
|
|
77
|
+
* @param text - Exactly what was delivered
|
|
78
|
+
* @param runtime - `pty` or `in-process`
|
|
79
|
+
* @returns The trace the turn is now on, or null
|
|
80
|
+
*/
|
|
81
|
+
export function noteTurnDelivery(session, text, runtime = 'pty') {
|
|
82
|
+
return safely(() => getTraceContext().noteTurnDelivery(session, text, runtime), null);
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* An in-process turn failed.
|
|
86
|
+
*
|
|
87
|
+
* @param session - Agent session
|
|
88
|
+
* @param error - What failed
|
|
89
|
+
*/
|
|
90
|
+
export function traceTurnError(session, error) {
|
|
91
|
+
safely(() => {
|
|
92
|
+
const traceId = getTraceContext().currentTrace(session);
|
|
93
|
+
if (!traceId)
|
|
94
|
+
return;
|
|
95
|
+
getTraceContext().record({
|
|
96
|
+
traceId,
|
|
97
|
+
type: 'turn.error',
|
|
98
|
+
actor: agentActor(session),
|
|
99
|
+
summary: `Turn of ${session} failed: ${error instanceof Error ? error.message : String(error)}`,
|
|
100
|
+
outcome: 'failed',
|
|
101
|
+
refs: { session },
|
|
102
|
+
});
|
|
103
|
+
}, undefined);
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Start a goal or experiment trace (POST /api/traces, #986 experiment cards).
|
|
107
|
+
*
|
|
108
|
+
* @param input - Kind, summary, who, refs, session to bind
|
|
109
|
+
* @returns Trace id, or null
|
|
110
|
+
*/
|
|
111
|
+
export function startGoalTrace(input) {
|
|
112
|
+
return safely(() => getTraceContext().startTrace({
|
|
113
|
+
kind: input.kind,
|
|
114
|
+
summary: input.summary,
|
|
115
|
+
actor: input.session ? agentActor(input.session) : { kind: 'owner' },
|
|
116
|
+
refs: input.refs ?? {},
|
|
117
|
+
...(input.session ? { session: input.session } : {}),
|
|
118
|
+
}), null);
|
|
119
|
+
}
|
|
120
|
+
// ---------------------------------------------------------------------------
|
|
121
|
+
// Requests (TKT tickets) and project tickets
|
|
122
|
+
// ---------------------------------------------------------------------------
|
|
123
|
+
/**
|
|
124
|
+
* Give a new Request its trace (call before its first save): an explicit or
|
|
125
|
+
* creator trace, the parent ticket's trace, or a new `request` root. Sets
|
|
126
|
+
* `request.traceId` and records `request.created`.
|
|
127
|
+
*
|
|
128
|
+
* @param request - The Request about to be saved (mutated)
|
|
129
|
+
* @param opts.traceId - Trace to join (e.g. the creating agent's)
|
|
130
|
+
* @param opts.creatorSession - Agent creating it, when known
|
|
131
|
+
* @returns The trace id, or null
|
|
132
|
+
*/
|
|
133
|
+
export function assignRequestTrace(request, opts = {}) {
|
|
134
|
+
return safely(() => {
|
|
135
|
+
const ctx = getTraceContext();
|
|
136
|
+
const store = ctx.store;
|
|
137
|
+
const label = typeof request.ticketNumber === 'number' ? formatTicketNumber(request.ticketNumber) : undefined;
|
|
138
|
+
const fromOwner = !opts.creatorSession && !!request.origin && !['agent', 'cron', 'mission', 'legacy'].includes(request.origin.channel);
|
|
139
|
+
const actor = opts.creatorSession ? agentActor(opts.creatorSession) : fromOwner ? { kind: 'owner' } : { kind: 'system' };
|
|
140
|
+
let traceId = known(request.traceId) ??
|
|
141
|
+
known(opts.traceId) ??
|
|
142
|
+
store.traceByRef('request', request.parentTicketId) ??
|
|
143
|
+
ensureTraceForSession(opts.creatorSession);
|
|
144
|
+
if (!traceId) {
|
|
145
|
+
traceId = ctx.startTrace({
|
|
146
|
+
kind: 'request',
|
|
147
|
+
summary: `${label ? `${label}: ` : ''}${request.title}`,
|
|
148
|
+
actor,
|
|
149
|
+
refs: { requestId: request.id, ...(label ? { ticketId: label } : {}) },
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
if (!traceId)
|
|
153
|
+
return null;
|
|
154
|
+
request.traceId = traceId;
|
|
155
|
+
store.linkRef('request', request.id, traceId);
|
|
156
|
+
if (label)
|
|
157
|
+
store.linkRef('ticket', label, traceId);
|
|
158
|
+
ctx.record({
|
|
159
|
+
traceId,
|
|
160
|
+
type: 'request.created',
|
|
161
|
+
actor,
|
|
162
|
+
summary: `Ticket ${label ?? request.id} created: ${request.title}`,
|
|
163
|
+
refs: { requestId: request.id, ...(label ? { ticketId: label } : {}), ...(request.assignee ? { session: request.assignee } : {}) },
|
|
164
|
+
data: { status: request.status, ...(request.parentTicketId ? { parentRequestId: request.parentTicketId } : {}) },
|
|
165
|
+
});
|
|
166
|
+
return traceId;
|
|
167
|
+
}, null);
|
|
168
|
+
}
|
|
169
|
+
/** Outcome of a Request (ticket) status. */
|
|
170
|
+
const REQUEST_STATUS_OUTCOME = {
|
|
171
|
+
done: 'ok',
|
|
172
|
+
cancelled: 'skipped',
|
|
173
|
+
waiting_confirmation: 'queued',
|
|
174
|
+
blocked: 'blocked',
|
|
175
|
+
};
|
|
176
|
+
/**
|
|
177
|
+
* A Request (ticket) changed status: submitted for review, accepted, sent
|
|
178
|
+
* back, reopened, cancelled.
|
|
179
|
+
*
|
|
180
|
+
* @param request - The Request after the change
|
|
181
|
+
* @param previous - Its status before
|
|
182
|
+
*/
|
|
183
|
+
export function traceRequestStatus(request, previous) {
|
|
184
|
+
safely(() => {
|
|
185
|
+
if (request.status === previous)
|
|
186
|
+
return;
|
|
187
|
+
const ctx = getTraceContext();
|
|
188
|
+
const traceId = known(request.traceId) ?? ctx.store.traceByRef('request', request.id);
|
|
189
|
+
if (!traceId)
|
|
190
|
+
return;
|
|
191
|
+
const label = typeof request.ticketNumber === 'number' ? formatTicketNumber(request.ticketNumber) : undefined;
|
|
192
|
+
const byOwner = request.status === 'done' && request.acceptedBy === 'owner';
|
|
193
|
+
ctx.record({
|
|
194
|
+
traceId,
|
|
195
|
+
type: 'request.status',
|
|
196
|
+
actor: byOwner ? { kind: 'owner' } : { kind: 'system' },
|
|
197
|
+
summary: `Ticket ${label ?? request.id} ${previous} → ${request.status}: ${request.title}`,
|
|
198
|
+
outcome: REQUEST_STATUS_OUTCOME[request.status] ?? 'info',
|
|
199
|
+
refs: { requestId: request.id, ...(label ? { ticketId: label } : {}) },
|
|
200
|
+
data: {
|
|
201
|
+
from: previous,
|
|
202
|
+
to: request.status,
|
|
203
|
+
...(request.acceptedBy ? { acceptedBy: request.acceptedBy } : {}),
|
|
204
|
+
...(typeof request.rejectCount === 'number' ? { rejectCount: request.rejectCount } : {}),
|
|
205
|
+
},
|
|
206
|
+
});
|
|
207
|
+
}, undefined);
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* A project ticket was created: link it to the trace of its Request or of the
|
|
211
|
+
* creating agent's turn, and record `ticket.created`.
|
|
212
|
+
*
|
|
213
|
+
* @param ticket - The ticket
|
|
214
|
+
* @param actor - Who created it (agent session, or a non-agent label)
|
|
215
|
+
* @returns The trace id, or null
|
|
216
|
+
*/
|
|
217
|
+
export function traceProjectTicketCreated(ticket, actor) {
|
|
218
|
+
return safely(() => {
|
|
219
|
+
const ctx = getTraceContext();
|
|
220
|
+
const traceId = ctx.store.traceByRef('request', ticket.requestId ?? undefined) ?? ensureTraceForSession(actor);
|
|
221
|
+
if (!traceId)
|
|
222
|
+
return null;
|
|
223
|
+
ctx.store.linkRef('ticket', ticket.id, traceId);
|
|
224
|
+
ctx.record({
|
|
225
|
+
traceId,
|
|
226
|
+
type: 'ticket.created',
|
|
227
|
+
actor: agentActor(actor),
|
|
228
|
+
summary: `Project ticket ${ticket.id} created: ${ticket.title}`,
|
|
229
|
+
refs: { ticketId: ticket.id, ...(ticket.requestId ? { requestId: ticket.requestId } : {}), ...(ticket.assignee ? { session: ticket.assignee } : {}) },
|
|
230
|
+
});
|
|
231
|
+
return traceId;
|
|
232
|
+
}, null);
|
|
233
|
+
}
|
|
234
|
+
// ---------------------------------------------------------------------------
|
|
235
|
+
// Work items
|
|
236
|
+
// ---------------------------------------------------------------------------
|
|
237
|
+
/**
|
|
238
|
+
* Give a work item its trace before it is stored. Order: its own `traceId`;
|
|
239
|
+
* the item it continues (parent / verify-of / source); its Request; its
|
|
240
|
+
* project ticket; the creating agent's turn. Sets `workItem.traceId`.
|
|
241
|
+
*
|
|
242
|
+
* @param workItem - The item (mutated)
|
|
243
|
+
* @param creatorSession - Agent creating it (X-Agent-Session), when known
|
|
244
|
+
* @returns The trace id, or null
|
|
245
|
+
*/
|
|
246
|
+
export function assignWorkItemTrace(workItem, creatorSession) {
|
|
247
|
+
return safely(() => {
|
|
248
|
+
const store = getTraceContext().store;
|
|
249
|
+
const meta = (workItem.metadata ?? {});
|
|
250
|
+
const str = (v) => (typeof v === 'string' && v.length > 0 ? v : undefined);
|
|
251
|
+
const explicit = known(workItem.traceId) ?? known(str(meta.traceId));
|
|
252
|
+
const parentTrace = [workItem.parentWorkItemId, str(meta.verifyOf), str(meta.sourceWorkItemId)]
|
|
253
|
+
.map((id) => store.traceByRef('workItem', id))
|
|
254
|
+
.find((id) => !!id);
|
|
255
|
+
const creator = creatorSession ?? str(meta.delegatedBy);
|
|
256
|
+
const traceId = explicit ??
|
|
257
|
+
parentTrace ??
|
|
258
|
+
store.traceByRef('request', workItem.requestId) ??
|
|
259
|
+
store.traceByRef('ticket', readProjectTicketLink(meta)?.id) ??
|
|
260
|
+
ensureTraceForSession(creator);
|
|
261
|
+
if (!traceId)
|
|
262
|
+
return null;
|
|
263
|
+
workItem.traceId = traceId;
|
|
264
|
+
store.linkRef('workItem', workItem.id, traceId);
|
|
265
|
+
return traceId;
|
|
266
|
+
}, null);
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* A work item entered the pool (PoolStorage.addWorkItem): fill in its trace if
|
|
270
|
+
* the caller did not, and record `workitem.created`.
|
|
271
|
+
*
|
|
272
|
+
* @param workItem - The stored item (mutated when its trace is filled in)
|
|
273
|
+
*/
|
|
274
|
+
export function traceWorkItemCreated(workItem) {
|
|
275
|
+
safely(() => {
|
|
276
|
+
const traceId = known(workItem.traceId) ?? assignWorkItemTrace(workItem);
|
|
277
|
+
if (!traceId)
|
|
278
|
+
return;
|
|
279
|
+
const ctx = getTraceContext();
|
|
280
|
+
ctx.store.linkRef('workItem', workItem.id, traceId);
|
|
281
|
+
const meta = (workItem.metadata ?? {});
|
|
282
|
+
const creator = typeof meta.delegatedBy === 'string' ? meta.delegatedBy : undefined;
|
|
283
|
+
const ticketId = readProjectTicketLink(meta)?.id;
|
|
284
|
+
ctx.record({
|
|
285
|
+
traceId,
|
|
286
|
+
type: 'workitem.created',
|
|
287
|
+
actor: workItem.owner === 'system' || !creator ? { kind: 'system' } : agentActor(creator),
|
|
288
|
+
summary: `Work item for ${workItem.target ?? 'anyone'}: ${workItem.title}`,
|
|
289
|
+
outcome: 'queued',
|
|
290
|
+
refs: {
|
|
291
|
+
workItemId: workItem.id,
|
|
292
|
+
...(workItem.requestId ? { requestId: workItem.requestId } : {}),
|
|
293
|
+
...(ticketId ? { ticketId } : {}),
|
|
294
|
+
...(workItem.target ? { session: workItem.target } : {}),
|
|
295
|
+
},
|
|
296
|
+
data: { type: workItem.type, status: workItem.status },
|
|
297
|
+
});
|
|
298
|
+
}, undefined);
|
|
299
|
+
}
|
|
300
|
+
/** Outcome of a work item status. */
|
|
301
|
+
const STATUS_OUTCOME = {
|
|
302
|
+
done: 'ok',
|
|
303
|
+
done_by_worker: 'ok',
|
|
304
|
+
verified: 'ok',
|
|
305
|
+
failed: 'failed',
|
|
306
|
+
rejected: 'failed',
|
|
307
|
+
blocked: 'blocked',
|
|
308
|
+
escalated: 'blocked',
|
|
309
|
+
cancelled: 'skipped',
|
|
310
|
+
queued: 'queued',
|
|
311
|
+
};
|
|
312
|
+
/** Statuses after which the item's agent is no longer working on it. */
|
|
313
|
+
const WORK_ENDED_STATUSES = new Set(['done', 'done_by_worker', 'verified', 'failed', 'rejected', 'cancelled']);
|
|
314
|
+
/**
|
|
315
|
+
* A work item changed status (PoolStorage.updateWorkItem). `running` is the
|
|
316
|
+
* claim.
|
|
317
|
+
*
|
|
318
|
+
* @param workItem - The item after the change
|
|
319
|
+
* @param previous - Its status before
|
|
320
|
+
*/
|
|
321
|
+
export function traceWorkItemStatus(workItem, previous) {
|
|
322
|
+
safely(() => {
|
|
323
|
+
if (workItem.status === previous)
|
|
324
|
+
return;
|
|
325
|
+
const traceId = known(workItem.traceId);
|
|
326
|
+
if (!traceId)
|
|
327
|
+
return;
|
|
328
|
+
const reason = workItem.error ?? workItem.blockedReason ?? workItem.cancelReason;
|
|
329
|
+
const ctx = getTraceContext();
|
|
330
|
+
ctx.record({
|
|
331
|
+
traceId,
|
|
332
|
+
type: 'workitem.status',
|
|
333
|
+
actor: workItem.status === 'running' ? agentActor(workItem.target) : { kind: 'system' },
|
|
334
|
+
summary: `Work item ${previous} → ${workItem.status}: ${workItem.title}${reason ? ` (${reason})` : ''}`,
|
|
335
|
+
outcome: STATUS_OUTCOME[workItem.status] ?? 'info',
|
|
336
|
+
refs: { workItemId: workItem.id, ...(workItem.target ? { session: workItem.target } : {}) },
|
|
337
|
+
data: { from: previous, to: workItem.status, retryCount: workItem.retryCount },
|
|
338
|
+
});
|
|
339
|
+
// The work is over for its agent: what it does next is not this run.
|
|
340
|
+
if (WORK_ENDED_STATUSES.has(workItem.status))
|
|
341
|
+
ctx.clearIfCurrent(workItem.target, traceId);
|
|
342
|
+
}, undefined);
|
|
343
|
+
}
|
|
344
|
+
/**
|
|
345
|
+
* The `[TRACE:…]` header line for a work item's prompt.
|
|
346
|
+
*
|
|
347
|
+
* @param workItem - The item
|
|
348
|
+
* @returns The marker, or '' when the item has no trace
|
|
349
|
+
*/
|
|
350
|
+
export function workItemTraceMarker(workItem) {
|
|
351
|
+
return safely(() => (known(workItem.traceId) ? formatTraceMarker(workItem.traceId) : ''), '');
|
|
352
|
+
}
|
|
353
|
+
/**
|
|
354
|
+
* Append a work item's trace marker as the last line of a hand-over message,
|
|
355
|
+
* unless it is already there. Appended, never prepended: routing parsers
|
|
356
|
+
* anchor on the start of a delivered message (`[CHAT:…]`, `[TASK]`).
|
|
357
|
+
*
|
|
358
|
+
* @param message - The hand-over text
|
|
359
|
+
* @param workItem - The item handed over
|
|
360
|
+
* @returns The text with the marker last
|
|
361
|
+
*/
|
|
362
|
+
export function withWorkItemTraceMarker(message, workItem) {
|
|
363
|
+
return safely(() => appendTraceMarker(message, known(workItem.traceId)), message);
|
|
364
|
+
}
|
|
365
|
+
// ---------------------------------------------------------------------------
|
|
366
|
+
// Messages, status, decisions
|
|
367
|
+
// ---------------------------------------------------------------------------
|
|
368
|
+
/**
|
|
369
|
+
* One agent messaged another through `/terminal/:to/*`: return the text with
|
|
370
|
+
* the sender's trace appended so the receiving turn joins it, and record
|
|
371
|
+
* `message.agent`.
|
|
372
|
+
*
|
|
373
|
+
* @param sender - Sending agent session
|
|
374
|
+
* @param target - Receiving session
|
|
375
|
+
* @param text - Message text
|
|
376
|
+
* @param maxLength - Longest text the endpoint accepts; the marker is skipped when it would not fit
|
|
377
|
+
* @returns The text to deliver (unchanged when the sender has no trace)
|
|
378
|
+
*/
|
|
379
|
+
export function carryAgentMessageTrace(sender, target, text, maxLength = TERMINAL_INPUT_MAX_LENGTH) {
|
|
380
|
+
return safely(() => {
|
|
381
|
+
if (!sender || sender === target)
|
|
382
|
+
return text;
|
|
383
|
+
const ctx = getTraceContext();
|
|
384
|
+
if (ctx.resolveTracesFromText(text).length > 0)
|
|
385
|
+
return text;
|
|
386
|
+
const traceId = ensureTraceForSession(sender);
|
|
387
|
+
if (!traceId)
|
|
388
|
+
return text;
|
|
389
|
+
ctx.record({
|
|
390
|
+
traceId,
|
|
391
|
+
type: 'message.agent',
|
|
392
|
+
actor: agentActor(sender),
|
|
393
|
+
summary: `${sender} → ${target}: ${text}`,
|
|
394
|
+
refs: { session: target },
|
|
395
|
+
});
|
|
396
|
+
const marked = appendTraceMarker(text, traceId);
|
|
397
|
+
// Never push a message over the terminal input limit: it would be refused.
|
|
398
|
+
return marked.length > maxLength ? text : marked;
|
|
399
|
+
}, text);
|
|
400
|
+
}
|
|
401
|
+
/**
|
|
402
|
+
* A status report was routed. Returns the trace so the routed text can carry
|
|
403
|
+
* its marker.
|
|
404
|
+
*
|
|
405
|
+
* @param input.sender - Reporting agent
|
|
406
|
+
* @param input.content - Report text
|
|
407
|
+
* @param input.workItem - The work item it is about, if found
|
|
408
|
+
* @param input.action - Route (`orc`, `team-lead`, `digest`, `record`)
|
|
409
|
+
* @param input.target - Who receives it
|
|
410
|
+
* @returns The trace id, or null
|
|
411
|
+
*/
|
|
412
|
+
export function traceStatusRouted(input) {
|
|
413
|
+
return safely(() => {
|
|
414
|
+
const ctx = getTraceContext();
|
|
415
|
+
const traceId = known(input.workItem?.traceId) ?? ctx.currentTrace(input.sender);
|
|
416
|
+
if (!traceId)
|
|
417
|
+
return null;
|
|
418
|
+
ctx.record({
|
|
419
|
+
traceId,
|
|
420
|
+
type: 'status.routed',
|
|
421
|
+
actor: agentActor(input.sender),
|
|
422
|
+
summary: `Status from ${input.sender} → ${input.target ?? input.action}: ${input.content}`,
|
|
423
|
+
outcome: input.action === 'record' || input.action === 'digest' ? 'queued' : 'ok',
|
|
424
|
+
refs: { ...(input.workItem?.id ? { workItemId: input.workItem.id } : {}), ...(input.target ? { session: input.target } : {}) },
|
|
425
|
+
data: { route: input.action },
|
|
426
|
+
});
|
|
427
|
+
return traceId;
|
|
428
|
+
}, null);
|
|
429
|
+
}
|
|
430
|
+
/**
|
|
431
|
+
* Append the trace marker to a routed status text.
|
|
432
|
+
*
|
|
433
|
+
* @param text - Status text
|
|
434
|
+
* @param traceId - Trace (no-op when null)
|
|
435
|
+
* @returns The text with the marker last
|
|
436
|
+
*/
|
|
437
|
+
export function withTraceMarker(text, traceId) {
|
|
438
|
+
return safely(() => appendTraceMarker(text, traceId), text);
|
|
439
|
+
}
|
|
440
|
+
/**
|
|
441
|
+
* The reply resolver (#954) delivered or refused an agent message.
|
|
442
|
+
*
|
|
443
|
+
* @param input.session - Agent
|
|
444
|
+
* @param input.content - Message text
|
|
445
|
+
* @param input.reference - The reference it named (ticket / work item / decision / message)
|
|
446
|
+
* @param result - The delivery
|
|
447
|
+
*/
|
|
448
|
+
export function traceOutboundReply(input, result) {
|
|
449
|
+
safely(() => {
|
|
450
|
+
const ctx = getTraceContext();
|
|
451
|
+
const ref = input.reference ?? {};
|
|
452
|
+
const traceId = ctx.store.traceByRef('workItem', ref.workItemId) ??
|
|
453
|
+
ctx.store.traceByRef('decision', ref.decisionId) ??
|
|
454
|
+
ctx.store.traceByRef('ticket', ref.ticket) ??
|
|
455
|
+
ctx.currentTrace(input.session);
|
|
456
|
+
if (!traceId)
|
|
457
|
+
return;
|
|
458
|
+
const where = result.conversationId
|
|
459
|
+
? `conversation ${result.conversationId}`
|
|
460
|
+
: result.slackChannelId
|
|
461
|
+
? `Slack ${result.slackChannelId}`
|
|
462
|
+
: (result.destination?.kind ?? 'nowhere');
|
|
463
|
+
ctx.record({
|
|
464
|
+
traceId,
|
|
465
|
+
type: 'message.outbound',
|
|
466
|
+
actor: agentActor(input.session),
|
|
467
|
+
summary: result.ok ? `${input.session} → ${where}: ${input.content}` : `Message from ${input.session} not delivered: ${result.error ?? 'unknown reason'}`,
|
|
468
|
+
outcome: result.ok ? 'ok' : 'failed',
|
|
469
|
+
refs: {
|
|
470
|
+
session: input.session,
|
|
471
|
+
...(result.messageId ? { messageId: result.messageId } : result.messageTs ? { messageId: result.messageTs } : {}),
|
|
472
|
+
...(ref.ticket ? { ticketId: ref.ticket } : {}),
|
|
473
|
+
...(ref.workItemId ? { workItemId: ref.workItemId } : {}),
|
|
474
|
+
...(ref.decisionId ? { decisionId: ref.decisionId } : {}),
|
|
475
|
+
},
|
|
476
|
+
data: { ...(result.destination?.source ? { source: result.destination.source } : {}), ...(result.destination?.kind ? { destination: result.destination.kind } : {}) },
|
|
477
|
+
});
|
|
478
|
+
}, undefined);
|
|
479
|
+
}
|
|
480
|
+
/** Outcome of a decision status. */
|
|
481
|
+
const DECISION_OUTCOME = {
|
|
482
|
+
resolved: 'ok',
|
|
483
|
+
defaulted: 'info',
|
|
484
|
+
parked: 'blocked',
|
|
485
|
+
cancelled: 'skipped',
|
|
486
|
+
expired: 'skipped',
|
|
487
|
+
skipped: 'skipped',
|
|
488
|
+
};
|
|
489
|
+
/**
|
|
490
|
+
* A decision card was asked: link it to the trace of its work item, Request,
|
|
491
|
+
* project ticket or asker's turn, and record `decision.created`.
|
|
492
|
+
*
|
|
493
|
+
* @param decision - The stored decision
|
|
494
|
+
*/
|
|
495
|
+
export function traceDecisionCreated(decision) {
|
|
496
|
+
safely(() => {
|
|
497
|
+
const ctx = getTraceContext();
|
|
498
|
+
const store = ctx.store;
|
|
499
|
+
const traceId = store.traceByRef('workItem', decision.workItemId) ??
|
|
500
|
+
store.traceByRef('request', decision.requestRef?.requestId) ??
|
|
501
|
+
store.traceByRef('ticket', decision.ticket?.id) ??
|
|
502
|
+
(decision.requestedBy === 'crewly' ? null : ensureTraceForSession(decision.asker));
|
|
503
|
+
if (!traceId)
|
|
504
|
+
return;
|
|
505
|
+
store.linkRef('decision', decision.id, traceId);
|
|
506
|
+
ctx.record({
|
|
507
|
+
traceId,
|
|
508
|
+
type: 'decision.created',
|
|
509
|
+
actor: decision.requestedBy === 'crewly' ? { kind: 'system' } : agentActor(decision.asker),
|
|
510
|
+
summary: `Decision ${decision.id} asked: ${decision.question}`,
|
|
511
|
+
outcome: 'queued',
|
|
512
|
+
refs: {
|
|
513
|
+
decisionId: decision.id,
|
|
514
|
+
session: decision.asker,
|
|
515
|
+
...(decision.workItemId ? { workItemId: decision.workItemId } : {}),
|
|
516
|
+
...(decision.ticket?.id ? { ticketId: decision.ticket.id } : {}),
|
|
517
|
+
},
|
|
518
|
+
data: { ...(decision.kind ? { kind: decision.kind } : {}), ...(decision.sensitive ? { sensitive: decision.sensitive } : {}) },
|
|
519
|
+
});
|
|
520
|
+
}, undefined);
|
|
521
|
+
}
|
|
522
|
+
/**
|
|
523
|
+
* A decision changed state (answered, defaulted, cancelled, …).
|
|
524
|
+
*
|
|
525
|
+
* @param previous - Before
|
|
526
|
+
* @param next - After
|
|
527
|
+
*/
|
|
528
|
+
export function traceDecisionChanged(previous, next) {
|
|
529
|
+
safely(() => {
|
|
530
|
+
if (previous.status === next.status)
|
|
531
|
+
return;
|
|
532
|
+
const ctx = getTraceContext();
|
|
533
|
+
const traceId = ctx.store.traceByRef('decision', next.id);
|
|
534
|
+
if (!traceId)
|
|
535
|
+
return;
|
|
536
|
+
ctx.record({
|
|
537
|
+
traceId,
|
|
538
|
+
type: 'decision.status',
|
|
539
|
+
actor: next.status === 'resolved' || next.status === 'skipped' ? { kind: 'owner' } : { kind: 'system' },
|
|
540
|
+
summary: `Decision ${next.id} ${previous.status} → ${next.status}${next.chosenKey ? ` (${next.chosenKey})` : ''}${next.closedReason ? `: ${next.closedReason}` : ''}`,
|
|
541
|
+
outcome: DECISION_OUTCOME[next.status] ?? 'info',
|
|
542
|
+
refs: { decisionId: next.id, session: next.asker },
|
|
543
|
+
data: {
|
|
544
|
+
from: previous.status,
|
|
545
|
+
to: next.status,
|
|
546
|
+
...(next.answeredVia ? { via: next.answeredVia } : {}),
|
|
547
|
+
...(next.chosenKey ? { chosenKey: next.chosenKey } : {}),
|
|
548
|
+
},
|
|
549
|
+
});
|
|
550
|
+
}, undefined);
|
|
551
|
+
}
|
|
552
|
+
/**
|
|
553
|
+
* The harness intervened (redelivery, wake, correction, nudge, guard block):
|
|
554
|
+
* record it in the trace of the work item, else of the session's turn.
|
|
555
|
+
*
|
|
556
|
+
* @param type - Event type
|
|
557
|
+
* @param input - What and on whom
|
|
558
|
+
* @returns True when recorded
|
|
559
|
+
*/
|
|
560
|
+
export function traceHarness(type, input) {
|
|
561
|
+
return safely(() => {
|
|
562
|
+
const ctx = getTraceContext();
|
|
563
|
+
const workItemId = input.workItem?.id ?? input.workItemId;
|
|
564
|
+
const traceId = known(input.traceId) ??
|
|
565
|
+
known(input.workItem?.traceId) ??
|
|
566
|
+
ctx.store.traceByRef('workItem', workItemId) ??
|
|
567
|
+
ctx.currentTrace(input.session);
|
|
568
|
+
if (!traceId)
|
|
569
|
+
return false;
|
|
570
|
+
return ctx.record({
|
|
571
|
+
traceId,
|
|
572
|
+
type,
|
|
573
|
+
actor: { kind: 'system' },
|
|
574
|
+
summary: input.summary,
|
|
575
|
+
outcome: input.outcome ?? 'info',
|
|
576
|
+
refs: { ...(workItemId ? { workItemId } : {}), ...(input.session ? { session: input.session } : {}) },
|
|
577
|
+
...(input.data ? { data: input.data } : {}),
|
|
578
|
+
});
|
|
579
|
+
}, false);
|
|
580
|
+
}
|
|
581
|
+
/**
|
|
582
|
+
* A token-ledger entry was recorded: find the trace the session was on at
|
|
583
|
+
* that time, record `usage`, and return the id to stamp on the entry.
|
|
584
|
+
*
|
|
585
|
+
* @param session - Agent session
|
|
586
|
+
* @param entry - The usage
|
|
587
|
+
* @returns Trace id, or null
|
|
588
|
+
*/
|
|
589
|
+
export function traceUsage(session, entry) {
|
|
590
|
+
return safely(() => {
|
|
591
|
+
const ctx = getTraceContext();
|
|
592
|
+
const at = Date.parse(entry.timestamp);
|
|
593
|
+
const traceId = ctx.traceAt(session, Number.isFinite(at) ? at : undefined);
|
|
594
|
+
if (!traceId)
|
|
595
|
+
return null;
|
|
596
|
+
ctx.record({
|
|
597
|
+
traceId,
|
|
598
|
+
type: 'usage',
|
|
599
|
+
actor: agentActor(session),
|
|
600
|
+
summary: `${session} used ${entry.input + entry.output} tokens (${entry.model})`,
|
|
601
|
+
refs: { session },
|
|
602
|
+
data: {
|
|
603
|
+
input: entry.input,
|
|
604
|
+
output: entry.output,
|
|
605
|
+
model: entry.model,
|
|
606
|
+
...(entry.cachedInput !== undefined ? { cachedInput: entry.cachedInput } : {}),
|
|
607
|
+
...(entry.runtime ? { runtime: entry.runtime } : {}),
|
|
608
|
+
},
|
|
609
|
+
...(Number.isFinite(at) ? { at: new Date(at) } : {}),
|
|
610
|
+
});
|
|
611
|
+
return traceId;
|
|
612
|
+
}, null);
|
|
613
|
+
}
|
|
614
|
+
/**
|
|
615
|
+
* An experiment card was created: join its ticket's trace when the ticket
|
|
616
|
+
* has one, else start an `experiment` root. Links `experiment:<EXP-n>` (and
|
|
617
|
+
* the ticket) in the index.
|
|
618
|
+
*
|
|
619
|
+
* @param experiment - The new card
|
|
620
|
+
* @param caller - Who created it (agent session, or `owner`)
|
|
621
|
+
* @returns The trace id, or null
|
|
622
|
+
*/
|
|
623
|
+
export function startExperimentTrace(experiment, caller) {
|
|
624
|
+
return safely(() => {
|
|
625
|
+
const ctx = getTraceContext();
|
|
626
|
+
const store = ctx.store;
|
|
627
|
+
const ticketId = experiment.ticket?.id;
|
|
628
|
+
const actor = !caller || caller === 'owner' ? { kind: 'owner' } : agentActor(caller);
|
|
629
|
+
const traceId = store.traceByRef('ticket', ticketId) ??
|
|
630
|
+
(experiment.ticket?.kind === 'harness' ? store.traceByRef('request', ticketId) : null) ??
|
|
631
|
+
ctx.startTrace({
|
|
632
|
+
kind: 'experiment',
|
|
633
|
+
summary: `${experiment.id}: ${experiment.title}`,
|
|
634
|
+
actor,
|
|
635
|
+
refs: { experimentId: experiment.id, ...(ticketId ? { ticketId } : {}) },
|
|
636
|
+
});
|
|
637
|
+
if (!traceId)
|
|
638
|
+
return null;
|
|
639
|
+
store.linkRef('experiment', experiment.id, traceId);
|
|
640
|
+
if (ticketId)
|
|
641
|
+
store.linkRef('ticket', ticketId, traceId);
|
|
642
|
+
return traceId;
|
|
643
|
+
}, null);
|
|
644
|
+
}
|
|
645
|
+
/**
|
|
646
|
+
* Mirror one experiment timeline entry (created, shipped, baseline, measured,
|
|
647
|
+
* verdict, …) into its trace.
|
|
648
|
+
*
|
|
649
|
+
* @param traceId - The card's trace
|
|
650
|
+
* @param experimentId - `EXP-n`
|
|
651
|
+
* @param event - Timeline event name
|
|
652
|
+
* @param detail - Optional detail
|
|
653
|
+
*/
|
|
654
|
+
export function traceExperimentEvent(traceId, experimentId, event, detail) {
|
|
655
|
+
safely(() => {
|
|
656
|
+
if (!known(traceId))
|
|
657
|
+
return;
|
|
658
|
+
getTraceContext().record({
|
|
659
|
+
traceId,
|
|
660
|
+
type: 'experiment.event',
|
|
661
|
+
actor: { kind: 'system' },
|
|
662
|
+
summary: `${experimentId} ${event.replace(/_/g, ' ')}${detail ? `: ${detail}` : ''}`,
|
|
663
|
+
outcome: /fail|error/.test(event) ? 'failed' : 'info',
|
|
664
|
+
refs: { experimentId },
|
|
665
|
+
data: { event },
|
|
666
|
+
});
|
|
667
|
+
}, undefined);
|
|
668
|
+
}
|
|
669
|
+
//# sourceMappingURL=trace-recorder.js.map
|