crewly 1.20.186 → 1.20.188
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/skills/agent/core/project-tickets/SKILL.md +3 -2
- package/config/skills/agent/core/project-tickets/execute.sh +4 -4
- package/config/skills/agent/core/project-tickets/execute.test.sh +2 -2
- package/config/skills/agent/core/remember/SKILL.md +1 -0
- package/config/skills/agent/core/remember/execute.sh +12 -0
- package/config/skills/agent/core/report-status/SKILL.md +7 -1
- package/config/skills/agent/core/report-status/execute.sh +41 -0
- package/config/skills/agent/core/slack-post/SKILL.md +1 -0
- package/config/skills/agent/core/slack-post/execute.sh +9 -2
- package/config/skills/team-leader/_common/lib.sh +45 -0
- package/config/skills/team-leader/start-agent/SKILL.md +6 -6
- package/config/skills/team-leader/start-agent/execute.sh +3 -12
- package/config/skills/team-leader/stop-agent/SKILL.md +6 -6
- package/config/skills/team-leader/stop-agent/execute.sh +3 -12
- package/dist/backend/backend/src/constants.d.ts +114 -2
- package/dist/backend/backend/src/constants.d.ts.map +1 -1
- package/dist/backend/backend/src/constants.js +114 -2
- package/dist/backend/backend/src/constants.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 +62 -0
- package/dist/backend/backend/src/controllers/monitoring/terminal.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/project-tickets/project-tickets.controller.d.ts +1 -1
- package/dist/backend/backend/src/controllers/project-tickets/project-tickets.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/project-tickets/project-tickets.controller.js +5 -1
- package/dist/backend/backend/src/controllers/project-tickets/project-tickets.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/project-tickets/project-tickets.routes.d.ts +1 -1
- package/dist/backend/backend/src/controllers/project-tickets/project-tickets.routes.js +1 -1
- package/dist/backend/backend/src/controllers/request/open-items.controller.js +1 -1
- package/dist/backend/backend/src/controllers/request/open-items.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/slack/slack.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/slack/slack.controller.js +4 -1
- package/dist/backend/backend/src/controllers/slack/slack.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/standing/standing.controller.d.ts +18 -1
- package/dist/backend/backend/src/controllers/standing/standing.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/standing/standing.controller.js +77 -4
- package/dist/backend/backend/src/controllers/standing/standing.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/system/system.controller.d.ts +12 -0
- package/dist/backend/backend/src/controllers/system/system.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/system/system.controller.js +28 -3
- package/dist/backend/backend/src/controllers/system/system.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/system/usage.controller.d.ts +46 -0
- package/dist/backend/backend/src/controllers/system/usage.controller.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/system/usage.controller.js +181 -0
- package/dist/backend/backend/src/controllers/system/usage.controller.js.map +1 -0
- package/dist/backend/backend/src/controllers/task-pool/task-pool.controller.d.ts +7 -0
- package/dist/backend/backend/src/controllers/task-pool/task-pool.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/task-pool/task-pool.controller.js +64 -1
- package/dist/backend/backend/src/controllers/task-pool/task-pool.controller.js.map +1 -1
- package/dist/backend/backend/src/index.d.ts +7 -0
- package/dist/backend/backend/src/index.d.ts.map +1 -1
- package/dist/backend/backend/src/index.js +115 -1
- package/dist/backend/backend/src/index.js.map +1 -1
- package/dist/backend/backend/src/routes/modules/system.routes.d.ts.map +1 -1
- package/dist/backend/backend/src/routes/modules/system.routes.js +3 -0
- package/dist/backend/backend/src/routes/modules/system.routes.js.map +1 -1
- package/dist/backend/backend/src/scripts/open-items-stale-followups.d.ts +51 -0
- package/dist/backend/backend/src/scripts/open-items-stale-followups.d.ts.map +1 -0
- package/dist/backend/backend/src/scripts/open-items-stale-followups.js +142 -0
- package/dist/backend/backend/src/scripts/open-items-stale-followups.js.map +1 -0
- 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 +32 -1
- package/dist/backend/backend/src/services/agent/agent-registration.service.js.map +1 -1
- package/dist/backend/backend/src/services/event-bus/event-bus.service.d.ts +28 -0
- package/dist/backend/backend/src/services/event-bus/event-bus.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/event-bus/event-bus.service.js +83 -2
- package/dist/backend/backend/src/services/event-bus/event-bus.service.js.map +1 -1
- package/dist/backend/backend/src/services/memory/memory.service.d.ts +14 -2
- package/dist/backend/backend/src/services/memory/memory.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/memory/memory.service.js +12 -1
- package/dist/backend/backend/src/services/memory/memory.service.js.map +1 -1
- package/dist/backend/backend/src/services/memory/project-memory.service.d.ts +18 -1
- package/dist/backend/backend/src/services/memory/project-memory.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/memory/project-memory.service.js +38 -1
- package/dist/backend/backend/src/services/memory/project-memory.service.js.map +1 -1
- package/dist/backend/backend/src/services/memory/standing-answers.service.d.ts +11 -0
- package/dist/backend/backend/src/services/memory/standing-answers.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/memory/standing-answers.service.js +40 -2
- package/dist/backend/backend/src/services/memory/standing-answers.service.js.map +1 -1
- package/dist/backend/backend/src/services/messaging/offline-agent-message.d.ts +70 -0
- package/dist/backend/backend/src/services/messaging/offline-agent-message.d.ts.map +1 -0
- package/dist/backend/backend/src/services/messaging/offline-agent-message.js +92 -0
- package/dist/backend/backend/src/services/messaging/offline-agent-message.js.map +1 -0
- package/dist/backend/backend/src/services/messaging/owner-message-watchdog.service.d.ts +7 -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 +16 -2
- package/dist/backend/backend/src/services/messaging/owner-message-watchdog.service.js.map +1 -1
- package/dist/backend/backend/src/services/messaging/owner-message-watchdog.wiring.d.ts.map +1 -1
- package/dist/backend/backend/src/services/messaging/owner-message-watchdog.wiring.js +2 -0
- package/dist/backend/backend/src/services/messaging/owner-message-watchdog.wiring.js.map +1 -1
- package/dist/backend/backend/src/services/messaging/queue-processor.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/messaging/queue-processor.service.js +9 -1
- package/dist/backend/backend/src/services/messaging/queue-processor.service.js.map +1 -1
- package/dist/backend/backend/src/services/messaging/sub-agent-message-queue.service.d.ts +41 -1
- package/dist/backend/backend/src/services/messaging/sub-agent-message-queue.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/messaging/sub-agent-message-queue.service.js +87 -2
- package/dist/backend/backend/src/services/messaging/sub-agent-message-queue.service.js.map +1 -1
- package/dist/backend/backend/src/services/monitoring/activity-monitor.service.d.ts +30 -12
- package/dist/backend/backend/src/services/monitoring/activity-monitor.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/monitoring/activity-monitor.service.js +87 -15
- package/dist/backend/backend/src/services/monitoring/activity-monitor.service.js.map +1 -1
- package/dist/backend/backend/src/services/monitoring/antigravity-usage-sync.service.d.ts +130 -0
- package/dist/backend/backend/src/services/monitoring/antigravity-usage-sync.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/monitoring/antigravity-usage-sync.service.js +274 -0
- package/dist/backend/backend/src/services/monitoring/antigravity-usage-sync.service.js.map +1 -0
- package/dist/backend/backend/src/services/monitoring/codex-rollout-sync.service.d.ts +152 -0
- package/dist/backend/backend/src/services/monitoring/codex-rollout-sync.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/monitoring/codex-rollout-sync.service.js +311 -0
- package/dist/backend/backend/src/services/monitoring/codex-rollout-sync.service.js.map +1 -0
- package/dist/backend/backend/src/services/monitoring/token-usage.service.d.ts +78 -1
- 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 +96 -4
- package/dist/backend/backend/src/services/monitoring/token-usage.service.js.map +1 -1
- package/dist/backend/backend/src/services/open-items/open-item-extractor.d.ts +10 -1
- package/dist/backend/backend/src/services/open-items/open-item-extractor.d.ts.map +1 -1
- package/dist/backend/backend/src/services/open-items/open-item-extractor.js +86 -5
- package/dist/backend/backend/src/services/open-items/open-item-extractor.js.map +1 -1
- package/dist/backend/backend/src/services/open-items/open-items-backfill.d.ts +2 -1
- package/dist/backend/backend/src/services/open-items/open-items-backfill.d.ts.map +1 -1
- package/dist/backend/backend/src/services/open-items/open-items-backfill.js +17 -6
- package/dist/backend/backend/src/services/open-items/open-items-backfill.js.map +1 -1
- package/dist/backend/backend/src/services/open-items/open-items.service.d.ts +62 -1
- package/dist/backend/backend/src/services/open-items/open-items.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/open-items/open-items.service.js +203 -9
- package/dist/backend/backend/src/services/open-items/open-items.service.js.map +1 -1
- package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-decision.d.ts +4 -4
- package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-decision.d.ts.map +1 -1
- package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-decision.js +1 -1
- package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-decision.js.map +1 -1
- package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-messages.d.ts +4 -3
- package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-messages.d.ts.map +1 -1
- package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-messages.js +7 -4
- package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-messages.js.map +1 -1
- package/dist/backend/backend/src/services/project-tickets/ticket-autopilot.service.d.ts +40 -9
- package/dist/backend/backend/src/services/project-tickets/ticket-autopilot.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/project-tickets/ticket-autopilot.service.js +68 -20
- package/dist/backend/backend/src/services/project-tickets/ticket-autopilot.service.js.map +1 -1
- package/dist/backend/backend/src/services/reconciler/idle-holder-surfacer.d.ts +40 -0
- package/dist/backend/backend/src/services/reconciler/idle-holder-surfacer.d.ts.map +1 -0
- package/dist/backend/backend/src/services/reconciler/idle-holder-surfacer.js +82 -0
- package/dist/backend/backend/src/services/reconciler/idle-holder-surfacer.js.map +1 -0
- package/dist/backend/backend/src/services/reconciler/reconcile-rules.d.ts +29 -0
- package/dist/backend/backend/src/services/reconciler/reconcile-rules.d.ts.map +1 -1
- package/dist/backend/backend/src/services/reconciler/reconcile-rules.js +49 -0
- package/dist/backend/backend/src/services/reconciler/reconcile-rules.js.map +1 -1
- package/dist/backend/backend/src/services/reconciler/reconciler-data-provider.d.ts.map +1 -1
- package/dist/backend/backend/src/services/reconciler/reconciler-data-provider.js +6 -11
- package/dist/backend/backend/src/services/reconciler/reconciler-data-provider.js.map +1 -1
- package/dist/backend/backend/src/services/reconciler/reconciler.service.d.ts +23 -0
- package/dist/backend/backend/src/services/reconciler/reconciler.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/reconciler/reconciler.service.js +55 -1
- package/dist/backend/backend/src/services/reconciler/reconciler.service.js.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-agent-post.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-agent-post.service.js +10 -4
- package/dist/backend/backend/src/services/slack/slack-agent-post.service.js.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-typing-placeholder.service.d.ts +13 -2
- package/dist/backend/backend/src/services/slack/slack-typing-placeholder.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-typing-placeholder.service.js +19 -5
- package/dist/backend/backend/src/services/slack/slack-typing-placeholder.service.js.map +1 -1
- package/dist/backend/backend/src/services/spend/spend-cap-command.d.ts +129 -0
- package/dist/backend/backend/src/services/spend/spend-cap-command.d.ts.map +1 -0
- package/dist/backend/backend/src/services/spend/spend-cap-command.js +323 -0
- package/dist/backend/backend/src/services/spend/spend-cap-command.js.map +1 -0
- package/dist/backend/backend/src/services/spend/spend-cap.gate.d.ts +60 -0
- package/dist/backend/backend/src/services/spend/spend-cap.gate.d.ts.map +1 -0
- package/dist/backend/backend/src/services/spend/spend-cap.gate.js +66 -0
- package/dist/backend/backend/src/services/spend/spend-cap.gate.js.map +1 -0
- package/dist/backend/backend/src/services/spend/spend-cap.service.d.ts +340 -0
- package/dist/backend/backend/src/services/spend/spend-cap.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/spend/spend-cap.service.js +760 -0
- package/dist/backend/backend/src/services/spend/spend-cap.service.js.map +1 -0
- package/dist/backend/backend/src/services/spend/spend-cap.store.d.ts +126 -0
- package/dist/backend/backend/src/services/spend/spend-cap.store.d.ts.map +1 -0
- package/dist/backend/backend/src/services/spend/spend-cap.store.js +141 -0
- package/dist/backend/backend/src/services/spend/spend-cap.store.js.map +1 -0
- package/dist/backend/backend/src/services/spend/spend-cap.wiring.d.ts +52 -0
- package/dist/backend/backend/src/services/spend/spend-cap.wiring.d.ts.map +1 -0
- package/dist/backend/backend/src/services/spend/spend-cap.wiring.js +112 -0
- package/dist/backend/backend/src/services/spend/spend-cap.wiring.js.map +1 -0
- package/dist/backend/backend/src/services/spend/spend-ledger.service.d.ts +145 -0
- package/dist/backend/backend/src/services/spend/spend-ledger.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/spend/spend-ledger.service.js +214 -0
- package/dist/backend/backend/src/services/spend/spend-ledger.service.js.map +1 -0
- package/dist/backend/backend/src/services/task-pool/claim-target-waker.d.ts +51 -0
- package/dist/backend/backend/src/services/task-pool/claim-target-waker.d.ts.map +1 -0
- package/dist/backend/backend/src/services/task-pool/claim-target-waker.js +43 -0
- package/dist/backend/backend/src/services/task-pool/claim-target-waker.js.map +1 -0
- package/dist/backend/backend/src/services/task-pool/task-pool.service.d.ts +38 -0
- 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 +73 -1
- package/dist/backend/backend/src/services/task-pool/task-pool.service.js.map +1 -1
- package/dist/backend/backend/src/services/task-pool/work-item-usage.d.ts +53 -0
- package/dist/backend/backend/src/services/task-pool/work-item-usage.d.ts.map +1 -0
- package/dist/backend/backend/src/services/task-pool/work-item-usage.js +39 -0
- package/dist/backend/backend/src/services/task-pool/work-item-usage.js.map +1 -0
- package/dist/backend/backend/src/services/usage/token-format.d.ts +49 -0
- package/dist/backend/backend/src/services/usage/token-format.d.ts.map +1 -0
- package/dist/backend/backend/src/services/usage/token-format.js +81 -0
- package/dist/backend/backend/src/services/usage/token-format.js.map +1 -0
- package/dist/backend/backend/src/services/usage/usage-stats.service.d.ts +132 -0
- package/dist/backend/backend/src/services/usage/usage-stats.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/usage/usage-stats.service.js +226 -0
- package/dist/backend/backend/src/services/usage/usage-stats.service.js.map +1 -0
- package/dist/backend/backend/src/services/v3/v3-data.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/v3/v3-data.service.js +11 -14
- package/dist/backend/backend/src/services/v3/v3-data.service.js.map +1 -1
- package/dist/backend/backend/src/services/v3/workitem-dispatch.subscriber.d.ts +25 -0
- 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 +50 -0
- package/dist/backend/backend/src/services/v3/workitem-dispatch.subscriber.js.map +1 -1
- package/dist/backend/backend/src/services/workflow/scheduler.service.d.ts +9 -1
- package/dist/backend/backend/src/services/workflow/scheduler.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/workflow/scheduler.service.js +16 -2
- package/dist/backend/backend/src/services/workflow/scheduler.service.js.map +1 -1
- package/dist/backend/backend/src/types/decision.types.d.ts +3 -1
- package/dist/backend/backend/src/types/decision.types.d.ts.map +1 -1
- package/dist/backend/backend/src/types/event-bus.types.d.ts +9 -1
- package/dist/backend/backend/src/types/event-bus.types.d.ts.map +1 -1
- package/dist/backend/backend/src/types/event-bus.types.js.map +1 -1
- package/dist/backend/backend/src/types/review-reason.types.d.ts +3 -1
- package/dist/backend/backend/src/types/review-reason.types.d.ts.map +1 -1
- package/dist/backend/backend/src/types/review-reason.types.js +1 -0
- package/dist/backend/backend/src/types/review-reason.types.js.map +1 -1
- package/dist/backend/backend/src/types/ticket-autopilot.types.d.ts +24 -7
- package/dist/backend/backend/src/types/ticket-autopilot.types.d.ts.map +1 -1
- package/dist/backend/backend/src/types/ticket-autopilot.types.js +29 -13
- package/dist/backend/backend/src/types/ticket-autopilot.types.js.map +1 -1
- package/dist/backend/backend/src/types/v2/open-item.types.d.ts +5 -1
- package/dist/backend/backend/src/types/v2/open-item.types.d.ts.map +1 -1
- package/dist/backend/backend/src/types/v2/open-item.types.js +1 -1
- package/dist/backend/backend/src/types/v2/open-item.types.js.map +1 -1
- package/dist/backend/build-info.json +2 -2
- package/dist/cli/backend/src/constants.d.ts +114 -2
- package/dist/cli/backend/src/constants.d.ts.map +1 -1
- package/dist/cli/backend/src/constants.js +114 -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 +32 -1
- package/dist/cli/backend/src/services/agent/agent-registration.service.js.map +1 -1
- package/dist/cli/backend/src/services/event-bus/event-bus.service.d.ts +28 -0
- package/dist/cli/backend/src/services/event-bus/event-bus.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/event-bus/event-bus.service.js +83 -2
- package/dist/cli/backend/src/services/event-bus/event-bus.service.js.map +1 -1
- package/dist/cli/backend/src/services/memory/memory.service.d.ts +14 -2
- package/dist/cli/backend/src/services/memory/memory.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/memory/memory.service.js +12 -1
- package/dist/cli/backend/src/services/memory/memory.service.js.map +1 -1
- package/dist/cli/backend/src/services/memory/project-memory.service.d.ts +18 -1
- package/dist/cli/backend/src/services/memory/project-memory.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/memory/project-memory.service.js +38 -1
- package/dist/cli/backend/src/services/memory/project-memory.service.js.map +1 -1
- package/dist/cli/backend/src/services/memory/standing-answers.service.d.ts +11 -0
- package/dist/cli/backend/src/services/memory/standing-answers.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/memory/standing-answers.service.js +40 -2
- package/dist/cli/backend/src/services/memory/standing-answers.service.js.map +1 -1
- package/dist/cli/backend/src/services/messaging/owner-message-watchdog.service.d.ts +7 -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 +16 -2
- package/dist/cli/backend/src/services/messaging/owner-message-watchdog.service.js.map +1 -1
- package/dist/cli/backend/src/services/messaging/queue-processor.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/messaging/queue-processor.service.js +9 -1
- package/dist/cli/backend/src/services/messaging/queue-processor.service.js.map +1 -1
- package/dist/cli/backend/src/services/messaging/sub-agent-message-queue.service.d.ts +41 -1
- package/dist/cli/backend/src/services/messaging/sub-agent-message-queue.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/messaging/sub-agent-message-queue.service.js +87 -2
- package/dist/cli/backend/src/services/messaging/sub-agent-message-queue.service.js.map +1 -1
- package/dist/cli/backend/src/services/monitoring/activity-monitor.service.d.ts +30 -12
- package/dist/cli/backend/src/services/monitoring/activity-monitor.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/monitoring/activity-monitor.service.js +87 -15
- package/dist/cli/backend/src/services/monitoring/activity-monitor.service.js.map +1 -1
- package/dist/cli/backend/src/services/monitoring/model-pricing.d.ts +97 -0
- package/dist/cli/backend/src/services/monitoring/model-pricing.d.ts.map +1 -0
- package/dist/cli/backend/src/services/monitoring/model-pricing.js +120 -0
- package/dist/cli/backend/src/services/monitoring/model-pricing.js.map +1 -0
- package/dist/cli/backend/src/services/monitoring/token-usage.service.d.ts +78 -1
- 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 +96 -4
- package/dist/cli/backend/src/services/monitoring/token-usage.service.js.map +1 -1
- package/dist/cli/backend/src/services/open-items/open-item-extractor.d.ts +10 -1
- package/dist/cli/backend/src/services/open-items/open-item-extractor.d.ts.map +1 -1
- package/dist/cli/backend/src/services/open-items/open-item-extractor.js +86 -5
- package/dist/cli/backend/src/services/open-items/open-item-extractor.js.map +1 -1
- package/dist/cli/backend/src/services/slack/slack-typing-placeholder.service.d.ts +13 -2
- package/dist/cli/backend/src/services/slack/slack-typing-placeholder.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/slack/slack-typing-placeholder.service.js +19 -5
- package/dist/cli/backend/src/services/slack/slack-typing-placeholder.service.js.map +1 -1
- package/dist/cli/backend/src/services/spend/spend-cap.gate.d.ts +60 -0
- package/dist/cli/backend/src/services/spend/spend-cap.gate.d.ts.map +1 -0
- package/dist/cli/backend/src/services/spend/spend-cap.gate.js +66 -0
- package/dist/cli/backend/src/services/spend/spend-cap.gate.js.map +1 -0
- package/dist/cli/backend/src/services/task-pool/task-pool.service.d.ts +38 -0
- 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 +73 -1
- package/dist/cli/backend/src/services/task-pool/task-pool.service.js.map +1 -1
- package/dist/cli/backend/src/services/task-pool/work-item-usage.d.ts +53 -0
- package/dist/cli/backend/src/services/task-pool/work-item-usage.d.ts.map +1 -0
- package/dist/cli/backend/src/services/task-pool/work-item-usage.js +39 -0
- package/dist/cli/backend/src/services/task-pool/work-item-usage.js.map +1 -0
- package/dist/cli/backend/src/services/usage/token-format.d.ts +49 -0
- package/dist/cli/backend/src/services/usage/token-format.d.ts.map +1 -0
- package/dist/cli/backend/src/services/usage/token-format.js +81 -0
- package/dist/cli/backend/src/services/usage/token-format.js.map +1 -0
- package/dist/cli/backend/src/services/v3/v3-data.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/v3/v3-data.service.js +11 -14
- package/dist/cli/backend/src/services/v3/v3-data.service.js.map +1 -1
- package/dist/cli/backend/src/types/decision.types.d.ts +3 -1
- package/dist/cli/backend/src/types/decision.types.d.ts.map +1 -1
- package/dist/cli/backend/src/types/event-bus.types.d.ts +9 -1
- package/dist/cli/backend/src/types/event-bus.types.d.ts.map +1 -1
- package/dist/cli/backend/src/types/event-bus.types.js.map +1 -1
- package/dist/cli/backend/src/types/ticket-autopilot.types.d.ts +24 -7
- package/dist/cli/backend/src/types/ticket-autopilot.types.d.ts.map +1 -1
- package/dist/cli/backend/src/types/ticket-autopilot.types.js +29 -13
- package/dist/cli/backend/src/types/ticket-autopilot.types.js.map +1 -1
- package/dist/cli/backend/src/types/v2/open-item.types.d.ts +5 -1
- package/dist/cli/backend/src/types/v2/open-item.types.d.ts.map +1 -1
- package/dist/cli/backend/src/types/v2/open-item.types.js +1 -1
- package/dist/cli/backend/src/types/v2/open-item.types.js.map +1 -1
- package/frontend/dist/assets/{index-a79c7852.css → index-20a67829.css} +1 -1
- package/frontend/dist/assets/{index-1ee8a9a2.js → index-49f50b45.js} +282 -282
- package/frontend/dist/index.html +2 -2
- package/package.json +1 -1
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Codex Rollout Sync — records Codex CLI token usage in the shared ledger.
|
|
3
|
+
*
|
|
4
|
+
* Codex writes every conversation to `<codexHome>/sessions/YYYY/MM/DD/
|
|
5
|
+
* rollout-<time>-<conversation id>.jsonl`. After each model call it appends
|
|
6
|
+
* an `event_msg` line of type `token_count` whose `info.total_token_usage`
|
|
7
|
+
* is the conversation's running total (OpenAI convention: `input_tokens`
|
|
8
|
+
* includes `cached_input_tokens`; `output_tokens` includes reasoning) and
|
|
9
|
+
* `info.last_token_usage` is that one call. The model comes from the
|
|
10
|
+
* preceding `turn_context` line.
|
|
11
|
+
*
|
|
12
|
+
* Each pass reads only the bytes appended since the last pass (a byte
|
|
13
|
+
* cursor per file, persisted under CREWLY_HOME like the Claude transcript
|
|
14
|
+
* cursors) and records the DELTA of the running total, so a `token_count`
|
|
15
|
+
* line Codex repeats (it re-emits the same totals) is counted once, and a
|
|
16
|
+
* restart never re-counts a file.
|
|
17
|
+
*
|
|
18
|
+
* Attribution: Crewly persists each Codex agent's conversation id (learned
|
|
19
|
+
* from the rollout right after launch, see runtime-session-recovery) in the
|
|
20
|
+
* session state, so the rollout named `…-<id>.jsonl` belongs to that
|
|
21
|
+
* session. A cursor keeps its session after the agent moves to a fresh
|
|
22
|
+
* conversation, so the old file's last turns are still counted. Rollouts no
|
|
23
|
+
* Crewly agent owns (the owner's own Codex use) are never read.
|
|
24
|
+
*
|
|
25
|
+
* Events are stored in the ledger's "cached on top" shape (`input` = fresh
|
|
26
|
+
* tokens, `cachedInput` beside it, `runtime: 'codex-cli'`), the same as
|
|
27
|
+
* Claude transcript turns. specs/2026-10-02-spend-cap.md §Sources.
|
|
28
|
+
*
|
|
29
|
+
* @module services/monitoring/codex-rollout-sync
|
|
30
|
+
*/
|
|
31
|
+
import { promises as fs } from 'fs';
|
|
32
|
+
import * as path from 'path';
|
|
33
|
+
import { CODEX_USAGE_SYNC_CONSTANTS as C, RUNTIME_TYPES } from '../../constants.js';
|
|
34
|
+
/**
|
|
35
|
+
* Read a usage block.
|
|
36
|
+
*
|
|
37
|
+
* @param u - `total_token_usage` / `last_token_usage`
|
|
38
|
+
* @returns Totals, or null when it is not one
|
|
39
|
+
*/
|
|
40
|
+
function totalsOf(u) {
|
|
41
|
+
if (!u || typeof u !== 'object')
|
|
42
|
+
return null;
|
|
43
|
+
const o = u;
|
|
44
|
+
const num = (k) => (typeof o[k] === 'number' && Number.isFinite(o[k]) ? Math.max(0, o[k]) : 0);
|
|
45
|
+
const input = num('input_tokens');
|
|
46
|
+
const output = num('output_tokens');
|
|
47
|
+
const total = typeof o.total_tokens === 'number' ? num('total_tokens') : input + output;
|
|
48
|
+
return { input, cached: Math.min(num('cached_input_tokens'), input), output, total };
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Turn whole JSONL lines of a rollout into usage events. Mutates `state`.
|
|
52
|
+
*
|
|
53
|
+
* - `turn_context` sets the model;
|
|
54
|
+
* - `token_count` with a running total records the delta since the last
|
|
55
|
+
* counted total (0 = a repeated line, skipped);
|
|
56
|
+
* - a running total that went DOWN, or the first total of a file, records
|
|
57
|
+
* only that call's `last_token_usage` (a resumed conversation's file may
|
|
58
|
+
* open with history counted elsewhere).
|
|
59
|
+
*
|
|
60
|
+
* @param text - Whole lines
|
|
61
|
+
* @param state - Parse state (model, last total)
|
|
62
|
+
* @returns Events in file order
|
|
63
|
+
*/
|
|
64
|
+
export function parseCodexRolloutLines(text, state) {
|
|
65
|
+
const events = [];
|
|
66
|
+
for (const line of text.split('\n')) {
|
|
67
|
+
if (!line.trim())
|
|
68
|
+
continue;
|
|
69
|
+
let entry;
|
|
70
|
+
try {
|
|
71
|
+
entry = JSON.parse(line);
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
const payload = entry.payload;
|
|
77
|
+
if (!payload || typeof payload !== 'object')
|
|
78
|
+
continue;
|
|
79
|
+
if (entry.type === 'turn_context') {
|
|
80
|
+
if (typeof payload.model === 'string' && payload.model)
|
|
81
|
+
state.model = payload.model;
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
if (entry.type !== 'event_msg' || payload.type !== 'token_count')
|
|
85
|
+
continue;
|
|
86
|
+
const info = payload.info;
|
|
87
|
+
if (!info)
|
|
88
|
+
continue;
|
|
89
|
+
const total = totalsOf(info.total_token_usage);
|
|
90
|
+
const last = totalsOf(info.last_token_usage);
|
|
91
|
+
if (!total && !last)
|
|
92
|
+
continue;
|
|
93
|
+
let delta;
|
|
94
|
+
const prev = state.lastTotal;
|
|
95
|
+
if (total && prev && total.total >= prev.total) {
|
|
96
|
+
delta = {
|
|
97
|
+
input: Math.max(0, total.input - prev.input),
|
|
98
|
+
cached: Math.max(0, total.cached - prev.cached),
|
|
99
|
+
output: Math.max(0, total.output - prev.output),
|
|
100
|
+
total: total.total - prev.total,
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
delta = last ?? total;
|
|
105
|
+
}
|
|
106
|
+
if (total)
|
|
107
|
+
state.lastTotal = total;
|
|
108
|
+
if (!delta || delta.input + delta.output <= 0)
|
|
109
|
+
continue;
|
|
110
|
+
const cached = Math.min(delta.cached, delta.input);
|
|
111
|
+
events.push({
|
|
112
|
+
timestamp: entry.timestamp || new Date().toISOString(),
|
|
113
|
+
model: state.model || C.DEFAULT_MODEL,
|
|
114
|
+
input: delta.input - cached,
|
|
115
|
+
cachedInput: cached,
|
|
116
|
+
output: delta.output,
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
return events;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Find a conversation's rollout file by id.
|
|
123
|
+
*
|
|
124
|
+
* @param codexHome - Codex home
|
|
125
|
+
* @param conversationId - Conversation id
|
|
126
|
+
* @returns Absolute path, or null
|
|
127
|
+
*/
|
|
128
|
+
export async function findCodexRollout(codexHome, conversationId) {
|
|
129
|
+
const suffix = `-${conversationId}.jsonl`;
|
|
130
|
+
const stack = [path.join(codexHome, 'sessions')];
|
|
131
|
+
let visited = 0;
|
|
132
|
+
while (stack.length > 0 && visited < C.MAX_SCAN_ENTRIES) {
|
|
133
|
+
const dir = stack.pop();
|
|
134
|
+
let entries;
|
|
135
|
+
try {
|
|
136
|
+
entries = await fs.readdir(dir, { withFileTypes: true });
|
|
137
|
+
}
|
|
138
|
+
catch {
|
|
139
|
+
continue;
|
|
140
|
+
}
|
|
141
|
+
// Newest day directories last on the stack = visited first.
|
|
142
|
+
entries.sort((a, b) => a.name.localeCompare(b.name));
|
|
143
|
+
for (const e of entries) {
|
|
144
|
+
visited += 1;
|
|
145
|
+
if (e.isDirectory())
|
|
146
|
+
stack.push(path.join(dir, e.name));
|
|
147
|
+
else if (e.name.startsWith('rollout-') && e.name.endsWith(suffix))
|
|
148
|
+
return path.join(dir, e.name);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
return null;
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Polls Codex rollouts of Crewly's Codex agents and records their usage.
|
|
155
|
+
*/
|
|
156
|
+
export class CodexRolloutSyncService {
|
|
157
|
+
deps;
|
|
158
|
+
cursors = new Map();
|
|
159
|
+
loaded = false;
|
|
160
|
+
running = false;
|
|
161
|
+
timer = null;
|
|
162
|
+
/** Conversation id → when a lookup last failed (ms), to avoid rescanning every pass */
|
|
163
|
+
missing = new Map();
|
|
164
|
+
/**
|
|
165
|
+
* @param deps - Collaborators
|
|
166
|
+
*/
|
|
167
|
+
constructor(deps) {
|
|
168
|
+
this.deps = deps;
|
|
169
|
+
}
|
|
170
|
+
/** Run a pass now, then poll. */
|
|
171
|
+
async start() {
|
|
172
|
+
if (this.timer)
|
|
173
|
+
return;
|
|
174
|
+
await this.sync();
|
|
175
|
+
this.timer = setInterval(() => void this.sync(), C.SYNC_INTERVAL_MS);
|
|
176
|
+
this.timer.unref?.();
|
|
177
|
+
}
|
|
178
|
+
/** Stop polling. */
|
|
179
|
+
stop() {
|
|
180
|
+
if (this.timer)
|
|
181
|
+
clearInterval(this.timer);
|
|
182
|
+
this.timer = null;
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* @param filePath - Rollout path
|
|
186
|
+
* @returns Its cursor (tests, diagnostics)
|
|
187
|
+
*/
|
|
188
|
+
getCursor(filePath) {
|
|
189
|
+
return this.cursors.get(filePath);
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* One pass: adopt rollouts of newly seen Codex conversations, then read
|
|
193
|
+
* the new tail of every known rollout.
|
|
194
|
+
*
|
|
195
|
+
* @returns What the pass recorded
|
|
196
|
+
*/
|
|
197
|
+
async sync() {
|
|
198
|
+
const result = { filesRead: 0, eventsRecorded: 0, tokensRecorded: 0 };
|
|
199
|
+
if (this.running)
|
|
200
|
+
return result;
|
|
201
|
+
this.running = true;
|
|
202
|
+
let changed = false;
|
|
203
|
+
try {
|
|
204
|
+
if (!this.loaded)
|
|
205
|
+
await this.load();
|
|
206
|
+
const known = new Set([...this.cursors.values()].map((c) => c.conversationId));
|
|
207
|
+
for (const [session, info] of this.deps.sessions()) {
|
|
208
|
+
const id = info.claudeSessionId;
|
|
209
|
+
if (info.runtimeType !== RUNTIME_TYPES.CODEX_CLI || !id || known.has(id))
|
|
210
|
+
continue;
|
|
211
|
+
const failedAt = this.missing.get(id);
|
|
212
|
+
if (failedAt !== undefined && Date.now() - failedAt < 10 * C.SYNC_INTERVAL_MS)
|
|
213
|
+
continue;
|
|
214
|
+
const file = await findCodexRollout(this.deps.codexHome, id);
|
|
215
|
+
if (!file) {
|
|
216
|
+
this.missing.set(id, Date.now());
|
|
217
|
+
continue;
|
|
218
|
+
}
|
|
219
|
+
this.missing.delete(id);
|
|
220
|
+
this.cursors.set(file, { session, conversationId: id, offset: 0, model: '', lastTotal: null });
|
|
221
|
+
known.add(id);
|
|
222
|
+
changed = true;
|
|
223
|
+
}
|
|
224
|
+
for (const [file, cursor] of this.cursors) {
|
|
225
|
+
const r = await this.syncFile(file, cursor);
|
|
226
|
+
if (r.read) {
|
|
227
|
+
result.filesRead += 1;
|
|
228
|
+
changed = true;
|
|
229
|
+
}
|
|
230
|
+
result.eventsRecorded += r.events;
|
|
231
|
+
result.tokensRecorded += r.tokens;
|
|
232
|
+
}
|
|
233
|
+
if (changed)
|
|
234
|
+
await this.save();
|
|
235
|
+
if (result.eventsRecorded > 0)
|
|
236
|
+
this.deps.logger?.info('Synced Codex rollouts', { ...result });
|
|
237
|
+
}
|
|
238
|
+
catch (err) {
|
|
239
|
+
this.deps.logger?.warn('Codex rollout sync pass failed', { error: err instanceof Error ? err.message : String(err) });
|
|
240
|
+
}
|
|
241
|
+
finally {
|
|
242
|
+
this.running = false;
|
|
243
|
+
}
|
|
244
|
+
return result;
|
|
245
|
+
}
|
|
246
|
+
async syncFile(file, cursor) {
|
|
247
|
+
let size;
|
|
248
|
+
try {
|
|
249
|
+
size = (await fs.stat(file)).size;
|
|
250
|
+
}
|
|
251
|
+
catch {
|
|
252
|
+
return { read: false, events: 0, tokens: 0 };
|
|
253
|
+
}
|
|
254
|
+
if (size < cursor.offset) {
|
|
255
|
+
// Rewritten underneath us: start over (the running-total delta keeps
|
|
256
|
+
// already counted calls from counting twice only within one file
|
|
257
|
+
// generation, so drop the total too).
|
|
258
|
+
cursor.offset = 0;
|
|
259
|
+
cursor.lastTotal = null;
|
|
260
|
+
}
|
|
261
|
+
if (size === cursor.offset)
|
|
262
|
+
return { read: false, events: 0, tokens: 0 };
|
|
263
|
+
const handle = await fs.open(file, 'r');
|
|
264
|
+
let tail;
|
|
265
|
+
try {
|
|
266
|
+
const buf = Buffer.alloc(size - cursor.offset);
|
|
267
|
+
await handle.read(buf, 0, buf.length, cursor.offset);
|
|
268
|
+
tail = buf.toString('utf-8');
|
|
269
|
+
}
|
|
270
|
+
finally {
|
|
271
|
+
await handle.close();
|
|
272
|
+
}
|
|
273
|
+
const nl = tail.lastIndexOf('\n');
|
|
274
|
+
if (nl < 0)
|
|
275
|
+
return { read: false, events: 0, tokens: 0 };
|
|
276
|
+
const complete = tail.slice(0, nl);
|
|
277
|
+
const state = { model: cursor.model, lastTotal: cursor.lastTotal };
|
|
278
|
+
const events = parseCodexRolloutLines(complete, state);
|
|
279
|
+
cursor.offset += Buffer.byteLength(complete, 'utf-8') + 1;
|
|
280
|
+
cursor.model = state.model;
|
|
281
|
+
cursor.lastTotal = state.lastTotal;
|
|
282
|
+
let tokens = 0;
|
|
283
|
+
for (const e of events) {
|
|
284
|
+
this.deps.record(cursor.session, e);
|
|
285
|
+
tokens += e.input + e.cachedInput + e.output;
|
|
286
|
+
}
|
|
287
|
+
return { read: true, events: events.length, tokens };
|
|
288
|
+
}
|
|
289
|
+
async load() {
|
|
290
|
+
this.loaded = true;
|
|
291
|
+
try {
|
|
292
|
+
const parsed = JSON.parse(await fs.readFile(this.deps.cursorFile, 'utf-8'));
|
|
293
|
+
this.cursors = new Map(Object.entries(parsed));
|
|
294
|
+
}
|
|
295
|
+
catch {
|
|
296
|
+
this.cursors = new Map();
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
async save() {
|
|
300
|
+
const tmp = `${this.deps.cursorFile}.tmp`;
|
|
301
|
+
try {
|
|
302
|
+
await fs.mkdir(path.dirname(this.deps.cursorFile), { recursive: true });
|
|
303
|
+
await fs.writeFile(tmp, JSON.stringify(Object.fromEntries(this.cursors), null, 2), 'utf-8');
|
|
304
|
+
await fs.rename(tmp, this.deps.cursorFile);
|
|
305
|
+
}
|
|
306
|
+
catch (err) {
|
|
307
|
+
this.deps.logger?.warn('Could not save Codex rollout cursors', { error: err instanceof Error ? err.message : String(err) });
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
//# sourceMappingURL=codex-rollout-sync.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codex-rollout-sync.service.js","sourceRoot":"","sources":["../../../../../../backend/src/services/monitoring/codex-rollout-sync.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -34,6 +34,12 @@ export interface TokenUsageEvent {
|
|
|
34
34
|
* rate) rather than read from it. Claude only; absent when unknown.
|
|
35
35
|
*/
|
|
36
36
|
cacheWrite?: number;
|
|
37
|
+
/**
|
|
38
|
+
* Runtime that produced the event (`codex-cli`, `antigravity-cli`, …), set
|
|
39
|
+
* by the sources that know it. Absent on older events and on sources that
|
|
40
|
+
* only know the model; {@link runtimeOfEvent} then infers it from the model.
|
|
41
|
+
*/
|
|
42
|
+
runtime?: string;
|
|
37
43
|
}
|
|
38
44
|
/** Optional per-event detail beyond the raw input/output counts. */
|
|
39
45
|
export interface TokenUsageDetail {
|
|
@@ -49,6 +55,8 @@ export interface TokenUsageDetail {
|
|
|
49
55
|
* any per-day or per-hour view of the data is wrong.
|
|
50
56
|
*/
|
|
51
57
|
timestamp?: string;
|
|
58
|
+
/** See {@link TokenUsageEvent.runtime}. */
|
|
59
|
+
runtime?: string;
|
|
52
60
|
}
|
|
53
61
|
/**
|
|
54
62
|
* Per-session token usage record containing all events and aggregates
|
|
@@ -137,6 +145,63 @@ export declare const TOKEN_COSTS: Record<string, {
|
|
|
137
145
|
* @returns Cost in USD
|
|
138
146
|
*/
|
|
139
147
|
export declare function calculateCost(inputTokens: number, outputTokens: number, model: string, cachedInputTokens?: number): number;
|
|
148
|
+
/**
|
|
149
|
+
* USD cost of one recorded usage event — the one cost computation every
|
|
150
|
+
* spend view uses (session windows, the team budget gate, the ticket
|
|
151
|
+
* autopilot budget, the per-agent spend cap).
|
|
152
|
+
*
|
|
153
|
+
* The ledger holds two shapes of event:
|
|
154
|
+
* - in-process runs (`provider/model`, e.g. DeepSeek): `cachedInput` is the
|
|
155
|
+
* cache-hit PART of `input`, priced with {@link TOKEN_COSTS};
|
|
156
|
+
* - Claude Code transcript turns: `input` is the fresh tokens only and
|
|
157
|
+
* `cachedInput` (cache reads + `cacheWrite`) comes on top, priced with the
|
|
158
|
+
* cache-aware model-pricing table. Pricing these with {@link TOKEN_COSTS}
|
|
159
|
+
* dropped every cached token and used sonnet rates for opus.
|
|
160
|
+
*
|
|
161
|
+
* @param event - The usage event
|
|
162
|
+
* @returns Cost in USD
|
|
163
|
+
*/
|
|
164
|
+
export declare function eventCostUsd(event: Pick<TokenUsageEvent, 'input' | 'output' | 'model' | 'cachedInput' | 'cacheWrite'>): number;
|
|
165
|
+
/** The token figures of one event in the owner-facing unit (see {@link eventTokens}). */
|
|
166
|
+
export interface EventTokens {
|
|
167
|
+
/** Every input token, cached ones included */
|
|
168
|
+
input: number;
|
|
169
|
+
/** The cached part of {@link input} (cache reads + cache writes) */
|
|
170
|
+
cachedInput: number;
|
|
171
|
+
output: number;
|
|
172
|
+
/** {@link input} + {@link output} — what caps, boosts and budgets count */
|
|
173
|
+
total: number;
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Whether an event's `cachedInput` is part of its `input` (true) or comes
|
|
177
|
+
* on top of it (false).
|
|
178
|
+
*
|
|
179
|
+
* - In-process runs (`provider/model`, e.g. DeepSeek) report the provider's
|
|
180
|
+
* prompt-token count, which includes cache hits: part of `input`.
|
|
181
|
+
* - Claude Code transcript turns, Codex rollouts and Antigravity record
|
|
182
|
+
* `input` as the fresh tokens only, with the cached ones on top.
|
|
183
|
+
*
|
|
184
|
+
* @param event - Usage event
|
|
185
|
+
* @returns True when cached tokens are already inside `input`
|
|
186
|
+
*/
|
|
187
|
+
export declare function cachedIsPartOfInput(event: Pick<TokenUsageEvent, 'model' | 'runtime'>): boolean;
|
|
188
|
+
/**
|
|
189
|
+
* The token unit — ONE formula for every cap, boost, budget and stat:
|
|
190
|
+
*
|
|
191
|
+
* total tokens = input tokens (fresh + cached) + output tokens
|
|
192
|
+
*
|
|
193
|
+
* Cached input counts in full (it is shown separately, never left out), and
|
|
194
|
+
* whether an account is billed by subscription or by API makes no
|
|
195
|
+
* difference. specs/2026-10-02-spend-cap.md §Token unit.
|
|
196
|
+
*
|
|
197
|
+
* @param event - Usage event
|
|
198
|
+
* @returns Input (cached included), cached input, output, total
|
|
199
|
+
*
|
|
200
|
+
* @example
|
|
201
|
+
* eventTokens({ model: 'claude-opus-5-5', input: 10, cachedInput: 990, output: 50 }).total // 1050
|
|
202
|
+
* eventTokens({ model: 'deepseek/deepseek-chat', input: 1000, cachedInput: 990, output: 50 }).total // 1050
|
|
203
|
+
*/
|
|
204
|
+
export declare function eventTokens(event: Pick<TokenUsageEvent, 'model' | 'runtime' | 'input' | 'output' | 'cachedInput'>): EventTokens;
|
|
140
205
|
/**
|
|
141
206
|
* Set a cost override for a session. When present, getSummary() uses this
|
|
142
207
|
* instead of recalculating from events.
|
|
@@ -264,13 +329,25 @@ export declare class TokenUsageService {
|
|
|
264
329
|
* @param sessionName - The session to query (e.g. 'crewly-orc')
|
|
265
330
|
* @param since - Only return events recorded at or after this time
|
|
266
331
|
* @param until - Only return events before this time (defaults to now)
|
|
267
|
-
* @returns Aggregated input tokens, output tokens, and cost in the window
|
|
332
|
+
* @returns Aggregated input tokens, output tokens, and cost in the window,
|
|
333
|
+
* plus the token-unit figures ({@link eventTokens}): `totalTokens` (the
|
|
334
|
+
* unit caps and budgets count) and `cachedInputTokens`
|
|
268
335
|
*/
|
|
269
336
|
getSessionUsageSince(sessionName: string, since: Date, until?: Date): {
|
|
270
337
|
inputTokens: number;
|
|
271
338
|
outputTokens: number;
|
|
272
339
|
cost: number;
|
|
340
|
+
totalTokens: number;
|
|
341
|
+
cachedInputTokens: number;
|
|
273
342
|
};
|
|
343
|
+
/**
|
|
344
|
+
* Visit every recorded event at or after `since` (all events when omitted).
|
|
345
|
+
* Read-only; used by the spend ledger for per-day / per-agent views.
|
|
346
|
+
*
|
|
347
|
+
* @param visit - Called with the session name and the event
|
|
348
|
+
* @param since - Lower bound (inclusive)
|
|
349
|
+
*/
|
|
350
|
+
forEachEvent(visit: (sessionName: string, event: TokenUsageEvent) => void, since?: Date): void;
|
|
274
351
|
/**
|
|
275
352
|
* Clear all tracked token usage data.
|
|
276
353
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"token-usage.service.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/monitoring/token-usage.service.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;
|
|
1
|
+
{"version":3,"file":"token-usage.service.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/monitoring/token-usage.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import { promises as fs } from 'fs';
|
|
10
10
|
import * as path from 'path';
|
|
11
|
+
import { calculateCost as calculateCacheAwareCost, resolveRate } from './model-pricing.js';
|
|
11
12
|
/** File name for persisting token usage data */
|
|
12
13
|
const TOKEN_USAGE_FILE = 'token-usage.json';
|
|
13
14
|
/** Interval in milliseconds between periodic flushes to disk (5 minutes) */
|
|
@@ -59,6 +60,73 @@ export function calculateCost(inputTokens, outputTokens, model, cachedInputToken
|
|
|
59
60
|
const cached = rates.cachedInput !== undefined ? Math.min(Math.max(cachedInputTokens, 0), inputTokens) : 0;
|
|
60
61
|
return (inputTokens - cached) * rates.input + cached * (rates.cachedInput ?? 0) + outputTokens * rates.output;
|
|
61
62
|
}
|
|
63
|
+
/**
|
|
64
|
+
* USD cost of one recorded usage event — the one cost computation every
|
|
65
|
+
* spend view uses (session windows, the team budget gate, the ticket
|
|
66
|
+
* autopilot budget, the per-agent spend cap).
|
|
67
|
+
*
|
|
68
|
+
* The ledger holds two shapes of event:
|
|
69
|
+
* - in-process runs (`provider/model`, e.g. DeepSeek): `cachedInput` is the
|
|
70
|
+
* cache-hit PART of `input`, priced with {@link TOKEN_COSTS};
|
|
71
|
+
* - Claude Code transcript turns: `input` is the fresh tokens only and
|
|
72
|
+
* `cachedInput` (cache reads + `cacheWrite`) comes on top, priced with the
|
|
73
|
+
* cache-aware model-pricing table. Pricing these with {@link TOKEN_COSTS}
|
|
74
|
+
* dropped every cached token and used sonnet rates for opus.
|
|
75
|
+
*
|
|
76
|
+
* @param event - The usage event
|
|
77
|
+
* @returns Cost in USD
|
|
78
|
+
*/
|
|
79
|
+
export function eventCostUsd(event) {
|
|
80
|
+
const model = event.model || '';
|
|
81
|
+
const unprefixed = model.includes('/') ? model.slice(model.indexOf('/') + 1) : model;
|
|
82
|
+
const legacyKey = TOKEN_COSTS[model] ? model : TOKEN_COSTS[unprefixed] ? unprefixed : null;
|
|
83
|
+
if (!model.includes('/') && resolveRate(model).source !== 'default') {
|
|
84
|
+
const write = Math.max(0, event.cacheWrite ?? 0);
|
|
85
|
+
const read = Math.max(0, (event.cachedInput ?? 0) - write);
|
|
86
|
+
return calculateCacheAwareCost({ input: event.input, output: event.output, cacheRead: read, cacheWrite: write }, model).cost;
|
|
87
|
+
}
|
|
88
|
+
return calculateCost(event.input, event.output, legacyKey ?? model, event.cachedInput ?? 0);
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Whether an event's `cachedInput` is part of its `input` (true) or comes
|
|
92
|
+
* on top of it (false).
|
|
93
|
+
*
|
|
94
|
+
* - In-process runs (`provider/model`, e.g. DeepSeek) report the provider's
|
|
95
|
+
* prompt-token count, which includes cache hits: part of `input`.
|
|
96
|
+
* - Claude Code transcript turns, Codex rollouts and Antigravity record
|
|
97
|
+
* `input` as the fresh tokens only, with the cached ones on top.
|
|
98
|
+
*
|
|
99
|
+
* @param event - Usage event
|
|
100
|
+
* @returns True when cached tokens are already inside `input`
|
|
101
|
+
*/
|
|
102
|
+
export function cachedIsPartOfInput(event) {
|
|
103
|
+
if (event.runtime)
|
|
104
|
+
return event.runtime === 'crewly-agent';
|
|
105
|
+
return (event.model || '').includes('/');
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* The token unit — ONE formula for every cap, boost, budget and stat:
|
|
109
|
+
*
|
|
110
|
+
* total tokens = input tokens (fresh + cached) + output tokens
|
|
111
|
+
*
|
|
112
|
+
* Cached input counts in full (it is shown separately, never left out), and
|
|
113
|
+
* whether an account is billed by subscription or by API makes no
|
|
114
|
+
* difference. specs/2026-10-02-spend-cap.md §Token unit.
|
|
115
|
+
*
|
|
116
|
+
* @param event - Usage event
|
|
117
|
+
* @returns Input (cached included), cached input, output, total
|
|
118
|
+
*
|
|
119
|
+
* @example
|
|
120
|
+
* eventTokens({ model: 'claude-opus-5-5', input: 10, cachedInput: 990, output: 50 }).total // 1050
|
|
121
|
+
* eventTokens({ model: 'deepseek/deepseek-chat', input: 1000, cachedInput: 990, output: 50 }).total // 1050
|
|
122
|
+
*/
|
|
123
|
+
export function eventTokens(event) {
|
|
124
|
+
const raw = Math.max(0, event.input || 0);
|
|
125
|
+
const cached = Math.max(0, event.cachedInput || 0);
|
|
126
|
+
const output = Math.max(0, event.output || 0);
|
|
127
|
+
const input = cachedIsPartOfInput(event) ? Math.max(raw, cached) : raw + cached;
|
|
128
|
+
return { input, cachedInput: Math.min(cached, input), output, total: input + output };
|
|
129
|
+
}
|
|
62
130
|
/**
|
|
63
131
|
* Stores a pre-calculated cost override for a session.
|
|
64
132
|
* Used when the caller has more accurate cost data (e.g., cache-aware pricing
|
|
@@ -169,6 +237,7 @@ export class TokenUsageService {
|
|
|
169
237
|
...(detail?.cachedInput !== undefined ? { cachedInput: detail.cachedInput } : {}),
|
|
170
238
|
...(detail?.steps !== undefined ? { steps: detail.steps } : {}),
|
|
171
239
|
...(detail?.cacheWrite ? { cacheWrite: detail.cacheWrite } : {}),
|
|
240
|
+
...(detail?.runtime ? { runtime: detail.runtime } : {}),
|
|
172
241
|
};
|
|
173
242
|
record.events.push(event);
|
|
174
243
|
record.totalInput += input;
|
|
@@ -326,17 +395,21 @@ export class TokenUsageService {
|
|
|
326
395
|
* @param sessionName - The session to query (e.g. 'crewly-orc')
|
|
327
396
|
* @param since - Only return events recorded at or after this time
|
|
328
397
|
* @param until - Only return events before this time (defaults to now)
|
|
329
|
-
* @returns Aggregated input tokens, output tokens, and cost in the window
|
|
398
|
+
* @returns Aggregated input tokens, output tokens, and cost in the window,
|
|
399
|
+
* plus the token-unit figures ({@link eventTokens}): `totalTokens` (the
|
|
400
|
+
* unit caps and budgets count) and `cachedInputTokens`
|
|
330
401
|
*/
|
|
331
402
|
getSessionUsageSince(sessionName, since, until) {
|
|
332
403
|
const record = this.sessions.get(sessionName);
|
|
333
404
|
if (!record)
|
|
334
|
-
return { inputTokens: 0, outputTokens: 0, cost: 0 };
|
|
405
|
+
return { inputTokens: 0, outputTokens: 0, cost: 0, totalTokens: 0, cachedInputTokens: 0 };
|
|
335
406
|
const sinceMs = since.getTime();
|
|
336
407
|
const untilMs = until ? until.getTime() : Infinity;
|
|
337
408
|
let inputTokens = 0;
|
|
338
409
|
let outputTokens = 0;
|
|
339
410
|
let cost = 0;
|
|
411
|
+
let totalTokens = 0;
|
|
412
|
+
let cachedInputTokens = 0;
|
|
340
413
|
for (const event of record.events) {
|
|
341
414
|
const eventMs = new Date(event.timestamp).getTime();
|
|
342
415
|
if (eventMs >= sinceMs && eventMs <= untilMs) {
|
|
@@ -345,10 +418,29 @@ export class TokenUsageService {
|
|
|
345
418
|
// Cache-aware: a cache hit is billed at a fraction of the miss rate,
|
|
346
419
|
// and the team budget gate keys on this figure — pricing every input
|
|
347
420
|
// token at the miss rate would trip monthly USD caps ~40x early.
|
|
348
|
-
cost +=
|
|
421
|
+
cost += eventCostUsd(event);
|
|
422
|
+
const t = eventTokens(event);
|
|
423
|
+
totalTokens += t.total;
|
|
424
|
+
cachedInputTokens += t.cachedInput;
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
return { inputTokens, outputTokens, cost, totalTokens, cachedInputTokens };
|
|
428
|
+
}
|
|
429
|
+
/**
|
|
430
|
+
* Visit every recorded event at or after `since` (all events when omitted).
|
|
431
|
+
* Read-only; used by the spend ledger for per-day / per-agent views.
|
|
432
|
+
*
|
|
433
|
+
* @param visit - Called with the session name and the event
|
|
434
|
+
* @param since - Lower bound (inclusive)
|
|
435
|
+
*/
|
|
436
|
+
forEachEvent(visit, since) {
|
|
437
|
+
const sinceMs = since ? since.getTime() : -Infinity;
|
|
438
|
+
for (const record of this.sessions.values()) {
|
|
439
|
+
for (const event of record.events) {
|
|
440
|
+
if (new Date(event.timestamp).getTime() >= sinceMs)
|
|
441
|
+
visit(record.sessionName, event);
|
|
349
442
|
}
|
|
350
443
|
}
|
|
351
|
-
return { inputTokens, outputTokens, cost };
|
|
352
444
|
}
|
|
353
445
|
/**
|
|
354
446
|
* Clear all tracked token usage data.
|