@bradygaster/squad-sdk 0.7.0 → 0.8.2
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/README.md +296 -296
- package/dist/adapter/client.d.ts +243 -0
- package/dist/adapter/client.d.ts.map +1 -0
- package/dist/adapter/client.js +567 -0
- package/dist/adapter/client.js.map +1 -0
- package/dist/adapter/errors.d.ts +260 -0
- package/dist/adapter/errors.d.ts.map +1 -0
- package/dist/adapter/errors.js +362 -0
- package/dist/adapter/errors.js.map +1 -0
- package/dist/adapter/types.d.ts +779 -0
- package/dist/adapter/types.d.ts.map +1 -0
- package/dist/adapter/types.js +11 -0
- package/dist/adapter/types.js.map +1 -0
- package/dist/agents/charter-compiler.d.ts +102 -0
- package/dist/agents/charter-compiler.d.ts.map +1 -0
- package/dist/agents/charter-compiler.js +157 -0
- package/dist/agents/charter-compiler.js.map +1 -0
- package/dist/agents/history-shadow.d.ts +80 -0
- package/dist/agents/history-shadow.d.ts.map +1 -0
- package/dist/agents/history-shadow.js +239 -0
- package/dist/agents/history-shadow.js.map +1 -0
- package/dist/agents/index.d.ts +71 -0
- package/dist/agents/index.d.ts.map +1 -0
- package/dist/agents/index.js +183 -0
- package/dist/agents/index.js.map +1 -0
- package/dist/agents/lifecycle.d.ts +138 -0
- package/dist/agents/lifecycle.d.ts.map +1 -0
- package/dist/agents/lifecycle.js +284 -0
- package/dist/agents/lifecycle.js.map +1 -0
- package/dist/agents/model-selector.d.ts +80 -0
- package/dist/agents/model-selector.d.ts.map +1 -0
- package/dist/agents/model-selector.js +171 -0
- package/dist/agents/model-selector.js.map +1 -0
- package/dist/agents/onboarding.d.ts +65 -0
- package/dist/agents/onboarding.d.ts.map +1 -0
- package/dist/agents/onboarding.js +373 -0
- package/dist/agents/onboarding.js.map +1 -0
- package/dist/build/bundle.d.ts +32 -0
- package/dist/build/bundle.d.ts.map +1 -0
- package/dist/build/bundle.js +97 -0
- package/dist/build/bundle.js.map +1 -0
- package/dist/build/ci-pipeline.d.ts +51 -0
- package/dist/build/ci-pipeline.d.ts.map +1 -0
- package/dist/build/ci-pipeline.js +180 -0
- package/dist/build/ci-pipeline.js.map +1 -0
- package/dist/build/github-dist.d.ts +37 -0
- package/dist/build/github-dist.d.ts.map +1 -0
- package/dist/build/github-dist.js +117 -0
- package/dist/build/github-dist.js.map +1 -0
- package/dist/build/index.d.ts +11 -0
- package/dist/build/index.d.ts.map +1 -0
- package/dist/build/index.js +11 -0
- package/dist/build/index.js.map +1 -0
- package/dist/build/install-migration.d.ts +28 -0
- package/dist/build/install-migration.d.ts.map +1 -0
- package/dist/build/install-migration.js +103 -0
- package/dist/build/install-migration.js.map +1 -0
- package/dist/build/npm-package.d.ts +54 -0
- package/dist/build/npm-package.d.ts.map +1 -0
- package/dist/build/npm-package.js +128 -0
- package/dist/build/npm-package.js.map +1 -0
- package/dist/build/release.d.ts +108 -0
- package/dist/build/release.d.ts.map +1 -0
- package/dist/build/release.js +295 -0
- package/dist/build/release.js.map +1 -0
- package/dist/build/versioning.d.ts +38 -0
- package/dist/build/versioning.d.ts.map +1 -0
- package/dist/build/versioning.js +113 -0
- package/dist/build/versioning.js.map +1 -0
- package/dist/casting/casting-engine.d.ts +60 -0
- package/dist/casting/casting-engine.d.ts.map +1 -0
- package/dist/casting/casting-engine.js +223 -0
- package/dist/casting/casting-engine.js.map +1 -0
- package/dist/casting/casting-history.d.ts +54 -0
- package/dist/casting/casting-history.d.ts.map +1 -0
- package/dist/casting/casting-history.js +63 -0
- package/dist/casting/casting-history.js.map +1 -0
- package/dist/casting/index.d.ts +46 -0
- package/dist/casting/index.d.ts.map +1 -0
- package/dist/casting/index.js +45 -0
- package/dist/casting/index.js.map +1 -0
- package/dist/client/event-bus.d.ts +29 -0
- package/dist/client/event-bus.d.ts.map +1 -0
- package/dist/client/event-bus.js +52 -0
- package/dist/client/event-bus.js.map +1 -0
- package/dist/client/index.d.ts +100 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +170 -0
- package/dist/client/index.js.map +1 -0
- package/dist/client/session-pool.d.ts +66 -0
- package/dist/client/session-pool.d.ts.map +1 -0
- package/dist/client/session-pool.js +145 -0
- package/dist/client/session-pool.js.map +1 -0
- package/dist/config/agent-doc.d.ts +43 -0
- package/dist/config/agent-doc.d.ts.map +1 -0
- package/dist/config/agent-doc.js +158 -0
- package/dist/config/agent-doc.js.map +1 -0
- package/dist/config/agent-source.d.ts +95 -0
- package/dist/config/agent-source.d.ts.map +1 -0
- package/dist/config/agent-source.js +274 -0
- package/dist/config/agent-source.js.map +1 -0
- package/dist/config/doc-sync.d.ts +66 -0
- package/dist/config/doc-sync.d.ts.map +1 -0
- package/dist/config/doc-sync.js +270 -0
- package/dist/config/doc-sync.js.map +1 -0
- package/dist/config/feature-audit.d.ts +49 -0
- package/dist/config/feature-audit.d.ts.map +1 -0
- package/dist/config/feature-audit.js +148 -0
- package/dist/config/feature-audit.js.map +1 -0
- package/dist/config/index.d.ts +15 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +15 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/init.d.ts +61 -0
- package/dist/config/init.d.ts.map +1 -0
- package/dist/config/init.js +376 -0
- package/dist/config/init.js.map +1 -0
- package/dist/config/legacy-fallback.d.ts +83 -0
- package/dist/config/legacy-fallback.d.ts.map +1 -0
- package/dist/config/legacy-fallback.js +212 -0
- package/dist/config/legacy-fallback.js.map +1 -0
- package/dist/config/markdown-migration.d.ts +157 -0
- package/dist/config/markdown-migration.d.ts.map +1 -0
- package/dist/config/markdown-migration.js +434 -0
- package/dist/config/markdown-migration.js.map +1 -0
- package/dist/config/migration.d.ts +123 -0
- package/dist/config/migration.d.ts.map +1 -0
- package/dist/config/migration.js +273 -0
- package/dist/config/migration.js.map +1 -0
- package/dist/config/migrations/index.d.ts +36 -0
- package/dist/config/migrations/index.d.ts.map +1 -0
- package/dist/config/migrations/index.js +216 -0
- package/dist/config/migrations/index.js.map +1 -0
- package/dist/config/models.d.ts +134 -0
- package/dist/config/models.d.ts.map +1 -0
- package/dist/config/models.js +354 -0
- package/dist/config/models.js.map +1 -0
- package/dist/config/routing.d.ts +118 -0
- package/dist/config/routing.d.ts.map +1 -0
- package/dist/config/routing.js +247 -0
- package/dist/config/routing.js.map +1 -0
- package/dist/config/schema.d.ts +72 -0
- package/dist/config/schema.d.ts.map +1 -0
- package/dist/config/schema.js +63 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/coordinator/coordinator.d.ts +82 -0
- package/dist/coordinator/coordinator.d.ts.map +1 -0
- package/dist/coordinator/coordinator.js +192 -0
- package/dist/coordinator/coordinator.js.map +1 -0
- package/dist/coordinator/direct-response.d.ts +83 -0
- package/dist/coordinator/direct-response.d.ts.map +1 -0
- package/dist/coordinator/direct-response.js +187 -0
- package/dist/coordinator/direct-response.js.map +1 -0
- package/dist/coordinator/fan-out.d.ts +83 -0
- package/dist/coordinator/fan-out.d.ts.map +1 -0
- package/dist/coordinator/fan-out.js +161 -0
- package/dist/coordinator/fan-out.js.map +1 -0
- package/dist/coordinator/index.d.ts +62 -0
- package/dist/coordinator/index.d.ts.map +1 -0
- package/dist/coordinator/index.js +171 -0
- package/dist/coordinator/index.js.map +1 -0
- package/dist/coordinator/response-tiers.d.ts +49 -0
- package/dist/coordinator/response-tiers.d.ts.map +1 -0
- package/dist/coordinator/response-tiers.js +149 -0
- package/dist/coordinator/response-tiers.js.map +1 -0
- package/dist/hooks/index.d.ts +103 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/index.js +279 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/index.d.ts +33 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +33 -3
- package/dist/index.js.map +1 -1
- package/dist/marketplace/backend.d.ts +35 -0
- package/dist/marketplace/backend.d.ts.map +1 -0
- package/dist/marketplace/backend.js +99 -0
- package/dist/marketplace/backend.js.map +1 -0
- package/dist/marketplace/browser.d.ts +33 -0
- package/dist/marketplace/browser.d.ts.map +1 -0
- package/dist/marketplace/browser.js +97 -0
- package/dist/marketplace/browser.js.map +1 -0
- package/dist/marketplace/extension-adapter.d.ts +51 -0
- package/dist/marketplace/extension-adapter.d.ts.map +1 -0
- package/dist/marketplace/extension-adapter.js +81 -0
- package/dist/marketplace/extension-adapter.js.map +1 -0
- package/dist/marketplace/index.d.ts +51 -0
- package/dist/marketplace/index.d.ts.map +1 -0
- package/dist/marketplace/index.js +108 -0
- package/dist/marketplace/index.js.map +1 -0
- package/dist/marketplace/packaging.d.ts +25 -0
- package/dist/marketplace/packaging.d.ts.map +1 -0
- package/dist/marketplace/packaging.js +117 -0
- package/dist/marketplace/packaging.js.map +1 -0
- package/dist/marketplace/schema.d.ts +50 -0
- package/dist/marketplace/schema.d.ts.map +1 -0
- package/dist/marketplace/schema.js +120 -0
- package/dist/marketplace/schema.js.map +1 -0
- package/dist/marketplace/security.d.ts +26 -0
- package/dist/marketplace/security.d.ts.map +1 -0
- package/dist/marketplace/security.js +199 -0
- package/dist/marketplace/security.js.map +1 -0
- package/dist/parsers.d.ts +15 -0
- package/dist/parsers.d.ts.map +1 -0
- package/dist/parsers.js +15 -0
- package/dist/parsers.js.map +1 -0
- package/dist/ralph/index.d.ts +58 -0
- package/dist/ralph/index.d.ts.map +1 -0
- package/dist/ralph/index.js +128 -0
- package/dist/ralph/index.js.map +1 -0
- package/dist/resolution.d.ts +47 -0
- package/dist/resolution.d.ts.map +1 -0
- package/dist/resolution.js +106 -0
- package/dist/resolution.js.map +1 -0
- package/dist/runtime/benchmarks.d.ts +121 -0
- package/dist/runtime/benchmarks.d.ts.map +1 -0
- package/dist/runtime/benchmarks.js +251 -0
- package/dist/runtime/benchmarks.js.map +1 -0
- package/dist/runtime/config.d.ts +314 -0
- package/dist/runtime/config.d.ts.map +1 -0
- package/dist/runtime/config.js +467 -0
- package/dist/runtime/config.js.map +1 -0
- package/dist/runtime/constants.d.ts +35 -0
- package/dist/runtime/constants.d.ts.map +1 -0
- package/dist/runtime/constants.js +58 -0
- package/dist/runtime/constants.js.map +1 -0
- package/dist/runtime/cost-tracker.d.ts +73 -0
- package/dist/runtime/cost-tracker.d.ts.map +1 -0
- package/dist/runtime/cost-tracker.js +157 -0
- package/dist/runtime/cost-tracker.js.map +1 -0
- package/dist/runtime/event-bus-otel-bridge.d.ts +19 -0
- package/dist/runtime/event-bus-otel-bridge.d.ts.map +1 -0
- package/dist/runtime/event-bus-otel-bridge.js +61 -0
- package/dist/runtime/event-bus-otel-bridge.js.map +1 -0
- package/dist/runtime/event-bus-ws-bridge.d.ts +35 -0
- package/dist/runtime/event-bus-ws-bridge.d.ts.map +1 -0
- package/dist/runtime/event-bus-ws-bridge.js +55 -0
- package/dist/runtime/event-bus-ws-bridge.js.map +1 -0
- package/dist/runtime/event-bus.d.ts +190 -0
- package/dist/runtime/event-bus.d.ts.map +1 -0
- package/dist/runtime/event-bus.js +218 -0
- package/dist/runtime/event-bus.js.map +1 -0
- package/dist/runtime/event-payloads.d.ts +108 -0
- package/dist/runtime/event-payloads.d.ts.map +1 -0
- package/dist/runtime/event-payloads.js +28 -0
- package/dist/runtime/event-payloads.js.map +1 -0
- package/dist/runtime/health.d.ts +66 -0
- package/dist/runtime/health.d.ts.map +1 -0
- package/dist/runtime/health.js +112 -0
- package/dist/runtime/health.js.map +1 -0
- package/dist/runtime/i18n.d.ts +54 -0
- package/dist/runtime/i18n.d.ts.map +1 -0
- package/dist/runtime/i18n.js +126 -0
- package/dist/runtime/i18n.js.map +1 -0
- package/dist/runtime/offline.d.ts +64 -0
- package/dist/runtime/offline.d.ts.map +1 -0
- package/dist/runtime/offline.js +108 -0
- package/dist/runtime/offline.js.map +1 -0
- package/dist/runtime/otel-bridge.d.ts +52 -0
- package/dist/runtime/otel-bridge.d.ts.map +1 -0
- package/dist/runtime/otel-bridge.js +132 -0
- package/dist/runtime/otel-bridge.js.map +1 -0
- package/dist/runtime/otel-init.d.ts +72 -0
- package/dist/runtime/otel-init.d.ts.map +1 -0
- package/dist/runtime/otel-init.js +68 -0
- package/dist/runtime/otel-init.js.map +1 -0
- package/dist/runtime/otel-metrics.d.ts +42 -0
- package/dist/runtime/otel-metrics.d.ts.map +1 -0
- package/dist/runtime/otel-metrics.js +196 -0
- package/dist/runtime/otel-metrics.js.map +1 -0
- package/dist/runtime/otel.d.ts +53 -0
- package/dist/runtime/otel.d.ts.map +1 -0
- package/dist/runtime/otel.js +127 -0
- package/dist/runtime/otel.js.map +1 -0
- package/dist/runtime/squad-observer.d.ts +75 -0
- package/dist/runtime/squad-observer.d.ts.map +1 -0
- package/dist/runtime/squad-observer.js +190 -0
- package/dist/runtime/squad-observer.js.map +1 -0
- package/dist/runtime/streaming.d.ts +106 -0
- package/dist/runtime/streaming.d.ts.map +1 -0
- package/dist/runtime/streaming.js +192 -0
- package/dist/runtime/streaming.js.map +1 -0
- package/dist/runtime/telemetry.d.ts +82 -0
- package/dist/runtime/telemetry.d.ts.map +1 -0
- package/dist/runtime/telemetry.js +120 -0
- package/dist/runtime/telemetry.js.map +1 -0
- package/dist/sharing/agent-repo.d.ts +33 -0
- package/dist/sharing/agent-repo.d.ts.map +1 -0
- package/dist/sharing/agent-repo.js +79 -0
- package/dist/sharing/agent-repo.js.map +1 -0
- package/dist/sharing/cache.d.ts +36 -0
- package/dist/sharing/cache.d.ts.map +1 -0
- package/dist/sharing/cache.js +85 -0
- package/dist/sharing/cache.js.map +1 -0
- package/dist/sharing/conflicts.d.ts +32 -0
- package/dist/sharing/conflicts.d.ts.map +1 -0
- package/dist/sharing/conflicts.js +121 -0
- package/dist/sharing/conflicts.js.map +1 -0
- package/dist/sharing/export.d.ts +50 -0
- package/dist/sharing/export.d.ts.map +1 -0
- package/dist/sharing/export.js +156 -0
- package/dist/sharing/export.js.map +1 -0
- package/dist/sharing/history-split.d.ts +34 -0
- package/dist/sharing/history-split.d.ts.map +1 -0
- package/dist/sharing/history-split.js +101 -0
- package/dist/sharing/history-split.js.map +1 -0
- package/dist/sharing/import.d.ts +37 -0
- package/dist/sharing/import.d.ts.map +1 -0
- package/dist/sharing/import.js +138 -0
- package/dist/sharing/import.js.map +1 -0
- package/dist/sharing/index.d.ts +11 -0
- package/dist/sharing/index.d.ts.map +1 -0
- package/dist/sharing/index.js +11 -0
- package/dist/sharing/index.js.map +1 -0
- package/dist/sharing/versioning.d.ts +32 -0
- package/dist/sharing/versioning.d.ts.map +1 -0
- package/dist/sharing/versioning.js +64 -0
- package/dist/sharing/versioning.js.map +1 -0
- package/dist/skills/index.d.ts +49 -0
- package/dist/skills/index.d.ts.map +1 -0
- package/dist/skills/index.js +85 -0
- package/dist/skills/index.js.map +1 -0
- package/dist/skills/skill-loader.d.ts +56 -0
- package/dist/skills/skill-loader.d.ts.map +1 -0
- package/dist/skills/skill-loader.js +106 -0
- package/dist/skills/skill-loader.js.map +1 -0
- package/dist/skills/skill-source.d.ts +63 -0
- package/dist/skills/skill-source.d.ts.map +1 -0
- package/dist/skills/skill-source.js +199 -0
- package/dist/skills/skill-source.js.map +1 -0
- package/dist/tools/index.d.ts +95 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +475 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/types.d.ts +43 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +8 -0
- package/dist/types.js.map +1 -0
- package/dist/upstream/index.d.ts +8 -0
- package/dist/upstream/index.d.ts.map +1 -0
- package/dist/upstream/index.js +7 -0
- package/dist/upstream/index.js.map +1 -0
- package/dist/upstream/resolver.d.ts +37 -0
- package/dist/upstream/resolver.d.ts.map +1 -0
- package/dist/upstream/resolver.js +234 -0
- package/dist/upstream/resolver.js.map +1 -0
- package/dist/upstream/types.d.ts +55 -0
- package/dist/upstream/types.d.ts.map +1 -0
- package/dist/upstream/types.js +11 -0
- package/dist/upstream/types.js.map +1 -0
- package/dist/utils/normalize-eol.d.ts +6 -0
- package/dist/utils/normalize-eol.d.ts.map +1 -0
- package/dist/utils/normalize-eol.js +8 -0
- package/dist/utils/normalize-eol.js.map +1 -0
- package/package.json +197 -63
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cost Tracker
|
|
3
|
+
*
|
|
4
|
+
* Accumulates cost and token data across a squad run with per-agent and
|
|
5
|
+
* per-session breakdowns. Wires into EventBus for real-time updates.
|
|
6
|
+
*
|
|
7
|
+
* @module runtime/cost-tracker
|
|
8
|
+
*/
|
|
9
|
+
// ============================================================================
|
|
10
|
+
// CostTracker
|
|
11
|
+
// ============================================================================
|
|
12
|
+
/**
|
|
13
|
+
* Accumulates cost/token data across the squad run.
|
|
14
|
+
*
|
|
15
|
+
* Can be wired to an EventBus to receive live usage events or fed
|
|
16
|
+
* data manually via `recordUsage()`.
|
|
17
|
+
*/
|
|
18
|
+
export class CostTracker {
|
|
19
|
+
agents = new Map();
|
|
20
|
+
sessions = new Map();
|
|
21
|
+
unsubscribe = null;
|
|
22
|
+
/**
|
|
23
|
+
* Record a single usage event.
|
|
24
|
+
*/
|
|
25
|
+
recordUsage(opts) {
|
|
26
|
+
const agentKey = opts.agentName ?? 'unknown';
|
|
27
|
+
// Per-agent
|
|
28
|
+
const agent = this.agents.get(agentKey);
|
|
29
|
+
if (agent) {
|
|
30
|
+
agent.inputTokens += opts.inputTokens;
|
|
31
|
+
agent.outputTokens += opts.outputTokens;
|
|
32
|
+
agent.estimatedCost += opts.estimatedCost;
|
|
33
|
+
agent.turnCount += 1;
|
|
34
|
+
agent.model = opts.model;
|
|
35
|
+
if (opts.isFallback)
|
|
36
|
+
agent.fallbackCount += 1;
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
this.agents.set(agentKey, {
|
|
40
|
+
agentName: agentKey,
|
|
41
|
+
model: opts.model,
|
|
42
|
+
inputTokens: opts.inputTokens,
|
|
43
|
+
outputTokens: opts.outputTokens,
|
|
44
|
+
estimatedCost: opts.estimatedCost,
|
|
45
|
+
turnCount: 1,
|
|
46
|
+
fallbackCount: opts.isFallback ? 1 : 0,
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
// Per-session
|
|
50
|
+
const session = this.sessions.get(opts.sessionId);
|
|
51
|
+
if (session) {
|
|
52
|
+
session.inputTokens += opts.inputTokens;
|
|
53
|
+
session.outputTokens += opts.outputTokens;
|
|
54
|
+
session.estimatedCost += opts.estimatedCost;
|
|
55
|
+
session.turnCount += 1;
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
this.sessions.set(opts.sessionId, {
|
|
59
|
+
sessionId: opts.sessionId,
|
|
60
|
+
agentName: opts.agentName,
|
|
61
|
+
inputTokens: opts.inputTokens,
|
|
62
|
+
outputTokens: opts.outputTokens,
|
|
63
|
+
estimatedCost: opts.estimatedCost,
|
|
64
|
+
turnCount: 1,
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
/** Record a model fallback for an agent (increments fallback counter). */
|
|
69
|
+
recordFallback(agentName) {
|
|
70
|
+
const agent = this.agents.get(agentName);
|
|
71
|
+
if (agent) {
|
|
72
|
+
agent.fallbackCount += 1;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
/** Get the full cost summary. */
|
|
76
|
+
getSummary() {
|
|
77
|
+
let totalInputTokens = 0;
|
|
78
|
+
let totalOutputTokens = 0;
|
|
79
|
+
let totalEstimatedCost = 0;
|
|
80
|
+
for (const entry of this.agents.values()) {
|
|
81
|
+
totalInputTokens += entry.inputTokens;
|
|
82
|
+
totalOutputTokens += entry.outputTokens;
|
|
83
|
+
totalEstimatedCost += entry.estimatedCost;
|
|
84
|
+
}
|
|
85
|
+
return {
|
|
86
|
+
totalInputTokens,
|
|
87
|
+
totalOutputTokens,
|
|
88
|
+
totalEstimatedCost,
|
|
89
|
+
agents: new Map(this.agents),
|
|
90
|
+
sessions: new Map(this.sessions),
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
/** Get formatted summary string suitable for terminal output. */
|
|
94
|
+
formatSummary() {
|
|
95
|
+
const summary = this.getSummary();
|
|
96
|
+
const lines = [];
|
|
97
|
+
lines.push('=== Squad Cost Summary ===');
|
|
98
|
+
lines.push(`Total input tokens: ${summary.totalInputTokens.toLocaleString()}`);
|
|
99
|
+
lines.push(`Total output tokens: ${summary.totalOutputTokens.toLocaleString()}`);
|
|
100
|
+
lines.push(`Estimated cost: $${summary.totalEstimatedCost.toFixed(4)}`);
|
|
101
|
+
if (summary.agents.size > 0) {
|
|
102
|
+
lines.push('');
|
|
103
|
+
lines.push('--- By Agent ---');
|
|
104
|
+
for (const [name, entry] of summary.agents) {
|
|
105
|
+
lines.push(` ${name}: ${entry.inputTokens.toLocaleString()}in / ${entry.outputTokens.toLocaleString()}out` +
|
|
106
|
+
` ($${entry.estimatedCost.toFixed(4)}) [${entry.turnCount} turns, model: ${entry.model}` +
|
|
107
|
+
`${entry.fallbackCount > 0 ? `, ${entry.fallbackCount} fallbacks` : ''}]`);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
if (summary.sessions.size > 0) {
|
|
111
|
+
lines.push('');
|
|
112
|
+
lines.push('--- By Session ---');
|
|
113
|
+
for (const [id, entry] of summary.sessions) {
|
|
114
|
+
lines.push(` ${id}: ${entry.inputTokens.toLocaleString()}in / ${entry.outputTokens.toLocaleString()}out` +
|
|
115
|
+
` ($${entry.estimatedCost.toFixed(4)}) [${entry.turnCount} turns]`);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return lines.join('\n');
|
|
119
|
+
}
|
|
120
|
+
/** Clear all accumulated data. */
|
|
121
|
+
reset() {
|
|
122
|
+
this.agents.clear();
|
|
123
|
+
this.sessions.clear();
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Wire into an EventBus to receive real-time `session:message` events
|
|
127
|
+
* that carry usage payloads. Returns an unsubscribe function.
|
|
128
|
+
*/
|
|
129
|
+
wireToEventBus(bus) {
|
|
130
|
+
const handler = (event) => {
|
|
131
|
+
const payload = event.payload;
|
|
132
|
+
if (!payload)
|
|
133
|
+
return;
|
|
134
|
+
// Accept events with usage data in the payload
|
|
135
|
+
if (typeof payload.inputTokens === 'number' &&
|
|
136
|
+
typeof payload.outputTokens === 'number') {
|
|
137
|
+
this.recordUsage({
|
|
138
|
+
sessionId: event.sessionId ?? 'unknown',
|
|
139
|
+
agentName: event.agentName,
|
|
140
|
+
model: payload.model ?? 'unknown',
|
|
141
|
+
inputTokens: payload.inputTokens,
|
|
142
|
+
outputTokens: payload.outputTokens,
|
|
143
|
+
estimatedCost: payload.estimatedCost ?? 0,
|
|
144
|
+
isFallback: payload.isFallback ?? false,
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
this.unsubscribe = bus.subscribe('session:message', handler);
|
|
149
|
+
return () => {
|
|
150
|
+
if (this.unsubscribe) {
|
|
151
|
+
this.unsubscribe();
|
|
152
|
+
this.unsubscribe = null;
|
|
153
|
+
}
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
//# sourceMappingURL=cost-tracker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cost-tracker.js","sourceRoot":"","sources":["../../src/runtime/cost-tracker.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* EventBus → OTel Span Bridge (Issue #304)
|
|
3
|
+
*
|
|
4
|
+
* Subscribes to EventBus events and creates OpenTelemetry spans for each.
|
|
5
|
+
* Complements the existing otel-bridge.ts which handles TelemetryEvent
|
|
6
|
+
* (dot-separated names like squad.init). This bridge handles runtime
|
|
7
|
+
* SquadEvent types (colon-separated like session:created).
|
|
8
|
+
*
|
|
9
|
+
* @module runtime/event-bus-otel-bridge
|
|
10
|
+
*/
|
|
11
|
+
import type { EventBus, UnsubscribeFn } from './event-bus.js';
|
|
12
|
+
/**
|
|
13
|
+
* Attach an OTel span bridge to an EventBus.
|
|
14
|
+
* Every event emitted on the bus produces a corresponding OTel span.
|
|
15
|
+
*
|
|
16
|
+
* @returns Unsubscribe function to detach the bridge.
|
|
17
|
+
*/
|
|
18
|
+
export declare function attachOTelBridge(bus: EventBus): UnsubscribeFn;
|
|
19
|
+
//# sourceMappingURL=event-bus-otel-bridge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event-bus-otel-bridge.d.ts","sourceRoot":"","sources":["../../src/runtime/event-bus-otel-bridge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,OAAO,KAAK,EAAE,QAAQ,EAAc,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAG1E;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,QAAQ,GAAG,aAAa,CAuC7D"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* EventBus → OTel Span Bridge (Issue #304)
|
|
3
|
+
*
|
|
4
|
+
* Subscribes to EventBus events and creates OpenTelemetry spans for each.
|
|
5
|
+
* Complements the existing otel-bridge.ts which handles TelemetryEvent
|
|
6
|
+
* (dot-separated names like squad.init). This bridge handles runtime
|
|
7
|
+
* SquadEvent types (colon-separated like session:created).
|
|
8
|
+
*
|
|
9
|
+
* @module runtime/event-bus-otel-bridge
|
|
10
|
+
*/
|
|
11
|
+
import { SpanStatusCode } from '@opentelemetry/api';
|
|
12
|
+
import { getTracer } from './otel.js';
|
|
13
|
+
import { isSquadEventOfType } from './event-payloads.js';
|
|
14
|
+
/**
|
|
15
|
+
* Attach an OTel span bridge to an EventBus.
|
|
16
|
+
* Every event emitted on the bus produces a corresponding OTel span.
|
|
17
|
+
*
|
|
18
|
+
* @returns Unsubscribe function to detach the bridge.
|
|
19
|
+
*/
|
|
20
|
+
export function attachOTelBridge(bus) {
|
|
21
|
+
return bus.subscribeAll((event) => {
|
|
22
|
+
const tracer = getTracer('squad-sdk');
|
|
23
|
+
const spanName = `squad.event.${event.type.replace(':', '.')}`;
|
|
24
|
+
const attrs = {
|
|
25
|
+
'squad.event.type': event.type,
|
|
26
|
+
};
|
|
27
|
+
if (event.sessionId)
|
|
28
|
+
attrs['squad.session.id'] = event.sessionId;
|
|
29
|
+
if (event.agentName)
|
|
30
|
+
attrs['squad.agent.name'] = event.agentName;
|
|
31
|
+
// Extract payload attributes for known event types
|
|
32
|
+
if (isSquadEventOfType(event, 'session:error')) {
|
|
33
|
+
attrs['squad.error'] = event.payload.error;
|
|
34
|
+
attrs['squad.error.agent'] = event.payload.agentName;
|
|
35
|
+
}
|
|
36
|
+
else if (isSquadEventOfType(event, 'session:tool_call')) {
|
|
37
|
+
attrs['squad.tool.name'] = event.payload.toolName;
|
|
38
|
+
if (event.payload.resultType) {
|
|
39
|
+
attrs['squad.tool.result'] = event.payload.resultType;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
else if (isSquadEventOfType(event, 'coordinator:routing')) {
|
|
43
|
+
attrs['squad.routing.phase'] = event.payload.phase;
|
|
44
|
+
}
|
|
45
|
+
else if (isSquadEventOfType(event, 'agent:milestone')) {
|
|
46
|
+
attrs['squad.milestone.event'] = event.payload.event;
|
|
47
|
+
attrs['squad.milestone.agent'] = event.payload.agentName;
|
|
48
|
+
}
|
|
49
|
+
else if (isSquadEventOfType(event, 'pool:health')) {
|
|
50
|
+
attrs['squad.pool.active'] = event.payload.activeSessions;
|
|
51
|
+
attrs['squad.pool.available'] = event.payload.availableSlots;
|
|
52
|
+
attrs['squad.pool.queued'] = event.payload.queuedRequests;
|
|
53
|
+
}
|
|
54
|
+
const span = tracer.startSpan(spanName, { attributes: attrs });
|
|
55
|
+
if (event.type === 'session:error') {
|
|
56
|
+
span.setStatus({ code: SpanStatusCode.ERROR });
|
|
57
|
+
}
|
|
58
|
+
span.end();
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=event-bus-otel-bridge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event-bus-otel-bridge.js","sourceRoot":"","sources":["../../src/runtime/event-bus-otel-bridge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtC,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAEzD;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,GAAa;IAC5C,OAAO,GAAG,CAAC,YAAY,CAAC,CAAC,KAAiB,EAAE,EAAE;QAC5C,MAAM,MAAM,GAAG,SAAS,CAAC,WAAW,CAAC,CAAC;QACtC,MAAM,QAAQ,GAAG,eAAe,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,CAAC;QAE/D,MAAM,KAAK,GAA8C;YACvD,kBAAkB,EAAE,KAAK,CAAC,IAAI;SAC/B,CAAC;QACF,IAAI,KAAK,CAAC,SAAS;YAAE,KAAK,CAAC,kBAAkB,CAAC,GAAG,KAAK,CAAC,SAAS,CAAC;QACjE,IAAI,KAAK,CAAC,SAAS;YAAE,KAAK,CAAC,kBAAkB,CAAC,GAAG,KAAK,CAAC,SAAS,CAAC;QAEjE,mDAAmD;QACnD,IAAI,kBAAkB,CAAC,KAAK,EAAE,eAAe,CAAC,EAAE,CAAC;YAC/C,KAAK,CAAC,aAAa,CAAC,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;YAC3C,KAAK,CAAC,mBAAmB,CAAC,GAAG,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC;QACvD,CAAC;aAAM,IAAI,kBAAkB,CAAC,KAAK,EAAE,mBAAmB,CAAC,EAAE,CAAC;YAC1D,KAAK,CAAC,iBAAiB,CAAC,GAAG,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC;YAClD,IAAI,KAAK,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC;gBAC7B,KAAK,CAAC,mBAAmB,CAAC,GAAG,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC;YACxD,CAAC;QACH,CAAC;aAAM,IAAI,kBAAkB,CAAC,KAAK,EAAE,qBAAqB,CAAC,EAAE,CAAC;YAC5D,KAAK,CAAC,qBAAqB,CAAC,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QACrD,CAAC;aAAM,IAAI,kBAAkB,CAAC,KAAK,EAAE,iBAAiB,CAAC,EAAE,CAAC;YACxD,KAAK,CAAC,uBAAuB,CAAC,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;YACrD,KAAK,CAAC,uBAAuB,CAAC,GAAG,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC;QAC3D,CAAC;aAAM,IAAI,kBAAkB,CAAC,KAAK,EAAE,aAAa,CAAC,EAAE,CAAC;YACpD,KAAK,CAAC,mBAAmB,CAAC,GAAG,KAAK,CAAC,OAAO,CAAC,cAAc,CAAC;YAC1D,KAAK,CAAC,sBAAsB,CAAC,GAAG,KAAK,CAAC,OAAO,CAAC,cAAc,CAAC;YAC7D,KAAK,CAAC,mBAAmB,CAAC,GAAG,KAAK,CAAC,OAAO,CAAC,cAAc,CAAC;QAC5D,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,CAAC,SAAS,CAAC,QAAQ,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,CAAC;QAE/D,IAAI,KAAK,CAAC,IAAI,KAAK,eAAe,EAAE,CAAC;YACnC,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,cAAc,CAAC,KAAK,EAAE,CAAC,CAAC;QACjD,CAAC;QAED,IAAI,CAAC,GAAG,EAAE,CAAC;IACb,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* EventBus to WebSocket Bridge (Issue #304)
|
|
3
|
+
*
|
|
4
|
+
* Broadcasts EventBus events over a WebSocket server so external
|
|
5
|
+
* consumers (e.g., SquadOffice visualization) can subscribe to
|
|
6
|
+
* real-time SDK events without coupling to OTel.
|
|
7
|
+
*
|
|
8
|
+
* @module runtime/event-bus-ws-bridge
|
|
9
|
+
*/
|
|
10
|
+
import type { EventBus } from './event-bus.js';
|
|
11
|
+
export interface WSBridgeOptions {
|
|
12
|
+
/** WebSocket server port. Defaults to 6277. */
|
|
13
|
+
port?: number;
|
|
14
|
+
/** Optional host to bind to. Defaults to '127.0.0.1'. */
|
|
15
|
+
host?: string;
|
|
16
|
+
}
|
|
17
|
+
export interface WSBridgeHandle {
|
|
18
|
+
/** Stop the bridge and close the WebSocket server. */
|
|
19
|
+
close: () => Promise<void>;
|
|
20
|
+
/** The port the WebSocket server is listening on. */
|
|
21
|
+
port: number;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Start a WebSocket server that broadcasts every EventBus event
|
|
25
|
+
* as a JSON message to all connected clients.
|
|
26
|
+
*
|
|
27
|
+
* Message format matches the SquadOffice WSMessage envelope:
|
|
28
|
+
* ```json
|
|
29
|
+
* { "kind": "event", "payload": { ...SquadEvent... } }
|
|
30
|
+
* ```
|
|
31
|
+
*
|
|
32
|
+
* @returns A handle to close the bridge.
|
|
33
|
+
*/
|
|
34
|
+
export declare function startWSBridge(bus: EventBus, options?: WSBridgeOptions): WSBridgeHandle;
|
|
35
|
+
//# sourceMappingURL=event-bus-ws-bridge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event-bus-ws-bridge.d.ts","sourceRoot":"","sources":["../../src/runtime/event-bus-ws-bridge.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,KAAK,EAAE,QAAQ,EAA6B,MAAM,gBAAgB,CAAC;AAE1E,MAAM,WAAW,eAAe;IAC9B,+CAA+C;IAC/C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,yDAAyD;IACzD,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,cAAc;IAC7B,sDAAsD;IACtD,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3B,qDAAqD;IACrD,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAC3B,GAAG,EAAE,QAAQ,EACb,OAAO,GAAE,eAAoB,GAC5B,cAAc,CA2BhB"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* EventBus to WebSocket Bridge (Issue #304)
|
|
3
|
+
*
|
|
4
|
+
* Broadcasts EventBus events over a WebSocket server so external
|
|
5
|
+
* consumers (e.g., SquadOffice visualization) can subscribe to
|
|
6
|
+
* real-time SDK events without coupling to OTel.
|
|
7
|
+
*
|
|
8
|
+
* @module runtime/event-bus-ws-bridge
|
|
9
|
+
*/
|
|
10
|
+
import { WebSocketServer, WebSocket } from 'ws';
|
|
11
|
+
/**
|
|
12
|
+
* Start a WebSocket server that broadcasts every EventBus event
|
|
13
|
+
* as a JSON message to all connected clients.
|
|
14
|
+
*
|
|
15
|
+
* Message format matches the SquadOffice WSMessage envelope:
|
|
16
|
+
* ```json
|
|
17
|
+
* { "kind": "event", "payload": { ...SquadEvent... } }
|
|
18
|
+
* ```
|
|
19
|
+
*
|
|
20
|
+
* @returns A handle to close the bridge.
|
|
21
|
+
*/
|
|
22
|
+
export function startWSBridge(bus, options = {}) {
|
|
23
|
+
const port = options.port ?? 6277;
|
|
24
|
+
const host = options.host ?? '127.0.0.1';
|
|
25
|
+
const wss = new WebSocketServer({ port, host });
|
|
26
|
+
const unsubscribe = bus.subscribeAll((event) => {
|
|
27
|
+
const message = JSON.stringify({
|
|
28
|
+
kind: 'event',
|
|
29
|
+
payload: serializeEvent(event),
|
|
30
|
+
});
|
|
31
|
+
for (const client of wss.clients) {
|
|
32
|
+
if (client.readyState === WebSocket.OPEN) {
|
|
33
|
+
client.send(message);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
return {
|
|
38
|
+
port,
|
|
39
|
+
close: () => new Promise((resolve, reject) => {
|
|
40
|
+
unsubscribe();
|
|
41
|
+
wss.close((err) => (err ? reject(err) : resolve()));
|
|
42
|
+
}),
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
/** Serialize a SquadEvent for JSON transport (Date to ISO string). */
|
|
46
|
+
function serializeEvent(event) {
|
|
47
|
+
return {
|
|
48
|
+
type: event.type,
|
|
49
|
+
sessionId: event.sessionId,
|
|
50
|
+
agentName: event.agentName,
|
|
51
|
+
payload: event.payload,
|
|
52
|
+
timestamp: event.timestamp.toISOString(),
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=event-bus-ws-bridge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event-bus-ws-bridge.js","sourceRoot":"","sources":["../../src/runtime/event-bus-ws-bridge.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AAiBhD;;;;;;;;;;GAUG;AACH,MAAM,UAAU,aAAa,CAC3B,GAAa,EACb,UAA2B,EAAE;IAE7B,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,IAAI,CAAC;IAClC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,WAAW,CAAC;IAEzC,MAAM,GAAG,GAAG,IAAI,eAAe,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;IAEhD,MAAM,WAAW,GAAkB,GAAG,CAAC,YAAY,CAAC,CAAC,KAAiB,EAAE,EAAE;QACxE,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC;YAC7B,IAAI,EAAE,OAAO;YACb,OAAO,EAAE,cAAc,CAAC,KAAK,CAAC;SAC/B,CAAC,CAAC;QAEH,KAAK,MAAM,MAAM,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC;YACjC,IAAI,MAAM,CAAC,UAAU,KAAK,SAAS,CAAC,IAAI,EAAE,CAAC;gBACzC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACvB,CAAC;QACH,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO;QACL,IAAI;QACJ,KAAK,EAAE,GAAG,EAAE,CACV,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACpC,WAAW,EAAE,CAAC;YACd,GAAG,CAAC,KAAK,CAAC,CAAC,GAAW,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QAC9D,CAAC,CAAC;KACL,CAAC;AACJ,CAAC;AAED,sEAAsE;AACtE,SAAS,cAAc,CAAC,KAAiB;IACvC,OAAO;QACL,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,SAAS,EAAE,KAAK,CAAC,SAAS;QAC1B,SAAS,EAAE,KAAK,CAAC,SAAS;QAC1B,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,SAAS,EAAE,KAAK,CAAC,SAAS,CAAC,WAAW,EAAE;KACzC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cross-Session Event Bus (M0-5, Issue #77)
|
|
3
|
+
*
|
|
4
|
+
* Pub/sub event bus for session lifecycle events with cross-session aggregation.
|
|
5
|
+
* Enables the coordinator to observe all agent sessions from a single subscription point.
|
|
6
|
+
* Decouples event producers (sessions) from consumers (coordinator, Ralph, UI).
|
|
7
|
+
*
|
|
8
|
+
* @module runtime/event-bus
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Core lifecycle events emitted by Squad sessions.
|
|
12
|
+
* All lifecycle events are persistent and logged for debugging.
|
|
13
|
+
*/
|
|
14
|
+
export type SquadLifecycleEvent = 'session:created' | 'session:idle' | 'session:error' | 'session:destroyed';
|
|
15
|
+
/**
|
|
16
|
+
* Additional operational events for coordination and monitoring.
|
|
17
|
+
*/
|
|
18
|
+
export type SquadOperationalEvent = 'session:message' | 'session:tool_call' | 'agent:milestone' | 'coordinator:routing' | 'pool:health';
|
|
19
|
+
/**
|
|
20
|
+
* All event types supported by the event bus.
|
|
21
|
+
*/
|
|
22
|
+
export type SquadEventType = SquadLifecycleEvent | SquadOperationalEvent;
|
|
23
|
+
/**
|
|
24
|
+
* Base event structure with required metadata.
|
|
25
|
+
* All events include a timestamp for chronological ordering and debugging.
|
|
26
|
+
*/
|
|
27
|
+
export interface SquadEvent {
|
|
28
|
+
/** Event type identifier */
|
|
29
|
+
type: SquadEventType;
|
|
30
|
+
/** Session ID that originated this event (optional for pool-level events) */
|
|
31
|
+
sessionId?: string;
|
|
32
|
+
/** Agent name associated with this event (optional) */
|
|
33
|
+
agentName?: string;
|
|
34
|
+
/** Event-specific payload data */
|
|
35
|
+
payload: unknown;
|
|
36
|
+
/** Timestamp when event was created */
|
|
37
|
+
timestamp: Date;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Handler function for processing events.
|
|
41
|
+
* Handlers may be synchronous or asynchronous.
|
|
42
|
+
* Errors in handlers are isolated and do not affect other handlers.
|
|
43
|
+
*/
|
|
44
|
+
export type EventHandler = (event: SquadEvent) => void | Promise<void>;
|
|
45
|
+
/**
|
|
46
|
+
* Unsubscribe function returned from subscription methods.
|
|
47
|
+
* Call this function to remove the handler from the event bus.
|
|
48
|
+
*/
|
|
49
|
+
export type UnsubscribeFn = () => void;
|
|
50
|
+
/**
|
|
51
|
+
* Cross-session event aggregation bus.
|
|
52
|
+
*
|
|
53
|
+
* Key features:
|
|
54
|
+
* - Subscribe to specific event types or all events
|
|
55
|
+
* - Async/sync handler support with error isolation
|
|
56
|
+
* - No race conditions — handlers run in subscription order
|
|
57
|
+
* - Lifecycle events: session:created, session:idle, session:error, session:destroyed
|
|
58
|
+
* - Cross-session aggregation — single subscription point for all sessions
|
|
59
|
+
*
|
|
60
|
+
* Usage:
|
|
61
|
+
* ```typescript
|
|
62
|
+
* const bus = new EventBus();
|
|
63
|
+
*
|
|
64
|
+
* // Subscribe to specific event
|
|
65
|
+
* const unsubscribe = bus.subscribe('session:created', (event) => {
|
|
66
|
+
* console.log('New session:', event.sessionId);
|
|
67
|
+
* });
|
|
68
|
+
*
|
|
69
|
+
* // Subscribe to all events
|
|
70
|
+
* const unsubscribeAll = bus.subscribeAll((event) => {
|
|
71
|
+
* console.log('Event:', event.type);
|
|
72
|
+
* });
|
|
73
|
+
*
|
|
74
|
+
* // Emit event
|
|
75
|
+
* await bus.emit({
|
|
76
|
+
* type: 'session:created',
|
|
77
|
+
* sessionId: 'abc-123',
|
|
78
|
+
* agentName: 'Ralph',
|
|
79
|
+
* payload: { model: 'claude-sonnet-4.5' },
|
|
80
|
+
* timestamp: new Date()
|
|
81
|
+
* });
|
|
82
|
+
*
|
|
83
|
+
* // Clean up
|
|
84
|
+
* unsubscribe();
|
|
85
|
+
* unsubscribeAll();
|
|
86
|
+
* ```
|
|
87
|
+
*/
|
|
88
|
+
export declare class EventBus {
|
|
89
|
+
private handlers;
|
|
90
|
+
private allHandlers;
|
|
91
|
+
private errorHandlers;
|
|
92
|
+
/**
|
|
93
|
+
* Subscribe to a specific event type.
|
|
94
|
+
*
|
|
95
|
+
* @param type - Event type to listen for
|
|
96
|
+
* @param handler - Handler function to call when event occurs
|
|
97
|
+
* @returns Unsubscribe function to remove this handler
|
|
98
|
+
*
|
|
99
|
+
* @example
|
|
100
|
+
* ```typescript
|
|
101
|
+
* const bus = new EventBus();
|
|
102
|
+
* const unsubscribe = bus.subscribe('session:created', (event) => {
|
|
103
|
+
* console.log('Session created:', event.sessionId);
|
|
104
|
+
* });
|
|
105
|
+
*
|
|
106
|
+
* // Later, remove subscription
|
|
107
|
+
* unsubscribe();
|
|
108
|
+
* ```
|
|
109
|
+
*/
|
|
110
|
+
subscribe(type: SquadEventType, handler: EventHandler): UnsubscribeFn;
|
|
111
|
+
/**
|
|
112
|
+
* Subscribe to all events regardless of type.
|
|
113
|
+
* Useful for logging, monitoring, or debugging.
|
|
114
|
+
*
|
|
115
|
+
* @param handler - Handler function to call for every event
|
|
116
|
+
* @returns Unsubscribe function to remove this handler
|
|
117
|
+
*
|
|
118
|
+
* @example
|
|
119
|
+
* ```typescript
|
|
120
|
+
* const bus = new EventBus();
|
|
121
|
+
* const unsubscribe = bus.subscribeAll((event) => {
|
|
122
|
+
* console.log(`[${event.type}] ${event.sessionId || 'global'}`);
|
|
123
|
+
* });
|
|
124
|
+
* ```
|
|
125
|
+
*/
|
|
126
|
+
subscribeAll(handler: EventHandler): UnsubscribeFn;
|
|
127
|
+
/**
|
|
128
|
+
* Unsubscribe a handler from a specific event type.
|
|
129
|
+
*
|
|
130
|
+
* @param type - Event type to unsubscribe from
|
|
131
|
+
* @param handler - Handler function to remove
|
|
132
|
+
*/
|
|
133
|
+
unsubscribe(type: SquadEventType, handler: EventHandler): void;
|
|
134
|
+
/**
|
|
135
|
+
* Register an error handler for handler execution failures.
|
|
136
|
+
* Error handlers are called when a subscribed handler throws an error.
|
|
137
|
+
*
|
|
138
|
+
* @param handler - Error handler function
|
|
139
|
+
* @returns Unsubscribe function to remove this error handler
|
|
140
|
+
*/
|
|
141
|
+
onError(handler: (error: Error, event: SquadEvent) => void): UnsubscribeFn;
|
|
142
|
+
/**
|
|
143
|
+
* Emit an event to all matching subscribers.
|
|
144
|
+
* Handlers are called in subscription order with error isolation.
|
|
145
|
+
* One handler failure does not prevent other handlers from executing.
|
|
146
|
+
*
|
|
147
|
+
* @param event - Event to emit
|
|
148
|
+
* @returns Promise that resolves when all handlers complete
|
|
149
|
+
*
|
|
150
|
+
* @example
|
|
151
|
+
* ```typescript
|
|
152
|
+
* await bus.emit({
|
|
153
|
+
* type: 'session:created',
|
|
154
|
+
* sessionId: 'abc-123',
|
|
155
|
+
* agentName: 'Ralph',
|
|
156
|
+
* payload: { model: 'claude-sonnet-4.5' },
|
|
157
|
+
* timestamp: new Date()
|
|
158
|
+
* });
|
|
159
|
+
* ```
|
|
160
|
+
*/
|
|
161
|
+
emit(event: SquadEvent): Promise<void>;
|
|
162
|
+
/**
|
|
163
|
+
* Execute a single handler with error isolation.
|
|
164
|
+
* Catches and reports handler errors without propagating them.
|
|
165
|
+
*
|
|
166
|
+
* @param handler - Handler function to execute
|
|
167
|
+
* @param event - Event to pass to handler
|
|
168
|
+
*/
|
|
169
|
+
private executeHandler;
|
|
170
|
+
/**
|
|
171
|
+
* Remove all handlers and reset the event bus.
|
|
172
|
+
* Useful for cleanup in tests or when shutting down.
|
|
173
|
+
*/
|
|
174
|
+
clear(): void;
|
|
175
|
+
/**
|
|
176
|
+
* Get count of handlers for a specific event type.
|
|
177
|
+
* Useful for debugging and testing.
|
|
178
|
+
*
|
|
179
|
+
* @param type - Event type to count handlers for
|
|
180
|
+
* @returns Number of handlers subscribed to this event type
|
|
181
|
+
*/
|
|
182
|
+
getHandlerCount(type: SquadEventType): number;
|
|
183
|
+
/**
|
|
184
|
+
* Get count of wildcard handlers.
|
|
185
|
+
*
|
|
186
|
+
* @returns Number of handlers subscribed to all events
|
|
187
|
+
*/
|
|
188
|
+
getAllHandlerCount(): number;
|
|
189
|
+
}
|
|
190
|
+
//# sourceMappingURL=event-bus.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event-bus.d.ts","sourceRoot":"","sources":["../../src/runtime/event-bus.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH;;;GAGG;AACH,MAAM,MAAM,mBAAmB,GAC3B,iBAAiB,GACjB,cAAc,GACd,eAAe,GACf,mBAAmB,CAAC;AAExB;;GAEG;AACH,MAAM,MAAM,qBAAqB,GAC7B,iBAAiB,GACjB,mBAAmB,GACnB,iBAAiB,GACjB,qBAAqB,GACrB,aAAa,CAAC;AAElB;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,mBAAmB,GAAG,qBAAqB,CAAC;AAEzE;;;GAGG;AACH,MAAM,WAAW,UAAU;IACzB,4BAA4B;IAC5B,IAAI,EAAE,cAAc,CAAC;IACrB,6EAA6E;IAC7E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,uDAAuD;IACvD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kCAAkC;IAClC,OAAO,EAAE,OAAO,CAAC;IACjB,uCAAuC;IACvC,SAAS,EAAE,IAAI,CAAC;CACjB;AAED;;;;GAIG;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAEvE;;;GAGG;AACH,MAAM,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC;AAMvC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,qBAAa,QAAQ;IACnB,OAAO,CAAC,QAAQ,CAAqD;IACrE,OAAO,CAAC,WAAW,CAAgC;IACnD,OAAO,CAAC,aAAa,CAA6D;IAElF;;;;;;;;;;;;;;;;;OAiBG;IACH,SAAS,CAAC,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,YAAY,GAAG,aAAa;IASrE;;;;;;;;;;;;;;OAcG;IACH,YAAY,CAAC,OAAO,EAAE,YAAY,GAAG,aAAa;IAKlD;;;;;OAKG;IACH,WAAW,CAAC,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,YAAY,GAAG,IAAI;IAS9D;;;;;;OAMG;IACH,OAAO,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,UAAU,KAAK,IAAI,GAAG,aAAa;IAK1E;;;;;;;;;;;;;;;;;;OAkBG;IACG,IAAI,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAmB5C;;;;;;OAMG;YACW,cAAc;IA2B5B;;;OAGG;IACH,KAAK,IAAI,IAAI;IAMb;;;;;;OAMG;IACH,eAAe,CAAC,IAAI,EAAE,cAAc,GAAG,MAAM;IAI7C;;;;OAIG;IACH,kBAAkB,IAAI,MAAM;CAG7B"}
|