feat(06-02): wire token usage tracking, session accumulation, and rotation into worker pipeline

- Add inputTokens/outputTokens fields to worker run-finished messages and workerMessageSchema
- Wire sessionService into WorkerServiceDependencies and ServiceGraph lazy slot
- Add token accumulation and rotation evaluation in run-finished handler
- Add 7 wiring integration tests verifying accumulation, rotation, and guard paths

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
ZacharyZhang-NYandClaude Opus 4.6 committed 2026-03-26 23:03:23 -04:00
1 parent e54c632fd6
commit 5271f7ee5d
4 files changed
+228

No files matched your search

+15
View File
@@ -14,6 +14,7 @@ import { createWorkerService } from "./worker-service";
import { createAppLifecycleService } from "./app-lifecycle-service";
import { createSkillService } from "./skill-service";
import { createBudgetEnforcementService } from "./budget-enforcement-service";
import { createSessionManagementService } from "./session-management-service";
import type { DesktopEvent, RunRecord } from "@shared/types";
import type { AutomationEventContext } from "./automation-service";
import type { NotificationOptions } from "./notification-service";
@@ -72,6 +73,7 @@ export function createServiceGraph({
let appLifecycleService: ReturnType<typeof createAppLifecycleService> | null = null;
let skillService: ReturnType<typeof createSkillService> | null = null;
let budgetEnforcementService: ReturnType<typeof createBudgetEnforcementService> | null = null;
let sessionManagementService: ReturnType<typeof createSessionManagementService> | null = null;
function getOrCreateSkillService() {
if (!skillService) {
@@ -96,6 +98,16 @@ export function createServiceGraph({
return budgetEnforcementService;
}
function getOrCreateSessionManagementService() {
if (!sessionManagementService) {
sessionManagementService = createSessionManagementService({
db,
logger,
});
}
return sessionManagementService;
}
const wakeAgentIfPossible =(agentId: string | null | undefined, companyId: string, trigger: string) => {
if (!orchestrationService) {
throw new Error("Orchestration service is not initialized.");
@@ -192,6 +204,7 @@ export function createServiceGraph({
processRunCompletion: (run, event) => processRunCompletion(run, event),
notify,
budgetService: getOrCreateBudgetEnforcementService(),
sessionService: getOrCreateSessionManagementService(),
});
orchestrationService = createOrchestrationService({
@@ -281,6 +294,7 @@ export function createServiceGraph({
appLifecycleService = null;
skillService = null;
budgetEnforcementService = null;
sessionManagementService = null;
db.close();
// Force exit after grace period — covers all platforms (macOS Dock, Windows tray, Linux)
// Worker child processes (claude/codex CLI) may keep the event loop alive indefinitely
@@ -302,5 +316,6 @@ export function createServiceGraph({
getAppLifecycleService: () => appLifecycleService,
getOrCreateSkillService,
getOrCreateBudgetEnforcementService,
getOrCreateSessionManagementService,
};
}