@dogpile/sdk 0.4.0 → 0.5.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 (83) hide show
  1. package/CHANGELOG.md +65 -0
  2. package/dist/browser/index.js +726 -176
  3. package/dist/browser/index.js.map +1 -1
  4. package/dist/index.d.ts +3 -1
  5. package/dist/index.d.ts.map +1 -1
  6. package/dist/index.js +1 -0
  7. package/dist/index.js.map +1 -1
  8. package/dist/providers/openai-compatible.d.ts.map +1 -1
  9. package/dist/providers/openai-compatible.js +1 -0
  10. package/dist/providers/openai-compatible.js.map +1 -1
  11. package/dist/runtime/audit.d.ts +42 -0
  12. package/dist/runtime/audit.d.ts.map +1 -0
  13. package/dist/runtime/audit.js +73 -0
  14. package/dist/runtime/audit.js.map +1 -0
  15. package/dist/runtime/broadcast.d.ts.map +1 -1
  16. package/dist/runtime/broadcast.js +39 -36
  17. package/dist/runtime/broadcast.js.map +1 -1
  18. package/dist/runtime/coordinator.d.ts +5 -0
  19. package/dist/runtime/coordinator.d.ts.map +1 -1
  20. package/dist/runtime/coordinator.js +50 -39
  21. package/dist/runtime/coordinator.js.map +1 -1
  22. package/dist/runtime/defaults.d.ts.map +1 -1
  23. package/dist/runtime/defaults.js +12 -4
  24. package/dist/runtime/defaults.js.map +1 -1
  25. package/dist/runtime/engine.d.ts +17 -4
  26. package/dist/runtime/engine.d.ts.map +1 -1
  27. package/dist/runtime/engine.js +523 -18
  28. package/dist/runtime/engine.js.map +1 -1
  29. package/dist/runtime/health.d.ts +51 -0
  30. package/dist/runtime/health.d.ts.map +1 -0
  31. package/dist/runtime/health.js +85 -0
  32. package/dist/runtime/health.js.map +1 -0
  33. package/dist/runtime/introspection.d.ts +96 -0
  34. package/dist/runtime/introspection.d.ts.map +1 -0
  35. package/dist/runtime/introspection.js +31 -0
  36. package/dist/runtime/introspection.js.map +1 -0
  37. package/dist/runtime/metrics.d.ts +44 -0
  38. package/dist/runtime/metrics.d.ts.map +1 -0
  39. package/dist/runtime/metrics.js +12 -0
  40. package/dist/runtime/metrics.js.map +1 -0
  41. package/dist/runtime/model.d.ts.map +1 -1
  42. package/dist/runtime/model.js +34 -7
  43. package/dist/runtime/model.js.map +1 -1
  44. package/dist/runtime/provenance.d.ts +25 -0
  45. package/dist/runtime/provenance.d.ts.map +1 -0
  46. package/dist/runtime/provenance.js +13 -0
  47. package/dist/runtime/provenance.js.map +1 -0
  48. package/dist/runtime/sequential.d.ts.map +1 -1
  49. package/dist/runtime/sequential.js +39 -36
  50. package/dist/runtime/sequential.js.map +1 -1
  51. package/dist/runtime/shared.d.ts.map +1 -1
  52. package/dist/runtime/shared.js +39 -36
  53. package/dist/runtime/shared.js.map +1 -1
  54. package/dist/runtime/tracing.d.ts +31 -0
  55. package/dist/runtime/tracing.d.ts.map +1 -0
  56. package/dist/runtime/tracing.js +18 -0
  57. package/dist/runtime/tracing.js.map +1 -0
  58. package/dist/types/events.d.ts +10 -4
  59. package/dist/types/events.d.ts.map +1 -1
  60. package/dist/types/replay.d.ts +2 -0
  61. package/dist/types/replay.d.ts.map +1 -1
  62. package/dist/types.d.ts +124 -1
  63. package/dist/types.d.ts.map +1 -1
  64. package/dist/types.js.map +1 -1
  65. package/package.json +39 -1
  66. package/src/index.ts +5 -0
  67. package/src/providers/openai-compatible.ts +1 -0
  68. package/src/runtime/audit.ts +121 -0
  69. package/src/runtime/broadcast.ts +40 -37
  70. package/src/runtime/coordinator.ts +54 -39
  71. package/src/runtime/defaults.ts +13 -4
  72. package/src/runtime/engine.ts +648 -18
  73. package/src/runtime/health.ts +136 -0
  74. package/src/runtime/introspection.ts +122 -0
  75. package/src/runtime/metrics.ts +45 -0
  76. package/src/runtime/model.ts +38 -6
  77. package/src/runtime/provenance.ts +43 -0
  78. package/src/runtime/sequential.ts +40 -37
  79. package/src/runtime/shared.ts +40 -37
  80. package/src/runtime/tracing.ts +35 -0
  81. package/src/types/events.ts +10 -4
  82. package/src/types/replay.ts +2 -0
  83. package/src/types.ts +132 -1
