@tangle-network/agent-runtime 0.49.0 → 0.51.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.
Files changed (56) hide show
  1. package/dist/agent.d.ts +1 -1
  2. package/dist/agent.js +1 -1
  3. package/dist/analyst-loop.d.ts +1 -1
  4. package/dist/{chunk-VIEDXELL.js → chunk-47SWANFA.js} +94 -348
  5. package/dist/chunk-47SWANFA.js.map +1 -0
  6. package/dist/{chunk-XTEZ3YJ4.js → chunk-FKHNHUXP.js} +2 -2
  7. package/dist/{chunk-PXUTIMGJ.js → chunk-FQH33M5N.js} +160 -28
  8. package/dist/chunk-FQH33M5N.js.map +1 -0
  9. package/dist/chunk-G3RGMA7C.js +361 -0
  10. package/dist/chunk-G3RGMA7C.js.map +1 -0
  11. package/dist/{chunk-IQS4HI3F.js → chunk-HAA4KZUD.js} +10 -6
  12. package/dist/{chunk-IQS4HI3F.js.map → chunk-HAA4KZUD.js.map} +1 -1
  13. package/dist/{chunk-GHX7XOJ2.js → chunk-HYG4ISNS.js} +196 -6
  14. package/dist/chunk-HYG4ISNS.js.map +1 -0
  15. package/dist/{chunk-U2VEWKKK.js → chunk-XEI7AIHU.js} +3 -3
  16. package/dist/{coder-CVZNGbyg.d.ts → coder-_YCf3BAK.d.ts} +2 -2
  17. package/dist/{driver-DYU2sgHr.d.ts → driver-DLI1io57.d.ts} +1 -1
  18. package/dist/improvement.d.ts +96 -8
  19. package/dist/improvement.js +191 -9
  20. package/dist/improvement.js.map +1 -1
  21. package/dist/index.d.ts +7 -7
  22. package/dist/index.js +14 -11
  23. package/dist/index.js.map +1 -1
  24. package/dist/intelligence.d.ts +423 -0
  25. package/dist/intelligence.js +427 -0
  26. package/dist/intelligence.js.map +1 -0
  27. package/dist/{kb-gate-CsXpNRk7.d.ts → kb-gate-CHAyt4aI.d.ts} +436 -10
  28. package/dist/{loop-runner-bin-Cgn0A-NW.d.ts → loop-runner-bin-DFUNgpeK.d.ts} +4 -4
  29. package/dist/loop-runner-bin.d.ts +5 -5
  30. package/dist/loop-runner-bin.js +4 -3
  31. package/dist/loops.d.ts +5 -5
  32. package/dist/loops.js +7 -1
  33. package/dist/mcp/bin.js +29 -14
  34. package/dist/mcp/bin.js.map +1 -1
  35. package/dist/mcp/index.d.ts +17 -56
  36. package/dist/mcp/index.js +18 -5
  37. package/dist/mcp/index.js.map +1 -1
  38. package/dist/openai-tools-D4HLDWgw.d.ts +45 -0
  39. package/dist/platform.d.ts +120 -62
  40. package/dist/platform.js +68 -26
  41. package/dist/platform.js.map +1 -1
  42. package/dist/profiles.d.ts +2 -2
  43. package/dist/{run-loop-DvD4aGiE.d.ts → run-loop-BIineL1T.d.ts} +1 -1
  44. package/dist/runtime.d.ts +119 -17
  45. package/dist/runtime.js +7 -1
  46. package/dist/{types-BpDfCPUp.d.ts → types-5MGt5KTY.d.ts} +1 -1
  47. package/dist/{types-nBMuollC.d.ts → types-BEQsBhOE.d.ts} +1 -1
  48. package/dist/workflow.d.ts +2 -2
  49. package/dist/workflow.js +1 -1
  50. package/package.json +6 -1
  51. package/dist/chunk-GHX7XOJ2.js.map +0 -1
  52. package/dist/chunk-PXUTIMGJ.js.map +0 -1
  53. package/dist/chunk-VIEDXELL.js.map +0 -1
  54. package/dist/otel-export-EzfsVUhh.d.ts +0 -191
  55. /package/dist/{chunk-XTEZ3YJ4.js.map → chunk-FKHNHUXP.js.map} +0 -0
  56. /package/dist/{chunk-U2VEWKKK.js.map → chunk-XEI7AIHU.js.map} +0 -0
package/dist/agent.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as _tangle_network_agent_eval from '@tangle-network/agent-eval';
2
2
  import { TraceAnalystKindSpec, AnalystFinding } from '@tangle-network/agent-eval';
