@stackbone/sdk 0.1.0-alpha.3 → 0.1.0-alpha.4

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.
@@ -3,6 +3,7 @@
3
3
  var promises = require('fs/promises');
4
4
  var os = require('os');
5
5
  var path = require('path');
6
+ var async_hooks = require('async_hooks');
6
7
  var crypto = require('crypto');
7
8
 
8
9
  var __defProp = Object.defineProperty;
@@ -10,6 +11,11 @@ var __name = (target, value) => __defProp(target, "name", { value, configurable:
10
11
 
11
12
  // package.json
12
13
  var version = "0.1.0-alpha.2";
14
+ var storage = new async_hooks.AsyncLocalStorage();
15
+ function getInvocationContext() {
16
+ return storage.getStore();
17
+ }
18
+ __name(getInvocationContext, "getInvocationContext");
13
19
 
14
20
  // src/observability/logger.ts
15
21
  var LOG_LEVELS = {
@@ -77,6 +83,14 @@ function buildLogger(opts) {
77
83
  if (typeof msg === "string") record.msg = msg;
78
84
  else if (typeof record.msg !== "string") record.msg = "";
79
85
  }
86
+ const ctx = getInvocationContext();
87
+ if (ctx) {
88
+ if (record.trace_id === void 0) record.trace_id = ctx.invocationId;
89
+ if (!record.run_id) record.run_id = ctx.runId;
90
+ if (record["handler"] === void 0 && ctx.handler !== void 0) {
91
+ record["handler"] = ctx.handler;
92
+ }
93
+ }
80
94
  opts.destination.write(record);
81
95
  }, "writeAt");
82
96
  const child = /* @__PURE__ */ __name((bindings) => buildLogger({
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../libs/sdk/package.json","../../../../libs/sdk/src/observability/logger.ts","../../../../libs/sdk/src/observability/run-steps-exporter.ts","../../../../libs/sdk/src/observability/aggregate-run-cost.ts"],"names":["LOG_LEVELS","trace","debug","info","warn","error","fatal","DEFAULT_BATCH_SIZE","DEFAULT_INTERVAL_MS","DEFAULT_HTTP_TIMEOUT_MS","createPlatformLogger","options","otelEndpoint","undefined","mode","baseBindings","run_id","runId","installationId","agentId","destination","OtlpHttpDestination","endpoint","resourceAttributes","httpTimeoutMs","flushBatchSize","flushIntervalMs","fetchImpl","JsonlFileDestination","runsDir","defaultRunsDir","appendFileImpl","mkdirImpl","now","Date","buildLogger","opts","writeAt","level","msgOrObj","msg","time","levelNumber","record","String","Object","assign","write","child","bindings","flush","close","path","appendFile","mkdir","inFlight","Promise","resolve","dirReady","p","d","recursive","line","JSON","stringify","then","dirname","process","stderr","Error","message","url","buffer","timer","closed","replace","fetch","push","length","armTimer","drained","splice","disarmTimer","post","catch","setTimeout","unref","clearTimeout","records","body","buildOtlpLogsBody","controller","AbortController","timeout","abort","resp","method","headers","signal","ok","text","status","slice","SDK_SCOPE","name","version","resourceLogs","resource","attributes","toOtlpAttributes","scopeLogs","scope","logRecords","map","toOtlpLogRecord","rest","timeUnixNano","severityNumber","severityText","stringValue","toOtlpAttributesFromUnknown","SEVERITY_TEXT_BY_LEVEL","fromEntries","entries","value","toUpperCase","attrs","key","out","Number","isInteger","intValue","doubleValue","boolValue","homedir","RUN_STEP_TYPES","STEP_TYPE_ATTRIBUTE","RUN_ID_ATTRIBUTE","NAME_PREFIX_MAP","RunStepsSpanProcessor","stepIdBySpanId","Map","batchSize","intervalMs","resolveStepType","newId","connectionString","ownsSql","sql","defaultStepTypeResolver","randomUUID","onStart","span","spanId","spanContext","has","set","onEnd","row","buildRow","forceFlush","shutdown","end","stepId","get","delete","readString","parentSpanId","parentSpanContext","parentStepId","startedAt","formatHrTime","startTime","finishedAt","endTime","durationMs","hrTimeToMs","duration","diffHrTime","isError","code","id","parent_step_id","type","payload","serialisablePayload","started_at","finished_at","duration_ms","writeBatch","finally","ensureSql","mod","default","rows","placeholders","params","base","join","unsafe","explicit","includes","pattern","test","hr","toISOString","seconds","nanos","Math","floor","start","SQL","aggregateRunCost","result","costEstimatedUsd","raw","cost_estimated_usd","num","isFinite"],"mappings":"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","file":"index.cjs","sourcesContent":["{\n \"name\": \"@stackbone/sdk\",\n \"version\": \"0.1.0-alpha.2\",\n \"license\": \"UNLICENSED\",\n \"description\": \"Official TypeScript SDK for Stackbone — the marketplace and managed runtime for containerized AI agents.\",\n \"type\": \"module\",\n \"sideEffects\": false,\n \"main\": \"./dist/index.cjs\",\n \"module\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"exports\": {\n \".\": {\n \"import\": {\n \"types\": \"./dist/index.d.ts\",\n \"default\": \"./dist/index.js\"\n },\n \"require\": {\n \"types\": \"./dist/index.d.cts\",\n \"default\": \"./dist/index.cjs\"\n }\n },\n \"./db\": {\n \"import\": {\n \"types\": \"./dist/db/index.d.ts\",\n \"default\": \"./dist/db/index.js\"\n },\n \"require\": {\n \"types\": \"./dist/db/index.d.cts\",\n \"default\": \"./dist/db/index.cjs\"\n }\n },\n \"./db/testing\": {\n \"import\": {\n \"types\": \"./dist/db/testing/index.d.ts\",\n \"default\": \"./dist/db/testing/index.js\"\n },\n \"require\": {\n \"types\": \"./dist/db/testing/index.d.cts\",\n \"default\": \"./dist/db/testing/index.cjs\"\n }\n },\n \"./observability\": {\n \"import\": {\n \"types\": \"./dist/observability/index.d.ts\",\n \"default\": \"./dist/observability/index.js\"\n },\n \"require\": {\n \"types\": \"./dist/observability/index.d.cts\",\n \"default\": \"./dist/observability/index.cjs\"\n }\n },\n \"./queues/types\": {\n \"import\": {\n \"types\": \"./dist/queues/types.d.ts\",\n \"default\": \"./dist/queues/types.js\"\n },\n \"require\": {\n \"types\": \"./dist/queues/types.d.cts\",\n \"default\": \"./dist/queues/types.cjs\"\n }\n },\n \"./rag/migrations\": {\n \"import\": {\n \"types\": \"./dist/rag/migrations/index.d.ts\",\n \"default\": \"./dist/rag/migrations/index.js\"\n },\n \"require\": {\n \"types\": \"./dist/rag/migrations/index.d.cts\",\n \"default\": \"./dist/rag/migrations/index.cjs\"\n }\n },\n \"./rag/schema\": {\n \"import\": {\n \"types\": \"./dist/rag/schema.d.ts\",\n \"default\": \"./dist/rag/schema.js\"\n },\n \"require\": {\n \"types\": \"./dist/rag/schema.d.cts\",\n \"default\": \"./dist/rag/schema.cjs\"\n }\n },\n \"./package.json\": \"./package.json\"\n },\n \"files\": [\n \"dist\",\n \"README.md\",\n \"CHANGELOG.md\"\n ],\n \"publishConfig\": {\n \"access\": \"public\"\n },\n \"engines\": {\n \"node\": \">=24\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/stackbone/stackbone.git\",\n \"directory\": \"libs/sdk\"\n },\n \"homepage\": \"https://stackbone.ai\",\n \"bugs\": {\n \"url\": \"https://github.com/stackbone/stackbone/issues\"\n },\n \"keywords\": [\n \"stackbone\",\n \"ai-agents\",\n \"agent-sdk\",\n \"containerized-agents\",\n \"openrouter\",\n \"rag\",\n \"pgvector\",\n \"drizzle\",\n \"openai\",\n \"postgres\"\n ],\n \"dependencies\": {\n \"@aws-sdk/client-s3\": \"^3.1038.0\",\n \"@aws-sdk/s3-request-presigner\": \"^3.1038.0\",\n \"@stackbone/validators\": \"workspace:*\",\n \"@testcontainers/postgresql\": \"^11.14.0\",\n \"drizzle-orm\": \"0.45.2\",\n \"openai\": \"^4.104.0\",\n \"postgres\": \"3.4.9\",\n \"unpdf\": \"^0.12.1\",\n \"zod\": \"*\"\n }\n}\n","import { appendFile, mkdir } from 'node:fs/promises';\nimport { homedir } from 'node:os';\nimport { dirname, resolve } from 'node:path';\n\nimport { version as SDK_VERSION } from '../../package.json';\n\n// Numeric levels match Pino so JSONL files produced in local mode work with\n// `pino-pretty` and other Pino-aware tooling without translation.\nexport const LOG_LEVELS = {\n trace: 10,\n debug: 20,\n info: 30,\n warn: 40,\n error: 50,\n fatal: 60,\n} as const;\n\nexport type LogLevelName = keyof typeof LOG_LEVELS;\nexport type LogLevelNumber = (typeof LOG_LEVELS)[LogLevelName];\n\nexport interface LogRecord {\n /** Pino-style numeric level. */\n level: LogLevelNumber;\n /** Epoch milliseconds. Pino uses `time` as a number. */\n time: number;\n msg: string;\n run_id: string;\n trace_id?: string;\n installation_id?: string;\n agent_id?: string;\n [key: string]: unknown;\n}\n\nexport interface PlatformLoggerOptions {\n runId: string;\n installationId?: string | undefined;\n agentId?: string | undefined;\n /**\n * When set (cloud), logs are batched and POSTed to `<endpoint>/v1/logs` as\n * OTLP/HTTP/JSON. When unset (local), logs are appended to\n * `<runsDir>/<runId>.jsonl`. Falls back to `OTEL_EXPORTER_OTLP_ENDPOINT`.\n */\n otelEndpoint?: string | undefined;\n /** Local-only: directory where JSONL files live. Defaults to `~/.stackbone/dev/runs`. */\n runsDir?: string | undefined;\n /** Cloud-only: extra OTel resource attributes to send with every batch. */\n resourceAttributes?: Record<string, string> | undefined;\n /** Cloud-only: HTTP timeout per OTLP POST in ms. Defaults to 5_000. */\n httpTimeoutMs?: number | undefined;\n /** Flush trigger by buffer size. Defaults to 50. */\n flushBatchSize?: number | undefined;\n /** Flush trigger by elapsed time (ms). Defaults to 1_000. */\n flushIntervalMs?: number | undefined;\n /** Test seam — fetch implementation. Defaults to global `fetch`. */\n fetchImpl?: typeof fetch | undefined;\n /** Test seam — `fs.appendFile`-shaped sink the local destination uses. */\n appendFileImpl?: ((path: string, data: string) => Promise<void>) | undefined;\n /** Test seam — `fs.mkdir`-shaped helper the local destination uses. */\n mkdirImpl?: ((path: string) => Promise<void>) | undefined;\n /** Test seam — clock for `time` field. Defaults to `Date.now`. */\n now?: (() => number) | undefined;\n /** Override mode resolution (skips the env detection). */\n mode?: PlatformLoggerMode | undefined;\n}\n\nexport type PlatformLoggerMode = 'local' | 'cloud';\n\nexport interface PinoLike {\n trace(msgOrObj: unknown, msg?: string): void;\n debug(msgOrObj: unknown, msg?: string): void;\n info(msgOrObj: unknown, msg?: string): void;\n warn(msgOrObj: unknown, msg?: string): void;\n error(msgOrObj: unknown, msg?: string): void;\n fatal(msgOrObj: unknown, msg?: string): void;\n}\n\nexport interface PlatformLogger extends PinoLike {\n readonly mode: PlatformLoggerMode;\n /** Bind extra fields and return a child logger sharing the same destination. */\n child(bindings: Record<string, unknown>): PlatformLogger;\n /** Force-flush pending writes (close file handle or POST OTLP batch). */\n flush(): Promise<void>;\n /** Stop accepting writes and release resources. */\n close(): Promise<void>;\n}\n\ninterface Destination {\n write(record: LogRecord): void;\n flush(): Promise<void>;\n close(): Promise<void>;\n}\n\nconst DEFAULT_BATCH_SIZE = 50;\nconst DEFAULT_INTERVAL_MS = 1_000;\nconst DEFAULT_HTTP_TIMEOUT_MS = 5_000;\n\n/**\n * Creates a Pino-aligned logger that writes JSONL to disk in local mode and\n * batches OTLP/HTTP/JSON log records to an OTel collector in cloud mode. Mode\n * is resolved from `OTEL_EXPORTER_OTLP_ENDPOINT` or the explicit override.\n */\nexport function createPlatformLogger(options: PlatformLoggerOptions): PlatformLogger {\n // The resolver is the single seam that reads `OTEL_EXPORTER_OTLP_ENDPOINT`\n // — callers building a logger through `client.observability.logger(...)`\n // already get the value plumbed in from `ResolvedConfig`. The `undefined`\n // here means \"no `otelEndpoint` ⇒ local JSONL mode\" (matches the docstring).\n const otelEndpoint = options.otelEndpoint ?? undefined;\n const mode: PlatformLoggerMode = options.mode ?? (otelEndpoint ? 'cloud' : 'local');\n\n const baseBindings: Record<string, unknown> = { run_id: options.runId };\n if (options.installationId !== undefined)\n baseBindings['installation_id'] = options.installationId;\n if (options.agentId !== undefined) baseBindings['agent_id'] = options.agentId;\n\n const destination: Destination =\n mode === 'cloud'\n ? new OtlpHttpDestination({\n endpoint: otelEndpoint ?? '',\n resourceAttributes: options.resourceAttributes ?? {},\n httpTimeoutMs: options.httpTimeoutMs ?? DEFAULT_HTTP_TIMEOUT_MS,\n flushBatchSize: options.flushBatchSize ?? DEFAULT_BATCH_SIZE,\n flushIntervalMs: options.flushIntervalMs ?? DEFAULT_INTERVAL_MS,\n ...(options.fetchImpl !== undefined ? { fetchImpl: options.fetchImpl } : {}),\n })\n : new JsonlFileDestination({\n runId: options.runId,\n runsDir: options.runsDir ?? defaultRunsDir(),\n ...(options.appendFileImpl !== undefined\n ? { appendFileImpl: options.appendFileImpl }\n : {}),\n ...(options.mkdirImpl !== undefined ? { mkdirImpl: options.mkdirImpl } : {}),\n });\n\n const now = options.now ?? Date.now;\n return buildLogger({ destination, baseBindings, mode, now });\n}\n\ninterface LoggerBuildOptions {\n destination: Destination;\n baseBindings: Record<string, unknown>;\n mode: PlatformLoggerMode;\n now: () => number;\n}\n\nfunction buildLogger(opts: LoggerBuildOptions): PlatformLogger {\n const writeAt = (level: LogLevelName, msgOrObj: unknown, msg?: string): void => {\n const time = opts.now();\n const levelNumber = LOG_LEVELS[level];\n const record: LogRecord = {\n level: levelNumber,\n time,\n msg: '',\n run_id: String(opts.baseBindings['run_id'] ?? ''),\n ...opts.baseBindings,\n };\n if (typeof msgOrObj === 'string') {\n record.msg = msgOrObj;\n } else if (msgOrObj && typeof msgOrObj === 'object') {\n Object.assign(record, msgOrObj);\n if (typeof msg === 'string') record.msg = msg;\n else if (typeof record.msg !== 'string') record.msg = '';\n }\n opts.destination.write(record);\n };\n\n const child = (bindings: Record<string, unknown>): PlatformLogger =>\n buildLogger({ ...opts, baseBindings: { ...opts.baseBindings, ...bindings } });\n\n return {\n mode: opts.mode,\n trace: (msgOrObj, msg) => writeAt('trace', msgOrObj, msg),\n debug: (msgOrObj, msg) => writeAt('debug', msgOrObj, msg),\n info: (msgOrObj, msg) => writeAt('info', msgOrObj, msg),\n warn: (msgOrObj, msg) => writeAt('warn', msgOrObj, msg),\n error: (msgOrObj, msg) => writeAt('error', msgOrObj, msg),\n fatal: (msgOrObj, msg) => writeAt('fatal', msgOrObj, msg),\n child,\n flush: () => opts.destination.flush(),\n close: () => opts.destination.close(),\n };\n}\n\ninterface JsonlFileDestinationOptions {\n runId: string;\n runsDir: string;\n appendFileImpl?: (path: string, data: string) => Promise<void>;\n mkdirImpl?: (path: string) => Promise<void>;\n}\n\nclass JsonlFileDestination implements Destination {\n private readonly path: string;\n private readonly appendFile: (path: string, data: string) => Promise<void>;\n private readonly mkdir: (path: string) => Promise<void>;\n private inFlight: Promise<void> = Promise.resolve();\n private dirReady = false;\n\n constructor(opts: JsonlFileDestinationOptions) {\n this.path = resolve(opts.runsDir, `${opts.runId}.jsonl`);\n this.appendFile = opts.appendFileImpl ?? ((p, d) => appendFile(p, d, 'utf8'));\n this.mkdir =\n opts.mkdirImpl ??\n (async (p) => {\n await mkdir(p, { recursive: true });\n });\n }\n\n write(record: LogRecord): void {\n const line = `${JSON.stringify(record)}\\n`;\n this.inFlight = this.inFlight.then(async () => {\n if (!this.dirReady) {\n await this.mkdir(dirname(this.path));\n this.dirReady = true;\n }\n try {\n await this.appendFile(this.path, line);\n } catch (error) {\n process.stderr.write(\n `[stackbone/sdk] PlatformLogger JSONL write failed: ${error instanceof Error ? error.message : String(error)}\\n`,\n );\n }\n });\n }\n\n async flush(): Promise<void> {\n await this.inFlight;\n }\n\n async close(): Promise<void> {\n await this.flush();\n }\n}\n\ninterface OtlpHttpDestinationOptions {\n endpoint: string;\n resourceAttributes: Record<string, string>;\n httpTimeoutMs: number;\n flushBatchSize: number;\n flushIntervalMs: number;\n fetchImpl?: typeof fetch;\n}\n\n// OTLP/HTTP/JSON spec: OpenTelemetry Logs Data Model §B.1. Failures log to\n// stderr — telemetry must never block agent execution.\nclass OtlpHttpDestination implements Destination {\n private readonly url: string;\n private readonly resourceAttributes: Record<string, string>;\n private readonly httpTimeoutMs: number;\n private readonly flushBatchSize: number;\n private readonly flushIntervalMs: number;\n private readonly fetchImpl: typeof fetch;\n private buffer: LogRecord[] = [];\n private timer: NodeJS.Timeout | null = null;\n private inFlight: Promise<void> = Promise.resolve();\n private closed = false;\n\n constructor(opts: OtlpHttpDestinationOptions) {\n this.url = `${opts.endpoint.replace(/\\/+$/, '')}/v1/logs`;\n this.resourceAttributes = opts.resourceAttributes;\n this.httpTimeoutMs = opts.httpTimeoutMs;\n this.flushBatchSize = opts.flushBatchSize;\n this.flushIntervalMs = opts.flushIntervalMs;\n this.fetchImpl = opts.fetchImpl ?? fetch;\n }\n\n write(record: LogRecord): void {\n if (this.closed) return;\n this.buffer.push(record);\n if (this.buffer.length >= this.flushBatchSize) {\n void this.flush();\n } else {\n this.armTimer();\n }\n }\n\n async flush(): Promise<void> {\n await this.inFlight;\n if (this.buffer.length === 0) return;\n const drained = this.buffer.splice(0, this.buffer.length);\n this.disarmTimer();\n this.inFlight = this.post(drained).catch((error) => {\n process.stderr.write(\n `[stackbone/sdk] PlatformLogger OTLP POST failed: ${error instanceof Error ? error.message : String(error)}\\n`,\n );\n });\n await this.inFlight;\n }\n\n async close(): Promise<void> {\n this.closed = true;\n await this.flush();\n }\n\n private armTimer(): void {\n if (this.timer) return;\n this.timer = setTimeout(() => {\n this.timer = null;\n void this.flush();\n }, this.flushIntervalMs);\n this.timer.unref?.();\n }\n\n private disarmTimer(): void {\n if (this.timer) {\n clearTimeout(this.timer);\n this.timer = null;\n }\n }\n\n private async post(records: LogRecord[]): Promise<void> {\n const body = JSON.stringify(buildOtlpLogsBody(records, this.resourceAttributes));\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), this.httpTimeoutMs);\n try {\n const resp = await this.fetchImpl(this.url, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body,\n signal: controller.signal,\n });\n if (!resp.ok) {\n const text = await resp.text().catch(() => '');\n throw new Error(`HTTP ${resp.status}${text ? `: ${text.slice(0, 200)}` : ''}`);\n }\n } finally {\n clearTimeout(timeout);\n }\n }\n}\n\ninterface OtlpKeyValue {\n key: string;\n value:\n | { stringValue: string }\n | { intValue: string }\n | { doubleValue: number }\n | { boolValue: boolean };\n}\n\ninterface OtlpResource {\n attributes: OtlpKeyValue[];\n}\n\ninterface OtlpLogRecord {\n timeUnixNano: string;\n severityNumber: number;\n severityText: string;\n body: { stringValue: string };\n attributes: OtlpKeyValue[];\n}\n\ninterface OtlpLogsBody {\n resourceLogs: Array<{\n resource: OtlpResource;\n scopeLogs: Array<{\n scope: { name: string; version: string };\n logRecords: OtlpLogRecord[];\n }>;\n }>;\n}\n\nconst SDK_SCOPE = { name: '@stackbone/sdk', version: SDK_VERSION };\n\nfunction buildOtlpLogsBody(\n records: LogRecord[],\n resourceAttributes: Record<string, string>,\n): OtlpLogsBody {\n return {\n resourceLogs: [\n {\n resource: { attributes: toOtlpAttributes(resourceAttributes) },\n scopeLogs: [\n {\n scope: SDK_SCOPE,\n logRecords: records.map(toOtlpLogRecord),\n },\n ],\n },\n ],\n };\n}\n\nfunction toOtlpLogRecord(record: LogRecord): OtlpLogRecord {\n const { level, time, msg, ...rest } = record;\n return {\n timeUnixNano: `${time * 1_000_000}`,\n severityNumber: level,\n severityText: severityText(level),\n body: { stringValue: msg },\n attributes: toOtlpAttributesFromUnknown(rest),\n };\n}\n\nconst SEVERITY_TEXT_BY_LEVEL: Record<number, string> = Object.fromEntries(\n Object.entries(LOG_LEVELS).map(([name, value]) => [value, name.toUpperCase()]),\n);\n\nfunction severityText(level: number): string {\n return SEVERITY_TEXT_BY_LEVEL[level] ?? 'INFO';\n}\n\nfunction toOtlpAttributes(attrs: Record<string, string>): OtlpKeyValue[] {\n return Object.entries(attrs).map(([key, value]) => ({\n key,\n value: { stringValue: value },\n }));\n}\n\nfunction toOtlpAttributesFromUnknown(attrs: Record<string, unknown>): OtlpKeyValue[] {\n const out: OtlpKeyValue[] = [];\n for (const [key, value] of Object.entries(attrs)) {\n if (value === null || value === undefined) continue;\n if (typeof value === 'string') {\n out.push({ key, value: { stringValue: value } });\n } else if (typeof value === 'number') {\n if (Number.isInteger(value)) out.push({ key, value: { intValue: String(value) } });\n else out.push({ key, value: { doubleValue: value } });\n } else if (typeof value === 'boolean') {\n out.push({ key, value: { boolValue: value } });\n } else {\n out.push({ key, value: { stringValue: JSON.stringify(value) } });\n }\n }\n return out;\n}\n\nexport function defaultRunsDir(): string {\n return resolve(homedir(), '.stackbone', 'dev', 'runs');\n}\n","import { randomUUID } from 'node:crypto';\n\n// Canonical step types stored in `stackbone_platform.run_steps.type`. The list\n// has to stay in sync with the CHECK constraint in\n// `libs/platform-schema/src/migrations/0001_runs.sql`. Exported so agents\n// can discover the closed set without reaching into the migration file.\nexport const RUN_STEP_TYPES = [\n 'agent',\n 'llm_call',\n 'db_query',\n 'http_fetch',\n 'queue_publish',\n 'hitl_pause',\n 'tool_call',\n 'rag_query',\n 'storage_op',\n] as const;\nexport type RunStepType = (typeof RUN_STEP_TYPES)[number];\n\n// Span attribute we read first to pin a step type explicitly. When absent,\n// the resolver falls back to a span.name prefix mapping.\nexport const STEP_TYPE_ATTRIBUTE = 'stackbone.step.type';\n\n// Span attribute that carries the active run id. The processor drops spans\n// without it because `stackbone_platform.run_steps.run_id` is NOT NULL — there\n// is no useful row we could write otherwise.\nexport const RUN_ID_ATTRIBUTE = 'stackbone.run.id';\n\nconst NAME_PREFIX_MAP: ReadonlyArray<readonly [RegExp, RunStepType]> = [\n [/^stackbone\\.ai\\./, 'llm_call'],\n [/^stackbone\\.db\\./, 'db_query'],\n [/^stackbone\\.http\\./, 'http_fetch'],\n [/^stackbone\\.queues\\./, 'queue_publish'],\n [/^stackbone\\.approval\\./, 'hitl_pause'],\n [/^stackbone\\.tool\\./, 'tool_call'],\n [/^stackbone\\.rag\\./, 'rag_query'],\n [/^stackbone\\.storage\\./, 'storage_op'],\n];\n\n/**\n * Minimal duck-typed view of an OpenTelemetry `ReadableSpan`. We mirror the\n * shape the OTel SDK exposes on `@opentelemetry/sdk-trace-base` rather than\n * importing the package so `@stackbone/sdk` doesn't pull the OTel runtime into\n * every agent that doesn't enable Studio. Agents wire the processor with\n * `provider.addSpanProcessor(new RunStepsSpanProcessor(...))` and the\n * structural match satisfies TypeScript.\n */\nexport interface SpanContextLike {\n spanId: string;\n traceId: string;\n}\n\nexport interface ReadableSpanLike {\n spanContext(): SpanContextLike;\n parentSpanContext?: SpanContextLike | undefined;\n parentSpanId?: string | undefined;\n name: string;\n attributes: Record<string, unknown>;\n status?: { code: number; message?: string } | undefined;\n startTime?: [number, number] | undefined;\n endTime?: [number, number] | undefined;\n duration?: [number, number] | undefined;\n}\n\nexport interface PostgresLike {\n unsafe(query: string, params?: unknown[]): Promise<unknown>;\n end?(): Promise<void>;\n}\n\nexport interface RunStepsSpanProcessorOptions {\n /**\n * Postgres connection string of the install (local emulator at :5433 in\n * dev, Neon TCP/HTTP URL in cloud). Falls back to `DATABASE_URL`.\n */\n connectionString?: string | undefined;\n /** Flush trigger by buffer size. Defaults to 50. */\n flushBatchSize?: number | undefined;\n /** Flush trigger by elapsed time (ms). Defaults to 500. */\n flushIntervalMs?: number | undefined;\n /** Override how a span maps to a step type. */\n resolveStepType?: ((span: ReadableSpanLike) => RunStepType) | undefined;\n /** Test seam — inject a postgres-js-compatible client. */\n sql?: PostgresLike | undefined;\n /** Test seam — deterministic UUID generator. */\n newId?: (() => string) | undefined;\n}\n\ninterface BufferedRow {\n id: string;\n run_id: string;\n parent_step_id: string | null;\n type: RunStepType;\n name: string;\n status: 'ok' | 'error';\n payload: Record<string, unknown>;\n error: { message: string } | null;\n started_at: string;\n finished_at: string;\n duration_ms: number;\n}\n\nconst DEFAULT_BATCH_SIZE = 50;\nconst DEFAULT_INTERVAL_MS = 500;\n\n/**\n * Materialises every OTel span produced by the agent into a row of\n * `stackbone_platform.run_steps`. Designed to coexist with the OTLP exporter:\n * cloud builds register both processors so Postgres feeds Studio (paridad\n * con local) and Tempo feeds Platform Ops with retention/aggregation. If a\n * write fails the processor logs to stderr and keeps accepting spans —\n * observability is never load-bearing for agent execution.\n *\n * Spec: docs/arquitectura/specs/stackbone-agent-protocol-v1.md §6.3\n * ADR: docs/arquitectura/decisiones/2026-05-03-stackbone-studio-datapath-y-scope-mvp.md §D9\n */\nexport class RunStepsSpanProcessor {\n private readonly buffer: BufferedRow[] = [];\n private readonly stepIdBySpanId = new Map<string, string>();\n private readonly batchSize: number;\n private readonly intervalMs: number;\n private readonly resolveStepType: (span: ReadableSpanLike) => RunStepType;\n private readonly newId: () => string;\n private readonly connectionString: string | undefined;\n private readonly ownsSql: boolean;\n private sql: PostgresLike | null;\n private timer: NodeJS.Timeout | null = null;\n private inFlight: Promise<void> | null = null;\n\n constructor(options: RunStepsSpanProcessorOptions = {}) {\n this.batchSize = options.flushBatchSize ?? DEFAULT_BATCH_SIZE;\n this.intervalMs = options.flushIntervalMs ?? DEFAULT_INTERVAL_MS;\n this.resolveStepType = options.resolveStepType ?? defaultStepTypeResolver;\n this.newId = options.newId ?? randomUUID;\n // The resolver owns reading `STACKBONE_POSTGRES_URL` — callers\n // building the processor through `client.observability.spanProcessor()`\n // already get the value plumbed in from `ResolvedConfig`. Direct\n // constructions on the `@stackbone/sdk/observability` subpath must\n // supply `connectionString` themselves.\n this.connectionString = options.connectionString;\n if (options.sql) {\n this.sql = options.sql;\n this.ownsSql = false;\n } else {\n this.sql = null;\n this.ownsSql = true;\n }\n }\n\n // OTel calls onStart for the parent before any child, and onEnd for\n // children before the parent. Reserving the UUID up-front lets the child's\n // onEnd resolve `parent_step_id` synchronously — the alternative (looking\n // up the parent at write time) would race the buffer flush.\n onStart(span: ReadableSpanLike): void {\n const spanId = span.spanContext().spanId;\n if (!this.stepIdBySpanId.has(spanId)) {\n this.stepIdBySpanId.set(spanId, this.newId());\n }\n }\n\n onEnd(span: ReadableSpanLike): void {\n const row = this.buildRow(span);\n if (!row) return;\n this.buffer.push(row);\n if (this.buffer.length >= this.batchSize) {\n void this.flush();\n } else {\n this.armTimer();\n }\n }\n\n async forceFlush(): Promise<void> {\n await this.flush();\n }\n\n async shutdown(): Promise<void> {\n this.disarmTimer();\n await this.flush();\n if (this.ownsSql && this.sql?.end) {\n await this.sql.end().catch(() => undefined);\n }\n }\n\n private buildRow(span: ReadableSpanLike): BufferedRow | null {\n const spanId = span.spanContext().spanId;\n // Always release the reservation from `onStart`, even when we drop the\n // row for lack of `run_id` — otherwise spans the SDK never persists\n // accumulate in the map.\n const stepId = this.stepIdBySpanId.get(spanId) ?? this.newId();\n this.stepIdBySpanId.delete(spanId);\n\n const runId = readString(span.attributes[RUN_ID_ATTRIBUTE]);\n if (!runId) return null;\n\n const parentSpanId = span.parentSpanContext?.spanId ?? span.parentSpanId ?? null;\n // Parents end after children, so the parent's UUID is still in the map\n // when the child's onEnd runs. Once the parent ends and gets removed the\n // child rows already reference it via `parent_step_id`.\n const parentStepId = parentSpanId ? (this.stepIdBySpanId.get(parentSpanId) ?? null) : null;\n\n const startedAt = formatHrTime(span.startTime);\n const finishedAt = formatHrTime(span.endTime ?? span.startTime);\n const durationMs = hrTimeToMs(span.duration ?? diffHrTime(span.endTime, span.startTime));\n\n const isError = span.status?.code === 2;\n\n return {\n id: stepId,\n run_id: runId,\n parent_step_id: parentStepId,\n type: this.resolveStepType(span),\n name: span.name,\n status: isError ? 'error' : 'ok',\n payload: serialisablePayload(span.attributes),\n error: isError ? { message: span.status?.message ?? 'span ended with ERROR status' } : null,\n started_at: startedAt,\n finished_at: finishedAt,\n duration_ms: durationMs,\n };\n }\n\n private armTimer(): void {\n if (this.timer) return;\n this.timer = setTimeout(() => {\n this.timer = null;\n void this.flush();\n }, this.intervalMs);\n // Don't keep the Node process alive just for the flush timer.\n this.timer.unref?.();\n }\n\n private disarmTimer(): void {\n if (this.timer) {\n clearTimeout(this.timer);\n this.timer = null;\n }\n }\n\n private async flush(): Promise<void> {\n if (this.inFlight) {\n await this.inFlight;\n }\n if (this.buffer.length === 0) return;\n const drained = this.buffer.splice(0, this.buffer.length);\n this.disarmTimer();\n this.inFlight = this.writeBatch(drained).finally(() => {\n this.inFlight = null;\n });\n await this.inFlight;\n }\n\n private async ensureSql(): Promise<PostgresLike | null> {\n if (this.sql) return this.sql;\n if (!this.connectionString) return null;\n // Lazy import — agents that never enable Studio don't pay the cost of\n // wiring a Postgres connection at boot.\n const mod = (await import('postgres')) as { default: (url: string) => PostgresLike };\n this.sql = mod.default(this.connectionString);\n return this.sql;\n }\n\n private async writeBatch(rows: BufferedRow[]): Promise<void> {\n try {\n const sql = await this.ensureSql();\n if (!sql) {\n process.stderr.write(\n '[stackbone/sdk] RunStepsSpanProcessor dropped batch: no DATABASE_URL configured.\\n',\n );\n return;\n }\n const placeholders: string[] = [];\n const params: unknown[] = [];\n for (const row of rows) {\n const base = params.length;\n placeholders.push(\n `($${base + 1}::uuid, $${base + 2}::uuid, $${base + 3}::uuid, $${base + 4}, $${base + 5}, $${base + 6}, $${base + 7}::jsonb, $${base + 8}::jsonb, $${base + 9}::timestamptz, $${base + 10}::timestamptz, $${base + 11}::int)`,\n );\n params.push(\n row.id,\n row.run_id,\n row.parent_step_id,\n row.type,\n row.name,\n row.status,\n JSON.stringify(row.payload),\n row.error ? JSON.stringify(row.error) : null,\n row.started_at,\n row.finished_at,\n row.duration_ms,\n );\n }\n const text = `INSERT INTO stackbone_platform.run_steps (\n id, run_id, parent_step_id, type, name, status, payload, error,\n started_at, finished_at, duration_ms\n ) VALUES ${placeholders.join(', ')}`;\n await sql.unsafe(text, params);\n } catch (error) {\n process.stderr.write(\n `[stackbone/sdk] RunStepsSpanProcessor write failed: ${error instanceof Error ? error.message : String(error)}\\n`,\n );\n }\n }\n}\n\nconst defaultStepTypeResolver = (span: ReadableSpanLike): RunStepType => {\n const explicit = readString(span.attributes[STEP_TYPE_ATTRIBUTE]);\n if (explicit && (RUN_STEP_TYPES as readonly string[]).includes(explicit)) {\n return explicit as RunStepType;\n }\n for (const [pattern, type] of NAME_PREFIX_MAP) {\n if (pattern.test(span.name)) return type;\n }\n return 'agent';\n};\n\nconst readString = (value: unknown): string | undefined =>\n typeof value === 'string' && value.length > 0 ? value : undefined;\n\nconst formatHrTime = (hr?: [number, number]): string =>\n new Date(hr ? hrTimeToMs(hr) : Date.now()).toISOString();\n\nconst hrTimeToMs = (hr?: [number, number]): number => {\n if (!hr) return 0;\n const [seconds, nanos] = hr;\n return seconds * 1_000 + Math.floor(nanos / 1_000_000);\n};\n\nconst diffHrTime = (\n end?: [number, number],\n start?: [number, number],\n): [number, number] | undefined => {\n if (!end || !start) return undefined;\n const seconds = end[0] - start[0];\n const nanos = end[1] - start[1];\n return [seconds, nanos];\n};\n\nconst serialisablePayload = (attributes: Record<string, unknown>): Record<string, unknown> => {\n const out: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(attributes)) {\n if (key === RUN_ID_ATTRIBUTE) continue;\n if (key === STEP_TYPE_ATTRIBUTE) continue;\n out[key] = value;\n }\n return out;\n};\n","import type { PostgresLike } from './run-steps-exporter';\n\n// Spans without a `cost_usd` attribute (unknown model / OpenRouter response\n// without the cost header) contribute 0 — observability is best-effort and\n// must not fail the run on missing telemetry.\n\nexport interface AggregateRunCostOptions {\n sql: PostgresLike;\n}\n\nexport interface AggregateRunCostResult {\n costEstimatedUsd: number;\n}\n\ninterface AggregatedRow {\n cost_estimated_usd: string | number | null;\n}\n\nconst SQL = `WITH llm_costs AS (\n SELECT COALESCE(SUM((payload->>'cost_usd')::numeric), 0) AS total\n FROM stackbone_platform.run_steps\n WHERE run_id = $1::uuid\n AND type = 'llm_call'\n )\n UPDATE stackbone_platform.runs\n SET cost_estimated_usd = (SELECT total FROM llm_costs)\n WHERE id = $1::uuid\n RETURNING cost_estimated_usd`;\n\nexport async function aggregateRunCost(\n runId: string,\n options: AggregateRunCostOptions,\n): Promise<AggregateRunCostResult> {\n const result = (await options.sql.unsafe(SQL, [runId])) as AggregatedRow[];\n const row = result[0];\n if (!row) {\n return { costEstimatedUsd: 0 };\n }\n // postgres-js returns numerics as strings to preserve precision; coerce\n // to a Number on the way out so callers don't need to know.\n const raw = row.cost_estimated_usd;\n if (raw === null || raw === undefined) return { costEstimatedUsd: 0 };\n const num = typeof raw === 'string' ? Number(raw) : raw;\n return { costEstimatedUsd: Number.isFinite(num) ? num : 0 };\n}\n"]}
1
+ {"version":3,"sources":["../../../../libs/sdk/package.json","../../../../libs/sdk/src/runtime/invocation-context.ts","../../../../libs/sdk/src/observability/logger.ts","../../../../libs/sdk/src/observability/run-steps-exporter.ts","../../../../libs/sdk/src/observability/aggregate-run-cost.ts"],"names":["storage","AsyncLocalStorage","getInvocationContext","getStore","LOG_LEVELS","trace","debug","info","warn","error","fatal","DEFAULT_BATCH_SIZE","DEFAULT_INTERVAL_MS","DEFAULT_HTTP_TIMEOUT_MS","createPlatformLogger","options","otelEndpoint","undefined","mode","baseBindings","run_id","runId","installationId","agentId","destination","OtlpHttpDestination","endpoint","resourceAttributes","httpTimeoutMs","flushBatchSize","flushIntervalMs","fetchImpl","JsonlFileDestination","runsDir","defaultRunsDir","appendFileImpl","mkdirImpl","now","Date","buildLogger","opts","writeAt","level","msgOrObj","msg","time","levelNumber","record","String","Object","assign","ctx","trace_id","invocationId","handler","write","child","bindings","flush","close","path","appendFile","mkdir","inFlight","Promise","resolve","dirReady","p","d","recursive","line","JSON","stringify","then","dirname","process","stderr","Error","message","url","buffer","timer","closed","replace","fetch","push","length","armTimer","drained","splice","disarmTimer","post","catch","setTimeout","unref","clearTimeout","records","body","buildOtlpLogsBody","controller","AbortController","timeout","abort","resp","method","headers","signal","ok","text","status","slice","SDK_SCOPE","name","version","resourceLogs","resource","attributes","toOtlpAttributes","scopeLogs","scope","logRecords","map","toOtlpLogRecord","rest","timeUnixNano","severityNumber","severityText","stringValue","toOtlpAttributesFromUnknown","SEVERITY_TEXT_BY_LEVEL","fromEntries","entries","value","toUpperCase","attrs","key","out","Number","isInteger","intValue","doubleValue","boolValue","homedir","RUN_STEP_TYPES","STEP_TYPE_ATTRIBUTE","RUN_ID_ATTRIBUTE","NAME_PREFIX_MAP","RunStepsSpanProcessor","stepIdBySpanId","Map","batchSize","intervalMs","resolveStepType","newId","connectionString","ownsSql","sql","defaultStepTypeResolver","randomUUID","onStart","span","spanId","spanContext","has","set","onEnd","row","buildRow","forceFlush","shutdown","end","stepId","get","delete","readString","parentSpanId","parentSpanContext","parentStepId","startedAt","formatHrTime","startTime","finishedAt","endTime","durationMs","hrTimeToMs","duration","diffHrTime","isError","code","id","parent_step_id","type","payload","serialisablePayload","started_at","finished_at","duration_ms","writeBatch","finally","ensureSql","mod","default","rows","placeholders","params","base","join","unsafe","explicit","includes","pattern","test","hr","toISOString","seconds","nanos","Math","floor","start","SQL","aggregateRunCost","result","costEstimatedUsd","raw","cost_estimated_usd","num","isFinite"],"mappings":"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","file":"index.cjs","sourcesContent":["{\n \"name\": \"@stackbone/sdk\",\n \"version\": \"0.1.0-alpha.2\",\n \"license\": \"UNLICENSED\",\n \"description\": \"Official TypeScript SDK for Stackbone — the marketplace and managed runtime for containerized AI agents.\",\n \"type\": \"module\",\n \"sideEffects\": false,\n \"main\": \"./dist/index.cjs\",\n \"module\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"exports\": {\n \".\": {\n \"import\": {\n \"types\": \"./dist/index.d.ts\",\n \"default\": \"./dist/index.js\"\n },\n \"require\": {\n \"types\": \"./dist/index.d.cts\",\n \"default\": \"./dist/index.cjs\"\n }\n },\n \"./db\": {\n \"import\": {\n \"types\": \"./dist/db/index.d.ts\",\n \"default\": \"./dist/db/index.js\"\n },\n \"require\": {\n \"types\": \"./dist/db/index.d.cts\",\n \"default\": \"./dist/db/index.cjs\"\n }\n },\n \"./db/testing\": {\n \"import\": {\n \"types\": \"./dist/db/testing/index.d.ts\",\n \"default\": \"./dist/db/testing/index.js\"\n },\n \"require\": {\n \"types\": \"./dist/db/testing/index.d.cts\",\n \"default\": \"./dist/db/testing/index.cjs\"\n }\n },\n \"./observability\": {\n \"import\": {\n \"types\": \"./dist/observability/index.d.ts\",\n \"default\": \"./dist/observability/index.js\"\n },\n \"require\": {\n \"types\": \"./dist/observability/index.d.cts\",\n \"default\": \"./dist/observability/index.cjs\"\n }\n },\n \"./queues/types\": {\n \"import\": {\n \"types\": \"./dist/queues/types.d.ts\",\n \"default\": \"./dist/queues/types.js\"\n },\n \"require\": {\n \"types\": \"./dist/queues/types.d.cts\",\n \"default\": \"./dist/queues/types.cjs\"\n }\n },\n \"./rag/schema\": {\n \"import\": {\n \"types\": \"./dist/rag/schema.d.ts\",\n \"default\": \"./dist/rag/schema.js\"\n },\n \"require\": {\n \"types\": \"./dist/rag/schema.d.cts\",\n \"default\": \"./dist/rag/schema.cjs\"\n }\n },\n \"./package.json\": \"./package.json\"\n },\n \"files\": [\n \"dist\",\n \"README.md\",\n \"CHANGELOG.md\"\n ],\n \"publishConfig\": {\n \"access\": \"public\"\n },\n \"engines\": {\n \"node\": \">=24\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/stackbone/stackbone.git\",\n \"directory\": \"libs/sdk\"\n },\n \"homepage\": \"https://stackbone.ai\",\n \"bugs\": {\n \"url\": \"https://github.com/stackbone/stackbone/issues\"\n },\n \"keywords\": [\n \"stackbone\",\n \"ai-agents\",\n \"agent-sdk\",\n \"containerized-agents\",\n \"openrouter\",\n \"rag\",\n \"pgvector\",\n \"drizzle\",\n \"openai\",\n \"postgres\"\n ],\n \"dependencies\": {\n \"@aws-sdk/client-s3\": \"^3.1038.0\",\n \"@aws-sdk/s3-request-presigner\": \"^3.1038.0\",\n \"@stackbone/crypto\": \"workspace:*\",\n \"@stackbone/prompt-compiler\": \"workspace:*\",\n \"@stackbone/rag-core\": \"workspace:*\",\n \"@stackbone/validators\": \"workspace:*\",\n \"@testcontainers/postgresql\": \"^11.14.0\",\n \"drizzle-orm\": \"0.45.2\",\n \"openai\": \"^4.104.0\",\n \"postgres\": \"3.4.9\",\n \"unpdf\": \"^0.12.1\",\n \"zod\": \"^4.3.6\"\n }\n}\n","// Process-wide invocation context, propagated with `AsyncLocalStorage`.\n//\n// The runtime request handler wraps each `capability.run(...)` in this context\n// (see `@stackbone/agent-server`'s `request-handler`), so any code running\n// inside an invoke — the creator's handler, the SDK's own loggers, a stray\n// `console.log` — can recover the active `invocationId` / `runId` without the\n// handler having to thread them through every call.\n//\n// Why an ALS and not a plain module variable: the agent process serves invokes\n// concurrently (the node:http adapter does not serialise requests). A single\n// mutable \"current invocation\" would be clobbered the moment two invokes\n// overlap. `AsyncLocalStorage` keeps a separate store per async call tree, so\n// each invoke's logs stay correlated to the right run even under concurrency.\n//\n// `invocationId` is the value the canonical logs call `trace_id` (the control\n// plane mints it once per invoke and threads it through the envelope); `runId`\n// is the run the invoke belongs to.\n\nimport { AsyncLocalStorage } from 'node:async_hooks';\n\nexport interface InvocationContext {\n /** The envelope's `invocationId` — surfaced on log lines as `trace_id`. */\n readonly invocationId: string;\n /** The run this invoke belongs to — surfaced on log lines as `run_id`. */\n readonly runId: string;\n /**\n * The handler this invoke routed to — `invoke` for a direct entry or the\n * named job handler (e.g. `demo-log-job`) the dispatcher delivered to.\n * Surfaced on log lines as `handler` so the Studio logs trail can tell which\n * entrypoint emitted each line. Optional so a caller that binds a context\n * without routing info (older tests, lifecycle hooks) still type-checks.\n */\n readonly handler?: string;\n}\n\nconst storage = new AsyncLocalStorage<InvocationContext>();\n\n/**\n * Runs `fn` with `context` bound as the active invocation. The context stays\n * available to every synchronous and asynchronous continuation rooted in this\n * call (i.e. across `await`s inside `fn`). Returns whatever `fn` returns.\n */\nexport function runWithInvocationContext<T>(context: InvocationContext, fn: () => T): T {\n return storage.run(context, fn);\n}\n\n/**\n * Returns the active invocation context, or `undefined` when called outside any\n * invoke (process boot, lifecycle events, tests that don't set one up).\n */\nexport function getInvocationContext(): InvocationContext | undefined {\n return storage.getStore();\n}\n","import { appendFile, mkdir } from 'node:fs/promises';\nimport { homedir } from 'node:os';\nimport { dirname, resolve } from 'node:path';\n\nimport { version as SDK_VERSION } from '../../package.json';\nimport { getInvocationContext } from '../runtime/invocation-context';\n\n// Numeric levels match Pino so JSONL files produced in local mode work with\n// `pino-pretty` and other Pino-aware tooling without translation.\nexport const LOG_LEVELS = {\n trace: 10,\n debug: 20,\n info: 30,\n warn: 40,\n error: 50,\n fatal: 60,\n} as const;\n\nexport type LogLevelName = keyof typeof LOG_LEVELS;\nexport type LogLevelNumber = (typeof LOG_LEVELS)[LogLevelName];\n\nexport interface LogRecord {\n /** Pino-style numeric level. */\n level: LogLevelNumber;\n /** Epoch milliseconds. Pino uses `time` as a number. */\n time: number;\n msg: string;\n run_id: string;\n trace_id?: string;\n installation_id?: string;\n agent_id?: string;\n [key: string]: unknown;\n}\n\nexport interface PlatformLoggerOptions {\n runId: string;\n installationId?: string | undefined;\n agentId?: string | undefined;\n /**\n * When set (cloud), logs are batched and POSTed to `<endpoint>/v1/logs` as\n * OTLP/HTTP/JSON. When unset (local), logs are appended to\n * `<runsDir>/<runId>.jsonl`. Falls back to `OTEL_EXPORTER_OTLP_ENDPOINT`.\n */\n otelEndpoint?: string | undefined;\n /** Local-only: directory where JSONL files live. Defaults to `~/.stackbone/dev/runs`. */\n runsDir?: string | undefined;\n /** Cloud-only: extra OTel resource attributes to send with every batch. */\n resourceAttributes?: Record<string, string> | undefined;\n /** Cloud-only: HTTP timeout per OTLP POST in ms. Defaults to 5_000. */\n httpTimeoutMs?: number | undefined;\n /** Flush trigger by buffer size. Defaults to 50. */\n flushBatchSize?: number | undefined;\n /** Flush trigger by elapsed time (ms). Defaults to 1_000. */\n flushIntervalMs?: number | undefined;\n /** Test seam — fetch implementation. Defaults to global `fetch`. */\n fetchImpl?: typeof fetch | undefined;\n /** Test seam — `fs.appendFile`-shaped sink the local destination uses. */\n appendFileImpl?: ((path: string, data: string) => Promise<void>) | undefined;\n /** Test seam — `fs.mkdir`-shaped helper the local destination uses. */\n mkdirImpl?: ((path: string) => Promise<void>) | undefined;\n /** Test seam — clock for `time` field. Defaults to `Date.now`. */\n now?: (() => number) | undefined;\n /** Override mode resolution (skips the env detection). */\n mode?: PlatformLoggerMode | undefined;\n}\n\nexport type PlatformLoggerMode = 'local' | 'cloud';\n\nexport interface PinoLike {\n trace(msgOrObj: unknown, msg?: string): void;\n debug(msgOrObj: unknown, msg?: string): void;\n info(msgOrObj: unknown, msg?: string): void;\n warn(msgOrObj: unknown, msg?: string): void;\n error(msgOrObj: unknown, msg?: string): void;\n fatal(msgOrObj: unknown, msg?: string): void;\n}\n\nexport interface PlatformLogger extends PinoLike {\n readonly mode: PlatformLoggerMode;\n /** Bind extra fields and return a child logger sharing the same destination. */\n child(bindings: Record<string, unknown>): PlatformLogger;\n /** Force-flush pending writes (close file handle or POST OTLP batch). */\n flush(): Promise<void>;\n /** Stop accepting writes and release resources. */\n close(): Promise<void>;\n}\n\ninterface Destination {\n write(record: LogRecord): void;\n flush(): Promise<void>;\n close(): Promise<void>;\n}\n\nconst DEFAULT_BATCH_SIZE = 50;\nconst DEFAULT_INTERVAL_MS = 1_000;\nconst DEFAULT_HTTP_TIMEOUT_MS = 5_000;\n\n/**\n * Creates a Pino-aligned logger that writes JSONL to disk in local mode and\n * batches OTLP/HTTP/JSON log records to an OTel collector in cloud mode. Mode\n * is resolved from `OTEL_EXPORTER_OTLP_ENDPOINT` or the explicit override.\n */\nexport function createPlatformLogger(options: PlatformLoggerOptions): PlatformLogger {\n // The resolver is the single seam that reads `OTEL_EXPORTER_OTLP_ENDPOINT`.\n // Runtime code building a logger on the `@stackbone/sdk/observability`\n // subpath supplies `otelEndpoint` explicitly (typically plumbed from\n // `ResolvedConfig`). The `undefined` here means \"no `otelEndpoint` ⇒ local\n // JSONL mode\" (matches the docstring).\n const otelEndpoint = options.otelEndpoint ?? undefined;\n const mode: PlatformLoggerMode = options.mode ?? (otelEndpoint ? 'cloud' : 'local');\n\n const baseBindings: Record<string, unknown> = { run_id: options.runId };\n if (options.installationId !== undefined)\n baseBindings['installation_id'] = options.installationId;\n if (options.agentId !== undefined) baseBindings['agent_id'] = options.agentId;\n\n const destination: Destination =\n mode === 'cloud'\n ? new OtlpHttpDestination({\n endpoint: otelEndpoint ?? '',\n resourceAttributes: options.resourceAttributes ?? {},\n httpTimeoutMs: options.httpTimeoutMs ?? DEFAULT_HTTP_TIMEOUT_MS,\n flushBatchSize: options.flushBatchSize ?? DEFAULT_BATCH_SIZE,\n flushIntervalMs: options.flushIntervalMs ?? DEFAULT_INTERVAL_MS,\n ...(options.fetchImpl !== undefined ? { fetchImpl: options.fetchImpl } : {}),\n })\n : new JsonlFileDestination({\n runId: options.runId,\n runsDir: options.runsDir ?? defaultRunsDir(),\n ...(options.appendFileImpl !== undefined\n ? { appendFileImpl: options.appendFileImpl }\n : {}),\n ...(options.mkdirImpl !== undefined ? { mkdirImpl: options.mkdirImpl } : {}),\n });\n\n const now = options.now ?? Date.now;\n return buildLogger({ destination, baseBindings, mode, now });\n}\n\ninterface LoggerBuildOptions {\n destination: Destination;\n baseBindings: Record<string, unknown>;\n mode: PlatformLoggerMode;\n now: () => number;\n}\n\nfunction buildLogger(opts: LoggerBuildOptions): PlatformLogger {\n const writeAt = (level: LogLevelName, msgOrObj: unknown, msg?: string): void => {\n const time = opts.now();\n const levelNumber = LOG_LEVELS[level];\n const record: LogRecord = {\n level: levelNumber,\n time,\n msg: '',\n run_id: String(opts.baseBindings['run_id'] ?? ''),\n ...opts.baseBindings,\n };\n if (typeof msgOrObj === 'string') {\n record.msg = msgOrObj;\n } else if (msgOrObj && typeof msgOrObj === 'object') {\n Object.assign(record, msgOrObj);\n if (typeof msg === 'string') record.msg = msg;\n else if (typeof record.msg !== 'string') record.msg = '';\n }\n // Ambient invocation correlation: when used inside an invoke (the request\n // handler wraps `capability.run` in an AsyncLocalStorage context), stamp\n // `trace_id` / `run_id` from that context unless the caller already set them\n // explicitly via bindings or per-call meta. Outside an invoke there is no\n // context, so the records keep their previous shape.\n const ctx = getInvocationContext();\n if (ctx) {\n if (record.trace_id === undefined) record.trace_id = ctx.invocationId;\n if (!record.run_id) record.run_id = ctx.runId;\n if (record['handler'] === undefined && ctx.handler !== undefined) {\n record['handler'] = ctx.handler;\n }\n }\n opts.destination.write(record);\n };\n\n const child = (bindings: Record<string, unknown>): PlatformLogger =>\n buildLogger({ ...opts, baseBindings: { ...opts.baseBindings, ...bindings } });\n\n return {\n mode: opts.mode,\n trace: (msgOrObj, msg) => writeAt('trace', msgOrObj, msg),\n debug: (msgOrObj, msg) => writeAt('debug', msgOrObj, msg),\n info: (msgOrObj, msg) => writeAt('info', msgOrObj, msg),\n warn: (msgOrObj, msg) => writeAt('warn', msgOrObj, msg),\n error: (msgOrObj, msg) => writeAt('error', msgOrObj, msg),\n fatal: (msgOrObj, msg) => writeAt('fatal', msgOrObj, msg),\n child,\n flush: () => opts.destination.flush(),\n close: () => opts.destination.close(),\n };\n}\n\ninterface JsonlFileDestinationOptions {\n runId: string;\n runsDir: string;\n appendFileImpl?: (path: string, data: string) => Promise<void>;\n mkdirImpl?: (path: string) => Promise<void>;\n}\n\nclass JsonlFileDestination implements Destination {\n private readonly path: string;\n private readonly appendFile: (path: string, data: string) => Promise<void>;\n private readonly mkdir: (path: string) => Promise<void>;\n private inFlight: Promise<void> = Promise.resolve();\n private dirReady = false;\n\n constructor(opts: JsonlFileDestinationOptions) {\n this.path = resolve(opts.runsDir, `${opts.runId}.jsonl`);\n this.appendFile = opts.appendFileImpl ?? ((p, d) => appendFile(p, d, 'utf8'));\n this.mkdir =\n opts.mkdirImpl ??\n (async (p) => {\n await mkdir(p, { recursive: true });\n });\n }\n\n write(record: LogRecord): void {\n const line = `${JSON.stringify(record)}\\n`;\n this.inFlight = this.inFlight.then(async () => {\n if (!this.dirReady) {\n await this.mkdir(dirname(this.path));\n this.dirReady = true;\n }\n try {\n await this.appendFile(this.path, line);\n } catch (error) {\n process.stderr.write(\n `[stackbone/sdk] PlatformLogger JSONL write failed: ${error instanceof Error ? error.message : String(error)}\\n`,\n );\n }\n });\n }\n\n async flush(): Promise<void> {\n await this.inFlight;\n }\n\n async close(): Promise<void> {\n await this.flush();\n }\n}\n\ninterface OtlpHttpDestinationOptions {\n endpoint: string;\n resourceAttributes: Record<string, string>;\n httpTimeoutMs: number;\n flushBatchSize: number;\n flushIntervalMs: number;\n fetchImpl?: typeof fetch;\n}\n\n// OTLP/HTTP/JSON spec: OpenTelemetry Logs Data Model §B.1. Failures log to\n// stderr — telemetry must never block agent execution.\nclass OtlpHttpDestination implements Destination {\n private readonly url: string;\n private readonly resourceAttributes: Record<string, string>;\n private readonly httpTimeoutMs: number;\n private readonly flushBatchSize: number;\n private readonly flushIntervalMs: number;\n private readonly fetchImpl: typeof fetch;\n private buffer: LogRecord[] = [];\n private timer: NodeJS.Timeout | null = null;\n private inFlight: Promise<void> = Promise.resolve();\n private closed = false;\n\n constructor(opts: OtlpHttpDestinationOptions) {\n this.url = `${opts.endpoint.replace(/\\/+$/, '')}/v1/logs`;\n this.resourceAttributes = opts.resourceAttributes;\n this.httpTimeoutMs = opts.httpTimeoutMs;\n this.flushBatchSize = opts.flushBatchSize;\n this.flushIntervalMs = opts.flushIntervalMs;\n this.fetchImpl = opts.fetchImpl ?? fetch;\n }\n\n write(record: LogRecord): void {\n if (this.closed) return;\n this.buffer.push(record);\n if (this.buffer.length >= this.flushBatchSize) {\n void this.flush();\n } else {\n this.armTimer();\n }\n }\n\n async flush(): Promise<void> {\n await this.inFlight;\n if (this.buffer.length === 0) return;\n const drained = this.buffer.splice(0, this.buffer.length);\n this.disarmTimer();\n this.inFlight = this.post(drained).catch((error) => {\n process.stderr.write(\n `[stackbone/sdk] PlatformLogger OTLP POST failed: ${error instanceof Error ? error.message : String(error)}\\n`,\n );\n });\n await this.inFlight;\n }\n\n async close(): Promise<void> {\n this.closed = true;\n await this.flush();\n }\n\n private armTimer(): void {\n if (this.timer) return;\n this.timer = setTimeout(() => {\n this.timer = null;\n void this.flush();\n }, this.flushIntervalMs);\n this.timer.unref?.();\n }\n\n private disarmTimer(): void {\n if (this.timer) {\n clearTimeout(this.timer);\n this.timer = null;\n }\n }\n\n private async post(records: LogRecord[]): Promise<void> {\n const body = JSON.stringify(buildOtlpLogsBody(records, this.resourceAttributes));\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), this.httpTimeoutMs);\n try {\n const resp = await this.fetchImpl(this.url, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body,\n signal: controller.signal,\n });\n if (!resp.ok) {\n const text = await resp.text().catch(() => '');\n throw new Error(`HTTP ${resp.status}${text ? `: ${text.slice(0, 200)}` : ''}`);\n }\n } finally {\n clearTimeout(timeout);\n }\n }\n}\n\ninterface OtlpKeyValue {\n key: string;\n value:\n | { stringValue: string }\n | { intValue: string }\n | { doubleValue: number }\n | { boolValue: boolean };\n}\n\ninterface OtlpResource {\n attributes: OtlpKeyValue[];\n}\n\ninterface OtlpLogRecord {\n timeUnixNano: string;\n severityNumber: number;\n severityText: string;\n body: { stringValue: string };\n attributes: OtlpKeyValue[];\n}\n\ninterface OtlpLogsBody {\n resourceLogs: Array<{\n resource: OtlpResource;\n scopeLogs: Array<{\n scope: { name: string; version: string };\n logRecords: OtlpLogRecord[];\n }>;\n }>;\n}\n\nconst SDK_SCOPE = { name: '@stackbone/sdk', version: SDK_VERSION };\n\nfunction buildOtlpLogsBody(\n records: LogRecord[],\n resourceAttributes: Record<string, string>,\n): OtlpLogsBody {\n return {\n resourceLogs: [\n {\n resource: { attributes: toOtlpAttributes(resourceAttributes) },\n scopeLogs: [\n {\n scope: SDK_SCOPE,\n logRecords: records.map(toOtlpLogRecord),\n },\n ],\n },\n ],\n };\n}\n\nfunction toOtlpLogRecord(record: LogRecord): OtlpLogRecord {\n const { level, time, msg, ...rest } = record;\n return {\n timeUnixNano: `${time * 1_000_000}`,\n severityNumber: level,\n severityText: severityText(level),\n body: { stringValue: msg },\n attributes: toOtlpAttributesFromUnknown(rest),\n };\n}\n\nconst SEVERITY_TEXT_BY_LEVEL: Record<number, string> = Object.fromEntries(\n Object.entries(LOG_LEVELS).map(([name, value]) => [value, name.toUpperCase()]),\n);\n\nfunction severityText(level: number): string {\n return SEVERITY_TEXT_BY_LEVEL[level] ?? 'INFO';\n}\n\nfunction toOtlpAttributes(attrs: Record<string, string>): OtlpKeyValue[] {\n return Object.entries(attrs).map(([key, value]) => ({\n key,\n value: { stringValue: value },\n }));\n}\n\nfunction toOtlpAttributesFromUnknown(attrs: Record<string, unknown>): OtlpKeyValue[] {\n const out: OtlpKeyValue[] = [];\n for (const [key, value] of Object.entries(attrs)) {\n if (value === null || value === undefined) continue;\n if (typeof value === 'string') {\n out.push({ key, value: { stringValue: value } });\n } else if (typeof value === 'number') {\n if (Number.isInteger(value)) out.push({ key, value: { intValue: String(value) } });\n else out.push({ key, value: { doubleValue: value } });\n } else if (typeof value === 'boolean') {\n out.push({ key, value: { boolValue: value } });\n } else {\n out.push({ key, value: { stringValue: JSON.stringify(value) } });\n }\n }\n return out;\n}\n\nexport function defaultRunsDir(): string {\n return resolve(homedir(), '.stackbone', 'dev', 'runs');\n}\n","import { randomUUID } from 'node:crypto';\n\n// Canonical step types stored in `stackbone_platform.run_steps.type`. The list\n// has to stay in sync with the CHECK constraint in\n// `libs/platform/platform-schema/src/migrations/0001_runs.sql`. Exported so agents\n// can discover the closed set without reaching into the migration file.\nexport const RUN_STEP_TYPES = [\n 'agent',\n 'llm_call',\n 'db_query',\n 'http_fetch',\n 'queue_publish',\n 'hitl_pause',\n 'tool_call',\n 'rag_query',\n 'storage_op',\n] as const;\nexport type RunStepType = (typeof RUN_STEP_TYPES)[number];\n\n// Span attribute we read first to pin a step type explicitly. When absent,\n// the resolver falls back to a span.name prefix mapping.\nexport const STEP_TYPE_ATTRIBUTE = 'stackbone.step.type';\n\n// Span attribute that carries the active run id. The processor drops spans\n// without it because `stackbone_platform.run_steps.run_id` is NOT NULL — there\n// is no useful row we could write otherwise.\nexport const RUN_ID_ATTRIBUTE = 'stackbone.run.id';\n\nconst NAME_PREFIX_MAP: ReadonlyArray<readonly [RegExp, RunStepType]> = [\n [/^stackbone\\.ai\\./, 'llm_call'],\n [/^stackbone\\.db\\./, 'db_query'],\n [/^stackbone\\.http\\./, 'http_fetch'],\n [/^stackbone\\.queues\\./, 'queue_publish'],\n [/^stackbone\\.approval\\./, 'hitl_pause'],\n [/^stackbone\\.tool\\./, 'tool_call'],\n [/^stackbone\\.rag\\./, 'rag_query'],\n [/^stackbone\\.storage\\./, 'storage_op'],\n];\n\n/**\n * Minimal duck-typed view of an OpenTelemetry `ReadableSpan`. We mirror the\n * shape the OTel SDK exposes on `@opentelemetry/sdk-trace-base` rather than\n * importing the package so `@stackbone/sdk` doesn't pull the OTel runtime into\n * every agent that doesn't enable Studio. Agents wire the processor with\n * `provider.addSpanProcessor(new RunStepsSpanProcessor(...))` and the\n * structural match satisfies TypeScript.\n */\nexport interface SpanContextLike {\n spanId: string;\n traceId: string;\n}\n\nexport interface ReadableSpanLike {\n spanContext(): SpanContextLike;\n parentSpanContext?: SpanContextLike | undefined;\n parentSpanId?: string | undefined;\n name: string;\n attributes: Record<string, unknown>;\n status?: { code: number; message?: string } | undefined;\n startTime?: [number, number] | undefined;\n endTime?: [number, number] | undefined;\n duration?: [number, number] | undefined;\n}\n\nexport interface PostgresLike {\n unsafe(query: string, params?: unknown[]): Promise<unknown>;\n end?(): Promise<void>;\n}\n\nexport interface RunStepsSpanProcessorOptions {\n /**\n * Postgres connection string of the install (local emulator at :5433 in\n * dev, Neon TCP/HTTP URL in cloud). Falls back to `DATABASE_URL`.\n */\n connectionString?: string | undefined;\n /** Flush trigger by buffer size. Defaults to 50. */\n flushBatchSize?: number | undefined;\n /** Flush trigger by elapsed time (ms). Defaults to 500. */\n flushIntervalMs?: number | undefined;\n /** Override how a span maps to a step type. */\n resolveStepType?: ((span: ReadableSpanLike) => RunStepType) | undefined;\n /** Test seam — inject a postgres-js-compatible client. */\n sql?: PostgresLike | undefined;\n /** Test seam — deterministic UUID generator. */\n newId?: (() => string) | undefined;\n}\n\ninterface BufferedRow {\n id: string;\n run_id: string;\n parent_step_id: string | null;\n type: RunStepType;\n name: string;\n status: 'ok' | 'error';\n payload: Record<string, unknown>;\n error: { message: string } | null;\n started_at: string;\n finished_at: string;\n duration_ms: number;\n}\n\nconst DEFAULT_BATCH_SIZE = 50;\nconst DEFAULT_INTERVAL_MS = 500;\n\n/**\n * Materialises every OTel span produced by the agent into a row of\n * `stackbone_platform.run_steps`. Designed to coexist with the OTLP exporter:\n * cloud builds register both processors so Postgres feeds Studio (paridad\n * con local) and Tempo feeds Platform Ops with retention/aggregation. If a\n * write fails the processor logs to stderr and keeps accepting spans —\n * observability is never load-bearing for agent execution.\n *\n * Spec: docs/arquitectura/specs/stackbone-agent-protocol-v1.md §6.3\n * ADR: docs/arquitectura/decisiones/2026-05-03-stackbone-studio-datapath-y-scope-mvp.md §D9\n */\nexport class RunStepsSpanProcessor {\n private readonly buffer: BufferedRow[] = [];\n private readonly stepIdBySpanId = new Map<string, string>();\n private readonly batchSize: number;\n private readonly intervalMs: number;\n private readonly resolveStepType: (span: ReadableSpanLike) => RunStepType;\n private readonly newId: () => string;\n private readonly connectionString: string | undefined;\n private readonly ownsSql: boolean;\n private sql: PostgresLike | null;\n private timer: NodeJS.Timeout | null = null;\n private inFlight: Promise<void> | null = null;\n\n constructor(options: RunStepsSpanProcessorOptions = {}) {\n this.batchSize = options.flushBatchSize ?? DEFAULT_BATCH_SIZE;\n this.intervalMs = options.flushIntervalMs ?? DEFAULT_INTERVAL_MS;\n this.resolveStepType = options.resolveStepType ?? defaultStepTypeResolver;\n this.newId = options.newId ?? randomUUID;\n // The resolver owns reading `STACKBONE_POSTGRES_URL`. Runtime code\n // constructing the processor on the `@stackbone/sdk/observability`\n // subpath must supply `connectionString` itself (typically plumbed\n // from `ResolvedConfig`).\n this.connectionString = options.connectionString;\n if (options.sql) {\n this.sql = options.sql;\n this.ownsSql = false;\n } else {\n this.sql = null;\n this.ownsSql = true;\n }\n }\n\n // OTel calls onStart for the parent before any child, and onEnd for\n // children before the parent. Reserving the UUID up-front lets the child's\n // onEnd resolve `parent_step_id` synchronously — the alternative (looking\n // up the parent at write time) would race the buffer flush.\n onStart(span: ReadableSpanLike): void {\n const spanId = span.spanContext().spanId;\n if (!this.stepIdBySpanId.has(spanId)) {\n this.stepIdBySpanId.set(spanId, this.newId());\n }\n }\n\n onEnd(span: ReadableSpanLike): void {\n const row = this.buildRow(span);\n if (!row) return;\n this.buffer.push(row);\n if (this.buffer.length >= this.batchSize) {\n void this.flush();\n } else {\n this.armTimer();\n }\n }\n\n async forceFlush(): Promise<void> {\n await this.flush();\n }\n\n async shutdown(): Promise<void> {\n this.disarmTimer();\n await this.flush();\n if (this.ownsSql && this.sql?.end) {\n await this.sql.end().catch(() => undefined);\n }\n }\n\n private buildRow(span: ReadableSpanLike): BufferedRow | null {\n const spanId = span.spanContext().spanId;\n // Always release the reservation from `onStart`, even when we drop the\n // row for lack of `run_id` — otherwise spans the SDK never persists\n // accumulate in the map.\n const stepId = this.stepIdBySpanId.get(spanId) ?? this.newId();\n this.stepIdBySpanId.delete(spanId);\n\n const runId = readString(span.attributes[RUN_ID_ATTRIBUTE]);\n if (!runId) return null;\n\n const parentSpanId = span.parentSpanContext?.spanId ?? span.parentSpanId ?? null;\n // Parents end after children, so the parent's UUID is still in the map\n // when the child's onEnd runs. Once the parent ends and gets removed the\n // child rows already reference it via `parent_step_id`.\n const parentStepId = parentSpanId ? (this.stepIdBySpanId.get(parentSpanId) ?? null) : null;\n\n const startedAt = formatHrTime(span.startTime);\n const finishedAt = formatHrTime(span.endTime ?? span.startTime);\n const durationMs = hrTimeToMs(span.duration ?? diffHrTime(span.endTime, span.startTime));\n\n const isError = span.status?.code === 2;\n\n return {\n id: stepId,\n run_id: runId,\n parent_step_id: parentStepId,\n type: this.resolveStepType(span),\n name: span.name,\n status: isError ? 'error' : 'ok',\n payload: serialisablePayload(span.attributes),\n error: isError ? { message: span.status?.message ?? 'span ended with ERROR status' } : null,\n started_at: startedAt,\n finished_at: finishedAt,\n duration_ms: durationMs,\n };\n }\n\n private armTimer(): void {\n if (this.timer) return;\n this.timer = setTimeout(() => {\n this.timer = null;\n void this.flush();\n }, this.intervalMs);\n // Don't keep the Node process alive just for the flush timer.\n this.timer.unref?.();\n }\n\n private disarmTimer(): void {\n if (this.timer) {\n clearTimeout(this.timer);\n this.timer = null;\n }\n }\n\n private async flush(): Promise<void> {\n if (this.inFlight) {\n await this.inFlight;\n }\n if (this.buffer.length === 0) return;\n const drained = this.buffer.splice(0, this.buffer.length);\n this.disarmTimer();\n this.inFlight = this.writeBatch(drained).finally(() => {\n this.inFlight = null;\n });\n await this.inFlight;\n }\n\n private async ensureSql(): Promise<PostgresLike | null> {\n if (this.sql) return this.sql;\n if (!this.connectionString) return null;\n // Lazy import — agents that never enable Studio don't pay the cost of\n // wiring a Postgres connection at boot.\n const mod = (await import('postgres')) as { default: (url: string) => PostgresLike };\n this.sql = mod.default(this.connectionString);\n return this.sql;\n }\n\n private async writeBatch(rows: BufferedRow[]): Promise<void> {\n try {\n const sql = await this.ensureSql();\n if (!sql) {\n process.stderr.write(\n '[stackbone/sdk] RunStepsSpanProcessor dropped batch: no DATABASE_URL configured.\\n',\n );\n return;\n }\n const placeholders: string[] = [];\n const params: unknown[] = [];\n for (const row of rows) {\n const base = params.length;\n placeholders.push(\n `($${base + 1}::uuid, $${base + 2}::uuid, $${base + 3}::uuid, $${base + 4}, $${base + 5}, $${base + 6}, $${base + 7}::jsonb, $${base + 8}::jsonb, $${base + 9}::timestamptz, $${base + 10}::timestamptz, $${base + 11}::int)`,\n );\n params.push(\n row.id,\n row.run_id,\n row.parent_step_id,\n row.type,\n row.name,\n row.status,\n JSON.stringify(row.payload),\n row.error ? JSON.stringify(row.error) : null,\n row.started_at,\n row.finished_at,\n row.duration_ms,\n );\n }\n const text = `INSERT INTO stackbone_platform.run_steps (\n id, run_id, parent_step_id, type, name, status, payload, error,\n started_at, finished_at, duration_ms\n ) VALUES ${placeholders.join(', ')}`;\n await sql.unsafe(text, params);\n } catch (error) {\n process.stderr.write(\n `[stackbone/sdk] RunStepsSpanProcessor write failed: ${error instanceof Error ? error.message : String(error)}\\n`,\n );\n }\n }\n}\n\nconst defaultStepTypeResolver = (span: ReadableSpanLike): RunStepType => {\n const explicit = readString(span.attributes[STEP_TYPE_ATTRIBUTE]);\n if (explicit && (RUN_STEP_TYPES as readonly string[]).includes(explicit)) {\n return explicit as RunStepType;\n }\n for (const [pattern, type] of NAME_PREFIX_MAP) {\n if (pattern.test(span.name)) return type;\n }\n return 'agent';\n};\n\nconst readString = (value: unknown): string | undefined =>\n typeof value === 'string' && value.length > 0 ? value : undefined;\n\nconst formatHrTime = (hr?: [number, number]): string =>\n new Date(hr ? hrTimeToMs(hr) : Date.now()).toISOString();\n\nconst hrTimeToMs = (hr?: [number, number]): number => {\n if (!hr) return 0;\n const [seconds, nanos] = hr;\n return seconds * 1_000 + Math.floor(nanos / 1_000_000);\n};\n\nconst diffHrTime = (\n end?: [number, number],\n start?: [number, number],\n): [number, number] | undefined => {\n if (!end || !start) return undefined;\n const seconds = end[0] - start[0];\n const nanos = end[1] - start[1];\n return [seconds, nanos];\n};\n\nconst serialisablePayload = (attributes: Record<string, unknown>): Record<string, unknown> => {\n const out: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(attributes)) {\n if (key === RUN_ID_ATTRIBUTE) continue;\n if (key === STEP_TYPE_ATTRIBUTE) continue;\n out[key] = value;\n }\n return out;\n};\n","import type { PostgresLike } from './run-steps-exporter';\n\n// Spans without a `cost_usd` attribute (unknown model / OpenRouter response\n// without the cost header) contribute 0 — observability is best-effort and\n// must not fail the run on missing telemetry.\n\nexport interface AggregateRunCostOptions {\n sql: PostgresLike;\n}\n\nexport interface AggregateRunCostResult {\n costEstimatedUsd: number;\n}\n\ninterface AggregatedRow {\n cost_estimated_usd: string | number | null;\n}\n\nconst SQL = `WITH llm_costs AS (\n SELECT COALESCE(SUM((payload->>'cost_usd')::numeric), 0) AS total\n FROM stackbone_platform.run_steps\n WHERE run_id = $1::uuid\n AND type = 'llm_call'\n )\n UPDATE stackbone_platform.runs\n SET cost_estimated_usd = (SELECT total FROM llm_costs)\n WHERE id = $1::uuid\n RETURNING cost_estimated_usd`;\n\nexport async function aggregateRunCost(\n runId: string,\n options: AggregateRunCostOptions,\n): Promise<AggregateRunCostResult> {\n const result = (await options.sql.unsafe(SQL, [runId])) as AggregatedRow[];\n const row = result[0];\n if (!row) {\n return { costEstimatedUsd: 0 };\n }\n // postgres-js returns numerics as strings to preserve precision; coerce\n // to a Number on the way out so callers don't need to know.\n const raw = row.cost_estimated_usd;\n if (raw === null || raw === undefined) return { costEstimatedUsd: 0 };\n const num = typeof raw === 'string' ? Number(raw) : raw;\n return { costEstimatedUsd: Number.isFinite(num) ? num : 0 };\n}\n"]}
@@ -1,3 +1,82 @@
1
+ declare const LOG_LEVELS: {
2
+ readonly trace: 10;
3
+ readonly debug: 20;
4
+ readonly info: 30;
5
+ readonly warn: 40;
6
+ readonly error: 50;
7
+ readonly fatal: 60;
8
+ };
9
+ type LogLevelName = keyof typeof LOG_LEVELS;
10
+ type LogLevelNumber = (typeof LOG_LEVELS)[LogLevelName];
11
+ interface LogRecord {
12
+ /** Pino-style numeric level. */
13
+ level: LogLevelNumber;
14
+ /** Epoch milliseconds. Pino uses `time` as a number. */
15
+ time: number;
16
+ msg: string;
17
+ run_id: string;
18
+ trace_id?: string;
19
+ installation_id?: string;
20
+ agent_id?: string;
21
+ [key: string]: unknown;
22
+ }
23
+ interface PlatformLoggerOptions {
24
+ runId: string;
25
+ installationId?: string | undefined;
26
+ agentId?: string | undefined;
27
+ /**
28
+ * When set (cloud), logs are batched and POSTed to `<endpoint>/v1/logs` as
29
+ * OTLP/HTTP/JSON. When unset (local), logs are appended to
30
+ * `<runsDir>/<runId>.jsonl`. Falls back to `OTEL_EXPORTER_OTLP_ENDPOINT`.
31
+ */
32
+ otelEndpoint?: string | undefined;
33
+ /** Local-only: directory where JSONL files live. Defaults to `~/.stackbone/dev/runs`. */
34
+ runsDir?: string | undefined;
35
+ /** Cloud-only: extra OTel resource attributes to send with every batch. */
36
+ resourceAttributes?: Record<string, string> | undefined;
37
+ /** Cloud-only: HTTP timeout per OTLP POST in ms. Defaults to 5_000. */
38
+ httpTimeoutMs?: number | undefined;
39
+ /** Flush trigger by buffer size. Defaults to 50. */
40
+ flushBatchSize?: number | undefined;
41
+ /** Flush trigger by elapsed time (ms). Defaults to 1_000. */
42
+ flushIntervalMs?: number | undefined;
43
+ /** Test seam — fetch implementation. Defaults to global `fetch`. */
44
+ fetchImpl?: typeof fetch | undefined;
45
+ /** Test seam — `fs.appendFile`-shaped sink the local destination uses. */
46
+ appendFileImpl?: ((path: string, data: string) => Promise<void>) | undefined;
47
+ /** Test seam — `fs.mkdir`-shaped helper the local destination uses. */
48
+ mkdirImpl?: ((path: string) => Promise<void>) | undefined;
49
+ /** Test seam — clock for `time` field. Defaults to `Date.now`. */
50
+ now?: (() => number) | undefined;
51
+ /** Override mode resolution (skips the env detection). */
52
+ mode?: PlatformLoggerMode | undefined;
53
+ }
54
+ type PlatformLoggerMode = 'local' | 'cloud';
55
+ interface PinoLike {
56
+ trace(msgOrObj: unknown, msg?: string): void;
57
+ debug(msgOrObj: unknown, msg?: string): void;
58
+ info(msgOrObj: unknown, msg?: string): void;
59
+ warn(msgOrObj: unknown, msg?: string): void;
60
+ error(msgOrObj: unknown, msg?: string): void;
61
+ fatal(msgOrObj: unknown, msg?: string): void;
62
+ }
63
+ interface PlatformLogger extends PinoLike {
64
+ readonly mode: PlatformLoggerMode;
65
+ /** Bind extra fields and return a child logger sharing the same destination. */
66
+ child(bindings: Record<string, unknown>): PlatformLogger;
67
+ /** Force-flush pending writes (close file handle or POST OTLP batch). */
68
+ flush(): Promise<void>;
69
+ /** Stop accepting writes and release resources. */
70
+ close(): Promise<void>;
71
+ }
72
+ /**
73
+ * Creates a Pino-aligned logger that writes JSONL to disk in local mode and
74
+ * batches OTLP/HTTP/JSON log records to an OTel collector in cloud mode. Mode
75
+ * is resolved from `OTEL_EXPORTER_OTLP_ENDPOINT` or the explicit override.
76
+ */
77
+ declare function createPlatformLogger(options: PlatformLoggerOptions): PlatformLogger;
78
+ declare function defaultRunsDir(): string;
79
+
1
80
  declare const RUN_STEP_TYPES: readonly ["agent", "llm_call", "db_query", "http_fetch", "queue_publish", "hitl_pause", "tool_call", "rag_query", "storage_op"];
2
81
  type RunStepType = (typeof RUN_STEP_TYPES)[number];
3
82
  declare const STEP_TYPE_ATTRIBUTE = "stackbone.step.type";
@@ -93,83 +172,4 @@ interface AggregateRunCostResult {
93
172
  }
94
173
  declare function aggregateRunCost(runId: string, options: AggregateRunCostOptions): Promise<AggregateRunCostResult>;
95
174
 
96
- declare const LOG_LEVELS: {
97
- readonly trace: 10;
98
- readonly debug: 20;
99
- readonly info: 30;
100
- readonly warn: 40;
101
- readonly error: 50;
102
- readonly fatal: 60;
103
- };
104
- type LogLevelName = keyof typeof LOG_LEVELS;
105
- type LogLevelNumber = (typeof LOG_LEVELS)[LogLevelName];
106
- interface LogRecord {
107
- /** Pino-style numeric level. */
108
- level: LogLevelNumber;
109
- /** Epoch milliseconds. Pino uses `time` as a number. */
110
- time: number;
111
- msg: string;
112
- run_id: string;
113
- trace_id?: string;
114
- installation_id?: string;
115
- agent_id?: string;
116
- [key: string]: unknown;
117
- }
118
- interface PlatformLoggerOptions {
119
- runId: string;
120
- installationId?: string | undefined;
121
- agentId?: string | undefined;
122
- /**
123
- * When set (cloud), logs are batched and POSTed to `<endpoint>/v1/logs` as
124
- * OTLP/HTTP/JSON. When unset (local), logs are appended to
125
- * `<runsDir>/<runId>.jsonl`. Falls back to `OTEL_EXPORTER_OTLP_ENDPOINT`.
126
- */
127
- otelEndpoint?: string | undefined;
128
- /** Local-only: directory where JSONL files live. Defaults to `~/.stackbone/dev/runs`. */
129
- runsDir?: string | undefined;
130
- /** Cloud-only: extra OTel resource attributes to send with every batch. */
131
- resourceAttributes?: Record<string, string> | undefined;
132
- /** Cloud-only: HTTP timeout per OTLP POST in ms. Defaults to 5_000. */
133
- httpTimeoutMs?: number | undefined;
134
- /** Flush trigger by buffer size. Defaults to 50. */
135
- flushBatchSize?: number | undefined;
136
- /** Flush trigger by elapsed time (ms). Defaults to 1_000. */
137
- flushIntervalMs?: number | undefined;
138
- /** Test seam — fetch implementation. Defaults to global `fetch`. */
139
- fetchImpl?: typeof fetch | undefined;
140
- /** Test seam — `fs.appendFile`-shaped sink the local destination uses. */
141
- appendFileImpl?: ((path: string, data: string) => Promise<void>) | undefined;
142
- /** Test seam — `fs.mkdir`-shaped helper the local destination uses. */
143
- mkdirImpl?: ((path: string) => Promise<void>) | undefined;
144
- /** Test seam — clock for `time` field. Defaults to `Date.now`. */
145
- now?: (() => number) | undefined;
146
- /** Override mode resolution (skips the env detection). */
147
- mode?: PlatformLoggerMode | undefined;
148
- }
149
- type PlatformLoggerMode = 'local' | 'cloud';
150
- interface PinoLike {
151
- trace(msgOrObj: unknown, msg?: string): void;
152
- debug(msgOrObj: unknown, msg?: string): void;
153
- info(msgOrObj: unknown, msg?: string): void;
154
- warn(msgOrObj: unknown, msg?: string): void;
155
- error(msgOrObj: unknown, msg?: string): void;
156
- fatal(msgOrObj: unknown, msg?: string): void;
157
- }
158
- interface PlatformLogger extends PinoLike {
159
- readonly mode: PlatformLoggerMode;
160
- /** Bind extra fields and return a child logger sharing the same destination. */
161
- child(bindings: Record<string, unknown>): PlatformLogger;
162
- /** Force-flush pending writes (close file handle or POST OTLP batch). */
163
- flush(): Promise<void>;
164
- /** Stop accepting writes and release resources. */
165
- close(): Promise<void>;
166
- }
167
- /**
168
- * Creates a Pino-aligned logger that writes JSONL to disk in local mode and
169
- * batches OTLP/HTTP/JSON log records to an OTel collector in cloud mode. Mode
170
- * is resolved from `OTEL_EXPORTER_OTLP_ENDPOINT` or the explicit override.
171
- */
172
- declare function createPlatformLogger(options: PlatformLoggerOptions): PlatformLogger;
173
- declare function defaultRunsDir(): string;
174
-
175
175
  export { type AggregateRunCostOptions, type AggregateRunCostResult, LOG_LEVELS, type LogLevelName, type LogLevelNumber, type LogRecord, type PinoLike, type PlatformLogger, type PlatformLoggerMode, type PlatformLoggerOptions, type PostgresLike, RUN_ID_ATTRIBUTE, RUN_STEP_TYPES, type ReadableSpanLike, type RunStepType, RunStepsSpanProcessor, type RunStepsSpanProcessorOptions, STEP_TYPE_ATTRIBUTE, type SpanContextLike, aggregateRunCost, createPlatformLogger, defaultRunsDir };