@@ -17,6 +17,7 @@ import type {
17
17
  TerminationCondition,
18
18
  TerminationStopRecord,
19
19
  Tier,
20
+ Trace,
20
21
  TranscriptEntry
21
22
  } from "../types.js";
22
23
  import { createRunId, elapsedMs, nowMs, providerCallIdFor } from "./ids.js";
@@ -35,6 +36,7 @@ import {
35
36
  createTranscriptLink,
36
37
  emptyCost
37
38
  } from "./defaults.js";
39
+ import { computeHealth, DEFAULT_HEALTH_THRESHOLDS } from "./health.js";
38
40
  import { throwIfAborted } from "./cancellation.js";
39
41
  import { parseAgentDecision } from "./decisions.js";
40
42
  import { generateModelTurn } from "./model.js";
@@ -289,45 +291,46 @@ export async function runBroadcast(options: BroadcastRunOptions): Promise<RunRes
289
291
  transcriptEntryCount: transcript.length
290
292
  });
291
293
  const finalEvent = events.at(-1);
294
+ const trace: Trace = {
295
+ schemaVersion: "1.0",
296
+ runId,
297
+ protocol: "broadcast",
298
+ tier: options.tier,
299
+ modelProviderId: options.model.id,
300
+ agentsUsed: options.agents,
301
+ inputs: createReplayTraceRunInputs({
302
+ intent: options.intent,
303
+ protocol: options.protocol,
304
+ tier: options.tier,
305
+ modelProviderId: options.model.id,
306
+ agents: options.agents,
307
+ temperature: options.temperature
308
+ }),
309
+ budget: createReplayTraceBudget({
310
+ tier: options.tier,
311
+ ...(options.budget ? { caps: options.budget } : {}),
312
+ ...(options.terminate ? { termination: options.terminate } : {})
313
+ }),
314
+ budgetStateChanges: createReplayTraceBudgetStateChanges(events),
315
+ seed: createReplayTraceSeed(options.seed),
316
+ protocolDecisions,
317
+ providerCalls,
318
+ finalOutput: createReplayTraceFinalOutput(output, finalEvent ?? {
319
+ type: "final",
320
+ runId,
321
+ at: "",
322
+ output,
323
+ cost: totalCost,
324
+ transcript: createTranscriptLink(transcript)
325
+ }),
326
+ events,
327
+ transcript
328
+ };
292
329
 
293
330
  return {
294
331
  output,
295
332
  eventLog: createRunEventLog(runId, "broadcast", events),
296
- trace: {
297
- schemaVersion: "1.0",
298
- runId,
299
- protocol: "broadcast",
300
- tier: options.tier,
301
- modelProviderId: options.model.id,
302
- agentsUsed: options.agents,
303
- inputs: createReplayTraceRunInputs({
304
- intent: options.intent,
305
- protocol: options.protocol,
306
- tier: options.tier,
307
- modelProviderId: options.model.id,
308
- agents: options.agents,
309
- temperature: options.temperature
310
- }),
311
- budget: createReplayTraceBudget({
312
- tier: options.tier,
313
- ...(options.budget ? { caps: options.budget } : {}),
314
- ...(options.terminate ? { termination: options.terminate } : {})
315
- }),
316
- budgetStateChanges: createReplayTraceBudgetStateChanges(events),
317
- seed: createReplayTraceSeed(options.seed),
318
- protocolDecisions,
319
- providerCalls,
320
- finalOutput: createReplayTraceFinalOutput(output, finalEvent ?? {
321
- type: "final",
322
- runId,
323
- at: "",
324
- output,
325
- cost: totalCost,
326
- transcript: createTranscriptLink(transcript)
327
- }),
328
- events,
329
- transcript
330
- },
333
+ trace,
331
334
  transcript,
332
335
  usage: createRunUsage(totalCost),
333
336
  metadata: createRunMetadata({
@@ -345,7 +348,8 @@ export async function runBroadcast(options: BroadcastRunOptions): Promise<RunRes
345
348
  cost: totalCost,
346
349
  events
347
350
  }),
348
- cost: totalCost
351
+ cost: totalCost,
352
+ health: computeHealth(trace, DEFAULT_HEALTH_THRESHOLDS)
349
353
  };
350
354
 
351
355
  function stopIfNeeded(): boolean {
@@ -440,4 +444,3 @@ function responseCost(response: ModelResponse): CostSummary {
440
444
  totalTokens: response.usage?.totalTokens ?? 0
441
445
  };
442
446
  }
