modelrig 0.11.0 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +82 -0
- package/dist/adapters/anthropic.d.ts +4 -4
- package/dist/adapters/anthropic.d.ts.map +1 -1
- package/dist/adapters/anthropic.js +8 -1
- package/dist/adapters/deepseek.d.ts +2 -4
- package/dist/adapters/deepseek.d.ts.map +1 -1
- package/dist/adapters/deepseek.js +9 -5
- package/dist/adapters/gemini.d.ts +4 -1
- package/dist/adapters/gemini.d.ts.map +1 -1
- package/dist/adapters/gemini.js +16 -1
- package/dist/adapters/grok.d.ts +2 -4
- package/dist/adapters/grok.d.ts.map +1 -1
- package/dist/adapters/grok.js +8 -4
- package/dist/adapters/history-mapping.d.ts +126 -0
- package/dist/adapters/history-mapping.d.ts.map +1 -0
- package/dist/adapters/history-mapping.js +230 -0
- package/dist/adapters/openai-compat.d.ts +2 -4
- package/dist/adapters/openai-compat.d.ts.map +1 -1
- package/dist/adapters/openai-compat.js +9 -5
- package/dist/adapters/openai.d.ts +2 -4
- package/dist/adapters/openai.d.ts.map +1 -1
- package/dist/adapters/openai.js +8 -4
- package/dist/adapters/responses-api.d.ts.map +1 -1
- package/dist/adapters/responses-api.js +9 -4
- package/dist/artifacts/artifact.d.ts.map +1 -1
- package/dist/artifacts/artifact.js +79 -0
- package/dist/artifacts/conversation.d.ts +128 -0
- package/dist/artifacts/conversation.d.ts.map +1 -0
- package/dist/artifacts/conversation.js +172 -0
- package/dist/artifacts/index.d.ts +1 -1
- package/dist/artifacts/index.d.ts.map +1 -1
- package/dist/artifacts/media.d.ts +46 -0
- package/dist/artifacts/media.d.ts.map +1 -0
- package/dist/artifacts/media.js +88 -0
- package/dist/artifacts/run-context.d.ts +61 -2
- package/dist/artifacts/run-context.d.ts.map +1 -1
- package/dist/artifacts/run-context.js +183 -12
- package/dist/artifacts/scrub.d.ts +3 -0
- package/dist/artifacts/scrub.d.ts.map +1 -1
- package/dist/bakeoff/engine.d.ts.map +1 -1
- package/dist/bakeoff/engine.js +34 -7
- package/dist/bakeoff/eval-cases.d.ts +5 -0
- package/dist/bakeoff/eval-cases.d.ts.map +1 -1
- package/dist/bakeoff/eval-cases.js +10 -1
- package/dist/bakeoff/replay.d.ts +15 -0
- package/dist/bakeoff/replay.d.ts.map +1 -1
- package/dist/bakeoff/replay.js +19 -1
- package/dist/bakeoff/report.d.ts.map +1 -1
- package/dist/bakeoff/report.js +9 -2
- package/dist/bakeoff/turn-replay.d.ts +93 -0
- package/dist/bakeoff/turn-replay.d.ts.map +1 -0
- package/dist/bakeoff/turn-replay.js +150 -0
- package/dist/bakeoff/types.d.ts +12 -0
- package/dist/bakeoff/types.d.ts.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +1 -0
- package/dist/config.d.ts +18 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +23 -3
- package/dist/doctor-preflight.d.ts.map +1 -1
- package/dist/doctor-preflight.js +6 -1
- package/dist/feedback/grade.d.ts +7 -2
- package/dist/feedback/grade.d.ts.map +1 -1
- package/dist/feedback/grade.js +14 -0
- package/dist/feedback/outcome.d.ts +103 -0
- package/dist/feedback/outcome.d.ts.map +1 -0
- package/dist/feedback/outcome.js +175 -0
- package/dist/gateway/history-bridge.d.ts +32 -0
- package/dist/gateway/history-bridge.d.ts.map +1 -0
- package/dist/gateway/history-bridge.js +64 -0
- package/dist/gateway/serve-client.d.ts.map +1 -1
- package/dist/gateway/serve-client.js +6 -0
- package/dist/index.d.ts +44 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +110 -9
- package/dist/init/init-cli.d.ts.map +1 -1
- package/dist/init/init-cli.js +21 -4
- package/dist/init/observe-cli.js +1 -1
- package/dist/init/observe.d.ts +7 -1
- package/dist/init/observe.d.ts.map +1 -1
- package/dist/init/observe.js +74 -22
- package/dist/init/starter.d.ts +36 -0
- package/dist/init/starter.d.ts.map +1 -0
- package/dist/init/starter.js +85 -0
- package/dist/registry/build.d.ts +4 -0
- package/dist/registry/build.d.ts.map +1 -1
- package/dist/registry/generation-models.d.ts +68 -0
- package/dist/registry/generation-models.d.ts.map +1 -0
- package/dist/registry/generation-models.js +168 -0
- package/dist/registry/model-kind.d.ts +34 -0
- package/dist/registry/model-kind.d.ts.map +1 -0
- package/dist/registry/model-kind.js +40 -0
- package/dist/registry/pricing-shape.d.ts +29 -1
- package/dist/registry/pricing-shape.d.ts.map +1 -1
- package/dist/registry/pricing-shape.js +9 -0
- package/dist/registry/pricing.d.ts +26 -0
- package/dist/registry/pricing.d.ts.map +1 -1
- package/dist/registry/pricing.js +29 -0
- package/dist/registry/rows.d.ts.map +1 -1
- package/dist/registry/rows.js +3 -1
- package/dist/registry/unit-pricing.d.ts +32 -0
- package/dist/registry/unit-pricing.d.ts.map +1 -0
- package/dist/registry/unit-pricing.js +62 -0
- package/dist/routes/input-loader.d.ts +38 -0
- package/dist/routes/input-loader.d.ts.map +1 -0
- package/dist/routes/input-loader.js +80 -0
- package/dist/routes/loader.d.ts.map +1 -1
- package/dist/routes/loader.js +3 -0
- package/dist/routes/resolved-bundle.d.ts +2 -0
- package/dist/routes/resolved-bundle.d.ts.map +1 -1
- package/dist/routes/resolved-bundle.js +3 -0
- package/dist/run/cost.d.ts +28 -0
- package/dist/run/cost.d.ts.map +1 -1
- package/dist/run/cost.js +74 -0
- package/dist/run/dispatch.d.ts +4 -1
- package/dist/run/dispatch.d.ts.map +1 -1
- package/dist/run/dispatch.js +3 -0
- package/dist/run/limits.d.ts +88 -0
- package/dist/run/limits.d.ts.map +1 -0
- package/dist/run/limits.js +155 -0
- package/dist/run/messages.d.ts +199 -0
- package/dist/run/messages.d.ts.map +1 -0
- package/dist/run/messages.js +430 -0
- package/dist/run/raw-finalize.d.ts +5 -2
- package/dist/run/raw-finalize.d.ts.map +1 -1
- package/dist/run/raw-finalize.js +8 -5
- package/dist/run/raw-request.d.ts.map +1 -1
- package/dist/run/raw-request.js +2 -1
- package/dist/run/raw.d.ts +10 -4
- package/dist/run/raw.d.ts.map +1 -1
- package/dist/run/raw.js +11 -3
- package/dist/run/rawonly.d.ts +29 -5
- package/dist/run/rawonly.d.ts.map +1 -1
- package/dist/run/rawonly.js +54 -19
- package/dist/run/record-attempt.d.ts.map +1 -1
- package/dist/run/record-attempt.js +16 -6
- package/dist/run/record-call.d.ts +13 -2
- package/dist/run/record-call.d.ts.map +1 -1
- package/dist/run/record-call.js +50 -7
- package/dist/run/run.d.ts.map +1 -1
- package/dist/run/run.js +12 -8
- package/dist/telemetry/attempt-meta.d.ts +49 -1
- package/dist/telemetry/attempt-meta.d.ts.map +1 -1
- package/dist/telemetry/attempt-meta.js +45 -1
- package/dist/telemetry/exporter.d.ts.map +1 -1
- package/dist/telemetry/exporter.js +2 -1
- package/dist/telemetry/grade-mappers.d.ts +1 -1
- package/dist/telemetry/grade-mappers.d.ts.map +1 -1
- package/dist/telemetry/grade-mappers.js +7 -1
- package/dist/telemetry/grade-task.d.ts +49 -0
- package/dist/telemetry/grade-task.d.ts.map +1 -0
- package/dist/telemetry/grade-task.js +85 -0
- package/dist/telemetry/grades-sql.d.ts +16 -1
- package/dist/telemetry/grades-sql.d.ts.map +1 -1
- package/dist/telemetry/grades-sql.js +64 -4
- package/dist/telemetry/ingest-protocol.d.ts +24 -1
- package/dist/telemetry/ingest-protocol.d.ts.map +1 -1
- package/dist/telemetry/ingest-protocol.js +72 -43
- package/dist/telemetry/otel-content.d.ts +31 -0
- package/dist/telemetry/otel-content.d.ts.map +1 -0
- package/dist/telemetry/otel-content.js +106 -0
- package/dist/telemetry/otel-hierarchy.d.ts +57 -0
- package/dist/telemetry/otel-hierarchy.d.ts.map +1 -0
- package/dist/telemetry/otel-hierarchy.js +155 -0
- package/dist/telemetry/otel-normalize.d.ts +15 -1
- package/dist/telemetry/otel-normalize.d.ts.map +1 -1
- package/dist/telemetry/otel-normalize.js +24 -39
- package/dist/telemetry/sinks.d.ts +4 -1
- package/dist/telemetry/sinks.d.ts.map +1 -1
- package/dist/telemetry/sinks.js +53 -34
- package/dist/telemetry/store-migrations.d.ts.map +1 -1
- package/dist/telemetry/store-migrations.js +8 -0
- package/dist/telemetry/store.d.ts +9 -0
- package/dist/telemetry/store.d.ts.map +1 -1
- package/dist/telemetry/store.js +10 -0
- package/dist/telemetry/uniform-rows.d.ts +43 -0
- package/dist/telemetry/uniform-rows.d.ts.map +1 -0
- package/dist/telemetry/uniform-rows.js +139 -0
- package/dist/types/failures-teaching.d.ts.map +1 -1
- package/dist/types/failures-teaching.js +11 -0
- package/dist/types/failures.d.ts +1 -1
- package/dist/types/failures.d.ts.map +1 -1
- package/dist/types/failures.js +2 -0
- package/dist/types/provider.d.ts +12 -0
- package/dist/types/provider.d.ts.map +1 -1
- package/dist/types/route.d.ts +13 -0
- package/dist/types/route.d.ts.map +1 -1
- package/dist/types/telemetry.d.ts +14 -1
- package/dist/types/telemetry.d.ts.map +1 -1
- package/docs/agent-skill/SKILL.md +122 -12
- package/docs/how-it-fits.md +4 -4
- package/docs/instrumentation.md +148 -44
- package/docs/llms.txt +143 -13
- package/docs/mcp-oracle.md +15 -4
- package/docs/quickstart.md +129 -16
- package/package.json +4 -2
- package/registry/registry.json +456 -0
- package/templates/creative-approval.json +81 -0
- package/templates/support-conversation.json +82 -0
|
@@ -34,8 +34,11 @@
|
|
|
34
34
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
35
35
|
exports.DEFAULT_INGEST_URL = exports.INGEST_PROTOCOL_VERSION_V1 = exports.INGEST_PROTOCOL_VERSION = exports.INGEST_PATH = exports.foreignOrgGrades = void 0;
|
|
36
36
|
exports.stampBatch = stampBatch;
|
|
37
|
+
exports.stepTaskRegistration = stepTaskRegistration;
|
|
37
38
|
const fingerprint_1 = require("../registry/fingerprint");
|
|
38
39
|
const grade_mappers_1 = require("./grade-mappers");
|
|
40
|
+
const uniform_rows_1 = require("./uniform-rows");
|
|
41
|
+
const grade_task_1 = require("./grade-task");
|
|
39
42
|
var grade_mappers_2 = require("./grade-mappers");
|
|
40
43
|
Object.defineProperty(exports, "foreignOrgGrades", { enumerable: true, get: function () { return grade_mappers_2.foreignOrgGrades; } });
|
|
41
44
|
/** The path the api sink posts to. Spelled once. */
|
|
@@ -88,14 +91,13 @@ function stampBatch(batch, tenancy, opts = {}) {
|
|
|
88
91
|
}
|
|
89
92
|
taskRows.push(taskRow);
|
|
90
93
|
}
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
merge: true,
|
|
97
|
-
|
|
98
|
-
});
|
|
94
|
+
// merge=true: a task row is a mutable projection of the latest sync, like
|
|
95
|
+
// the routes mirror, unlike inferences. onConflict on the PK (S5). Split by
|
|
96
|
+
// key set (COV-1c, PGRST102): a bundle-less task row must neither fail nor
|
|
97
|
+
// null out its bundled neighbours' schema columns.
|
|
98
|
+
for (const group of (0, uniform_rows_1.splitByKeySet)(taskRows)) {
|
|
99
|
+
writes.push({ table: "tasks", onConflict: "org_id,task", merge: true, rows: group });
|
|
100
|
+
}
|
|
99
101
|
const routeRow = (r) => ({
|
|
100
102
|
org_id: tenancy.org_id,
|
|
101
103
|
route: r.route,
|
|
@@ -130,31 +132,31 @@ function stampBatch(batch, tenancy, opts = {}) {
|
|
|
130
132
|
}
|
|
131
133
|
}
|
|
132
134
|
if (batch.runs !== undefined && batch.runs.length > 0) {
|
|
133
|
-
|
|
134
|
-
//
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
})
|
|
157
|
-
}
|
|
135
|
+
const runRows = batch.runs.map((r) => ({
|
|
136
|
+
// Field-by-field from the principal's tenancy — org_id and source_id are
|
|
137
|
+
// NEVER carried on the wire (T3). source_id identifies the rig instance,
|
|
138
|
+
// exactly like inferences.
|
|
139
|
+
org_id: tenancy.org_id,
|
|
140
|
+
id: r.id,
|
|
141
|
+
source_id: tenancy.source_id,
|
|
142
|
+
pipeline: r.pipeline,
|
|
143
|
+
pipeline_version: r.pipeline_version,
|
|
144
|
+
environment: r.environment,
|
|
145
|
+
episode_key: r.episode_key,
|
|
146
|
+
started_at: r.started_at,
|
|
147
|
+
ended_at: r.ended_at,
|
|
148
|
+
status: r.status,
|
|
149
|
+
updated_at: now,
|
|
150
|
+
// WI-1 (spec §3): the run metadata envelope. spread-iff-present (the
|
|
151
|
+
// 00027 pattern) — a run without `meta` leaves runs.meta untouched.
|
|
152
|
+
...(r.meta !== undefined && r.meta !== null ? { meta: r.meta } : {}),
|
|
153
|
+
}));
|
|
154
|
+
// runs are a mutable projection (start → end): merge=true on the PK (S5).
|
|
155
|
+
// Split by key set (COV-1c, PGRST102): a meta-less run row must not fail,
|
|
156
|
+
// or null out, a neighbour's meta.
|
|
157
|
+
for (const group of (0, uniform_rows_1.splitByKeySet)(runRows)) {
|
|
158
|
+
writes.push({ table: "runs", onConflict: "org_id,id", merge: true, rows: group });
|
|
159
|
+
}
|
|
158
160
|
}
|
|
159
161
|
if (batch.steps !== undefined && batch.steps.length > 0) {
|
|
160
162
|
writes.push({
|
|
@@ -163,7 +165,8 @@ function stampBatch(batch, tenancy, opts = {}) {
|
|
|
163
165
|
table: "steps",
|
|
164
166
|
onConflict: "org_id,run_id,step_key,attempt_no",
|
|
165
167
|
merge: false,
|
|
166
|
-
|
|
168
|
+
// fillNulls (COV-1c, PGRST102): merge=false, so a null never rewrites a row.
|
|
169
|
+
rows: (0, uniform_rows_1.fillNulls)(batch.steps.map((s) => ({
|
|
167
170
|
org_id: tenancy.org_id,
|
|
168
171
|
run_id: s.run_id,
|
|
169
172
|
step_key: s.step_key,
|
|
@@ -185,7 +188,7 @@ function stampBatch(batch, tenancy, opts = {}) {
|
|
|
185
188
|
// ground-truth step carries no `attested`, so the column stays null and
|
|
186
189
|
// the 00038 CHECK holds. An SDK batch never sets it → byte-identical.
|
|
187
190
|
...(s.attested !== undefined ? { attested: s.attested } : {}),
|
|
188
|
-
})),
|
|
191
|
+
})), ["attested"]),
|
|
189
192
|
});
|
|
190
193
|
}
|
|
191
194
|
if (batch.artifacts !== undefined && batch.artifacts.length > 0) {
|
|
@@ -193,7 +196,7 @@ function stampBatch(batch, tenancy, opts = {}) {
|
|
|
193
196
|
table: "artifacts",
|
|
194
197
|
onConflict: "org_id,id",
|
|
195
198
|
merge: false, // an artifact metadata row is a fact; a retry must not rewrite it
|
|
196
|
-
rows: batch.artifacts.map((a) => ({
|
|
199
|
+
rows: (0, uniform_rows_1.fillNulls)(batch.artifacts.map((a) => ({
|
|
197
200
|
org_id: tenancy.org_id,
|
|
198
201
|
id: a.id,
|
|
199
202
|
run_id: a.run_id,
|
|
@@ -214,7 +217,7 @@ function stampBatch(batch, tenancy, opts = {}) {
|
|
|
214
217
|
// spread-iff-present (00027 pattern): a batch without `scrub` (older SDK,
|
|
215
218
|
// custody off) leaves the column null rather than overwriting it.
|
|
216
219
|
...(a.scrub !== undefined ? { scrub: a.scrub } : {}),
|
|
217
|
-
})),
|
|
220
|
+
})), ["scrub"]),
|
|
218
221
|
});
|
|
219
222
|
}
|
|
220
223
|
if (batch.artifact_edges !== undefined && batch.artifact_edges.length > 0) {
|
|
@@ -280,12 +283,11 @@ function stampBatch(batch, tenancy, opts = {}) {
|
|
|
280
283
|
// An inference is a fact that happened. A retry must not be able to
|
|
281
284
|
// rewrite it — idempotent by doing nothing, not by overwriting.
|
|
282
285
|
merge: false,
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
})),
|
|
286
|
+
// ONE key set for every row (COV-1c): a PostgREST bulk insert 400s with
|
|
287
|
+
// PGRST102 when keys differ — a web-search surcharge row (meta: null)
|
|
288
|
+
// beside metered rows (meta set) used to drop the whole batch. merge=false
|
|
289
|
+
// makes writing absent columns as their defaults safe.
|
|
290
|
+
rows: batch.inferences.map((row) => (0, uniform_rows_1.normalizeInferenceRow)(row, tenancy)),
|
|
289
291
|
});
|
|
290
292
|
}
|
|
291
293
|
if (batch.watermarkAt !== undefined) {
|
|
@@ -329,3 +331,30 @@ function stampBatch(batch, tenancy, opts = {}) {
|
|
|
329
331
|
}
|
|
330
332
|
return writes;
|
|
331
333
|
}
|
|
334
|
+
/**
|
|
335
|
+
* GRADE-RAW (grade-ux-plan §1 item 1): the step-task registration write for a
|
|
336
|
+
* batch — a raw-lane or recorded call that names a step (`tags.step`) registers
|
|
337
|
+
* that step as a task, so a grading guide can be written for it. Or null when
|
|
338
|
+
* the batch names no step.
|
|
339
|
+
*
|
|
340
|
+
* DELIBERATELY NOT part of `stampBatch` (architect S2-1): it is a BEST-EFFORT
|
|
341
|
+
* write both sinks issue only AFTER the batch's rows are confirmed, with any
|
|
342
|
+
* error swallowed — a refused registration must never turn a batch of
|
|
343
|
+
* inferences into a poison-skipped 422. merge=false (ignore-duplicates on the
|
|
344
|
+
* PK): it never rewrites an existing row (a route-synced task, or a step's
|
|
345
|
+
* settings/guide); a retry is a no-op. Tenant from the PRINCIPAL only (T3).
|
|
346
|
+
* Capped per batch (registrableStepTasks).
|
|
347
|
+
*/
|
|
348
|
+
function stepTaskRegistration(batch, tenancy) {
|
|
349
|
+
if (batch.inferences === undefined || batch.inferences.length === 0)
|
|
350
|
+
return null;
|
|
351
|
+
const steps = (0, grade_task_1.registrableStepTasks)(batch.inferences);
|
|
352
|
+
if (steps.length === 0)
|
|
353
|
+
return null;
|
|
354
|
+
return {
|
|
355
|
+
table: "tasks",
|
|
356
|
+
onConflict: "org_id,task",
|
|
357
|
+
merge: false,
|
|
358
|
+
rows: steps.map((task) => ({ org_id: tenancy.org_id, task, source: "registered" })),
|
|
359
|
+
};
|
|
360
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ARC-6 / ARC-D6 — OTLP content extraction, GATED. M14 is UNRULED, so this
|
|
3
|
+
* ships OFF: the server calls it ONLY when its feature gate is on AND the org's
|
|
4
|
+
* capture posture is `managed` (modelrig-server otlp-content.ts). With the gate
|
|
5
|
+
* off nothing here runs, and the normalizer (otel-normalize.ts) keeps its STOP
|
|
6
|
+
* invariant: zero content read.
|
|
7
|
+
*
|
|
8
|
+
* When it does run: for each GENERATION span (operation class `generation`) it
|
|
9
|
+
* reads the gen_ai input/output message attributes as TEXT — string-valued
|
|
10
|
+
* only (kvlist/bytes are never decoded) — across the vintages:
|
|
11
|
+
* input: gen_ai.input.messages · gen_ai.prompt (deprecated) ·
|
|
12
|
+
* ai.prompt.messages · ai.prompt (Vercel AI SDK)
|
|
13
|
+
* output: gen_ai.output.messages · gen_ai.completion (deprecated) ·
|
|
14
|
+
* ai.response.text (Vercel AI SDK)
|
|
15
|
+
* The first present attribute per role wins. Pure; scrub + custody are the
|
|
16
|
+
* server's (the same scrub the import path uses, then the custody store).
|
|
17
|
+
*/
|
|
18
|
+
export declare const CONTENT_INPUT_CHAIN: readonly ["gen_ai.input.messages", "gen_ai.prompt", "ai.prompt.messages", "ai.prompt"];
|
|
19
|
+
export declare const CONTENT_OUTPUT_CHAIN: readonly ["gen_ai.output.messages", "gen_ai.completion", "ai.response.text"];
|
|
20
|
+
export interface ExtractedContent {
|
|
21
|
+
/** Lowercase hex trace + span id (the attested step's identity). */
|
|
22
|
+
readonly traceId: string;
|
|
23
|
+
readonly spanId: string;
|
|
24
|
+
readonly role: "input" | "output";
|
|
25
|
+
/** Which attribute it came from. */
|
|
26
|
+
readonly attribute: string;
|
|
27
|
+
readonly text: string;
|
|
28
|
+
}
|
|
29
|
+
/** Extract generation-span message text from a decoded TracesData body. */
|
|
30
|
+
export declare function extractGenerationContent(data: unknown): ExtractedContent[];
|
|
31
|
+
//# sourceMappingURL=otel-content.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"otel-content.d.ts","sourceRoot":"","sources":["../../src/telemetry/otel-content.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAIH,eAAO,MAAM,mBAAmB,wFAAyF,CAAC;AAC1H,eAAO,MAAM,oBAAoB,8EAA+E,CAAC;AAEjH,MAAM,WAAW,gBAAgB;IAC/B,oEAAoE;IACpE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,OAAO,GAAG,QAAQ,CAAC;IAClC,oCAAoC;IACpC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AA+CD,2EAA2E;AAC3E,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,OAAO,GAAG,gBAAgB,EAAE,CAwB1E"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* ARC-6 / ARC-D6 — OTLP content extraction, GATED. M14 is UNRULED, so this
|
|
4
|
+
* ships OFF: the server calls it ONLY when its feature gate is on AND the org's
|
|
5
|
+
* capture posture is `managed` (modelrig-server otlp-content.ts). With the gate
|
|
6
|
+
* off nothing here runs, and the normalizer (otel-normalize.ts) keeps its STOP
|
|
7
|
+
* invariant: zero content read.
|
|
8
|
+
*
|
|
9
|
+
* When it does run: for each GENERATION span (operation class `generation`) it
|
|
10
|
+
* reads the gen_ai input/output message attributes as TEXT — string-valued
|
|
11
|
+
* only (kvlist/bytes are never decoded) — across the vintages:
|
|
12
|
+
* input: gen_ai.input.messages · gen_ai.prompt (deprecated) ·
|
|
13
|
+
* ai.prompt.messages · ai.prompt (Vercel AI SDK)
|
|
14
|
+
* output: gen_ai.output.messages · gen_ai.completion (deprecated) ·
|
|
15
|
+
* ai.response.text (Vercel AI SDK)
|
|
16
|
+
* The first present attribute per role wins. Pure; scrub + custody are the
|
|
17
|
+
* server's (the same scrub the import path uses, then the custody store).
|
|
18
|
+
*/
|
|
19
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
+
exports.CONTENT_OUTPUT_CHAIN = exports.CONTENT_INPUT_CHAIN = void 0;
|
|
21
|
+
exports.extractGenerationContent = extractGenerationContent;
|
|
22
|
+
const otel_hierarchy_1 = require("./otel-hierarchy");
|
|
23
|
+
exports.CONTENT_INPUT_CHAIN = ["gen_ai.input.messages", "gen_ai.prompt", "ai.prompt.messages", "ai.prompt"];
|
|
24
|
+
exports.CONTENT_OUTPUT_CHAIN = ["gen_ai.output.messages", "gen_ai.completion", "ai.response.text"];
|
|
25
|
+
const isRec = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
|
|
26
|
+
const HEX = /^[0-9a-fA-F]+$/;
|
|
27
|
+
function hexId(v, bytes) {
|
|
28
|
+
if (typeof v === "string" && HEX.test(v) && v.length === bytes * 2 && !/^0+$/.test(v))
|
|
29
|
+
return v.toLowerCase();
|
|
30
|
+
if (typeof v === "string" && /^[A-Za-z0-9+/]+={0,2}$/.test(v)) {
|
|
31
|
+
const hex = Buffer.from(v, "base64").toString("hex");
|
|
32
|
+
if (hex.length === bytes * 2 && !/^0+$/.test(hex))
|
|
33
|
+
return hex;
|
|
34
|
+
}
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
/** String attributes only — content shapes (kvlist/bytes) are never decoded. */
|
|
38
|
+
function stringAttrs(attributes) {
|
|
39
|
+
const out = new Map();
|
|
40
|
+
for (const kv of Array.isArray(attributes) ? attributes : []) {
|
|
41
|
+
if (!isRec(kv) || typeof kv.key !== "string" || !isRec(kv.value))
|
|
42
|
+
continue;
|
|
43
|
+
const s = kv.value.stringValue;
|
|
44
|
+
if (typeof s === "string" && s !== "")
|
|
45
|
+
out.set(kv.key, s);
|
|
46
|
+
}
|
|
47
|
+
return out;
|
|
48
|
+
}
|
|
49
|
+
/** The raw operation the normalizer would classify — the same priority. */
|
|
50
|
+
function operationOf(attrs) {
|
|
51
|
+
const oi = attrs.get("openinference.span.kind");
|
|
52
|
+
if (oi !== undefined)
|
|
53
|
+
return oi.toLowerCase();
|
|
54
|
+
const op = attrs.get("gen_ai.operation.name");
|
|
55
|
+
if (op !== undefined)
|
|
56
|
+
return op;
|
|
57
|
+
if (attrs.has("gen_ai.tool.name") || attrs.has("tool.name"))
|
|
58
|
+
return "execute_tool";
|
|
59
|
+
for (const k of ["gen_ai.response.model", "ai.model.id", "gen_ai.request.model", "llm.response.model", "llm.model_name", "model"]) {
|
|
60
|
+
if (attrs.has(k))
|
|
61
|
+
return "chat";
|
|
62
|
+
}
|
|
63
|
+
return "span";
|
|
64
|
+
}
|
|
65
|
+
function first(attrs, chain) {
|
|
66
|
+
for (const k of chain) {
|
|
67
|
+
const v = attrs.get(k);
|
|
68
|
+
if (v !== undefined)
|
|
69
|
+
return [k, v];
|
|
70
|
+
}
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
/** Extract generation-span message text from a decoded TracesData body. */
|
|
74
|
+
function extractGenerationContent(data) {
|
|
75
|
+
const out = [];
|
|
76
|
+
if (!isRec(data))
|
|
77
|
+
return out;
|
|
78
|
+
const rsList = data.resourceSpans ?? data.resource_spans;
|
|
79
|
+
for (const rs of Array.isArray(rsList) ? rsList : []) {
|
|
80
|
+
if (!isRec(rs))
|
|
81
|
+
continue;
|
|
82
|
+
const ssList = rs.scopeSpans ?? rs.scope_spans;
|
|
83
|
+
for (const ss of Array.isArray(ssList) ? ssList : []) {
|
|
84
|
+
if (!isRec(ss))
|
|
85
|
+
continue;
|
|
86
|
+
for (const span of Array.isArray(ss.spans) ? ss.spans : []) {
|
|
87
|
+
if (!isRec(span))
|
|
88
|
+
continue;
|
|
89
|
+
const traceId = hexId(span.traceId ?? span.trace_id, 16);
|
|
90
|
+
const spanId = hexId(span.spanId ?? span.span_id, 8);
|
|
91
|
+
if (traceId === null || spanId === null)
|
|
92
|
+
continue;
|
|
93
|
+
const attrs = stringAttrs(span.attributes);
|
|
94
|
+
if ((0, otel_hierarchy_1.operationClassOf)(operationOf(attrs)) !== "generation")
|
|
95
|
+
continue;
|
|
96
|
+
const input = first(attrs, exports.CONTENT_INPUT_CHAIN);
|
|
97
|
+
const output = first(attrs, exports.CONTENT_OUTPUT_CHAIN);
|
|
98
|
+
if (input !== null)
|
|
99
|
+
out.push({ traceId, spanId, role: "input", attribute: input[0], text: input[1] });
|
|
100
|
+
if (output !== null)
|
|
101
|
+
out.push({ traceId, spanId, role: "output", attribute: output[0], text: output[1] });
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return out;
|
|
106
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OTLP-in — the trace HIERARCHY half of the normalizer, extracted from
|
|
3
|
+
* otel-normalize.ts (ARC-γ: the normalizer sat at 662 LOC, near the 700 cap).
|
|
4
|
+
* PURE: span identity → run/step identity, and step ordering within a run.
|
|
5
|
+
* No attribute is read here and no content ever reaches this module.
|
|
6
|
+
*/
|
|
7
|
+
import type { WireStep } from "./ingest-protocol";
|
|
8
|
+
/** ARC-6: the classified operation kept in the attested envelope — the five
|
|
9
|
+
* classes OTLP-in v1 uses (turn numbering + tool counts), or `span` for
|
|
10
|
+
* anything else (honest: never guessed into a class). */
|
|
11
|
+
export type OperationClass = "generation" | "tool" | "agent" | "retriever" | "embedding" | "span";
|
|
12
|
+
/** Map the normalizer's raw operation string to its class. */
|
|
13
|
+
export declare function operationClassOf(operation: string): OperationClass;
|
|
14
|
+
/** span name → step_key: trimmed, whitespace-collapsed, length-capped, never
|
|
15
|
+
* empty (the step PK forbids it). */
|
|
16
|
+
export declare function toStepKey(name: unknown): string;
|
|
17
|
+
/** 32-hex trace id → canonical UUID string (runs.id is uuid; 16 bytes ≡ a UUID).
|
|
18
|
+
* A trace id that is not 16 bytes gets a deterministic UUID derived from it. */
|
|
19
|
+
export declare function traceIdToRunUuid(traceHex: string): string;
|
|
20
|
+
/** The structural identity of the span a pending step came from (ARC-6). */
|
|
21
|
+
export interface SpanShape {
|
|
22
|
+
readonly id: string;
|
|
23
|
+
readonly parent: string | null;
|
|
24
|
+
/** The normalizer's raw operation (`invoke_agent`, `chat`, …). */
|
|
25
|
+
readonly operation: string;
|
|
26
|
+
readonly operationClass: OperationClass;
|
|
27
|
+
}
|
|
28
|
+
/** One normalized span awaiting its attempt number. */
|
|
29
|
+
export interface PendingStep {
|
|
30
|
+
readonly step: WireStep;
|
|
31
|
+
readonly stepKey: string;
|
|
32
|
+
readonly startMs: number;
|
|
33
|
+
readonly span?: SpanShape;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Assign attempt_no per (run, step_key): repeated same-named spans become
|
|
37
|
+
* attempts in start-time (then span-id) order — deterministic within a trace.
|
|
38
|
+
* v0 limitation: a trace split across batches is not deduped (no seen-store);
|
|
39
|
+
* one trace = one batch is the common, correct case.
|
|
40
|
+
*/
|
|
41
|
+
export declare function assignAttempts(pending: readonly PendingStep[]): WireStep[];
|
|
42
|
+
/**
|
|
43
|
+
* ARC-6 turn numbering for ONE trace that is a conversation (it carries
|
|
44
|
+
* `gen_ai.conversation.id` and has `invoke_agent` spans). Each TOP-LEVEL
|
|
45
|
+
* `invoke_agent` span (no `invoke_agent` ancestor), in start order, is turn n;
|
|
46
|
+
* every generation span under it (any depth) becomes step `turn:<n>.<k>` in
|
|
47
|
+
* start order — ARC-α's step-key convention exactly (`turnStepKey`; a repeated
|
|
48
|
+
* key would read as a retry). The turn number and, on the agent span, the
|
|
49
|
+
* count of tool spans in that turn ride the attested envelope (`turn`,
|
|
50
|
+
* `turn_tool_calls`, `turn_generations`). Spans outside every turn are left
|
|
51
|
+
* as they were. Returns the rewritten list and the number of turns.
|
|
52
|
+
*/
|
|
53
|
+
export declare function numberTurns(pending: readonly PendingStep[]): {
|
|
54
|
+
pending: PendingStep[];
|
|
55
|
+
turns: number;
|
|
56
|
+
};
|
|
57
|
+
//# sourceMappingURL=otel-hierarchy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"otel-hierarchy.d.ts","sourceRoot":"","sources":["../../src/telemetry/otel-hierarchy.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAElD;;yDAEyD;AACzD,MAAM,MAAM,cAAc,GAAG,YAAY,GAAG,MAAM,GAAG,OAAO,GAAG,WAAW,GAAG,WAAW,GAAG,MAAM,CAAC;AAuBlG,8DAA8D;AAC9D,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,cAAc,CAElE;AAID;qCACqC;AACrC,wBAAgB,SAAS,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CAI/C;AAED;gFACgF;AAChF,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAGzD;AAED,4EAA4E;AAC5E,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,kEAAkE;IAClE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,cAAc,EAAE,cAAc,CAAC;CACzC;AAED,uDAAuD;AACvD,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,CAAC;CAC3B;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,SAAS,WAAW,EAAE,GAAG,QAAQ,EAAE,CAmB1E;AAUD;;;;;;;;;;GAUG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,SAAS,WAAW,EAAE,GAAG;IAAE,OAAO,EAAE,WAAW,EAAE,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAgDtG"}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* OTLP-in — the trace HIERARCHY half of the normalizer, extracted from
|
|
4
|
+
* otel-normalize.ts (ARC-γ: the normalizer sat at 662 LOC, near the 700 cap).
|
|
5
|
+
* PURE: span identity → run/step identity, and step ordering within a run.
|
|
6
|
+
* No attribute is read here and no content ever reaches this module.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.operationClassOf = operationClassOf;
|
|
10
|
+
exports.toStepKey = toStepKey;
|
|
11
|
+
exports.traceIdToRunUuid = traceIdToRunUuid;
|
|
12
|
+
exports.assignAttempts = assignAttempts;
|
|
13
|
+
exports.numberTurns = numberTurns;
|
|
14
|
+
const node_crypto_1 = require("node:crypto");
|
|
15
|
+
const conversation_1 = require("../artifacts/conversation");
|
|
16
|
+
const OPERATION_CLASSES = {
|
|
17
|
+
// gen_ai.operation.name (semconv) + the normalizer's model-presence fallback
|
|
18
|
+
chat: "generation",
|
|
19
|
+
text_completion: "generation",
|
|
20
|
+
generate_content: "generation",
|
|
21
|
+
completion: "generation",
|
|
22
|
+
// openinference.span.kind (lower-cased by the normalizer)
|
|
23
|
+
llm: "generation",
|
|
24
|
+
generation: "generation",
|
|
25
|
+
execute_tool: "tool",
|
|
26
|
+
tool: "tool",
|
|
27
|
+
invoke_agent: "agent",
|
|
28
|
+
create_agent: "agent",
|
|
29
|
+
agent_step: "agent",
|
|
30
|
+
agent: "agent",
|
|
31
|
+
retriever: "retriever",
|
|
32
|
+
retrieval: "retriever",
|
|
33
|
+
embeddings: "embedding",
|
|
34
|
+
embedding: "embedding",
|
|
35
|
+
};
|
|
36
|
+
/** Map the normalizer's raw operation string to its class. */
|
|
37
|
+
function operationClassOf(operation) {
|
|
38
|
+
return OPERATION_CLASSES[operation] ?? "span";
|
|
39
|
+
}
|
|
40
|
+
const WS_RE = /\s+/g;
|
|
41
|
+
/** span name → step_key: trimmed, whitespace-collapsed, length-capped, never
|
|
42
|
+
* empty (the step PK forbids it). */
|
|
43
|
+
function toStepKey(name) {
|
|
44
|
+
const raw = typeof name === "string" ? name.trim().replace(WS_RE, " ") : "";
|
|
45
|
+
if (raw === "")
|
|
46
|
+
return "span";
|
|
47
|
+
return raw.slice(0, 200);
|
|
48
|
+
}
|
|
49
|
+
/** 32-hex trace id → canonical UUID string (runs.id is uuid; 16 bytes ≡ a UUID).
|
|
50
|
+
* A trace id that is not 16 bytes gets a deterministic UUID derived from it. */
|
|
51
|
+
function traceIdToRunUuid(traceHex) {
|
|
52
|
+
const hex = traceHex.length === 32 ? traceHex : (0, node_crypto_1.createHash)("sha256").update(traceHex).digest("hex").slice(0, 32);
|
|
53
|
+
return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20, 32)}`;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Assign attempt_no per (run, step_key): repeated same-named spans become
|
|
57
|
+
* attempts in start-time (then span-id) order — deterministic within a trace.
|
|
58
|
+
* v0 limitation: a trace split across batches is not deduped (no seen-store);
|
|
59
|
+
* one trace = one batch is the common, correct case.
|
|
60
|
+
*/
|
|
61
|
+
function assignAttempts(pending) {
|
|
62
|
+
const out = [];
|
|
63
|
+
const perKey = new Map();
|
|
64
|
+
for (const p of pending) {
|
|
65
|
+
const list = perKey.get(p.stepKey) ?? [];
|
|
66
|
+
list.push({ step: p.step, startMs: p.startMs });
|
|
67
|
+
perKey.set(p.stepKey, list);
|
|
68
|
+
}
|
|
69
|
+
for (const list of perKey.values()) {
|
|
70
|
+
list.sort((a, b) => a.startMs !== b.startMs
|
|
71
|
+
? a.startMs - b.startMs
|
|
72
|
+
: (a.step.span_id ?? "") < (b.step.span_id ?? "")
|
|
73
|
+
? -1
|
|
74
|
+
: 1);
|
|
75
|
+
list.forEach(({ step }, i) => out.push({ ...step, attempt_no: i + 1 }));
|
|
76
|
+
}
|
|
77
|
+
return out;
|
|
78
|
+
}
|
|
79
|
+
/** Parent-chain walk bound (a malformed trace can carry a cycle). */
|
|
80
|
+
const MAX_DEPTH = 64;
|
|
81
|
+
function byStart(a, b) {
|
|
82
|
+
if (a.startMs !== b.startMs)
|
|
83
|
+
return a.startMs - b.startMs;
|
|
84
|
+
return (a.span?.id ?? "") < (b.span?.id ?? "") ? -1 : 1;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* ARC-6 turn numbering for ONE trace that is a conversation (it carries
|
|
88
|
+
* `gen_ai.conversation.id` and has `invoke_agent` spans). Each TOP-LEVEL
|
|
89
|
+
* `invoke_agent` span (no `invoke_agent` ancestor), in start order, is turn n;
|
|
90
|
+
* every generation span under it (any depth) becomes step `turn:<n>.<k>` in
|
|
91
|
+
* start order — ARC-α's step-key convention exactly (`turnStepKey`; a repeated
|
|
92
|
+
* key would read as a retry). The turn number and, on the agent span, the
|
|
93
|
+
* count of tool spans in that turn ride the attested envelope (`turn`,
|
|
94
|
+
* `turn_tool_calls`, `turn_generations`). Spans outside every turn are left
|
|
95
|
+
* as they were. Returns the rewritten list and the number of turns.
|
|
96
|
+
*/
|
|
97
|
+
function numberTurns(pending) {
|
|
98
|
+
const byId = new Map();
|
|
99
|
+
for (const p of pending)
|
|
100
|
+
if (p.span !== undefined)
|
|
101
|
+
byId.set(p.span.id, p);
|
|
102
|
+
const isAgent = (p) => p?.span?.operation === "invoke_agent";
|
|
103
|
+
/** The top-level invoke_agent ancestor of a span (itself when it is one), or null. */
|
|
104
|
+
const topAgentOf = (p) => {
|
|
105
|
+
let top = isAgent(p) ? p : null;
|
|
106
|
+
let cur = p.span?.parent != null ? byId.get(p.span.parent) : undefined;
|
|
107
|
+
const seen = new Set([p.span?.id ?? ""]);
|
|
108
|
+
for (let d = 0; cur !== undefined && d < MAX_DEPTH; d++) {
|
|
109
|
+
const id = cur.span?.id ?? "";
|
|
110
|
+
if (seen.has(id))
|
|
111
|
+
break;
|
|
112
|
+
seen.add(id);
|
|
113
|
+
if (isAgent(cur))
|
|
114
|
+
top = cur;
|
|
115
|
+
cur = cur.span?.parent != null ? byId.get(cur.span.parent) : undefined;
|
|
116
|
+
}
|
|
117
|
+
return top;
|
|
118
|
+
};
|
|
119
|
+
const agents = pending.filter((p) => isAgent(p) && topAgentOf(p) === p).sort(byStart);
|
|
120
|
+
if (agents.length === 0)
|
|
121
|
+
return { pending: [...pending], turns: 0 };
|
|
122
|
+
const turnOf = new Map(agents.map((a, i) => [a, i + 1]));
|
|
123
|
+
const generations = new Map();
|
|
124
|
+
const tools = new Map();
|
|
125
|
+
const turnBySpan = new Map();
|
|
126
|
+
for (const p of pending) {
|
|
127
|
+
const top = topAgentOf(p);
|
|
128
|
+
const n = top !== null ? turnOf.get(top) : undefined;
|
|
129
|
+
if (n === undefined)
|
|
130
|
+
continue;
|
|
131
|
+
turnBySpan.set(p, n);
|
|
132
|
+
if (p.span?.operationClass === "generation")
|
|
133
|
+
generations.set(n, [...(generations.get(n) ?? []), p]);
|
|
134
|
+
if (p.span?.operationClass === "tool")
|
|
135
|
+
tools.set(n, (tools.get(n) ?? 0) + 1);
|
|
136
|
+
}
|
|
137
|
+
const keyOf = new Map();
|
|
138
|
+
for (const [n, list] of generations)
|
|
139
|
+
list.sort(byStart).forEach((p, i) => keyOf.set(p, (0, conversation_1.turnStepKey)(n, i + 1)));
|
|
140
|
+
const out = pending.map((p) => {
|
|
141
|
+
const n = turnBySpan.get(p);
|
|
142
|
+
if (n === undefined)
|
|
143
|
+
return p;
|
|
144
|
+
const env = (typeof p.step.attested === "object" && p.step.attested !== null ? p.step.attested : {});
|
|
145
|
+
const isTop = turnOf.has(p);
|
|
146
|
+
const attested = {
|
|
147
|
+
...env,
|
|
148
|
+
turn: n,
|
|
149
|
+
...(isTop ? { turn_tool_calls: tools.get(n) ?? 0, turn_generations: generations.get(n)?.length ?? 0 } : {}),
|
|
150
|
+
};
|
|
151
|
+
const stepKey = keyOf.get(p) ?? p.stepKey;
|
|
152
|
+
return { ...p, stepKey, step: { ...p.step, step_key: stepKey, attested } };
|
|
153
|
+
});
|
|
154
|
+
return { pending: out, turns: agents.length };
|
|
155
|
+
}
|
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
* pattern per §5.3 — implemented fresh here, no bodies copied).
|
|
24
24
|
*/
|
|
25
25
|
import type { WireRun, WireStep } from "./ingest-protocol";
|
|
26
|
+
import { type OperationClass } from "./otel-hierarchy";
|
|
26
27
|
export interface AttestedUsage {
|
|
27
28
|
/** Non-cached input tokens (cache buckets subtracted, floored 0). */
|
|
28
29
|
readonly input?: number;
|
|
@@ -41,8 +42,21 @@ export interface AttestedEnvelope {
|
|
|
41
42
|
readonly model: string | null;
|
|
42
43
|
/** Resolved provider — honest, ending at "unknown", NEVER guessed. */
|
|
43
44
|
readonly provider: string;
|
|
44
|
-
/**
|
|
45
|
+
/** The classifier's raw operation (`invoke_agent`, `chat`, `retriever`, …). */
|
|
45
46
|
readonly operation: string;
|
|
47
|
+
/** ARC-6: the operation's class — generation | tool | agent | retriever |
|
|
48
|
+
* embedding, or `span` (unclassified). Additive. */
|
|
49
|
+
readonly operation_class?: OperationClass;
|
|
50
|
+
/** ARC-6: the parent span id (lowercase hex), or null for a root span.
|
|
51
|
+
* Kept for turn numbering + per-turn tool counts only — never rendered as a
|
|
52
|
+
* tree (spec §9). Additive. */
|
|
53
|
+
readonly parent_span_id?: string | null;
|
|
54
|
+
/** ARC-6: in a conversation trace, the turn this span belongs to. */
|
|
55
|
+
readonly turn?: number;
|
|
56
|
+
/** ARC-6: on a turn's top-level `invoke_agent` span — tool / generation
|
|
57
|
+
* spans counted in that turn. */
|
|
58
|
+
readonly turn_tool_calls?: number;
|
|
59
|
+
readonly turn_generations?: number;
|
|
46
60
|
/** De-double-counted usage; omitted entirely on agent-aggregate spans. */
|
|
47
61
|
readonly usage?: AttestedUsage;
|
|
48
62
|
/** The emitting instrumentation scope (name + optional version). */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"otel-normalize.d.ts","sourceRoot":"","sources":["../../src/telemetry/otel-normalize.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;
|
|
1
|
+
{"version":3,"file":"otel-normalize.d.ts","sourceRoot":"","sources":["../../src/telemetry/otel-normalize.ts"],"names":[],"mappings":"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"}
|