nexus-ai-pro 2.0.0 → 2.2.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 (282) hide show
  1. package/API_STABILITY.md +65 -0
  2. package/CHANGELOG.md +267 -1
  3. package/MIGRATING.md +1 -1
  4. package/README.md +17 -8
  5. package/dist/agent/create-agent.d.ts +9 -1
  6. package/dist/agent/create-agent.js +40 -1
  7. package/dist/cache/memory-cache.d.ts +8 -0
  8. package/dist/cache/memory-cache.js +9 -0
  9. package/dist/cache/semantic-cache.d.ts +6 -3
  10. package/dist/cache/semantic-cache.js +5 -2
  11. package/dist/cli/args.js +3 -0
  12. package/dist/cli/db.d.ts +16 -4
  13. package/dist/cli/db.js +169 -22
  14. package/dist/cli/doctor.d.ts +17 -0
  15. package/dist/cli/doctor.js +53 -0
  16. package/dist/cli/graph.d.ts +9 -0
  17. package/dist/cli/graph.js +47 -0
  18. package/dist/cli.js +21 -2
  19. package/dist/core/lifecycle.js +11 -6
  20. package/dist/core/nexus.d.ts +12 -2
  21. package/dist/core/nexus.js +106 -23
  22. package/dist/doctor/index.d.ts +90 -0
  23. package/dist/doctor/index.js +237 -0
  24. package/dist/evals/judge.d.ts +11 -0
  25. package/dist/evals/judge.js +33 -0
  26. package/dist/evaluate/index.d.ts +1 -0
  27. package/dist/evaluate/index.js +1 -0
  28. package/dist/evaluate/provenance.d.ts +22 -0
  29. package/dist/evaluate/provenance.js +10 -0
  30. package/dist/evaluate/run.js +20 -4
  31. package/dist/graph/durability.d.ts +27 -0
  32. package/dist/graph/durability.js +66 -0
  33. package/dist/graph/errors.d.ts +30 -4
  34. package/dist/graph/errors.js +18 -2
  35. package/dist/graph/event-stream.d.ts +75 -0
  36. package/dist/graph/event-stream.js +289 -0
  37. package/dist/graph/functional.d.ts +80 -7
  38. package/dist/graph/functional.js +138 -35
  39. package/dist/graph/graph.d.ts +56 -8
  40. package/dist/graph/graph.js +331 -49
  41. package/dist/graph/index.d.ts +4 -2
  42. package/dist/graph/index.js +3 -1
  43. package/dist/graph/lint.d.ts +57 -0
  44. package/dist/graph/lint.js +141 -0
  45. package/dist/graph/run-control.d.ts +28 -0
  46. package/dist/graph/run-control.js +26 -0
  47. package/dist/images/evals.js +4 -2
  48. package/dist/operations/adapters.d.ts +52 -4
  49. package/dist/operations/adapters.js +194 -7
  50. package/dist/operations/runner.js +14 -15
  51. package/dist/operations/stats.js +8 -1
  52. package/dist/operations/store.d.ts +5 -1
  53. package/dist/operations/store.js +7 -0
  54. package/dist/ops/circuit-breaker.d.ts +52 -0
  55. package/dist/ops/circuit-breaker.js +4 -0
  56. package/dist/ops/circuit-store.d.ts +13 -2
  57. package/dist/ops/circuit-store.js +68 -0
  58. package/dist/ops/circuit-sync.d.ts +17 -0
  59. package/dist/ops/circuit-sync.js +86 -0
  60. package/dist/ops/health.d.ts +24 -0
  61. package/dist/ops/health.js +38 -10
  62. package/dist/ops/index.d.ts +1 -1
  63. package/dist/ops/index.js +1 -1
  64. package/dist/ops/rate-limit-adapters.d.ts +23 -0
  65. package/dist/ops/rate-limit-adapters.js +34 -0
  66. package/dist/ops/rate-limiter.d.ts +14 -2
  67. package/dist/ops/rate-limiter.js +31 -0
  68. package/dist/postgres/circuits.d.ts +21 -4
  69. package/dist/postgres/circuits.js +65 -4
  70. package/dist/postgres/client.d.ts +0 -2
  71. package/dist/postgres/client.js +0 -4
  72. package/dist/postgres/evaluate.d.ts +16 -4
  73. package/dist/postgres/evaluate.js +17 -5
  74. package/dist/postgres/index.d.ts +32 -11
  75. package/dist/postgres/index.js +65 -31
  76. package/dist/postgres/migrations.d.ts +60 -0
  77. package/dist/postgres/migrations.js +121 -0
  78. package/dist/postgres/operations.d.ts +14 -3
  79. package/dist/postgres/operations.js +45 -15
  80. package/dist/postgres/prompts.d.ts +11 -2
  81. package/dist/postgres/prompts.js +14 -3
  82. package/dist/postgres/rollups.d.ts +35 -0
  83. package/dist/postgres/rollups.js +129 -0
  84. package/dist/postgres/store.d.ts +11 -2
  85. package/dist/postgres/store.js +14 -3
  86. package/dist/postgres/traces.d.ts +13 -3
  87. package/dist/postgres/traces.js +25 -3
  88. package/dist/postgres/vectors.d.ts +11 -2
  89. package/dist/postgres/vectors.js +14 -3
  90. package/dist/router/auto-router.d.ts +34 -7
  91. package/dist/router/auto-router.js +201 -68
  92. package/dist/server/assistant.d.ts +44 -0
  93. package/dist/server/assistant.js +39 -0
  94. package/dist/server/errors.d.ts +12 -0
  95. package/dist/server/errors.js +7 -0
  96. package/dist/server/index.d.ts +1 -1
  97. package/dist/server/index.js +1 -1
  98. package/dist/server/runs.d.ts +28 -1
  99. package/dist/server/runs.js +110 -14
  100. package/dist/sqlite/index.d.ts +16 -3
  101. package/dist/sqlite/index.js +16 -3
  102. package/dist/sqlite/migrations.d.ts +26 -0
  103. package/dist/sqlite/migrations.js +63 -0
  104. package/dist/sqlite/operations.d.ts +14 -3
  105. package/dist/sqlite/operations.js +42 -15
  106. package/dist/sqlite/store.d.ts +9 -2
  107. package/dist/sqlite/store.js +13 -3
  108. package/dist/sqlite/vectors.d.ts +11 -2
  109. package/dist/sqlite/vectors.js +13 -2
  110. package/dist/store/tenant.d.ts +12 -0
  111. package/dist/store/tenant.js +29 -0
  112. package/dist/tenancy/index.d.ts +113 -0
  113. package/dist/tenancy/index.js +233 -0
  114. package/dist/testing/record.d.ts +42 -0
  115. package/dist/testing/record.js +57 -5
  116. package/dist/tracing/index.d.ts +3 -3
  117. package/dist/tracing/index.js +2 -2
  118. package/dist/tracing/instrument.js +30 -0
  119. package/dist/tracing/otlp.d.ts +91 -0
  120. package/dist/tracing/otlp.js +124 -0
  121. package/dist/tracing/rollups.d.ts +100 -0
  122. package/dist/tracing/rollups.js +139 -0
  123. package/dist/tracing/stores.d.ts +17 -0
  124. package/dist/tracing/stores.js +23 -0
  125. package/dist/tracing/tracer.d.ts +50 -4
  126. package/dist/tracing/tracer.js +85 -6
  127. package/dist/types/config.d.ts +33 -2
  128. package/dist/types/evaluate.d.ts +37 -0
  129. package/dist/types/graph.d.ts +354 -9
  130. package/dist/types/graph.js +3 -1
  131. package/dist/types/messages.d.ts +5 -0
  132. package/dist/types/operations.d.ts +22 -2
  133. package/dist/types/response.d.ts +20 -0
  134. package/dist/types/server.d.ts +18 -0
  135. package/dist/types/tracing.d.ts +11 -0
  136. package/dist/utils/schema-migrations.d.ts +97 -0
  137. package/dist/utils/schema-migrations.js +91 -0
  138. package/dist/utils/signals.d.ts +17 -0
  139. package/dist/utils/signals.js +26 -0
  140. package/dist/utils/tenant.d.ts +14 -0
  141. package/dist/utils/tenant.js +16 -0
  142. package/dist/version.d.ts +5 -0
  143. package/dist/version.js +1 -0
  144. package/dist-cjs/agent/create-agent.d.ts +9 -1
  145. package/dist-cjs/agent/create-agent.js +40 -1
  146. package/dist-cjs/cache/memory-cache.d.ts +8 -0
  147. package/dist-cjs/cache/memory-cache.js +9 -0
  148. package/dist-cjs/cache/semantic-cache.d.ts +6 -3
  149. package/dist-cjs/cache/semantic-cache.js +5 -2
  150. package/dist-cjs/cli/args.js +3 -0
  151. package/dist-cjs/cli/db.d.ts +16 -4
  152. package/dist-cjs/cli/db.js +200 -20
  153. package/dist-cjs/cli/doctor.d.ts +17 -0
  154. package/dist-cjs/cli/doctor.js +56 -0
  155. package/dist-cjs/cli/graph.d.ts +9 -0
  156. package/dist-cjs/cli/graph.js +50 -0
  157. package/dist-cjs/core/lifecycle.js +11 -6
  158. package/dist-cjs/core/nexus.d.ts +12 -2
  159. package/dist-cjs/core/nexus.js +106 -23
  160. package/dist-cjs/doctor/index.d.ts +90 -0
  161. package/dist-cjs/doctor/index.js +276 -0
  162. package/dist-cjs/evals/judge.d.ts +11 -0
  163. package/dist-cjs/evals/judge.js +33 -0
  164. package/dist-cjs/evaluate/index.d.ts +1 -0
  165. package/dist-cjs/evaluate/index.js +3 -1
  166. package/dist-cjs/evaluate/provenance.d.ts +22 -0
  167. package/dist-cjs/evaluate/provenance.js +14 -0
  168. package/dist-cjs/evaluate/run.js +20 -4
  169. package/dist-cjs/graph/durability.d.ts +27 -0
  170. package/dist-cjs/graph/durability.js +70 -0
  171. package/dist-cjs/graph/errors.d.ts +30 -4
  172. package/dist-cjs/graph/errors.js +20 -3
  173. package/dist-cjs/graph/event-stream.d.ts +75 -0
  174. package/dist-cjs/graph/event-stream.js +295 -0
  175. package/dist-cjs/graph/functional.d.ts +80 -7
  176. package/dist-cjs/graph/functional.js +137 -34
  177. package/dist-cjs/graph/graph.d.ts +56 -8
  178. package/dist-cjs/graph/graph.js +330 -48
  179. package/dist-cjs/graph/index.d.ts +4 -2
  180. package/dist-cjs/graph/index.js +7 -1
  181. package/dist-cjs/graph/lint.d.ts +57 -0
  182. package/dist-cjs/graph/lint.js +144 -0
  183. package/dist-cjs/graph/run-control.d.ts +28 -0
  184. package/dist-cjs/graph/run-control.js +30 -0
  185. package/dist-cjs/images/evals.js +4 -2
  186. package/dist-cjs/operations/adapters.d.ts +52 -4
  187. package/dist-cjs/operations/adapters.js +193 -6
  188. package/dist-cjs/operations/runner.js +14 -15
  189. package/dist-cjs/operations/stats.js +8 -1
  190. package/dist-cjs/operations/store.d.ts +5 -1
  191. package/dist-cjs/operations/store.js +7 -0
  192. package/dist-cjs/ops/circuit-breaker.d.ts +52 -0
  193. package/dist-cjs/ops/circuit-breaker.js +4 -0
  194. package/dist-cjs/ops/circuit-store.d.ts +13 -2
  195. package/dist-cjs/ops/circuit-store.js +68 -0
  196. package/dist-cjs/ops/circuit-sync.d.ts +17 -0
  197. package/dist-cjs/ops/circuit-sync.js +87 -0
  198. package/dist-cjs/ops/health.d.ts +24 -0
  199. package/dist-cjs/ops/health.js +38 -10
  200. package/dist-cjs/ops/index.d.ts +1 -1
  201. package/dist-cjs/ops/rate-limit-adapters.d.ts +23 -0
  202. package/dist-cjs/ops/rate-limit-adapters.js +35 -1
  203. package/dist-cjs/ops/rate-limiter.d.ts +14 -2
  204. package/dist-cjs/ops/rate-limiter.js +32 -0
  205. package/dist-cjs/postgres/circuits.d.ts +21 -4
  206. package/dist-cjs/postgres/circuits.js +98 -3
  207. package/dist-cjs/postgres/client.d.ts +0 -2
  208. package/dist-cjs/postgres/client.js +0 -5
  209. package/dist-cjs/postgres/evaluate.d.ts +16 -4
  210. package/dist-cjs/postgres/evaluate.js +50 -4
  211. package/dist-cjs/postgres/index.d.ts +32 -11
  212. package/dist-cjs/postgres/index.js +69 -20
  213. package/dist-cjs/postgres/migrations.d.ts +60 -0
  214. package/dist-cjs/postgres/migrations.js +129 -0
  215. package/dist-cjs/postgres/operations.d.ts +14 -3
  216. package/dist-cjs/postgres/operations.js +78 -14
  217. package/dist-cjs/postgres/prompts.d.ts +11 -2
  218. package/dist-cjs/postgres/prompts.js +47 -2
  219. package/dist-cjs/postgres/rollups.d.ts +35 -0
  220. package/dist-cjs/postgres/rollups.js +168 -0
  221. package/dist-cjs/postgres/store.d.ts +11 -2
  222. package/dist-cjs/postgres/store.js +47 -2
  223. package/dist-cjs/postgres/traces.d.ts +13 -3
  224. package/dist-cjs/postgres/traces.js +58 -2
  225. package/dist-cjs/postgres/vectors.d.ts +11 -2
  226. package/dist-cjs/postgres/vectors.js +47 -2
  227. package/dist-cjs/router/auto-router.d.ts +34 -7
  228. package/dist-cjs/router/auto-router.js +201 -68
  229. package/dist-cjs/server/assistant.d.ts +44 -0
  230. package/dist-cjs/server/assistant.js +39 -0
  231. package/dist-cjs/server/errors.d.ts +12 -0
  232. package/dist-cjs/server/errors.js +9 -1
  233. package/dist-cjs/server/index.d.ts +1 -1
  234. package/dist-cjs/server/index.js +2 -1
  235. package/dist-cjs/server/runs.d.ts +28 -1
  236. package/dist-cjs/server/runs.js +109 -13
  237. package/dist-cjs/sqlite/index.d.ts +16 -3
  238. package/dist-cjs/sqlite/index.js +31 -10
  239. package/dist-cjs/sqlite/migrations.d.ts +26 -0
  240. package/dist-cjs/sqlite/migrations.js +71 -0
  241. package/dist-cjs/sqlite/operations.d.ts +14 -3
  242. package/dist-cjs/sqlite/operations.js +76 -15
  243. package/dist-cjs/sqlite/store.d.ts +9 -2
  244. package/dist-cjs/sqlite/store.js +47 -3
  245. package/dist-cjs/sqlite/vectors.d.ts +11 -2
  246. package/dist-cjs/sqlite/vectors.js +47 -2
  247. package/dist-cjs/store/tenant.d.ts +12 -0
  248. package/dist-cjs/store/tenant.js +33 -0
  249. package/dist-cjs/tenancy/index.d.ts +113 -0
  250. package/dist-cjs/tenancy/index.js +250 -0
  251. package/dist-cjs/testing/record.d.ts +42 -0
  252. package/dist-cjs/testing/record.js +57 -5
  253. package/dist-cjs/tracing/index.d.ts +3 -3
  254. package/dist-cjs/tracing/index.js +4 -1
  255. package/dist-cjs/tracing/instrument.js +30 -0
  256. package/dist-cjs/tracing/otlp.d.ts +91 -0
  257. package/dist-cjs/tracing/otlp.js +129 -0
  258. package/dist-cjs/tracing/rollups.d.ts +100 -0
  259. package/dist-cjs/tracing/rollups.js +147 -0
  260. package/dist-cjs/tracing/stores.d.ts +17 -0
  261. package/dist-cjs/tracing/stores.js +24 -0
  262. package/dist-cjs/tracing/tracer.d.ts +50 -4
  263. package/dist-cjs/tracing/tracer.js +87 -6
  264. package/dist-cjs/types/config.d.ts +33 -2
  265. package/dist-cjs/types/evaluate.d.ts +37 -0
  266. package/dist-cjs/types/graph.d.ts +354 -9
  267. package/dist-cjs/types/graph.js +3 -1
  268. package/dist-cjs/types/messages.d.ts +5 -0
  269. package/dist-cjs/types/operations.d.ts +22 -2
  270. package/dist-cjs/types/response.d.ts +20 -0
  271. package/dist-cjs/types/server.d.ts +18 -0
  272. package/dist-cjs/types/tracing.d.ts +11 -0
  273. package/dist-cjs/utils/schema-migrations.d.ts +97 -0
  274. package/dist-cjs/utils/schema-migrations.js +102 -0
  275. package/dist-cjs/utils/signals.d.ts +17 -0
  276. package/dist-cjs/utils/signals.js +29 -0
  277. package/dist-cjs/utils/tenant.d.ts +14 -0
  278. package/dist-cjs/utils/tenant.js +22 -0
  279. package/dist-cjs/version.d.ts +5 -0
  280. package/dist-cjs/version.js +4 -0
  281. package/llms.txt +4 -3
  282. package/package.json +110 -2