443
-
@@ -46,6 +46,7 @@ import {
46
46
  lastCostBearingEventCost,
47
47
  nextProviderCallId
48
48
  } from "./defaults.js";
49
+ import { computeHealth, DEFAULT_HEALTH_THRESHOLDS } from "./health.js";
49
50
  import {
50
51
  classifyAbortReason,
51
52
  classifyChildTimeoutSource,
@@ -64,6 +65,11 @@ import { createWrapUpHintController } from "./wrap-up.js";
64
65
  * in by `engine.ts` so coordinator avoids a circular import.
65
66
  */
66
67
  export type RunProtocolFn = (input: {
68
+ /**
69
+ * Planned child run id emitted on sub-run lifecycle events before dispatch.
70
+ * The engine callback uses this to look up the matching sub-run span.
71
+ */
72
+ readonly runId: string;
67
73
  readonly intent: string;
68
74
  readonly protocol: ProtocolSelection;
69
75
  readonly tier: Tier;
@@ -748,46 +754,47 @@ export async function runCoordinator(options: CoordinatorRunOptions): Promise<Ru
748
754
  transcriptEntryCount: transcript.length
749
755
  });
750
756
  const finalEvent = events.at(-1);
757
+ const trace: Trace = {
758
+ schemaVersion: "1.0",
759
+ runId,
760
+ protocol: "coordinator",
761
+ tier: options.tier,
762
+ modelProviderId: options.model.id,
763
+ agentsUsed: activeAgents,
764
+ inputs: createReplayTraceRunInputs({
765
+ intent: options.intent,
766
+ protocol: options.protocol,
767
+ tier: options.tier,
768
+ modelProviderId: options.model.id,
769
+ agents: activeAgents,
770
+ temperature: options.temperature
771
+ }),
772
+ budget: createReplayTraceBudget({
773
+ tier: options.tier,
774
+ ...(options.budget ? { caps: options.budget } : {}),
775
+ ...(options.terminate ? { termination: options.terminate } : {})
776
+ }),
777
+ budgetStateChanges: createReplayTraceBudgetStateChanges(events),
778
+ seed: createReplayTraceSeed(options.seed),
779
+ protocolDecisions,
780
+ providerCalls,
781
+ finalOutput: createReplayTraceFinalOutput(output, finalEvent ?? {
782
+ type: "final",
783
+ runId,
784
+ at: "",
785
+ output,
786
+ cost: totalCost,
787
+ transcript: createTranscriptLink(transcript)
788
+ }),
789
+ ...(triggeringFailureForAbortMode !== undefined ? { triggeringFailureForAbortMode } : {}),
790
+ events,
791
+ transcript
792
+ };
751
793
 
752
794
  return {
753
795
  output,
754
796
  eventLog: createRunEventLog(runId, "coordinator", events),
755
- trace: {
756
- schemaVersion: "1.0",
757
- runId,
758
- protocol: "coordinator",
759
- tier: options.tier,
760
- modelProviderId: options.model.id,
761
- agentsUsed: activeAgents,
762
- inputs: createReplayTraceRunInputs({
763
- intent: options.intent,
764
- protocol: options.protocol,
765
- tier: options.tier,
766
- modelProviderId: options.model.id,
767
- agents: activeAgents,
768
- temperature: options.temperature
769
- }),
770
- budget: createReplayTraceBudget({
771
- tier: options.tier,
772
- ...(options.budget ? { caps: options.budget } : {}),
773
- ...(options.terminate ? { termination: options.terminate } : {})
774
- }),
775
- budgetStateChanges: createReplayTraceBudgetStateChanges(events),
776
- seed: createReplayTraceSeed(options.seed),
777
- protocolDecisions,
778
- providerCalls,
779
- finalOutput: createReplayTraceFinalOutput(output, finalEvent ?? {
780
- type: "final",
781
- runId,
782
- at: "",
783
- output,
784
- cost: totalCost,
785
- transcript: createTranscriptLink(transcript)
786
- }),
787
- ...(triggeringFailureForAbortMode !== undefined ? { triggeringFailureForAbortMode } : {}),
788
- events,
789
- transcript
790
- },
797
+ trace,
791
798
  transcript,
792
799
  usage: createRunUsage(totalCost),
793
800
  metadata: createRunMetadata({
@@ -805,7 +812,8 @@ export async function runCoordinator(options: CoordinatorRunOptions): Promise<Ru
805
812
  cost: totalCost,
806
813
  events
807
814
  }),
808
- cost: totalCost
815
+ cost: totalCost,
816
+ health: computeHealth(trace, DEFAULT_HEALTH_THRESHOLDS)
809
817
  };
810
818
 
811
819
  function stopIfNeeded(): boolean {
@@ -1404,6 +1412,7 @@ async function dispatchDelegate(input: DispatchDelegateOptions): Promise<Dispatc
1404
1412
  : undefined;
1405
1413
 
1406
1414
  const childOptions = {
1415
+ runId: childRunId,
1407
1416
  intent: decision.intent,
1408
1417
  protocol: decision.protocol,
1409
1418
  tier: options.tier,
@@ -1614,8 +1623,8 @@ async function dispatchDelegate(input: DispatchDelegateOptions): Promise<Dispatc
1614
1623
  function renderSubRunResult(childRunId: string, subResult: RunResult): string {
1615
1624
  const turns = subResult.transcript.length;
1616
1625
  const costUsd = subResult.cost.usd ?? 0;
1617
- const startedAt = subResult.trace.events[0]?.at;
1618
- const endedAt = subResult.trace.events.at(-1)?.at;
1626
+ const startedAt = eventTimestamp(subResult.trace.events[0]);
1627
+ const endedAt = eventTimestamp(subResult.trace.events.at(-1));
1619
1628
  const durationMs =
1620
1629
  startedAt && endedAt
1621
1630
  ? Math.max(0, Date.parse(endedAt) - Date.parse(startedAt))
@@ -1626,6 +1635,12 @@ function renderSubRunResult(childRunId: string, subResult: RunResult): string {
1626
1635
  ].join("\n");
1627
1636
  }
1628
1637
 
1638
+ function eventTimestamp(event: RunEvent | undefined): string | undefined {
1639
+ if (event === undefined) return undefined;
1640
+ if ("at" in event) return event.at;
1641
+ return event.type === "model-response" ? event.completedAt : event.startedAt;
1642
+ }
1643
+
1629
1644
  /**
1630
1645
  * Build a JSON-serializable {@link Trace} for `sub-run-failed.partialTrace`
1631
1646
  * from a buffered tee of child emits. Keeps `runProtocol`'s error contract
@@ -236,8 +236,8 @@ export function createRunMetadata(options: {
236
236
  tier: options.tier,
237
237
  modelProviderId: options.modelProviderId,
238
238
  agentsUsed: options.agentsUsed,
239
- startedAt: firstEvent?.at ?? "",
240
- completedAt: lastEvent?.at ?? ""
239
+ startedAt: eventTimestamp(firstEvent) ?? "",
240
+ completedAt: eventTimestamp(lastEvent) ?? ""
241
241
  };
242
242
  }
243
243
 
@@ -365,7 +365,7 @@ export function createReplayTraceProtocolDecision(
365
365
  eventType: event.type,
366
366
  protocol,
367
367
  decision: options.decision ?? defaultProtocolDecision(event),
368
- at: event.at,
368
+ at: eventTimestamp(event),
369
369
  ...(options.turn !== undefined ? { turn: options.turn } : {}),
370
370
  ...(options.phase !== undefined ? { phase: options.phase } : {}),
371
371
  ...(options.round !== undefined ? { round: options.round } : {}),
@@ -550,7 +550,7 @@ export function createReplayTraceFinalOutput(output: string, event: RunEvent): R
550
550
  kind: "replay-trace-final-output",
551
551
  output,
552
552
  cost: emptyCost(),
553
- completedAt: event.at,
553
+ completedAt: eventTimestamp(event),
554
554
  transcript: {
555
555
  kind: "trace-transcript",
556
556
  entryCount: 0,
@@ -559,6 +559,14 @@ export function createReplayTraceFinalOutput(output: string, event: RunEvent): R
559
559
  };
560
560
  }
561
561
 
562
+ function eventTimestamp(event: RunEvent): string;
563
+ function eventTimestamp(event: RunEvent | undefined): string | undefined;
564
+ function eventTimestamp(event: RunEvent | undefined): string | undefined {
565
+ if (event === undefined) return undefined;
566
+ if ("at" in event) return event.at;
567
+ return event.type === "model-response" ? event.completedAt : event.startedAt;
568
+ }
569
+
562
570
  export function nextProviderCallId(
563
571
  runId: string,
564
572
  providerCalls: readonly ReplayTraceProviderCall[]
@@ -589,6 +597,7 @@ export function canonicalizeRunResult(result: RunResult): RunResult {
589
597
  cost: canonicalizeSerializable(result.cost),
590
598
  ...(result.evaluation !== undefined ? { evaluation: canonicalizeSerializable(result.evaluation) } : {}),
591
599
  eventLog,
600
+ health: canonicalizeSerializable(result.health),
592
601
  metadata: canonicalizeSerializable(result.metadata),
593
602
  output: result.output,
594
603
  ...(result.quality !== undefined ? { quality: canonicalizeSerializable(result.quality) } : {}),