@vauban-org/agent-sdk 1.2.0 → 1.3.0
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/CONTRACT.md +595 -7
- package/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/orchestration/ooda/agent.d.ts.map +1 -1
- package/dist/orchestration/ooda/agent.js +36 -0
- package/dist/orchestration/ooda/agent.js.map +1 -1
- package/dist/orchestration/ooda/types.d.ts +11 -0
- package/dist/orchestration/ooda/types.d.ts.map +1 -1
- package/dist/skills/_secrets.d.ts +16 -0
- package/dist/skills/_secrets.d.ts.map +1 -0
- package/dist/skills/_secrets.js +20 -0
- package/dist/skills/_secrets.js.map +1 -0
- package/dist/skills/alpaca-quote.d.ts +2 -2
- package/dist/skills/alpaca-quote.d.ts.map +1 -1
- package/dist/skills/alpaca-quote.js +51 -20
- package/dist/skills/alpaca-quote.js.map +1 -1
- package/dist/skills/send-email.d.ts +2 -2
- package/dist/skills/send-email.d.ts.map +1 -1
- package/dist/skills/send-email.js +1 -12
- package/dist/skills/send-email.js.map +1 -1
- package/dist/skills/slack-notify.d.ts.map +1 -1
- package/dist/skills/slack-notify.js +52 -21
- package/dist/skills/slack-notify.js.map +1 -1
- package/dist/skills/telegram-notify.d.ts.map +1 -1
- package/dist/skills/telegram-notify.js +48 -19
- package/dist/skills/telegram-notify.js.map +1 -1
- package/dist/skills/web-search.d.ts.map +1 -1
- package/dist/skills/web-search.js +85 -40
- package/dist/skills/web-search.js.map +1 -1
- package/dist/telemetry/bus.d.ts +54 -0
- package/dist/telemetry/bus.d.ts.map +1 -0
- package/dist/telemetry/bus.js +159 -0
- package/dist/telemetry/bus.js.map +1 -0
- package/dist/telemetry/index.d.ts +35 -0
- package/dist/telemetry/index.d.ts.map +1 -0
- package/dist/telemetry/index.js +30 -0
- package/dist/telemetry/index.js.map +1 -0
- package/dist/telemetry/port.d.ts +121 -0
- package/dist/telemetry/port.d.ts.map +1 -0
- package/dist/telemetry/port.js +48 -0
- package/dist/telemetry/port.js.map +1 -0
- package/dist/telemetry/sinks/otlp.d.ts +45 -0
- package/dist/telemetry/sinks/otlp.d.ts.map +1 -0
- package/dist/telemetry/sinks/otlp.js +195 -0
- package/dist/telemetry/sinks/otlp.js.map +1 -0
- package/dist/telemetry/sinks/sqlite.d.ts +32 -0
- package/dist/telemetry/sinks/sqlite.d.ts.map +1 -0
- package/dist/telemetry/sinks/sqlite.js +170 -0
- package/dist/telemetry/sinks/sqlite.js.map +1 -0
- package/dist/telemetry/sinks/stdout.d.ts +22 -0
- package/dist/telemetry/sinks/stdout.d.ts.map +1 -0
- package/dist/telemetry/sinks/stdout.js +38 -0
- package/dist/telemetry/sinks/stdout.js.map +1 -0
- package/docs/telemetry/migration.md +155 -0
- package/docs/telemetry/overview.md +154 -0
- package/docs/telemetry/privacy.md +127 -0
- package/docs/telemetry/sinks/cc.md +155 -0
- package/docs/telemetry/sinks/otlp.md +146 -0
- package/docs/telemetry/sinks/sqlite.md +126 -0
- package/docs/telemetry/sinks/stdout.md +82 -0
- package/package.json +18 -19
- package/src/index.ts +30 -1
- package/src/orchestration/ooda/agent.ts +50 -0
- package/src/orchestration/ooda/types.ts +12 -0
- package/src/skills/_secrets.ts +25 -0
- package/src/skills/alpaca-quote.ts +68 -23
- package/src/skills/send-email.ts +1 -12
- package/src/skills/slack-notify.ts +73 -30
- package/src/skills/telegram-notify.ts +70 -24
- package/src/skills/web-search.ts +132 -50
- package/src/telemetry/bus.test.ts +231 -0
- package/src/telemetry/bus.ts +241 -0
- package/src/telemetry/index.ts +49 -0
- package/src/telemetry/port.ts +160 -0
- package/src/telemetry/sinks/otlp.test.ts +146 -0
- package/src/telemetry/sinks/otlp.ts +250 -0
- package/src/telemetry/sinks/sqlite.test.ts +121 -0
- package/src/telemetry/sinks/sqlite.ts +260 -0
- package/src/telemetry/sinks/stdout.test.ts +109 -0
- package/src/telemetry/sinks/stdout.ts +59 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"otlp.js","sourceRoot":"","sources":["../../../src/telemetry/sinks/otlp.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* localSqliteTelemetrySink — sovereign local mirror of agent runs.
|
|
3
|
+
*
|
|
4
|
+
* Per ADR-ECO-039 §5 : SQLite sink is ON by default. It is the exit plan for
|
|
5
|
+
* any remote sink (CC SaaS, OTLP backend) — if the network sink is revoked,
|
|
6
|
+
* the local SQLite file retains the full history.
|
|
7
|
+
*
|
|
8
|
+
* Schema (created on first use) :
|
|
9
|
+
* - `agent_run` : one row per OODA cycle (start + finish join)
|
|
10
|
+
* - `agent_run_step` : one row per OODA step
|
|
11
|
+
*
|
|
12
|
+
* Dependency : `better-sqlite3` declared as **peerDependency optional**.
|
|
13
|
+
* If absent, this sink degrades gracefully — logs a warning and no-ops.
|
|
14
|
+
*
|
|
15
|
+
* Ref: command-center:sprint-693:sink-sqlite
|
|
16
|
+
*/
|
|
17
|
+
import type { TelemetrySink } from "../port.js";
|
|
18
|
+
export interface LocalSqliteTelemetrySinkOptions {
|
|
19
|
+
/**
|
|
20
|
+
* Database file path. Default `~/.vauban/runs.db`.
|
|
21
|
+
* Pass `:memory:` for ephemeral test mode.
|
|
22
|
+
*/
|
|
23
|
+
path?: string;
|
|
24
|
+
/** Synchronous mode (better-sqlite3 default). Tests may override. */
|
|
25
|
+
readonly?: boolean;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Build a local SQLite sink. Returns a no-op sink if `better-sqlite3` is not
|
|
29
|
+
* installed — the caller is warned via `console.warn` once.
|
|
30
|
+
*/
|
|
31
|
+
export declare function localSqliteTelemetrySink(opts?: LocalSqliteTelemetrySinkOptions): TelemetrySink;
|
|
32
|
+
//# sourceMappingURL=sqlite.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sqlite.d.ts","sourceRoot":"","sources":["../../../src/telemetry/sinks/sqlite.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAMH,OAAO,KAAK,EAIV,aAAa,EACd,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,+BAA+B;IAC9C;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,qEAAqE;IACrE,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAkED;;;GAGG;AACH,wBAAgB,wBAAwB,CACtC,IAAI,GAAE,+BAAoC,GACzC,aAAa,CA2Ff"}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* localSqliteTelemetrySink — sovereign local mirror of agent runs.
|
|
3
|
+
*
|
|
4
|
+
* Per ADR-ECO-039 §5 : SQLite sink is ON by default. It is the exit plan for
|
|
5
|
+
* any remote sink (CC SaaS, OTLP backend) — if the network sink is revoked,
|
|
6
|
+
* the local SQLite file retains the full history.
|
|
7
|
+
*
|
|
8
|
+
* Schema (created on first use) :
|
|
9
|
+
* - `agent_run` : one row per OODA cycle (start + finish join)
|
|
10
|
+
* - `agent_run_step` : one row per OODA step
|
|
11
|
+
*
|
|
12
|
+
* Dependency : `better-sqlite3` declared as **peerDependency optional**.
|
|
13
|
+
* If absent, this sink degrades gracefully — logs a warning and no-ops.
|
|
14
|
+
*
|
|
15
|
+
* Ref: command-center:sprint-693:sink-sqlite
|
|
16
|
+
*/
|
|
17
|
+
import { homedir } from "node:os";
|
|
18
|
+
import { dirname, resolve as resolvePath } from "node:path";
|
|
19
|
+
import { mkdirSync } from "node:fs";
|
|
20
|
+
// ─── Schema ──────────────────────────────────────────────────────────────────
|
|
21
|
+
const SCHEMA = `
|
|
22
|
+
CREATE TABLE IF NOT EXISTS agent_run (
|
|
23
|
+
run_id TEXT PRIMARY KEY,
|
|
24
|
+
agent_id TEXT NOT NULL,
|
|
25
|
+
agent_version TEXT NOT NULL,
|
|
26
|
+
model TEXT,
|
|
27
|
+
provider TEXT,
|
|
28
|
+
tenant_id TEXT,
|
|
29
|
+
trace_id TEXT,
|
|
30
|
+
started_at TEXT NOT NULL,
|
|
31
|
+
finished_at TEXT,
|
|
32
|
+
status TEXT,
|
|
33
|
+
stop_reason TEXT,
|
|
34
|
+
error_message TEXT,
|
|
35
|
+
total_input_tokens INTEGER DEFAULT 0,
|
|
36
|
+
total_output_tokens INTEGER DEFAULT 0,
|
|
37
|
+
total_cost_usd REAL DEFAULT 0,
|
|
38
|
+
total_tool_calls INTEGER DEFAULT 0
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
CREATE INDEX IF NOT EXISTS idx_agent_run_agent_started
|
|
42
|
+
ON agent_run (agent_id, started_at DESC);
|
|
43
|
+
|
|
44
|
+
CREATE INDEX IF NOT EXISTS idx_agent_run_status
|
|
45
|
+
ON agent_run (status, started_at DESC);
|
|
46
|
+
|
|
47
|
+
CREATE TABLE IF NOT EXISTS agent_run_step (
|
|
48
|
+
run_id TEXT NOT NULL,
|
|
49
|
+
step_index INTEGER NOT NULL,
|
|
50
|
+
kind TEXT NOT NULL,
|
|
51
|
+
status TEXT NOT NULL,
|
|
52
|
+
input_tokens INTEGER DEFAULT 0,
|
|
53
|
+
output_tokens INTEGER DEFAULT 0,
|
|
54
|
+
tool_calls INTEGER DEFAULT 0,
|
|
55
|
+
cost_usd REAL DEFAULT 0,
|
|
56
|
+
duration_ms INTEGER,
|
|
57
|
+
metadata TEXT,
|
|
58
|
+
recorded_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
59
|
+
PRIMARY KEY (run_id, step_index)
|
|
60
|
+
);
|
|
61
|
+
|
|
62
|
+
CREATE INDEX IF NOT EXISTS idx_agent_run_step_run
|
|
63
|
+
ON agent_run_step (run_id, step_index);
|
|
64
|
+
`;
|
|
65
|
+
// ─── Factory ─────────────────────────────────────────────────────────────────
|
|
66
|
+
/**
|
|
67
|
+
* Build a local SQLite sink. Returns a no-op sink if `better-sqlite3` is not
|
|
68
|
+
* installed — the caller is warned via `console.warn` once.
|
|
69
|
+
*/
|
|
70
|
+
export function localSqliteTelemetrySink(opts = {}) {
|
|
71
|
+
const dbPath = resolveDbPath(opts.path);
|
|
72
|
+
const db = openDatabaseSafely(dbPath, opts.readonly ?? false);
|
|
73
|
+
if (!db) {
|
|
74
|
+
return degradedSink(dbPath);
|
|
75
|
+
}
|
|
76
|
+
db.exec(SCHEMA);
|
|
77
|
+
db.pragma("journal_mode = WAL");
|
|
78
|
+
db.pragma("synchronous = NORMAL");
|
|
79
|
+
const insertRun = db.prepare(`
|
|
80
|
+
INSERT INTO agent_run
|
|
81
|
+
(run_id, agent_id, agent_version, model, provider,
|
|
82
|
+
tenant_id, trace_id, started_at)
|
|
83
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
84
|
+
ON CONFLICT (run_id) DO NOTHING
|
|
85
|
+
`);
|
|
86
|
+
const insertStep = db.prepare(`
|
|
87
|
+
INSERT INTO agent_run_step
|
|
88
|
+
(run_id, step_index, kind, status,
|
|
89
|
+
input_tokens, output_tokens, tool_calls, cost_usd,
|
|
90
|
+
duration_ms, metadata)
|
|
91
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
92
|
+
ON CONFLICT (run_id, step_index) DO NOTHING
|
|
93
|
+
`);
|
|
94
|
+
const updateFinish = db.prepare(`
|
|
95
|
+
UPDATE agent_run
|
|
96
|
+
SET finished_at = ?,
|
|
97
|
+
status = ?,
|
|
98
|
+
stop_reason = ?,
|
|
99
|
+
error_message = ?,
|
|
100
|
+
total_input_tokens = COALESCE(?, total_input_tokens),
|
|
101
|
+
total_output_tokens = COALESCE(?, total_output_tokens),
|
|
102
|
+
total_cost_usd = COALESCE(?, total_cost_usd),
|
|
103
|
+
total_tool_calls = COALESCE(?, total_tool_calls)
|
|
104
|
+
WHERE run_id = ?
|
|
105
|
+
`);
|
|
106
|
+
return {
|
|
107
|
+
name: "sqlite",
|
|
108
|
+
async start(event) {
|
|
109
|
+
insertRun.run(event.runId, event.agentId, event.agentVersion, event.model ?? null, event.provider ?? null, event.tenantId ?? null, event.traceId ?? null, event.startedAt);
|
|
110
|
+
},
|
|
111
|
+
async step(runId, delta) {
|
|
112
|
+
insertStep.run(runId, delta.stepIndex, delta.kind, delta.status, delta.inputTokens, delta.outputTokens, delta.toolCalls ?? 0, delta.costUsd, delta.durationMs ?? null, delta.metadata ? JSON.stringify(delta.metadata) : null);
|
|
113
|
+
},
|
|
114
|
+
async finish(runId, event) {
|
|
115
|
+
updateFinish.run(event.finishedAt, event.status, event.stopReason ?? null, event.errorMessage ?? null, event.totalInputTokens ?? null, event.totalOutputTokens ?? null, event.totalCostUsd ?? null, event.totalToolCalls ?? null, runId);
|
|
116
|
+
},
|
|
117
|
+
async flush() {
|
|
118
|
+
// better-sqlite3 is synchronous — no buffer to flush.
|
|
119
|
+
},
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
// ─── Helpers ─────────────────────────────────────────────────────────────────
|
|
123
|
+
function resolveDbPath(input) {
|
|
124
|
+
if (!input)
|
|
125
|
+
return resolvePath(homedir(), ".vauban", "runs.db");
|
|
126
|
+
if (input === ":memory:")
|
|
127
|
+
return input;
|
|
128
|
+
// Expand leading ~ manually (Node doesn't do it).
|
|
129
|
+
if (input.startsWith("~/")) {
|
|
130
|
+
return resolvePath(homedir(), input.slice(2));
|
|
131
|
+
}
|
|
132
|
+
return resolvePath(input);
|
|
133
|
+
}
|
|
134
|
+
let warnedMissing = false;
|
|
135
|
+
function openDatabaseSafely(path, readonly) {
|
|
136
|
+
try {
|
|
137
|
+
// Dynamic require so better-sqlite3 stays optional.
|
|
138
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
139
|
+
const createRequire = require("node:module").createRequire;
|
|
140
|
+
const req = createRequire(import.meta.url);
|
|
141
|
+
const BetterSqlite = req("better-sqlite3");
|
|
142
|
+
if (path !== ":memory:") {
|
|
143
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
144
|
+
}
|
|
145
|
+
return new BetterSqlite(path, { readonly });
|
|
146
|
+
}
|
|
147
|
+
catch (err) {
|
|
148
|
+
if (!warnedMissing) {
|
|
149
|
+
warnedMissing = true;
|
|
150
|
+
// eslint-disable-next-line no-console
|
|
151
|
+
console.warn("[telemetry:sqlite] better-sqlite3 not installed — sink degraded to no-op.", "Install with: `pnpm add better-sqlite3` (peerDependencyOptional).", err instanceof Error ? err.message : "");
|
|
152
|
+
}
|
|
153
|
+
return null;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
function degradedSink(path) {
|
|
157
|
+
return {
|
|
158
|
+
name: `sqlite:degraded(${path})`,
|
|
159
|
+
async start() {
|
|
160
|
+
/* no-op when better-sqlite3 missing */
|
|
161
|
+
},
|
|
162
|
+
async step() {
|
|
163
|
+
/* no-op */
|
|
164
|
+
},
|
|
165
|
+
async finish() {
|
|
166
|
+
/* no-op */
|
|
167
|
+
},
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
//# sourceMappingURL=sqlite.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sqlite.js","sourceRoot":"","sources":["../../../src/telemetry/sinks/sqlite.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,WAAW,CAAC;AAC5D,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAkCpC,gFAAgF;AAEhF,MAAM,MAAM,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2Cd,CAAC;AAEF,gFAAgF;AAEhF;;;GAGG;AACH,MAAM,UAAU,wBAAwB,CACtC,OAAwC,EAAE;IAE1C,MAAM,MAAM,GAAG,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACxC,MAAM,EAAE,GAAG,kBAAkB,CAAC,MAAM,EAAE,IAAI,CAAC,QAAQ,IAAI,KAAK,CAAC,CAAC;IAE9D,IAAI,CAAC,EAAE,EAAE,CAAC;QACR,OAAO,YAAY,CAAC,MAAM,CAAC,CAAC;IAC9B,CAAC;IAED,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAChB,EAAE,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;IAChC,EAAE,CAAC,MAAM,CAAC,sBAAsB,CAAC,CAAC;IAElC,MAAM,SAAS,GAAG,EAAE,CAAC,OAAO,CAAC;;;;;;GAM5B,CAAC,CAAC;IAEH,MAAM,UAAU,GAAG,EAAE,CAAC,OAAO,CAAC;;;;;;;GAO7B,CAAC,CAAC;IAEH,MAAM,YAAY,GAAG,EAAE,CAAC,OAAO,CAAC;;;;;;;;;;;GAW/B,CAAC,CAAC;IAEH,OAAO;QACL,IAAI,EAAE,QAAQ;QAEd,KAAK,CAAC,KAAK,CAAC,KAAwB;YAClC,SAAS,CAAC,GAAG,CACX,KAAK,CAAC,KAAK,EACX,KAAK,CAAC,OAAO,EACb,KAAK,CAAC,YAAY,EAClB,KAAK,CAAC,KAAK,IAAI,IAAI,EACnB,KAAK,CAAC,QAAQ,IAAI,IAAI,EACtB,KAAK,CAAC,QAAQ,IAAI,IAAI,EACtB,KAAK,CAAC,OAAO,IAAI,IAAI,EACrB,KAAK,CAAC,SAAS,CAChB,CAAC;QACJ,CAAC;QAED,KAAK,CAAC,IAAI,CAAC,KAAa,EAAE,KAAuB;YAC/C,UAAU,CAAC,GAAG,CACZ,KAAK,EACL,KAAK,CAAC,SAAS,EACf,KAAK,CAAC,IAAI,EACV,KAAK,CAAC,MAAM,EACZ,KAAK,CAAC,WAAW,EACjB,KAAK,CAAC,YAAY,EAClB,KAAK,CAAC,SAAS,IAAI,CAAC,EACpB,KAAK,CAAC,OAAO,EACb,KAAK,CAAC,UAAU,IAAI,IAAI,EACxB,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CACvD,CAAC;QACJ,CAAC;QAED,KAAK,CAAC,MAAM,CAAC,KAAa,EAAE,KAAyB;YACnD,YAAY,CAAC,GAAG,CACd,KAAK,CAAC,UAAU,EAChB,KAAK,CAAC,MAAM,EACZ,KAAK,CAAC,UAAU,IAAI,IAAI,EACxB,KAAK,CAAC,YAAY,IAAI,IAAI,EAC1B,KAAK,CAAC,gBAAgB,IAAI,IAAI,EAC9B,KAAK,CAAC,iBAAiB,IAAI,IAAI,EAC/B,KAAK,CAAC,YAAY,IAAI,IAAI,EAC1B,KAAK,CAAC,cAAc,IAAI,IAAI,EAC5B,KAAK,CACN,CAAC;QACJ,CAAC;QAED,KAAK,CAAC,KAAK;YACT,sDAAsD;QACxD,CAAC;KACF,CAAC;AACJ,CAAC;AAED,gFAAgF;AAEhF,SAAS,aAAa,CAAC,KAAc;IACnC,IAAI,CAAC,KAAK;QAAE,OAAO,WAAW,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;IAChE,IAAI,KAAK,KAAK,UAAU;QAAE,OAAO,KAAK,CAAC;IACvC,kDAAkD;IAClD,IAAI,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QAC3B,OAAO,WAAW,CAAC,OAAO,EAAE,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAChD,CAAC;IACD,OAAO,WAAW,CAAC,KAAK,CAAC,CAAC;AAC5B,CAAC;AAED,IAAI,aAAa,GAAG,KAAK,CAAC;AAE1B,SAAS,kBAAkB,CAAC,IAAY,EAAE,QAAiB;IACzD,IAAI,CAAC;QACH,oDAAoD;QACpD,iEAAiE;QACjE,MAAM,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC,aAE1B,CAAC;QACpB,MAAM,GAAG,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC3C,MAAM,YAAY,GAAG,GAAG,CAAC,gBAAgB,CAG5B,CAAC;QAEd,IAAI,IAAI,KAAK,UAAU,EAAE,CAAC;YACxB,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAChD,CAAC;QACD,OAAO,IAAI,YAAY,CAAC,IAAI,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC;IAC9C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,CAAC,aAAa,EAAE,CAAC;YACnB,aAAa,GAAG,IAAI,CAAC;YACrB,sCAAsC;YACtC,OAAO,CAAC,IAAI,CACV,2EAA2E,EAC3E,mEAAmE,EACnE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CACxC,CAAC;QACJ,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,SAAS,YAAY,CAAC,IAAY;IAChC,OAAO;QACL,IAAI,EAAE,mBAAmB,IAAI,GAAG;QAChC,KAAK,CAAC,KAAK;YACT,uCAAuC;QACzC,CAAC;QACD,KAAK,CAAC,IAAI;YACR,WAAW;QACb,CAAC;QACD,KAAK,CAAC,MAAM;YACV,WAAW;QACb,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* stdoutTelemetrySink — JSON line emission to stderr (dev-friendly default).
|
|
3
|
+
*
|
|
4
|
+
* One JSON object per event, suitable for `jq`, `pino-pretty`, or any
|
|
5
|
+
* structured-log pipeline. Writes to stderr (not stdout) so that the agent's
|
|
6
|
+
* own stdout remains free for user output.
|
|
7
|
+
*
|
|
8
|
+
* Ref: command-center:sprint-693:sink-stdout
|
|
9
|
+
*/
|
|
10
|
+
import type { TelemetrySink } from "../port.js";
|
|
11
|
+
export interface StdoutTelemetrySinkOptions {
|
|
12
|
+
/** Stream to write to. Defaults to `process.stderr`. */
|
|
13
|
+
stream?: NodeJS.WritableStream;
|
|
14
|
+
/** When true (default), emits as `key=value` instead of JSON. */
|
|
15
|
+
json?: boolean;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Default sink for dev visibility. Zero dependency, zero I/O latency
|
|
19
|
+
* (synchronous write to stream).
|
|
20
|
+
*/
|
|
21
|
+
export declare function stdoutTelemetrySink(opts?: StdoutTelemetrySinkOptions): TelemetrySink;
|
|
22
|
+
//# sourceMappingURL=stdout.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stdout.d.ts","sourceRoot":"","sources":["../../../src/telemetry/sinks/stdout.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAIV,aAAa,EACd,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,0BAA0B;IACzC,wDAAwD;IACxD,MAAM,CAAC,EAAE,MAAM,CAAC,cAAc,CAAC;IAC/B,iEAAiE;IACjE,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,GAAE,0BAA+B,GACpC,aAAa,CA4Bf"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* stdoutTelemetrySink — JSON line emission to stderr (dev-friendly default).
|
|
3
|
+
*
|
|
4
|
+
* One JSON object per event, suitable for `jq`, `pino-pretty`, or any
|
|
5
|
+
* structured-log pipeline. Writes to stderr (not stdout) so that the agent's
|
|
6
|
+
* own stdout remains free for user output.
|
|
7
|
+
*
|
|
8
|
+
* Ref: command-center:sprint-693:sink-stdout
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Default sink for dev visibility. Zero dependency, zero I/O latency
|
|
12
|
+
* (synchronous write to stream).
|
|
13
|
+
*/
|
|
14
|
+
export function stdoutTelemetrySink(opts = {}) {
|
|
15
|
+
const stream = opts.stream ?? process.stderr;
|
|
16
|
+
const useJson = opts.json ?? true;
|
|
17
|
+
function emit(event) {
|
|
18
|
+
const line = useJson
|
|
19
|
+
? JSON.stringify(event)
|
|
20
|
+
: Object.entries(event)
|
|
21
|
+
.map(([k, v]) => `${k}=${JSON.stringify(v)}`)
|
|
22
|
+
.join(" ");
|
|
23
|
+
stream.write(`${line}\n`);
|
|
24
|
+
}
|
|
25
|
+
return {
|
|
26
|
+
name: "stdout",
|
|
27
|
+
async start(event) {
|
|
28
|
+
emit({ telemetry: "run.start", ...event });
|
|
29
|
+
},
|
|
30
|
+
async step(runId, delta) {
|
|
31
|
+
emit({ telemetry: "run.step", runId, ...delta });
|
|
32
|
+
},
|
|
33
|
+
async finish(runId, event) {
|
|
34
|
+
emit({ telemetry: "run.finish", runId, ...event });
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=stdout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stdout.js","sourceRoot":"","sources":["../../../src/telemetry/sinks/stdout.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAgBH;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CACjC,OAAmC,EAAE;IAErC,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC;IAC7C,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC;IAElC,SAAS,IAAI,CAAC,KAA8B;QAC1C,MAAM,IAAI,GAAG,OAAO;YAClB,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC;YACvB,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC;iBAClB,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC;iBAC5C,IAAI,CAAC,GAAG,CAAC,CAAC;QACjB,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,IAAI,CAAC,CAAC;IAC5B,CAAC;IAED,OAAO;QACL,IAAI,EAAE,QAAQ;QAEd,KAAK,CAAC,KAAK,CAAC,KAAwB;YAClC,IAAI,CAAC,EAAE,SAAS,EAAE,WAAW,EAAE,GAAG,KAAK,EAAE,CAAC,CAAC;QAC7C,CAAC;QAED,KAAK,CAAC,IAAI,CAAC,KAAa,EAAE,KAAuB;YAC/C,IAAI,CAAC,EAAE,SAAS,EAAE,UAAU,EAAE,KAAK,EAAE,GAAG,KAAK,EAAE,CAAC,CAAC;QACnD,CAAC;QAED,KAAK,CAAC,MAAM,CAAC,KAAa,EAAE,KAAyB;YACnD,IAAI,CAAC,EAAE,SAAS,EAAE,YAAY,EAAE,KAAK,EAAE,GAAG,KAAK,EAAE,CAAC,CAAC;QACrD,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
# Migration : 1.2 → 1.3
|
|
2
|
+
|
|
3
|
+
!!! success "Zero breaking changes"
|
|
4
|
+
Existing 1.2.x consumers continue to work unchanged. All new APIs are
|
|
5
|
+
additive.
|
|
6
|
+
|
|
7
|
+
## TL;DR
|
|
8
|
+
|
|
9
|
+
- `AgentRunTracker` still works. Marked deprecated, will be removed in 2.0.
|
|
10
|
+
- New `telemetry` field on `OODAAgentConfig`. Opt-in.
|
|
11
|
+
- 4 new sinks shipped : `stdout`, `sqlite`, `otlp` in core ; `cc` in
|
|
12
|
+
`@vauban-org/cc-telemetry`.
|
|
13
|
+
|
|
14
|
+
## What changed
|
|
15
|
+
|
|
16
|
+
### `AgentRunFinalStatus` adds `"skipped"`
|
|
17
|
+
|
|
18
|
+
Before :
|
|
19
|
+
|
|
20
|
+
```ts
|
|
21
|
+
type AgentRunFinalStatus = "success" | "failed" | "timeout" | "incoherent";
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
After :
|
|
25
|
+
|
|
26
|
+
```ts
|
|
27
|
+
type AgentRunFinalStatus = "success" | "failed" | "skipped" | "timeout" | "incoherent";
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
`"skipped"` distinguishes session_guard / risk_guard / heap_exceeded
|
|
31
|
+
short-circuits from real successes. Existing exhaustive `switch` statements
|
|
32
|
+
on this type will need to add a case (TypeScript will surface it).
|
|
33
|
+
|
|
34
|
+
For the new `TelemetryRunStatus` type (used by the new sinks), see the
|
|
35
|
+
[port.ts source](https://github.com/vauban-org/command-center/blob/main/packages/agent-sdk/src/telemetry/port.ts).
|
|
36
|
+
|
|
37
|
+
### New optional `OODAAgentConfig.telemetry`
|
|
38
|
+
|
|
39
|
+
```ts
|
|
40
|
+
interface OODAAgentConfig {
|
|
41
|
+
// …existing fields…
|
|
42
|
+
readonly telemetry?: TelemetrySink; // NEW, optional
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
When set, the OODA loop auto-emits `start` + `step` + `finish` events.
|
|
47
|
+
When omitted, behavior is identical to 1.2.
|
|
48
|
+
|
|
49
|
+
### Legacy `AgentRunTracker` is deprecated
|
|
50
|
+
|
|
51
|
+
```ts
|
|
52
|
+
import { createAgentRunTracker } from "@vauban-org/agent-sdk"; // deprecated
|
|
53
|
+
|
|
54
|
+
const tracker = createAgentRunTracker(db);
|
|
55
|
+
// Still works, still INSERTs into agent_run. Will be removed in 2.0.
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Migration target :
|
|
59
|
+
|
|
60
|
+
```ts
|
|
61
|
+
import {
|
|
62
|
+
createTelemetryBus,
|
|
63
|
+
localSqliteTelemetrySink,
|
|
64
|
+
} from "@vauban-org/agent-sdk";
|
|
65
|
+
import { commandCenterTelemetrySink } from "@vauban-org/cc-telemetry";
|
|
66
|
+
|
|
67
|
+
const telemetry = createTelemetryBus({
|
|
68
|
+
sinks: [
|
|
69
|
+
localSqliteTelemetrySink(),
|
|
70
|
+
commandCenterTelemetrySink({ apiKey: process.env.VAUBAN_API_KEY! }),
|
|
71
|
+
],
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
createOODAAgent({
|
|
75
|
+
agentId: "my-agent",
|
|
76
|
+
telemetry,
|
|
77
|
+
// …no more `createAgentRunTracker(db)` needed
|
|
78
|
+
});
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Recipes for common migrations
|
|
82
|
+
|
|
83
|
+
### From `AgentRunTracker` to sinks
|
|
84
|
+
|
|
85
|
+
Before :
|
|
86
|
+
|
|
87
|
+
```ts
|
|
88
|
+
const tracker = createAgentRunTracker(db);
|
|
89
|
+
const uuid = await tracker.start({ agentId, agentVersion, runId, model, provider });
|
|
90
|
+
await tracker.recordStep(uuid, { inputTokens, outputTokens, costUsd });
|
|
91
|
+
await tracker.finish(uuid, { status: "success" });
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
After :
|
|
95
|
+
|
|
96
|
+
```ts
|
|
97
|
+
// No imperative calls — the OODA loop handles it.
|
|
98
|
+
createOODAAgent({
|
|
99
|
+
agentId: "my-agent",
|
|
100
|
+
telemetry: localSqliteTelemetrySink(),
|
|
101
|
+
});
|
|
102
|
+
// runCycle() automatically emits start/step/finish.
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
If you ran tracker calls *outside* the OODA loop (e.g. from a custom
|
|
106
|
+
event handler), you can still use it ; the loop's telemetry and the
|
|
107
|
+
custom calls coexist (they write to different tables in v1.3 :
|
|
108
|
+
`agent_run` for legacy tracker, `telemetry_run_step` for SDK sinks).
|
|
109
|
+
|
|
110
|
+
### From `console.log` to stdoutTelemetrySink
|
|
111
|
+
|
|
112
|
+
Before :
|
|
113
|
+
|
|
114
|
+
```ts
|
|
115
|
+
console.log("[my-agent] cycle start", { runId, agentId });
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
After :
|
|
119
|
+
|
|
120
|
+
```ts
|
|
121
|
+
createOODAAgent({
|
|
122
|
+
agentId: "my-agent",
|
|
123
|
+
telemetry: stdoutTelemetrySink(),
|
|
124
|
+
});
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
You get structured JSON automatically, plus the same data lands in any
|
|
128
|
+
other sinks you configure later.
|
|
129
|
+
|
|
130
|
+
## Removed (only in 2.0, not yet)
|
|
131
|
+
|
|
132
|
+
Targeted for removal in **2.0** (no earlier than Q4 2026) :
|
|
133
|
+
|
|
134
|
+
- `createAgentRunTracker(db)`
|
|
135
|
+
- `AgentRunTracker` interface
|
|
136
|
+
- `tracking/agent-run-tracker.ts` module
|
|
137
|
+
- `tracking/cost-tracked-agent-run-tracker.ts` (consumer in CC backend)
|
|
138
|
+
|
|
139
|
+
Until then, both APIs coexist.
|
|
140
|
+
|
|
141
|
+
## Testing the upgrade
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
# Pin to old version
|
|
145
|
+
pnpm add @vauban-org/agent-sdk@1.2.0
|
|
146
|
+
|
|
147
|
+
# Pin to new version
|
|
148
|
+
pnpm add @vauban-org/agent-sdk@1.3.0
|
|
149
|
+
|
|
150
|
+
# Run your test suite
|
|
151
|
+
pnpm test
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
You should see 0 failures, 0 new warnings (other than the deprecation
|
|
155
|
+
notice if you still call `createAgentRunTracker`).
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
# Telemetry Overview
|
|
2
|
+
|
|
3
|
+
!!! info "Status — public-experimental"
|
|
4
|
+
Introduced in `@vauban-org/agent-sdk@1.3.0` (ADR-ECO-039). Interface
|
|
5
|
+
stable, additional event fields may be added before 2.0.
|
|
6
|
+
|
|
7
|
+
The agent-sdk exposes a **port-based telemetry pipeline** : agents emit
|
|
8
|
+
lifecycle events (`start` → `step…` → `finish`) and configurable **sinks**
|
|
9
|
+
decide where those events go. Sovereignty is preserved by default — no
|
|
10
|
+
network calls happen unless you explicitly opt in.
|
|
11
|
+
|
|
12
|
+
## Why a port + sinks pattern ?
|
|
13
|
+
|
|
14
|
+
Before v1.3, the SDK had an implicit DB coupling (`AgentRunTracker.start`
|
|
15
|
+
INSERTed directly into a Command Center–specific `agent_run` table). That
|
|
16
|
+
violated three invariants : sovereignty (SDK unusable without the CC DB),
|
|
17
|
+
boundary discipline (SDK knowing CC schema), and standalone-product
|
|
18
|
+
design (CC should be an optional consumer).
|
|
19
|
+
|
|
20
|
+
The port pattern fixes all three. See the design rationale in
|
|
21
|
+
[ADR-ECO-039](https://github.com/vauban-org/vauban-gouvernance/blob/main/governance/decisions/ADR-ECO-039-sdk-telemetry-port.md).
|
|
22
|
+
|
|
23
|
+
## Three usage modes
|
|
24
|
+
|
|
25
|
+
```mermaid
|
|
26
|
+
graph TD
|
|
27
|
+
A[OODA loop runCycle()] -->|TelemetrySink| B[TelemetryBus]
|
|
28
|
+
B --> S1[stdoutTelemetrySink]
|
|
29
|
+
B --> S2[localSqliteTelemetrySink]
|
|
30
|
+
B --> S3[otlpTelemetrySink]
|
|
31
|
+
B --> S4["commandCenterTelemetrySink<br/>(separate npm pkg)"]
|
|
32
|
+
|
|
33
|
+
S1 -.-> O1[stderr / pino-pretty]
|
|
34
|
+
S2 -.-> O2["~/.vauban/runs.db"]
|
|
35
|
+
S3 -.-> O3["Langfuse / Tempo / Jaeger"]
|
|
36
|
+
S4 -.-> O4["command.vauban.tech<br/>or self-hosted CC"]
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### Mode 1 — Standalone (sovereign default)
|
|
40
|
+
|
|
41
|
+
Zero phone-home. Zero account required. Runs everywhere.
|
|
42
|
+
|
|
43
|
+
```ts
|
|
44
|
+
import {
|
|
45
|
+
createOODAAgent,
|
|
46
|
+
createTelemetryBus,
|
|
47
|
+
stdoutTelemetrySink,
|
|
48
|
+
localSqliteTelemetrySink,
|
|
49
|
+
} from "@vauban-org/agent-sdk";
|
|
50
|
+
|
|
51
|
+
createOODAAgent({
|
|
52
|
+
agentId: "my-agent",
|
|
53
|
+
/* …other config… */
|
|
54
|
+
telemetry: createTelemetryBus({
|
|
55
|
+
sinks: [
|
|
56
|
+
stdoutTelemetrySink(),
|
|
57
|
+
localSqliteTelemetrySink(), // ~/.vauban/runs.db by default
|
|
58
|
+
],
|
|
59
|
+
}),
|
|
60
|
+
});
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Inspect locally via `sqlite3` or the upcoming `vauban-agent runs list` CLI.
|
|
64
|
+
|
|
65
|
+
### Mode 2 — Free Vauban CC SaaS
|
|
66
|
+
|
|
67
|
+
Adds remote backup + a hosted dashboard at `command.vauban.tech`.
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
pnpm add @vauban-org/cc-telemetry
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
```ts
|
|
74
|
+
import {
|
|
75
|
+
createOODAAgent,
|
|
76
|
+
createTelemetryBus,
|
|
77
|
+
localSqliteTelemetrySink,
|
|
78
|
+
} from "@vauban-org/agent-sdk";
|
|
79
|
+
import { commandCenterTelemetrySink } from "@vauban-org/cc-telemetry";
|
|
80
|
+
|
|
81
|
+
createOODAAgent({
|
|
82
|
+
agentId: "my-agent",
|
|
83
|
+
telemetry: createTelemetryBus({
|
|
84
|
+
sinks: [
|
|
85
|
+
localSqliteTelemetrySink(), // sovereign mirror
|
|
86
|
+
commandCenterTelemetrySink({ apiKey: process.env.VAUBAN_API_KEY! }),
|
|
87
|
+
],
|
|
88
|
+
}),
|
|
89
|
+
});
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Free tier policy : **1 000 runs / month + 7 day retention** (see
|
|
93
|
+
[ADR-ECO-039 §3](https://github.com/vauban-org/vauban-gouvernance/blob/main/governance/decisions/ADR-ECO-039-sdk-telemetry-port.md)).
|
|
94
|
+
Sign up at [`command.vauban.tech`](https://command.vauban.tech).
|
|
95
|
+
|
|
96
|
+
### Mode 3 — Tiered (Team / Pro / Sovereign)
|
|
97
|
+
|
|
98
|
+
Same code as Mode 2. The API key prefix (`vauban_team_*` / `vauban_pro_*` /
|
|
99
|
+
`vauban_sovereign_*`) determines server-side entitlement. Pro tier signs
|
|
100
|
+
each run with a Vauban Claim Algebra attestation ; Sovereign runs in a
|
|
101
|
+
TDX/SEV-SNP enclave with L3 Madara anchoring. See
|
|
102
|
+
[sinks/cc.md](sinks/cc.md#tiers).
|
|
103
|
+
|
|
104
|
+
### Mode 4 — Self-hosted Command Center
|
|
105
|
+
|
|
106
|
+
Compatible with the AGPL CC backend (per [ADR-ECO-014](https://github.com/vauban-org/vauban-gouvernance/blob/main/governance/decisions/ADR-ECO-014-cc-oss-release.md)).
|
|
107
|
+
|
|
108
|
+
```ts
|
|
109
|
+
commandCenterTelemetrySink({
|
|
110
|
+
apiKey: "internal",
|
|
111
|
+
baseUrl: "https://cc.myorg.internal",
|
|
112
|
+
});
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## Privacy guarantees
|
|
116
|
+
|
|
117
|
+
| # | Guarantee | Enforced by |
|
|
118
|
+
|---|---|---|
|
|
119
|
+
| 1 | Zero phone-home by default | No sinks configured = no network |
|
|
120
|
+
| 2 | Local sink always available | `localSqliteTelemetrySink` ships with SDK |
|
|
121
|
+
| 3 | PII never crosses sinks | `metadata` hashed unless `includePayloads: true` |
|
|
122
|
+
| 4 | Tenant isolation | RLS in CC backend, scoped Bearer keys |
|
|
123
|
+
| 5 | Audit log of active sinks | `vauban-agent telemetry status` (upcoming) |
|
|
124
|
+
| 6 | Sink failures never block agent | TelemetryBus isolates per-sink failures |
|
|
125
|
+
|
|
126
|
+
## Failure modes & guarantees
|
|
127
|
+
|
|
128
|
+
- **One sink crashes** → others continue. The agent loop is never blocked.
|
|
129
|
+
- **Network sink unreachable** → events queue locally up to `maxQueueDepth`
|
|
130
|
+
(default 1000), then drop-oldest with a Prometheus-friendly counter.
|
|
131
|
+
- **OOM / heap exceeded** → no retry storm ; the agent enters `skipped`
|
|
132
|
+
state with a `stopReason: "heap_exceeded:Xmb"` that surfaces in every
|
|
133
|
+
sink.
|
|
134
|
+
- **CC backend down** → SDK auto-retries 5xx with exponential backoff +
|
|
135
|
+
jitter. 4xx (auth, quota) are NOT retried (would only burn quota).
|
|
136
|
+
|
|
137
|
+
## Where it sits relative to Langfuse
|
|
138
|
+
|
|
139
|
+
Both coexist by design ([Brain entry 1b9ab97d](https://command.vauban.tech/brain/1b9ab97d)) :
|
|
140
|
+
|
|
141
|
+
| Layer | What | Tool |
|
|
142
|
+
|---|---|---|
|
|
143
|
+
| Token-level | Per LLM call, latency, tokens, cost | Langfuse self-host |
|
|
144
|
+
| **Run-level** | **Per OODA cycle, status, outcome** | **TelemetryPort (this module)** |
|
|
145
|
+
| Outcome-level | Business value, HITL, proof | CC `outcome` table + L3 anchor |
|
|
146
|
+
|
|
147
|
+
## Next steps
|
|
148
|
+
|
|
149
|
+
- [stdout sink](sinks/stdout.md) — dev visibility
|
|
150
|
+
- [SQLite sink](sinks/sqlite.md) — sovereign local mirror
|
|
151
|
+
- [OTLP sink](sinks/otlp.md) — push to any OpenTelemetry receiver
|
|
152
|
+
- [CC sink](sinks/cc.md) — Vauban Command Center (free → sovereign)
|
|
153
|
+
- [Privacy & spotlighting](privacy.md)
|
|
154
|
+
- [Migration 1.2 → 1.3](migration.md)
|