3
- import { R as RuntimeStreamEvent, S as SandboxClient, O as OutputAdapter, A as AgentRunSpec } from './types-nBMuollC.js';
3
+ import { R as RuntimeStreamEvent, S as SandboxClient, O as OutputAdapter, A as AgentRunSpec } from './types-BEQsBhOE.js';
4
4
  import { A as AgentSurfaces } from './improvement-adapter-BC4HhuAR.js';
5
5
  export { C as CreateSurfaceImprovementAdapterOpts, D as DraftPatchInput, a as DraftPatchOutput, R as ResolvedSurface, S as SurfaceImprovementEdit, b as SurfaceValidationIssue, c as createSurfaceImprovementAdapter, r as renderSurfaceIssues, d as resolveSubjectPath, v as validateSurfaces } from './improvement-adapter-BC4HhuAR.js';
6
6
  import { K as KnowledgeAdapter, a as RunAnalystLoopResult } from './types-p8dWBIXL.js';
package/dist/agent.js CHANGED
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-7JITYN6T.js";
4
4
  import {
5
5
  createSandboxForSpec
6
- } from "./chunk-PXUTIMGJ.js";
6
+ } from "./chunk-FQH33M5N.js";
7
7
  import {
8
8
  mapSandboxEvent
9
9
  } from "./chunk-GSUO5QS6.js";
@@ -1,5 +1,5 @@
1
1
  import { TraceAnalystByteBudgets, TraceAnalysisStore } from '@tangle-network/agent-eval';
2
- import { I as Iteration } from './types-nBMuollC.js';
2
+ import { I as Iteration } from './types-BEQsBhOE.js';
3
3
  import { R as RunAnalystLoopOpts, a as RunAnalystLoopResult } from './types-p8dWBIXL.js';
4
4
  export { A as AnalystLoopEvent, b as AnalystRegistryLike, c as AnalystRegistryStreamingLike, d as AutoApplyPolicy, F as FindingsStoreLike, I as ImprovementAdapter, e as ImprovementEditBatch, f as ImprovementReport, K as KnowledgeAdapter, g as KnowledgeProposalBatch, h as KnowledgeReport } from './types-p8dWBIXL.js';
5
5
  import '@tangle-network/sandbox';