@@ -4,6 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.JsonlTraceStore = exports.MemoryTraceStore = exports.assembleTree = exports.applyQuery = void 0;
7
+ exports.closeAbandonedRuns = closeAbandonedRuns;
7
8
  const promises_1 = require("node:fs/promises");
8
9
  const node_path_1 = __importDefault(require("node:path"));
9
10
  const query_js_1 = require("./query.js");
@@ -52,6 +53,29 @@ class MemoryTraceStore {
52
53
  }
53
54
  }
54
55
  exports.MemoryTraceStore = MemoryTraceStore;
56
+ async function closeAbandonedRuns(store, options) {
57
+ const now = options.now?.() ?? new Date();
58
+ const until = new Date(now.getTime() - options.olderThanMs).toISOString();
59
+ let closed = 0;
60
+ const seen = new Set();
61
+ for (;;) {
62
+ const stuck = (await store.query({ status: 'running', until, limit: 500 })).filter((run) => !seen.has(run.id));
63
+ if (stuck.length === 0)
64
+ return closed;
65
+ for (const run of stuck) {
66
+ seen.add(run.id);
67
+ await store.save({
68
+ ...run,
69
+ status: 'error',
70
+ endedAt: now.toISOString(),
71
+ latencyMs: Math.max(0, now.getTime() - Date.parse(run.startedAt)),
72
+ error: { name: 'RunAbandoned', message: 'The process running this ended before it finished' },
73
+ metadata: { ...run.metadata, abandoned: true },
74
+ });
75
+ closed += 1;
76
+ }
77
+ }
78
+ }
55
79
  class JsonlTraceStore {
56
80
  file;
57
81
  maxBytes;
@@ -1,16 +1,32 @@
1
- import type { RunFeedback, RunKind, RedactionPolicy, SamplingPolicy, TraceStore } from '../types/tracing.js';
1
+ import type { RunFeedback, RunKind, RedactionPolicy, SamplingPolicy, TraceExporter, TraceStore } from '../types/tracing.js';
2
2
  /** Configuration for a tracer. */
3
3
  export interface TracerOptions {
4
- /** Where finished traces are written. */
4
+ /** Where runs are written. */
5
5
  store: TraceStore;
6
6
  /** Which traces are kept. */
7
7
  sampling?: SamplingPolicy;
8
- /** What is removed from runs before they are stored. */
8
+ /** What is removed from runs before they are stored or exported. */
9
9
  redaction?: RedactionPolicy;
10
10
  /** Tags added to every run, such as the deployment or the release. */
11
11
  tags?: string[];
12
12
  /** Metadata added to every run. */
13
13
  metadata?: Record<string, unknown>;
14
+ /**
15
+ * Writes each run when it starts and again when it ends, instead of a whole trace once its root
16
+ * finishes.
17
+ *
18
+ * A trace written at the end is lost with the process that held it. Written as it runs, a crashed
19
+ * run stays in the store with every run that finished, and a run in progress can be watched.
20
+ * Sampling is then decided when the root starts. A trace not sampled is still held in memory and
21
+ * written at the end when tail sampling keeps it, so `keepErrors` still shows every failure.
22
+ * Defaults to false, which writes at the end, as before.
23
+ */
24
+ incremental?: boolean;
25
+ /**
26
+ * Also hands every finished run that is kept to these exporters, after redaction, such as an
27
+ * `OtlpTraceExporter` sending OpenTelemetry spans to a collector.
28
+ */
29
+ exporters?: TraceExporter[];
14
30
  /** Replaces the system clock, for tests. */
15
31
  now?: () => Date;
16
32
  /** Errors from the store are swallowed by default; a hook lets an application notice them. */
@@ -36,6 +52,12 @@ export interface StartRunOptions {
36
52
  parentId?: string;
37
53
  /** Joins an existing trace instead of starting a new one. */
38
54
  traceId?: string;
55
+ /**
56
+ * Continues a trace another process started, from a W3C `traceparent` header such as the one
57
+ * `RunHandle.traceparent()` returns or an OpenTelemetry service sends. The run joins that trace,
58
+ * under the span the header names, and keeps its sampling decision.
59
+ */
60
+ traceparent?: string;
39
61
  }
40
62
  /** Options for finishing a run. */
41
63
  export interface FinishRunOptions {
@@ -60,10 +82,19 @@ export interface RunHandle {
60
82
  readonly id: string;
61
83
  /** The trace it belongs to. */
62
84
  readonly traceId: string;
63
- /** Finishes the run. The trace is written once its root finishes. */
85
+ /**
86
+ * Finishes the run. By default the trace is written once its root finishes; with `incremental`,
87
+ * this run is written now.
88
+ */
64
89
  finish(options?: FinishRunOptions): Promise<void>;
65
90
  /** Starts a run beneath this one, without relying on the ambient context. */
66
91
  child(options: StartRunOptions): RunHandle;
92
+ /**
93
+ * This run as a W3C `traceparent` header, for work it hands to another process: an operation's
94
+ * `traceContext`, a request to a remote graph, a call to any OpenTelemetry service. Pass it back
95
+ * as `StartRunOptions.traceparent` there.
96
+ */
97
+ traceparent(): string;
67
98
  }
68
99
  /**
69
100
  * Records run trees.
@@ -75,6 +106,8 @@ export declare class Tracer {
75
106
  private readonly options;
76
107
  private readonly context;
77
108
  private readonly pending;
109
+ /** Each trace's writes, in order, so a run's end can never land before its start. */
110
+ private readonly writes;
78
111
  private readonly now;
79
112
  constructor(options: TracerOptions);
80
113
  /** The run currently in scope, if any. */
@@ -95,12 +128,25 @@ export declare class Tracer {
95
128
  recordFeedback(runId: string, feedback: Omit<RunFeedback, 'createdAt'> & {
96
129
  createdAt?: string;
97
130
  }): Promise<void>;
131
+ /** Waits for every write and export handed over so far. */
132
+ flush(): Promise<void>;
98
133
  private handle;
99
134
  private close;
135
+ /** Chains a write behind the trace's earlier ones. A failed write is reported, never thrown. */
136
+ private enqueue;
137
+ private settle;
138
+ private export;
100
139
  private keepByTail;
101
140
  private decideSampling;
102
141
  /** Applies the redaction policy. What a trace must not hold, it never holds. */
103
142
  private prepare;
104
143
  }
144
+ /**
145
+ * A trace id as the 32 hex digits W3C trace context and OpenTelemetry use. An id that already is one
146
+ * is kept; a tracer's own `trace-…` id is padded, so every process derives the same one.
147
+ */
148
+ export declare function w3cTraceId(traceId: string): string;
149
+ /** A run id as the 16 hex digits of a W3C span id. */
150
+ export declare function w3cSpanId(runId: string): string;
105
151
  /** Removes fields by dot path, deeply, without mutating what the caller passed in. */
106
152
  export declare function stripFields(value: unknown, fields: readonly string[]): unknown;
@@ -1,6 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Tracer = void 0;
4
+ exports.w3cTraceId = w3cTraceId;
5
+ exports.w3cSpanId = w3cSpanId;
4
6
  exports.stripFields = stripFields;
5
7
  const node_async_hooks_1 = require("node:async_hooks");
6
8
  const node_crypto_1 = require("node:crypto");
@@ -8,6 +10,7 @@ class Tracer {
8
10
  options;
9
11
  context = new node_async_hooks_1.AsyncLocalStorage();
10
12
  pending = new Map();
13
+ writes = new Map();
11
14
  now;
12
15
  constructor(options) {
13
16
  this.options = options;
@@ -19,13 +22,15 @@ class Tracer {
19
22
  }
20
23
  startRun(options) {
21
24
  const parent = this.context.getStore();
22
- const traceId = options.traceId ?? parent?.traceId ?? id('trace');
25
+ const remote = options.traceparent ? parseTraceparent(options.traceparent) : undefined;
26
+ const traceId = options.traceId ?? remote?.traceId ?? parent?.traceId ?? id('trace');
23
27
  const runId = id('run');
24
- const sampled = parent?.sampled ?? this.decideSampling();
28
+ const parentId = options.parentId ?? (remote ? `run-${remote.spanId}` : parent?.runId);
29
+ const sampled = parent?.sampled ?? remote?.sampled ?? this.decideSampling();
25
30
  const run = {
26
31
  id: runId,
27
32
  traceId,
28
- ...((options.parentId ?? parent?.runId) ? { parentId: options.parentId ?? parent?.runId } : {}),
33
+ ...(parentId ? { parentId } : {}),
29
34
  name: options.name,
30
35
  kind: options.kind ?? 'chain',
31
36
  status: 'running',
@@ -36,7 +41,12 @@ class Tracer {
36
41
  tags: [...(this.options.tags ?? []), ...(options.tags ?? [])],
37
42
  metadata: { ...this.options.metadata, ...options.metadata },
38
43
  };
39
- this.pending.set(traceId, [...(this.pending.get(traceId) ?? []), run]);
44
+ if (this.options.incremental && sampled) {
45
+ this.enqueue(run.traceId, () => this.options.store.save(this.prepare(run)));
46
+ }
47
+ else {
48
+ this.pending.set(traceId, [...(this.pending.get(traceId) ?? []), run]);
49
+ }
40
50
  return this.handle(run, sampled);
41
51
  }
42
52
  async trace(options, fn) {
@@ -70,6 +80,10 @@ class Tracer {
70
80
  this.options.onError?.(error);
71
81
  }
72
82
  }
83
+ async flush() {
84
+ await Promise.all([...this.writes.values()]);
85
+ await Promise.all((this.options.exporters ?? []).map((exporter) => Promise.resolve(exporter.flush?.()).catch((error) => this.options.onError?.(error))));
86
+ }
73
87
  handle(run, sampled) {
74
88
  const finish = async (options = {}) => {
75
89
  const endedAt = this.now();
@@ -86,6 +100,16 @@ class Tracer {
86
100
  ...(options.provider ? { provider: options.provider } : {}),
87
101
  metadata: { ...run.metadata, ...options.metadata },
88
102
  };
103
+ if (this.options.incremental && sampled) {
104
+ await this.enqueue(run.traceId, async () => {
105
+ const prepared = this.prepare(finished);
106
+ await this.options.store.save(prepared);
107
+ this.export(prepared);
108
+ });
109
+ if (!run.parentId)
110
+ this.settle(run.traceId);
111
+ return;
112
+ }
89
113
  await this.close(finished, sampled);
90
114
  };
91
115
  return {
@@ -93,6 +117,7 @@ class Tracer {
93
117
  traceId: run.traceId,
94
118
  finish,
95
119
  child: (options) => this.startRun({ ...options, traceId: run.traceId, parentId: run.id }),
120
+ traceparent: () => formatTraceparent(run.traceId, run.id, sampled),
96
121
  };
97
122
  }
98
123
  async close(run, sampled) {
@@ -102,7 +127,7 @@ class Tracer {
102
127
  runs[index] = run;
103
128
  else
104
129
  runs.push(run);
105
- const root = runs.find((item) => !item.parentId);
130
+ const root = runs.find((item) => !item.parentId || !runs.some((other) => other.id === item.parentId));
106
131
  if (root && root.status === 'running')
107
132
  return;
108
133
  this.pending.delete(run.traceId);
@@ -110,7 +135,34 @@ class Tracer {
110
135
  return;
111
136
  for (const item of runs) {
112
137
  try {
113
- await this.options.store.save(this.prepare(item));
138
+ const prepared = this.prepare(item);
139
+ await this.options.store.save(prepared);
140
+ if (prepared.status !== 'running')
141
+ this.export(prepared);
142
+ }
143
+ catch (error) {
144
+ this.options.onError?.(error);
145
+ }
146
+ }
147
+ }
148
+ enqueue(traceId, write) {
149
+ const next = (this.writes.get(traceId) ?? Promise.resolve())
150
+ .then(write)
151
+ .catch((error) => this.options.onError?.(error));
152
+ this.writes.set(traceId, next);
153
+ return next;
154
+ }
155
+ settle(traceId) {
156
+ const last = this.writes.get(traceId);
157
+ void last?.then(() => {
158
+ if (this.writes.get(traceId) === last)
159
+ this.writes.delete(traceId);
160
+ });
161
+ }
162
+ export(run) {
163
+ for (const exporter of this.options.exporters ?? []) {
164
+ try {
165
+ void Promise.resolve(exporter.export(run)).catch((error) => this.options.onError?.(error));
114
166
  }
115
167
  catch (error) {
116
168
  this.options.onError?.(error);
@@ -151,6 +203,35 @@ exports.Tracer = Tracer;
151
203
  function id(prefix) {
152
204
  return `${prefix}-${(0, node_crypto_1.randomBytes)(8).toString('hex')}`;
153
205
  }
206
+ function w3cTraceId(traceId) {
207
+ if (/^[0-9a-f]{32}$/.test(traceId))
208
+ return traceId;
209
+ const hex = traceId
210
+ .replace(/^trace-/, '')
211
+ .replace(/[^0-9a-f]/gi, '')
212
+ .toLowerCase();
213
+ return hex.length >= 32 ? hex.slice(-32) : hex.padStart(32, '0');
214
+ }
215
+ function w3cSpanId(runId) {
216
+ const hex = runId
217
+ .replace(/^run-/, '')
218
+ .replace(/[^0-9a-f]/gi, '')
219
+ .toLowerCase();
220
+ return hex.length >= 16 ? hex.slice(-16) : hex.padStart(16, '0');
221
+ }
222
+ function formatTraceparent(traceId, runId, sampled) {
223
+ return `00-${w3cTraceId(traceId)}-${w3cSpanId(runId)}-${sampled ? '01' : '00'}`;
224
+ }
225
+ function parseTraceparent(header) {
226
+ const match = /^([0-9a-f]{2})-([0-9a-f]{32})-([0-9a-f]{16})-([0-9a-f]{2})$/.exec(header.trim().toLowerCase());
227
+ if (!match || match[2] === '0'.repeat(32) || match[3] === '0'.repeat(16))
228
+ return undefined;
229
+ return {
230
+ traceId: match[2],
231
+ spanId: match[3],
232
+ sampled: (Number.parseInt(match[4], 16) & 1) === 1,
233
+ };
234
+ }
154
235
  function describeError(error) {
155
236
  if (error instanceof Error)
156
237
  return { name: error.name, message: error.message };
@@ -8,6 +8,7 @@ import type { TelephonyConfig } from './telephony.js';
8
8
  import type { AliasMetadata, InputModality, ModelCapabilities, ModelStatus, OutputModality, RoutingModelPreference } from './providers.js';
9
9
  import type { CapabilityConfig } from './capabilities.js';
10
10
  import type { LifecycleConfig, OperationFamily } from './lifecycle.js';
11
+ import type { CompletionRequest } from './messages.js';
11
12
  import type { PipelineConfig } from '../pipeline/types.js';
12
13
  import type { CacheAdapter } from '../cache/adapters.js';
13
14
  import type { SemanticCacheOptions } from '../cache/semantic-cache.js';
@@ -228,6 +229,24 @@ export interface CacheConfig {
228
229
  strategy?: 'exact' | 'semantic' | 'hybrid';
229
230
  adapter?: CacheAdapter;
230
231
  semantic?: SemanticCacheOptions;
232
+ /**
233
+ * What cached responses are kept apart by, fixed or per request. A response is reused only within
234
+ * its namespace, so a new model revision or context version starts from an empty cache, and no
235
+ * tenant is answered from another's. The tenant defaults to the request's `tenantId`. Without it,
236
+ * exact-cache keys are what they were before 2.2; semantic matches are always kept to one tenant.
237
+ */
238
+ namespace?: CacheNamespace | ((request: CompletionRequest) => CacheNamespace);
239
+ }
240
+ /** What a cached response is kept apart by. Each field narrows the namespace. */
241
+ export interface CacheNamespace {
242
+ /** The tenant. Defaults to the request's `tenantId`. */
243
+ tenant?: string;
244
+ /** The deployment environment, such as `staging`. */
245
+ environment?: string;
246
+ /** A revision of the model or its prompts; changing it retires every earlier entry. */
247
+ modelRevision?: string;
248
+ /** The version of the context an answer depends on, such as a context hub bundle's. */
249
+ contextVersion?: string;
231
250
  }
232
251
  /** A response format applied to every request that does not set its own. */
233
252
  export interface ResponseFormatConfig {
@@ -244,8 +263,20 @@ export interface RateLimitConfig {
244
263
  maxRequests: number;
245
264
  /** Window length in milliseconds. */
246
265
  windowMs: number;
247
- /** What a budget is counted per: each user, each model, or everything together. */
248
- key?: 'userId' | 'model' | 'global';
266
+ /**
267
+ * What a budget is counted per: each user, each model, each tenant (the request's `tenantId`), or
268
+ * everything together. Per tenant, one tenant cannot spend another's share of a shared client.
269
+ */
270
+ key?: 'userId' | 'model' | 'tenantId' | 'global';
271
+ /**
272
+ * How calls are counted. `fixed-window` (the default) counts per window, so a burst at the end of
273
+ * one window and another at the start of the next can pass twice the limit in a moment. `gcra` is
274
+ * the token-bucket algorithm kept as one timestamp per key: calls are spread at `maxRequests` per
275
+ * `windowMs`, with at most `burst` at once, and no window edge to burst across.
276
+ */
277
+ algorithm?: 'fixed-window' | 'gcra';
278
+ /** With `gcra`, the calls allowed at once after a quiet spell. Defaults to `maxRequests`. */
279
+ burst?: number;
249
280
  /**
250
281
  * Where counters live. Omitted means process-local, which multiplies the real limit by the
251
282
  * number of workers; supply `RedisRateLimitStore` to share one budget across them.
@@ -166,6 +166,43 @@ export interface Experiment {
166
166
  hits: number;
167
167
  misses: number;
168
168
  };
169
+ /** Where each evaluator's scores came from, in the order the evaluators were given. */
170
+ evaluators?: EvaluatorProvenance[];
171
+ /** The framework that ran the experiment. */
172
+ framework?: {
173
+ name: string;
174
+ version: string;
175
+ };
176
+ }
177
+ /**
178
+ * Where one evaluator's scores came from. `position`, `name`, and `keys` are always recorded; the
179
+ * rest is what the evaluator declared through `withProvenance()`, or what an `LLMJudge` declares for
180
+ * itself.
181
+ */
182
+ export interface EvaluatorProvenance {
183
+ /** Its place among the evaluators passed to `evaluate()`, from 0. */
184
+ position: number;
185
+ /** What it is called: as declared, its function's name, or `evaluator-<position>`. */
186
+ name: string;
187
+ /** The score keys it produced in this experiment. */
188
+ keys: string[];
189
+ /** Its version, as declared. */
190
+ version?: string;
191
+ /** The model behind a judge, and how it was called. */
192
+ judge?: {
193
+ /** The judge model. */
194
+ model: string;
195
+ /** The provider, when known. */
196
+ provider?: string;
197
+ /** Identifies the judge's instructions: a version, or a hash of its prompt. */
198
+ promptVersion?: string;
199
+ /** Its sampling temperature. */
200
+ temperature?: number;
201
+ };
202
+ /** What a good answer looks like, as the evaluator was told. */
203
+ rubric?: string;
204
+ /** Anything else worth recording. */
205
+ metadata?: Record<string, unknown>;
169
206
  }
170
207
  /** Where experiments are kept, for later comparison. */
171
208
  export interface ExperimentStore {