@@ -1,6 +1,9 @@
1
1
  import {
2
- formatDetachedSessionRef
3
- } from "./chunk-GHX7XOJ2.js";
2
+ capDelegationTrace,
3
+ createDelegationTraceCollector,
4
+ formatDetachedSessionRef,
5
+ generateDelegationSpanId
6
+ } from "./chunk-HYG4ISNS.js";
4
7
  import {
5
8
  AgentEvalError,
6
9
  NotFoundError,
@@ -178,6 +181,7 @@ var DelegationTaskQueue = class _DelegationTaskQueue {
178
181
  resumeDelegate;
179
182
  maxTerminalRecords;
180
183
  onPersistError;
184
+ traceContext;
181
185
  persistTail = Promise.resolve();
182
186
  persistFailure;
183
187
  constructor(options = {}) {
@@ -193,6 +197,7 @@ var DelegationTaskQueue = class _DelegationTaskQueue {
193
197
  }
194
198
  }
195
199
  this.maxTerminalRecords = options.maxTerminalRecords ?? Number.POSITIVE_INFINITY;
200
+ this.traceContext = options.traceContext;
196
201
  this.onPersistError = options.onPersistError ?? ((error) => {
197
202
  queueMicrotask(() => {
198
203
  throw error;
@@ -243,7 +248,11 @@ var DelegationTaskQueue = class _DelegationTaskQueue {
243
248
  startedAt: this.now(),
244
249
  feedback: [],
245
250
  idempotencyKey: input.idempotencyKey,
246
- detachedSessionRef: input.detachedSessionRef
251
+ detachedSessionRef: input.detachedSessionRef,
252
+ ...this.traceContext !== void 0 ? {
253
+ traceId: this.traceContext.traceId,
254
+ ...this.traceContext.parentSpanId !== void 0 ? { parentSpanId: this.traceContext.parentSpanId } : {}
255
+ } : {}
247
256
  };
248
257
  this.records.set(taskId, record);
249
258
  this.controllers.set(taskId, controller);
@@ -257,11 +266,13 @@ var DelegationTaskQueue = class _DelegationTaskQueue {
257
266
  /**
258
267
  * Snapshot the current state of a delegation. Returns `undefined` for
259
268
  * unknown ids so callers can distinguish missing from terminal.
269
+ * `includeTrace` attaches the journaled loop-trace span tree — off by
270
+ * default so status polls stay light.
260
271
  */
261
- status(taskId) {
272
+ status(taskId, opts) {
262
273
  const record = this.records.get(taskId);
263
274
  if (!record) return void 0;
264
- return toStatusResult(record);
275
+ return toStatusResult(record, opts);
265
276
  }
266
277
  /**
267
278
  * Abort an in-flight delegation. Returns `false` if the task is unknown
@@ -335,6 +346,11 @@ var DelegationTaskQueue = class _DelegationTaskQueue {
335
346
  if (!record) return;
336
347
  record.status = "running";
337
348
  this.persist(record);
349
+ const traceCollector = createDelegationTraceCollector((spans) => {
350
+ if (isTerminal(currentStatus(record))) return;
351
+ this.appendTrace(record, spans);
352
+ this.persist(record);
353
+ });
338
354
  try {
339
355
  const output = await input.run({
340
356
  signal: controller.signal,
@@ -344,6 +360,7 @@ var DelegationTaskQueue = class _DelegationTaskQueue {
344
360
  this.persist(record);
345
361
  }
346
362
  },
363
+ traceEmitter: traceCollector.emitter,
347
364
  ...record.detachedSessionRef !== void 0 ? { detachedSessionRef: record.detachedSessionRef } : {},
348
365
  updateDetachedSessionRef: (ref) => {
349
366
  if (typeof ref !== "string" || ref.length === 0) {
@@ -356,6 +373,7 @@ var DelegationTaskQueue = class _DelegationTaskQueue {
356
373
  this.persist(record);
357
374
  }
358
375
  });
376
+ traceCollector.settle();
359
377
  if (currentStatus(record) === "cancelled") return;
360
378
  record.status = "completed";
361
379
  record.completedAt = this.now();
@@ -363,6 +381,7 @@ var DelegationTaskQueue = class _DelegationTaskQueue {
363
381
  this.persist(record);
364
382
  this.enforceRetention();
365
383
  } catch (err) {
384
+ traceCollector.settle();
366
385
  if (currentStatus(record) === "cancelled") return;
367
386
  record.status = "failed";
368
387
  record.completedAt = this.now();
@@ -373,6 +392,12 @@ var DelegationTaskQueue = class _DelegationTaskQueue {
373
392
  this.controllers.delete(taskId);
374
393
  }
375
394
  }
395
+ appendTrace(record, spans) {
396
+ if (spans.length === 0) return;
397
+ const { trace, truncated } = capDelegationTrace([...record.trace ?? [], ...spans]);
398
+ record.trace = trace;
399
+ if (truncated) record.traceTruncated = true;
400
+ }
376
401
  rehydrate(loaded) {
377
402
  const records = [...loaded].sort((a, b) => a.startedAt.localeCompare(b.startedAt));
378
403
  for (const record of records) {
@@ -404,6 +429,7 @@ var DelegationTaskQueue = class _DelegationTaskQueue {
404
429
  }
405
430
  async driveResume(record, detachedSessionRef, driver, controller) {
406
431
  const intervalMs = driver.intervalMs ?? 5e3;
432
+ const resumeStartMs = Date.parse(this.now());
407
433
  const ctx = {
408
434
  signal: controller.signal,
409
435
  report: (progress) => {
@@ -417,6 +443,7 @@ var DelegationTaskQueue = class _DelegationTaskQueue {
417
443
  const tick = await driver.tick({ record: structuredClone(record), detachedSessionRef }, ctx);
418
444
  if (currentStatus(record) === "cancelled") return;
419
445
  if (tick.state === "completed") {
446
+ this.appendResumeSpan(record, detachedSessionRef, resumeStartMs);
420
447
  record.status = "completed";
421
448
  record.completedAt = this.now();
422
449
  record.result = {
@@ -429,6 +456,7 @@ var DelegationTaskQueue = class _DelegationTaskQueue {
429
456
  return;
430
457
  }
431
458
  if (tick.state === "failed") {
459
+ this.appendResumeSpan(record, detachedSessionRef, resumeStartMs, tick.error.message);
432
460
  record.status = "failed";
433
461
  record.completedAt = this.now();
434
462
  record.error = tick.error;
@@ -440,6 +468,7 @@ var DelegationTaskQueue = class _DelegationTaskQueue {
440
468
  }
441
469
  } catch (err) {
442
470
  if (currentStatus(record) === "cancelled") return;
471
+ this.appendResumeSpan(record, detachedSessionRef, resumeStartMs, errorToShape(err).message);
443
472
  record.status = "failed";
444
473
  record.completedAt = this.now();
445
474
  record.error = errorToShape(err);
@@ -449,6 +478,30 @@ var DelegationTaskQueue = class _DelegationTaskQueue {
449
478
  this.controllers.delete(record.taskId);
450
479
  }
451
480
  }
481
+ /**
482
+ * Journal the resumed segment of a detached run as one compact span. The
483
+ * resume driver re-attaches after a process restart, so the original
484
+ * process's loop events are gone — this span records the post-restart
485
+ * observation window (re-attach → terminal tick) under the
486
+ * `'detached-resume'` driver tag, keeping restored delegations observable
487
+ * in the journal alongside trace-carrying live runs.
488
+ */
489
+ appendResumeSpan(record, detachedSessionRef, startMs, error) {
490
+ this.appendTrace(record, [
491
+ {
492
+ spanId: generateDelegationSpanId(),
493
+ name: "loop",
494
+ kind: "loop",
495
+ startMs,
496
+ endMs: Date.parse(this.now()),
497
+ meta: {
498
+ "tangle.loop.driver": "detached-resume",
499
+ "tangle.loop.detached_session_ref": detachedSessionRef,
500
+ ...error !== void 0 ? { "tangle.loop.error": error } : {}
501
+ }
502
+ }
503
+ ]);
504
+ }
452
505
  persist(record) {
453
506
  if (this.persistFailure) return;
454
507
  const snapshot = structuredClone(record);
@@ -531,7 +584,7 @@ function abortableDelay(ms, signal) {
531
584
  signal.addEventListener("abort", onAbort, { once: true });
532
585
  });
533
586
  }
534
- function toStatusResult(record) {
587
+ function toStatusResult(record, opts) {
535
588
  const out = {
536
589
  taskId: record.taskId,
537
590
  profile: record.profile,
@@ -543,6 +596,12 @@ function toStatusResult(record) {
543
596
  if (record.error) out.error = record.error;
544
597
  if (record.costUsd !== void 0) out.costUsd = record.costUsd;
545
598
  if (record.completedAt) out.completedAt = record.completedAt;
599
+ if (record.traceId !== void 0) out.traceId = record.traceId;
600
+ if (record.parentSpanId !== void 0) out.parentSpanId = record.parentSpanId;
601
+ if (opts?.includeTrace === true && record.trace && record.trace.length > 0) {
602
+ out.trace = record.trace.map((span) => ({ ...span }));
603
+ if (record.traceTruncated) out.traceTruncated = true;
604
+ }
546
605
  return out;
547
606
  }
548
607
  function toHistoryEntry(record) {
@@ -551,12 +610,14 @@ function toHistoryEntry(record) {
551
610
  profile: record.profile,
552
611
  args: record.args,
553
612
  status: record.status,
554
- startedAt: record.startedAt
613
+ startedAt: record.startedAt,
614
+ hasTrace: record.trace !== void 0 && record.trace.length > 0
555
615
  };
556
616
  if (record.namespace) entry.namespace = record.namespace;
557
617
  if (record.completedAt) entry.completedAt = record.completedAt;
558
618
  if (record.costUsd !== void 0) entry.costUsd = record.costUsd;
559
619
  if (record.feedback.length > 0) entry.feedback = [...record.feedback];
620
+ if (record.traceId !== void 0) entry.traceId = record.traceId;
560
621
  return entry;
561
622
  }
562
623
  function errorToShape(err) {
@@ -1133,6 +1194,9 @@ var DELEGATION_HISTORY_DESCRIPTION = [
1133
1194
  'success rate of coder delegations on this repo?". Feed the results back',
1134
1195
  "into your own routing and calibration.",
1135
1196
  "",
1197
+ "Each entry carries `hasTrace` \u2014 when true, the full loop-trace span tree",
1198
+ "is retrievable via delegation_status { taskId, includeTrace: true }.",
1199
+ "",
1136
1200
  'Filters: `namespace` (multi-tenant scope), `profile` ("coder" | "researcher"),',
1137
1201
  "`since` (ISO date \u2014 only delegations started at-or-after). `limit` defaults",
1138
1202
  "to 50, capped at 500."
@@ -1203,13 +1267,21 @@ var DELEGATION_STATUS_DESCRIPTION = [
1203
1267
  "patch, test/typecheck results, and diff stats. For a completed research",
1204
1268
  "task, `result.output` is the items + citations + proposedWrites bundle.",
1205
1269
  "",
1270
+ "Pass includeTrace: true to also receive the journaled loop-trace span",
1271
+ "tree (loop \u2192 round \u2192 iteration, with placement/cost/verdict metadata).",
1272
+ "Default false \u2014 keep routine polls light.",
1273
+ "",
1206
1274
  "Throws NotFoundError when taskId is unknown \u2014 never silently returns",
1207
1275
  "`pending` for a typo."
1208
1276
  ].join("\n");
1209
1277
  var DELEGATION_STATUS_INPUT_SCHEMA = {
1210
1278
  type: "object",
1211
1279
  properties: {
1212
- taskId: { type: "string", description: "Returned by delegate_code / delegate_research." }
1280
+ taskId: { type: "string", description: "Returned by delegate_code / delegate_research." },
1281
+ includeTrace: {
1282
+ type: "boolean",
1283
+ description: "Also return the journaled loop-trace span tree for this delegation. Default false."
1284
+ }
1213
1285
  },
1214
1286
  required: ["taskId"],
1215
1287
  additionalProperties: false
@@ -1223,12 +1295,22 @@ function validateDelegationStatusArgs(raw) {
1223
1295
  if (typeof taskId !== "string" || taskId.trim().length === 0) {
1224
1296
  throw new TypeError("delegation_status: `taskId` must be a non-empty string");
1225
1297
  }
1226
- return { taskId: taskId.trim() };
1298
+ const out = { taskId: taskId.trim() };
1299
+ if (value.includeTrace !== void 0) {
1300
+ if (typeof value.includeTrace !== "boolean") {
1301
+ throw new TypeError("delegation_status: `includeTrace` must be a boolean");
1302
+ }
1303
+ out.includeTrace = value.includeTrace;
1304
+ }
1305
+ return out;
1227
1306
  }
1228
1307
  function createDelegationStatusHandler(options) {
1229
1308
  return async (raw) => {
1230
1309
  const args = validateDelegationStatusArgs(raw);
1231
- const status = options.queue.status(args.taskId);
1310
+ const status = options.queue.status(
1311
+ args.taskId,
1312
+ args.includeTrace !== void 0 ? { includeTrace: args.includeTrace } : void 0
1313
+ );
1232
1314
  if (!status) {
1233
1315
  throw new NotFoundError(`delegation_status: unknown taskId "${args.taskId}"`);
1234
1316
  }
@@ -1236,337 +1318,6 @@ function createDelegationStatusHandler(options) {
1236
1318
  };
1237
1319
  }
1238
1320
 
1239
- // src/otel-export.ts
1240
- var SCOPE = { name: "@tangle-network/agent-runtime", version: "0.33.0" };
1241
- var GEN_AI = {
1242
- operation: "gen_ai.operation.name",
1243
- agentName: "gen_ai.agent.name",
1244
- conversationId: "gen_ai.conversation.id",
1245
- inputTokens: "gen_ai.usage.input_tokens",
1246
- outputTokens: "gen_ai.usage.output_tokens"
1247
- };
1248
- function createOtelExporter(config) {
1249
- const resolvedEndpoint = config?.endpoint ?? (typeof process !== "undefined" ? process.env.OTEL_EXPORTER_OTLP_ENDPOINT : void 0);
1250
- if (!resolvedEndpoint) return void 0;
1251
- const endpoint = resolvedEndpoint;
1252
- const headers = config?.headers ?? parseHeadersFromEnv();
1253
- const batchSize = config?.batchSize ?? 64;
1254
- const flushIntervalMs = config?.flushIntervalMs ?? 5e3;
1255
- const serviceName = config?.serviceName ?? "agent-runtime";
1256
- const resourceAttrs = config?.resourceAttributes ?? {};
1257
- const pending = [];
1258
- let timer;
1259
- let stopped = false;
1260
- const exporter = {
1261
- exportSpan(span) {
1262
- if (stopped) return;
1263
- pending.push(span);
1264
- if (pending.length >= batchSize) {
1265
- void doFlush();
1266
- }
1267
- },
1268
- async flush() {
1269
- await doFlush();
1270
- },
1271
- async shutdown() {
1272
- stopped = true;
1273
- if (timer !== void 0) {
1274
- clearInterval(timer);
1275
- timer = void 0;
1276
- }
1277
- await doFlush();
1278
- }
1279
- };
1280
- timer = setInterval(() => {
1281
- if (pending.length > 0) void doFlush();
1282
- }, flushIntervalMs);
1283
- if (typeof timer === "object" && "unref" in timer) {
1284
- ;
1285
- timer.unref();
1286
- }
1287
- async function doFlush() {
1288
- if (pending.length === 0) return;
1289
- const batch = pending.splice(0);
1290
- const body = {
1291
- resourceSpans: [
1292
- {
1293
- resource: {
1294
- attributes: toAttributes({
1295
- "service.name": serviceName,
1296
- ...resourceAttrs
1297
- })
1298
- },
1299
- scopeSpans: [{ scope: SCOPE, spans: batch }]
1300
- }
1301
- ]
1302
- };
1303
- const url = `${endpoint.replace(/\/+$/, "")}/v1/traces`;
1304
- try {
1305
- await fetch(url, {
1306
- method: "POST",
1307
- headers: { "content-type": "application/json", ...headers },
1308
- body: JSON.stringify(body)
1309
- });
1310
- } catch {
1311
- }
1312
- }
1313
- return exporter;
1314
- }
1315
- function loopEventToOtelSpan(event, traceId, parentSpanId) {
1316
- const spanId = generateSpanId();
1317
- const attrs = {
1318
- "loop.event_kind": event.kind,
1319
- "loop.run_id": event.runId
1320
- };
1321
- for (const [k, v] of Object.entries(event.payload)) {
1322
- if (typeof v === "string" || typeof v === "number" || typeof v === "boolean") {
1323
- attrs[`loop.${k}`] = v;
1324
- }
1325
- }
1326
- const ts = msToNs(event.timestamp);
1327
- return {
1328
- traceId: padTraceId(traceId),
1329
- spanId,
1330
- parentSpanId: parentSpanId ? padSpanId(parentSpanId) : void 0,
1331
- name: event.kind,
1332
- kind: 1,
1333
- startTimeUnixNano: ts,
1334
- endTimeUnixNano: ts,
1335
- attributes: toAttributes(attrs),
1336
- status: { code: 1 }
1337
- };
1338
- }
1339
- function buildLoopOtelSpans(events, traceId, rootParentSpanId) {
1340
- if (events.length === 0) return [];
1341
- const tid = padTraceId(traceId);
1342
- const out = [];
1343
- const num = (v) => typeof v === "number" && Number.isFinite(v) ? v : void 0;
1344
- const str = (v) => typeof v === "string" && v.length > 0 ? v : void 0;
1345
- const rec = (v) => v && typeof v === "object" ? v : {};
1346
- const started = events.find((e) => e.kind === "loop.started");
1347
- const ended = events.find((e) => e.kind === "loop.ended");
1348
- const runId = events[0]?.runId ?? "";
1349
- const rootStart = started?.timestamp ?? events[0].timestamp;
1350
- const rootEnd = ended?.timestamp ?? events[events.length - 1].timestamp;
1351
- const rootId = generateSpanId();
1352
- const make = (spanId, parentSpanId, name, startMs, endMs, attrs, statusCode = 1) => ({
1353
- traceId: tid,
1354
- spanId,
1355
- parentSpanId: parentSpanId ? padSpanId(parentSpanId) : void 0,
1356
- name,
1357
- kind: 1,
1358
- startTimeUnixNano: msToNs(startMs),
1359
- endTimeUnixNano: msToNs(endMs),
1360
- attributes: toAttributes(attrs),
1361
- status: { code: statusCode }
1362
- });
1363
- const sp = rec(started?.payload);
1364
- const rootAttrs = {
1365
- [GEN_AI.operation]: "invoke_workflow",
1366
- [GEN_AI.conversationId]: runId,
1367
- "tangle.loop.driver": str(sp.driver) ?? "driver"
1368
- };
1369
- if (Array.isArray(sp.agentRunNames) && sp.agentRunNames.length > 0) {
1370
- rootAttrs["tangle.loop.agents"] = sp.agentRunNames.map(String).join(",");
1371
- }
1372
- if (ended) {
1373
- const ep = rec(ended.payload);
1374
- const win = num(ep.winnerIterationIndex);
1375
- if (win !== void 0) rootAttrs["tangle.loop.winner.iteration_index"] = win;
1376
- const cost = num(ep.totalCostUsd);
1377
- if (cost !== void 0) rootAttrs["tangle.cost.usd"] = cost;
1378
- const dur = num(ep.durationMs);
1379
- if (dur !== void 0) rootAttrs["tangle.loop.duration_ms"] = dur;
1380
- const iters = num(ep.iterations);
1381
- if (iters !== void 0) rootAttrs["tangle.loop.iterations"] = iters;
1382
- }
1383
- out.push(make(rootId, rootParentSpanId, "loop", rootStart, rootEnd, rootAttrs));
1384
- const iterStartTs = /* @__PURE__ */ new Map();
1385
- const placementByIdx = /* @__PURE__ */ new Map();
1386
- let currentRoundId;
1387
- let pendingRound;
1388
- const flushRound = (endMs) => {
1389
- if (!pendingRound) return;
1390
- out.push(
1391
- make(pendingRound.id, rootId, "loop.round", pendingRound.start, endMs, pendingRound.attrs)
1392
- );
1393
- pendingRound = void 0;
1394
- };
1395
- for (const e of events) {
1396
- const p = rec(e.payload);
1397
- switch (e.kind) {
1398
- case "loop.plan": {
1399
- flushRound(e.timestamp);
1400
- const id = generateSpanId();
1401
- const roundIdx = num(p.roundIndex) ?? 0;
1402
- const attrs = {
1403
- [GEN_AI.operation]: "invoke_workflow",
1404
- "tangle.loop.round.index": roundIdx,
1405
- "tangle.loop.move.kind": str(p.moveKind) ?? "unknown",
1406
- "tangle.loop.move.round": roundIdx,
1407
- "tangle.loop.move.width": num(p.plannedCount) ?? 0
1408
- };
1409
- const r = str(p.rationale);
1410
- if (r) attrs["tangle.loop.move.rationale"] = r;
1411
- const parent = num(p.parentIndex);
1412
- if (parent !== void 0) attrs["tangle.loop.move.parent_index"] = parent;
1413
- if (Array.isArray(p.childIndices) && p.childIndices.length > 0) {
1414
- attrs["tangle.loop.move.child_indices"] = p.childIndices.map(String).join(",");
1415
- }
1416
- pendingRound = { id, start: e.timestamp, attrs };
1417
- currentRoundId = id;
1418
- break;
1419
- }
1420
- case "loop.iteration.started": {
1421
- const idx = num(p.iterationIndex);
1422
- if (idx !== void 0) iterStartTs.set(idx, e.timestamp);
1423
- break;
1424
- }
1425
- case "loop.iteration.dispatch": {
1426
- const idx = num(p.iterationIndex);
1427
- if (idx === void 0) break;
1428
- const place = {};
1429
- const kind = str(p.placement);
1430
- if (kind) place["tangle.loop.placement.kind"] = kind;
1431
- const sid = str(p.sandboxId);
1432
- if (sid) place["tangle.sandbox.id"] = sid;
1433
- const fid = str(p.fleetId);
1434
- if (fid) place["tangle.fleet.id"] = fid;
1435
- const mid = str(p.machineId);
1436
- if (mid) place["tangle.machine.id"] = mid;
1437
- placementByIdx.set(idx, place);
1438
- break;
1439
- }
1440
- case "loop.iteration.ended": {
1441
- const idx = num(p.iterationIndex) ?? 0;
1442
- const start = iterStartTs.get(idx) ?? e.timestamp;
1443
- const err = str(p.error);
1444
- const attrs = {
1445
- [GEN_AI.operation]: "invoke_agent",
1446
- "tangle.loop.iteration.index": idx
1447
- };
1448
- const agent = str(p.agentRunName);
1449
- if (agent) attrs[GEN_AI.agentName] = agent;
1450
- const tu = rec(p.tokenUsage);
1451
- const inTok = num(tu.input);
1452
- if (inTok !== void 0) attrs[GEN_AI.inputTokens] = inTok;
1453
- const outTok = num(tu.output);
1454
- if (outTok !== void 0) attrs[GEN_AI.outputTokens] = outTok;
1455
- const cost = num(p.costUsd);
1456
- if (cost !== void 0) attrs["tangle.cost.usd"] = cost;
1457
- const verdict = rec(p.verdict);
1458
- if (typeof verdict.valid === "boolean") attrs["tangle.loop.verdict.valid"] = verdict.valid;
1459
- const score = num(verdict.score);
1460
- if (score !== void 0) attrs["tangle.loop.verdict.score"] = score;
1461
- if (err) attrs["tangle.loop.error"] = err;
1462
- const gid = num(p.groupId);
1463
- if (gid !== void 0) attrs["tangle.loop.iteration.group_id"] = gid;
1464
- const par = num(p.parentIndex);
1465
- if (par !== void 0) attrs["tangle.loop.iteration.parent_index"] = par;
1466
- const dur = num(p.durationMs);
1467
- if (dur !== void 0) attrs["tangle.loop.iteration.duration_ms"] = dur;
1468
- const preview = str(p.outputPreview);
1469
- if (preview) attrs["tangle.loop.iteration.output_preview"] = preview;
1470
- Object.assign(attrs, placementByIdx.get(idx) ?? {});
1471
- out.push(
1472
- make(
1473
- generateSpanId(),
1474
- currentRoundId ?? rootId,
1475
- "loop.iteration",
1476
- start,
1477
- e.timestamp,
1478
- attrs,
1479
- err ? 2 : 1
1480
- )
1481
- );
1482
- break;
1483
- }
1484
- case "loop.decision": {
1485
- if (pendingRound) {
1486
- const dec = str(p.decision);
1487
- if (dec) pendingRound.attrs["tangle.loop.decision"] = dec;
1488
- flushRound(e.timestamp);
1489
- }
1490
- currentRoundId = void 0;
1491
- break;
1492
- }
1493
- }
1494
- }
1495
- flushRound(rootEnd);
1496
- return out;
1497
- }
1498
- function parseHeadersFromEnv() {
1499
- if (typeof process === "undefined") return {};
1500
- const raw = process.env.OTEL_EXPORTER_OTLP_HEADERS;
1501
- if (!raw) return {};
1502
- const out = {};
1503
- for (const pair of raw.split(",")) {
1504
- const eq = pair.indexOf("=");
1505
- if (eq < 0) continue;
1506
- const key = pair.slice(0, eq).trim();
1507
- const value = pair.slice(eq + 1).trim();
1508
- if (key) out[key] = value;
1509
- }
1510
- return out;
1511
- }
1512
- function toAttributes(record) {
1513
- return Object.entries(record).map(([key, value]) => ({
1514
- key,
1515
- value: typeof value === "number" ? Number.isInteger(value) ? { intValue: value.toString() } : { doubleValue: value } : typeof value === "boolean" ? { boolValue: value } : { stringValue: value }
1516
- }));
1517
- }
1518
- function msToNs(ms) {
1519
- return (BigInt(Math.floor(ms)) * 1000000n).toString();
1520
- }
1521
- function padSpanId(id) {
1522
- const cleaned = id.replace(/-/g, "");
1523
- return cleaned.slice(0, 16).padEnd(16, "0");
1524
- }
1525
- function padTraceId(id) {
1526
- const cleaned = id.replace(/-/g, "");
1527
- return cleaned.slice(0, 32).padEnd(32, "0");
1528
- }
1529
- function generateSpanId() {
1530
- const bytes = new Uint8Array(8);
1531
- if (typeof globalThis.crypto?.getRandomValues === "function") {
1532
- globalThis.crypto.getRandomValues(bytes);
1533
- } else {
1534
- for (let i = 0; i < 8; i++) bytes[i] = Math.floor(Math.random() * 256);
1535
- }
1536
- return Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join("");
1537
- }
1538
- var INTELLIGENCE_WIRE_VERSION = "2026-05-26.v1";
1539
- var DEFAULT_INTELLIGENCE_BASE = "https://intelligence.tangle.tools";
1540
- async function exportEvalRuns(events, config) {
1541
- if (events.length === 0) return { ok: true, status: 0, accepted: 0, rejected: [] };
1542
- const apiKey = config?.apiKey ?? (typeof process !== "undefined" ? process.env.TANGLE_API_KEY : void 0);
1543
- if (!apiKey)
1544
- throw new Error("exportEvalRuns: apiKey required (pass config.apiKey or set TANGLE_API_KEY)");
1545
- const base = config?.base ?? (typeof process !== "undefined" ? process.env.INTELLIGENCE_BASE : void 0) ?? DEFAULT_INTELLIGENCE_BASE;
1546
- const url = `${base.replace(/\/+$/, "")}/v1/ingest/eval-runs`;
1547
- const res = await fetch(url, {
1548
- method: "POST",
1549
- headers: {
1550
- "content-type": "application/json",
1551
- authorization: `Bearer ${apiKey}`,
1552
- "X-Tangle-Wire-Version": INTELLIGENCE_WIRE_VERSION,
1553
- ...config?.idempotencyKey ? { "Idempotency-Key": config.idempotencyKey } : {}
1554
- },
1555
- body: JSON.stringify({ wireVersion: INTELLIGENCE_WIRE_VERSION, events })
1556
- });
1557
- let parsed = {};
1558
- try {
1559
- parsed = await res.json();
1560
- } catch {
1561
- }
1562
- return {
1563
- ok: res.ok,
1564
- status: res.status,
1565
- accepted: parsed.accepted ?? (res.ok ? events.length : 0),
1566
- rejected: parsed.rejected ?? []
1567
- };
1568
- }
1569
-
1570
1321
  export {
1571
1322
  DelegationStateCorruptError,
1572
1323
  DelegationPersistenceError,
@@ -1600,11 +1351,6 @@ export {
1600
1351
  DELEGATION_STATUS_DESCRIPTION,
1601
1352
  DELEGATION_STATUS_INPUT_SCHEMA,
1602
1353
  validateDelegationStatusArgs,
1603
- createDelegationStatusHandler,
1604
- createOtelExporter,
1605
- loopEventToOtelSpan,
1606
- buildLoopOtelSpans,
1607
- INTELLIGENCE_WIRE_VERSION,
1608
- exportEvalRuns
1354
+ createDelegationStatusHandler
1609
1355
  };
1610
- //# sourceMappingURL=chunk-VIEDXELL.js.map
1356
+ //# sourceMappingURL=chunk-47SWANFA.js.map