@runtypelabs/flue-otel 0.3.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.
- package/README.md +137 -32
- package/dist/index.cjs +172 -46
- package/dist/index.d.cts +81 -299
- package/dist/index.d.ts +81 -299
- package/dist/index.mjs +172 -46
- package/package.json +6 -5
package/dist/index.d.cts
CHANGED
|
@@ -1,41 +1,5 @@
|
|
|
1
1
|
import { Tracer } from '@opentelemetry/api';
|
|
2
2
|
|
|
3
|
-
/**
|
|
4
|
-
* The Flue observation surface this package reads, declared structurally.
|
|
5
|
-
*
|
|
6
|
-
* ## Why these are hand-declared rather than imported from `@flue/runtime`
|
|
7
|
-
*
|
|
8
|
-
* Two reasons, and the second is the load-bearing one.
|
|
9
|
-
*
|
|
10
|
-
* 1. `@flue/runtime` is a PEER dependency with no dev counterpart: its tree is
|
|
11
|
-
* ~43 packages, and pulling it into the root lockfile for type resolution
|
|
12
|
-
* alone is the cost this monorepo already refuses for `examples/flue-persona`
|
|
13
|
-
* (root `CLAUDE.md`, "examples/* is deliberately NOT a pnpm workspace").
|
|
14
|
-
*
|
|
15
|
-
* 2. The package supports BOTH the 1.x and 2.x lines from one entry point, and
|
|
16
|
-
* their declarations are not the same type. 1.x has `run_start`/`run_end`,
|
|
17
|
-
* envelope `runId`/`dispatchId`, and `FlueObservationDetail.toolType`; 2.x
|
|
18
|
-
* removes all of those and adds `toolcall_delta`, the `submission_*` family,
|
|
19
|
-
* and `FlueErrorInfo.meta`/`.stack`. Importing EITHER line's types would make
|
|
20
|
-
* the compiler enforce a shape the other line does not have. What this
|
|
21
|
-
* package actually consumes is the INTERSECTION — the observation plane Flue
|
|
22
|
-
* publishes as stable — so that is what is declared here.
|
|
23
|
-
*
|
|
24
|
-
* ## What is safe to read
|
|
25
|
-
*
|
|
26
|
-
* Flue's published stability boundary (flueframework.com/docs/reference/events)
|
|
27
|
-
* covers the event type names, the envelope/correlation fields, and the
|
|
28
|
-
* normalized `turn_request` / `turn` / `tool_*` / `task` / `operation` /
|
|
29
|
-
* `compaction` / `log` / `submission_settled` payloads. It EXPLICITLY excludes
|
|
30
|
-
* `AgentMessage`, which appears on `message_start` / `message_end` /
|
|
31
|
-
* `turn_messages` / `agent_end` — so none of those four are read here, and the
|
|
32
|
-
* type below does not even name the field. That exclusion is why the stock
|
|
33
|
-
* projection survived the 1.x → 2.x rewrite unchanged, and it is the same
|
|
34
|
-
* reason this one will.
|
|
35
|
-
*
|
|
36
|
-
* Fields the two lines disagree on are declared OPTIONAL and probed at runtime
|
|
37
|
-
* (`compat.ts`), never version-compared.
|
|
38
|
-
*/
|
|
39
3
|
/** Correlation fields stamped onto every delivered observation. */
|
|
40
4
|
interface FlueEventEnvelope {
|
|
41
5
|
/** Durable event-format version. `3` on both supported lines. */
|
|
@@ -82,12 +46,13 @@ interface FlueModelRequestInfo {
|
|
|
82
46
|
contextCompacted?: true;
|
|
83
47
|
}
|
|
84
48
|
/**
|
|
85
|
-
* The request's payload half.
|
|
86
|
-
* `
|
|
87
|
-
*
|
|
88
|
-
* deliberately untouched in this release — see the README's content section.
|
|
49
|
+
* The request's payload half. `tools` is read for its PRESENCE only (`runtype.tools.reported`).
|
|
50
|
+
* `messages` and `systemPrompt` are Flue's normalized `LlmMessage` history and system prompt,
|
|
51
|
+
* byte-identical on both lines, read only when message content is opted in — see `messages.ts`.
|
|
89
52
|
*/
|
|
90
53
|
interface FlueModelRequestInput {
|
|
54
|
+
systemPrompt?: string;
|
|
55
|
+
messages?: unknown[];
|
|
91
56
|
tools?: unknown[];
|
|
92
57
|
}
|
|
93
58
|
interface FlueModelRequest extends FlueModelRequestInfo {
|
|
@@ -96,6 +61,8 @@ interface FlueModelRequest extends FlueModelRequestInfo {
|
|
|
96
61
|
interface FlueModelResponse {
|
|
97
62
|
responseId?: string;
|
|
98
63
|
responseModel?: string;
|
|
64
|
+
/** The assistant message this turn produced, in Flue's normalized `LlmAssistantMessage` shape. */
|
|
65
|
+
output?: unknown;
|
|
99
66
|
usage?: FluePromptUsage;
|
|
100
67
|
finishReason?: string;
|
|
101
68
|
/** 2.x only. The provider's raw finish value before normalization. */
|
|
@@ -110,13 +77,8 @@ interface FlueModelResponse {
|
|
|
110
77
|
error?: FlueErrorInfo;
|
|
111
78
|
}
|
|
112
79
|
/**
|
|
113
|
-
* Classified error details
|
|
114
|
-
*
|
|
115
|
-
* `stack` is declared so the type is honest about what arrives, and is NEVER
|
|
116
|
-
* read: it exposes filesystem paths and deployment layout, which is exactly the
|
|
117
|
-
* class of value a vendor package landing in a healthcare stack must not put on
|
|
118
|
-
* a wire the customer did not opt into. Flue's own durable serializers drop it
|
|
119
|
-
* for the same reason.
|
|
80
|
+
* Classified error details. stack is described but never read or exported because it can expose
|
|
81
|
+
* deployment paths.
|
|
120
82
|
*/
|
|
121
83
|
interface FlueErrorInfo {
|
|
122
84
|
type?: string;
|
|
@@ -276,58 +238,21 @@ interface FlueInstrumentation {
|
|
|
276
238
|
}
|
|
277
239
|
|
|
278
240
|
/**
|
|
279
|
-
*
|
|
280
|
-
* `gen_ai.
|
|
281
|
-
*
|
|
282
|
-
* PURE, like `projection.ts`: value in, attribute string out. The projection
|
|
283
|
-
* decides WHEN to call this (arguments when the tool span opens, the result
|
|
284
|
-
* just before it closes); this module decides WHAT reaches the wire and how
|
|
285
|
-
* much of it.
|
|
286
|
-
*
|
|
287
|
-
* ## Why opt-in, and why only tools
|
|
288
|
-
*
|
|
289
|
-
* The package's default contract is that no content leaves the process, and
|
|
290
|
-
* that stays the default: an instrumentation that lands inside a PHI-bearing
|
|
291
|
-
* process must not start shipping tool payloads because of a version bump.
|
|
292
|
-
* The `content` option is the explicit decision, and it is per kind, so a
|
|
293
|
-
* deployment can export the arguments it controls without the results a
|
|
294
|
-
* third-party API returns.
|
|
295
|
-
*
|
|
296
|
-
* Tool content is the one kind this release can emit honestly. Flue declares
|
|
297
|
-
* `tool_start.args` and `tool.result` stable, so both are on the same payloads
|
|
298
|
-
* the span lifecycle already reads. Prompts and completions are NOT here:
|
|
299
|
-
* they live on `AgentMessage`, which Flue marks unstable and this package
|
|
300
|
-
* refuses to read (see `flue-types.ts`).
|
|
301
|
-
*
|
|
302
|
-
* ## The read-side contract this honours
|
|
303
|
-
*
|
|
304
|
-
* Runtype's ingest reads exactly these two attributes off an `execute_tool`
|
|
305
|
-
* span (`packages/shared/src/otlp-runtype-semconv.ts`,
|
|
306
|
-
* `GEN_AI_CONTENT_ATTRIBUTES`) and projects them to the tool card's input and
|
|
307
|
-
* output. The value is a STRING: a JSON document is parsed back, anything
|
|
308
|
-
* that does not parse is kept as plain text. It is admitted under a budget
|
|
309
|
-
* (`packages/execution-ingest/src/ingest-content.ts`): a single attribute over
|
|
310
|
-
* `MAX_CONTENT_ATTRIBUTE_CHARS` (256 KiB) is dropped WHOLE, not cut, and one
|
|
311
|
-
* span may carry at most `MAX_CONTENT_SPAN_CHARS` (384 KiB) across every
|
|
312
|
-
* content attribute. Both ceilings are why `maxChars` exists and why its
|
|
313
|
-
* default sits where it does: arguments plus result at the default each fit
|
|
314
|
-
* inside the per-span ceiling with room to spare, and a value this module has
|
|
315
|
-
* already cut can never trip the per-attribute drop.
|
|
316
|
-
*
|
|
317
|
-
* The canonical `gen_ai.tool.call.*` names are emitted for every value,
|
|
318
|
-
* string or not. Stock `@flue/opentelemetry` routes a stringified non-object
|
|
319
|
-
* to `flue.tool.call.*` instead; ingest reads that alias only as a fallback,
|
|
320
|
-
* and the semconv attribute type is a string either way, so there is nothing
|
|
321
|
-
* to gain from the split.
|
|
322
|
-
*
|
|
323
|
-
* The two kinds are encoded differently because ingest projects them
|
|
324
|
-
* differently: a RESULT is any text (a string as-is, anything else as JSON,
|
|
325
|
-
* cut in place when over budget), while ARGUMENTS are always a JSON object,
|
|
326
|
-
* see {@link encodeArguments}.
|
|
241
|
+
* One semconv structured message, the element shape of `gen_ai.input.messages`
|
|
242
|
+
* and `gen_ai.output.messages`. Text parts only; see the README's content section.
|
|
327
243
|
*/
|
|
244
|
+
interface FlueContentMessage {
|
|
245
|
+
role: 'system' | 'user' | 'assistant';
|
|
246
|
+
parts: Array<{
|
|
247
|
+
type: 'text';
|
|
248
|
+
content: string;
|
|
249
|
+
}>;
|
|
250
|
+
}
|
|
251
|
+
|
|
328
252
|
/**
|
|
329
|
-
* What to emit
|
|
330
|
-
*
|
|
253
|
+
* What to emit. Every switch defaults to ON, so `{}` and an absent option both
|
|
254
|
+
* emit everything; set a switch to `false` to drop that one kind, or pass
|
|
255
|
+
* `content: false` to emit no content at all.
|
|
331
256
|
*/
|
|
332
257
|
interface FlueContentOptions {
|
|
333
258
|
/**
|
|
@@ -336,40 +261,51 @@ interface FlueContentOptions {
|
|
|
336
261
|
*/
|
|
337
262
|
toolArguments?: boolean;
|
|
338
263
|
/**
|
|
339
|
-
* Emit
|
|
340
|
-
*
|
|
341
|
-
* `effectiveResult` — what the model was actually shown — when present).
|
|
342
|
-
*
|
|
343
|
-
* A FAILED tool's result is never emitted: on both Flue lines it commonly
|
|
344
|
-
* IS the error payload, and error messages stay off the wire under every
|
|
345
|
-
* setting of this option. The span still closes with its error type and
|
|
346
|
-
* exception class name, as before.
|
|
264
|
+
* Emit successful tool results when the span closes; failed-tool payloads stay off the wire. Prefer
|
|
265
|
+
* effectiveResult when present, including undefined; otherwise use result.
|
|
347
266
|
*/
|
|
348
267
|
toolResults?: boolean;
|
|
349
268
|
/**
|
|
350
|
-
*
|
|
351
|
-
*
|
|
352
|
-
*
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
*
|
|
269
|
+
* Emit the conversation the run's first model turn was given as `gen_ai.input.messages` on the
|
|
270
|
+
* `invoke_agent` span: text-only user and assistant rows from Flue's normalized
|
|
271
|
+
* `turn_request.request.input.messages`. Later turns of the same run only add tool traffic.
|
|
272
|
+
*/
|
|
273
|
+
inputMessages?: boolean;
|
|
274
|
+
/**
|
|
275
|
+
* Emit the run's final assistant text as `gen_ai.output.messages` on the `invoke_agent` span, read
|
|
276
|
+
* from the last agent turn whose `turn.response.output` carried text.
|
|
277
|
+
*/
|
|
278
|
+
outputMessages?: boolean;
|
|
279
|
+
/**
|
|
280
|
+
* Emit the system prompt as `gen_ai.system_instructions` on the `invoke_agent` span, read from
|
|
281
|
+
* `turn_request.request.input.systemPrompt`. Usually the largest value a run carries; mind `maxChars`.
|
|
282
|
+
*/
|
|
283
|
+
systemInstructions?: boolean;
|
|
284
|
+
/**
|
|
285
|
+
* Per-value UTF-16 code-unit ceiling, including the truncation marker. Defaults to
|
|
286
|
+
* DEFAULT_CONTENT_MAX_CHARS and clamps to INGEST_CONTENT_ATTRIBUTE_CEILING, above which ingest drops
|
|
287
|
+
* the whole attribute.
|
|
357
288
|
*/
|
|
358
289
|
maxChars?: number;
|
|
359
290
|
/**
|
|
360
|
-
*
|
|
361
|
-
*
|
|
362
|
-
* Return `undefined` to suppress the attribute for this call entirely.
|
|
363
|
-
*
|
|
364
|
-
* An exception thrown here suppresses the attribute and nothing else: the
|
|
365
|
-
* span still opens and closes normally.
|
|
291
|
+
* Redact the raw value before encoding or truncation. Returning undefined or throwing suppresses only
|
|
292
|
+
* this attribute, not the span.
|
|
366
293
|
*/
|
|
367
294
|
redact?: (value: unknown, context: FlueContentRedactContext) => unknown;
|
|
368
295
|
}
|
|
369
|
-
|
|
296
|
+
/**
|
|
297
|
+
* What `redact` is looking at. Tool kinds receive the raw Flue payload; `input_messages` and
|
|
298
|
+
* `output_messages` receive the projected {@link FlueContentMessage} array; `system_instructions`
|
|
299
|
+
* receives the prompt string.
|
|
300
|
+
*/
|
|
301
|
+
type FlueContentRedactContext = {
|
|
370
302
|
kind: 'arguments' | 'result';
|
|
371
303
|
toolName: string;
|
|
372
|
-
}
|
|
304
|
+
} | {
|
|
305
|
+
kind: 'input_messages' | 'output_messages' | 'system_instructions';
|
|
306
|
+
toolName?: undefined;
|
|
307
|
+
};
|
|
308
|
+
type FlueMessageContentKind = 'input_messages' | 'output_messages';
|
|
373
309
|
/**
|
|
374
310
|
* The default per-value ceiling: 64 KiB of ASCII. Large enough for any
|
|
375
311
|
* realistic tool argument object and most results, and small enough that
|
|
@@ -378,67 +314,12 @@ interface FlueContentRedactContext {
|
|
|
378
314
|
*/
|
|
379
315
|
declare const DEFAULT_CONTENT_MAX_CHARS = 65536;
|
|
380
316
|
/**
|
|
381
|
-
*
|
|
382
|
-
*
|
|
383
|
-
* reason `semconv.ts` inlines the attribute names — that package is private
|
|
384
|
-
* and cannot resolve for a customer installing from npm. `tests/contract.test.ts`
|
|
385
|
-
* pins the two equal.
|
|
317
|
+
* Inline the private ingest per-attribute ceiling so npm installs need no private dependency.
|
|
318
|
+
* tests/contract.test.ts pins equality.
|
|
386
319
|
*/
|
|
387
320
|
declare const INGEST_CONTENT_ATTRIBUTE_CEILING = 262144;
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
* Flue observations → span intents. PURE: no `@opentelemetry/api`, no clock, no
|
|
391
|
-
* I/O. `spans.ts` is the only module that touches a `Tracer`.
|
|
392
|
-
*
|
|
393
|
-
* The split is what makes the emit contract testable. Every attribute this
|
|
394
|
-
* package puts on the wire is decided here, from a synthesized observation, and
|
|
395
|
-
* asserted in `tests/projection.test.ts` against both the 1.x and 2.x shapes —
|
|
396
|
-
* so a mapping regression is a unit-test failure rather than something only a
|
|
397
|
-
* live export against a real agent would show.
|
|
398
|
-
*
|
|
399
|
-
* ## What is emitted, and why exactly this
|
|
400
|
-
*
|
|
401
|
-
* The read side is `packages/execution-ingest/src/otel-trace-ingest-service.ts`.
|
|
402
|
-
* What it reads is this module's specification, so each choice below is a
|
|
403
|
-
* consequence of a rule stated there:
|
|
404
|
-
*
|
|
405
|
-
* - **`invoke_agent` is the ENVELOPE and there is exactly one per trace.**
|
|
406
|
-
* `selectEnvelopeSpan` takes the first ARRAY-order `invoke_agent` span, and
|
|
407
|
-
* array order is exporter-controlled. A second one — which stock
|
|
408
|
-
* `@flue/opentelemetry` opens for every `task` delegation — is therefore a
|
|
409
|
-
* coin flip over which invocation bounds the run, whose status closes it, and
|
|
410
|
-
* (via `resolveTraceAgentId`'s span-level source) which agent it files under.
|
|
411
|
-
* So a delegated sub-agent gets a `flue.task` span with NO
|
|
412
|
-
* `gen_ai.operation.name`, and the delegation itself is reported where it
|
|
413
|
-
* actually belongs: as the `execute_tool` span for the `task` tool, typed
|
|
414
|
-
* `subagent`. Stock does the opposite — it suppresses that tool span and
|
|
415
|
-
* opens the nested `invoke_agent` — which is the one place this projection
|
|
416
|
-
* deliberately diverges from it.
|
|
417
|
-
*
|
|
418
|
-
* - **Usage is rolled up ONTO the envelope, summed from `turn` leaves.**
|
|
419
|
-
* `projectUsage` prefers an envelope roll-up precisely because a
|
|
420
|
-
* `BatchSpanProcessor` flushes children before their parent, so the batch
|
|
421
|
-
* carrying the terminal may hold no model calls at all. Flue's own docs say
|
|
422
|
-
* to sum model-turn leaves rather than the `operation` roll-up, because
|
|
423
|
-
* nested duration and usage values overlap. Both point the same way: sum
|
|
424
|
-
* `turn.response.usage`, put the total on `invoke_agent`.
|
|
425
|
-
*
|
|
426
|
-
* - **The envelope carries the model.** Stock puts none there, which left the
|
|
427
|
-
* envelope's log record showing no model at all; the server-side normalizer
|
|
428
|
-
* now lifts one, but only for traces it recognizes as Flue's. Emitting it
|
|
429
|
-
* directly is F1 and costs one attribute. Both ids come off the SAME turn, so
|
|
430
|
-
* the request-model fallback can never price one call's served model against
|
|
431
|
-
* another's requested one.
|
|
432
|
-
*
|
|
433
|
-
* - **`runtype.turn.index` / `runtype.iteration` ARE derived here, and are not
|
|
434
|
-
* derivable at ingest.** The server-side normalizer deliberately refuses
|
|
435
|
-
* them: Flue puts no absolute ordinal on the wire, and ranking opaque turn
|
|
436
|
-
* ids ranks whatever the export batch happened to carry — a five-turn run
|
|
437
|
-
* whose closing batch holds two turns would be recorded as two iterations.
|
|
438
|
-
* In-process the count is exact, because we see every `turn_request` in
|
|
439
|
-
* order. This is the clearest thing this package buys that a normalizer
|
|
440
|
-
* structurally cannot.
|
|
441
|
-
*/
|
|
321
|
+
/** The resolved, always-complete policy the projection consults. */
|
|
322
|
+
type FlueContentSetting = FlueContentOptions | false;
|
|
442
323
|
|
|
443
324
|
/** Attribute values OTLP can carry. Deliberately narrower than OTel's type. */
|
|
444
325
|
type SpanAttributes = Record<string, string | number | boolean | string[]>;
|
|
@@ -461,20 +342,8 @@ interface OpenSpanIntent {
|
|
|
461
342
|
startTime?: string;
|
|
462
343
|
attributes: SpanAttributes;
|
|
463
344
|
/**
|
|
464
|
-
* Drop
|
|
465
|
-
*
|
|
466
|
-
* Set on framework bookkeeping that only means anything INSIDE a run —
|
|
467
|
-
* `flue.operation shell` and `flue.compaction`. Both can occur outside one:
|
|
468
|
-
* `session.shell()` and `session.compact()` are public host APIs, and Flue
|
|
469
|
-
* intercepts only `prompt` and `skill` operations, so neither has a parent
|
|
470
|
-
* span or an active context to inherit.
|
|
471
|
-
*
|
|
472
|
-
* Started as a root, such a span becomes the ONLY span in its trace — and
|
|
473
|
-
* ingest's `selectEnvelopeSpan` falls back to the first parentless span when
|
|
474
|
-
* a trace carries no agent invocation, so it would be read as the envelope
|
|
475
|
-
* of a run and write a phantom execution row for every host-initiated shell
|
|
476
|
-
* command. This is the same reasoning `index.ts` applies to `coordinator`
|
|
477
|
-
* operations, applied to the other two paths that reach the same state.
|
|
345
|
+
* Drop bookkeeping spans without a parent: ingest could otherwise treat a host shell or compaction
|
|
346
|
+
* span as a phantom run envelope.
|
|
478
347
|
*/
|
|
479
348
|
requiresParent?: boolean;
|
|
480
349
|
}
|
|
@@ -488,11 +357,8 @@ interface CloseSpanIntent {
|
|
|
488
357
|
ref: string;
|
|
489
358
|
endTime?: string;
|
|
490
359
|
/**
|
|
491
|
-
*
|
|
492
|
-
*
|
|
493
|
-
* provider error message routinely quotes the prompt back, and a stack
|
|
494
|
-
* exposes filesystem paths and deployment layout. Neither is read under any
|
|
495
|
-
* setting; the `content` opt-in covers tool payloads only.
|
|
360
|
+
* Failure type and exception class only. Error messages and stacks can expose prompts or deployment
|
|
361
|
+
* paths and are excluded even when tool-content export is enabled.
|
|
496
362
|
*/
|
|
497
363
|
error?: {
|
|
498
364
|
type: string;
|
|
@@ -502,26 +368,17 @@ interface CloseSpanIntent {
|
|
|
502
368
|
type SpanIntent = OpenSpanIntent | UpdateSpanIntent | CloseSpanIntent;
|
|
503
369
|
interface FlueProjectionOptions {
|
|
504
370
|
/**
|
|
505
|
-
*
|
|
506
|
-
*
|
|
507
|
-
*
|
|
508
|
-
* attribution placement, for the one shape a `Resource` cannot express: a
|
|
509
|
-
* single process running several Runtype agents. A single-agent deployment
|
|
510
|
-
* should set the resource attribute instead (see
|
|
511
|
-
* {@link runtypeFlueResourceAttributes} and the README recipe), which the
|
|
512
|
-
* ingest reader prefers.
|
|
513
|
-
*
|
|
514
|
-
* A delegated sub-agent is deliberately NOT attributed separately: its work
|
|
515
|
-
* runs inside the delegating agent's trace, and one trace is one execution.
|
|
371
|
+
* Agent id by Flue agent name, stamped on the envelope. Resource attribution takes precedence;
|
|
372
|
+
* delegated subagents are not separate executions. Use runtypeFlueResourceAttributes for single-agent
|
|
373
|
+
* processes.
|
|
516
374
|
*/
|
|
517
375
|
agents?: Record<string, string>;
|
|
518
376
|
/**
|
|
519
|
-
*
|
|
520
|
-
*
|
|
521
|
-
*
|
|
522
|
-
* honour.
|
|
377
|
+
* Content: tool arguments and results on `execute_tool` spans, messages and the system prompt on
|
|
378
|
+
* the `invoke_agent` envelope. All ON by default; set a switch to `false` to drop one kind, or
|
|
379
|
+
* `content: false` for none. See {@link FlueContentOptions} for the size ceiling and redaction hook.
|
|
523
380
|
*/
|
|
524
|
-
content?:
|
|
381
|
+
content?: FlueContentSetting;
|
|
525
382
|
}
|
|
526
383
|
/**
|
|
527
384
|
* Resource attributes for the customer's `Resource`. Exported rather than set
|
|
@@ -533,28 +390,6 @@ declare function runtypeFlueResourceAttributes(resource?: {
|
|
|
533
390
|
agentId?: string | null;
|
|
534
391
|
}): SpanAttributes;
|
|
535
392
|
|
|
536
|
-
/**
|
|
537
|
-
* The attribute vocabulary this instrumentation emits: the GenAI semantic
|
|
538
|
-
* conventions plus Runtype's ratified `runtype.*` extension names.
|
|
539
|
-
*
|
|
540
|
-
* ## Why the literals are inlined rather than imported
|
|
541
|
-
*
|
|
542
|
-
* The canonical home for the `runtype.*` names is
|
|
543
|
-
* `packages/shared/src/otlp-runtype-semconv.ts`, and this module is a
|
|
544
|
-
* CONSUMER of that contract, never a fork of it. But `@runtypelabs/shared` is
|
|
545
|
-
* `private: true` and is not published to npm, while this package is — so a
|
|
546
|
-
* runtime import would resolve in the monorepo and fail for every customer who
|
|
547
|
-
* installs `@runtypelabs/flue-otel` from the registry.
|
|
548
|
-
*
|
|
549
|
-
* The discipline that keeps a copy from becoming a fork is
|
|
550
|
-
* `tests/contract.test.ts`: a DEV-ONLY cross-import that asserts every literal
|
|
551
|
-
* here is identical to the shared module's. A rename on either side is a red
|
|
552
|
-
* build, in the same PR, which is the only mechanism that actually holds. It is
|
|
553
|
-
* the same posture `examples/flue-persona` uses for the unified SSE vocabulary.
|
|
554
|
-
*
|
|
555
|
-
* Exact strings are load-bearing: a misspelled attribute fails no build — it
|
|
556
|
-
* silently empties a column of every ingested run.
|
|
557
|
-
*/
|
|
558
393
|
/**
|
|
559
394
|
* GenAI semantic-convention attribute names. Mirrors the subset of
|
|
560
395
|
* `packages/shared/src/gen-ai-semconv.ts` this instrumentation can populate
|
|
@@ -586,14 +421,14 @@ declare const GEN_AI: {
|
|
|
586
421
|
readonly serverPort: "server.port";
|
|
587
422
|
};
|
|
588
423
|
/**
|
|
589
|
-
*
|
|
590
|
-
*
|
|
591
|
-
*
|
|
592
|
-
* two reach the wire only under the `content` option (`content.ts`), and only
|
|
593
|
-
* on `execute_tool` spans. Mirrors `GEN_AI_CONTENT_ATTRIBUTES` in
|
|
594
|
-
* `packages/shared/src/otlp-runtype-semconv.ts`, which is what ingest reads.
|
|
424
|
+
* Content attribute names, separate from the structural GEN_AI set. Tool content goes on
|
|
425
|
+
* `execute_tool` spans, message content on the `invoke_agent` envelope; each kind can be switched
|
|
426
|
+
* off through the content options. Mirrored in shared ingest semconv.
|
|
595
427
|
*/
|
|
596
428
|
declare const GEN_AI_CONTENT: {
|
|
429
|
+
readonly inputMessages: "gen_ai.input.messages";
|
|
430
|
+
readonly outputMessages: "gen_ai.output.messages";
|
|
431
|
+
readonly systemInstructions: "gen_ai.system_instructions";
|
|
597
432
|
readonly toolCallArguments: "gen_ai.tool.call.arguments";
|
|
598
433
|
readonly toolCallResult: "gen_ai.tool.call.result";
|
|
599
434
|
};
|
|
@@ -640,52 +475,6 @@ declare const ADAPTER_NAME = "@runtypelabs/flue-otel";
|
|
|
640
475
|
/** What this package reports itself as in `runtype.adapter.version`. */
|
|
641
476
|
declare const ADAPTER_VERSION: string;
|
|
642
477
|
|
|
643
|
-
/**
|
|
644
|
-
* `@runtypelabs/flue-otel` — Runtype's OpenTelemetry instrumentation for Flue
|
|
645
|
-
* agents.
|
|
646
|
-
*
|
|
647
|
-
* Install it with Flue's `instrument()` and every agent run becomes a trace of
|
|
648
|
-
* GenAI-semconv spans carrying Runtype's `runtype.*` extension vocabulary, so
|
|
649
|
-
* the run lands in Runtype at `t2-runtype` fidelity — full parity with a native
|
|
650
|
-
* run — instead of the generic tier a stock export reaches.
|
|
651
|
-
*
|
|
652
|
-
* ```ts
|
|
653
|
-
* import { instrument } from '@flue/runtime'
|
|
654
|
-
* import { createRuntypeFlueInstrumentation } from '@runtypelabs/flue-otel'
|
|
655
|
-
*
|
|
656
|
-
* const stop = instrument(createRuntypeFlueInstrumentation())
|
|
657
|
-
* ```
|
|
658
|
-
*
|
|
659
|
-
* ## What it is not
|
|
660
|
-
*
|
|
661
|
-
* It owns **no** OpenTelemetry SDK. There is no `@opentelemetry/sdk-*`
|
|
662
|
-
* dependency, no provider, no exporter, no sampler, no flush. The application
|
|
663
|
-
* configures those, this package writes spans through whatever is registered,
|
|
664
|
-
* and the README carries the twelve-line recipe for a process that has none
|
|
665
|
-
* yet. That is deliberate: a vendor package that installs its own tracing
|
|
666
|
-
* pipeline fights the one the customer already runs, and in a stack exporting
|
|
667
|
-
* to two backends it silently wins one of those fights.
|
|
668
|
-
*
|
|
669
|
-
* It also emits **no content by default** — no prompts, no completions, no
|
|
670
|
-
* tool arguments or results, no error messages, no stack traces. Only
|
|
671
|
-
* identifiers, structure and metrics reach the wire, which is the right
|
|
672
|
-
* default for a package landing inside a PHI-bearing process. The one
|
|
673
|
-
* explicit opt-in is `content`: tool arguments and results on `execute_tool`
|
|
674
|
-
* spans, per kind, size-capped and redactable (`content.ts`). Prompts and
|
|
675
|
-
* completions remain off the table until Flue exposes a stable message shape.
|
|
676
|
-
*
|
|
677
|
-
* ## Composing with other instrumentations
|
|
678
|
-
*
|
|
679
|
-
* Flue's `instrument()` composes — an error reporter and a tracer can subscribe
|
|
680
|
-
* side by side — and this instrumentation carries its own `key`, so installing
|
|
681
|
-
* it never replaces `@flue/opentelemetry`.
|
|
682
|
-
*
|
|
683
|
-
* **Point exactly one instrumentation at Runtype.** If both this package and a
|
|
684
|
-
* stock `@flue/opentelemetry` export to the same Runtype endpoint, ingest sees
|
|
685
|
-
* two `invoke_agent` spans for one run and the usage DOUBLES. Running both is
|
|
686
|
-
* fine when they export to different backends.
|
|
687
|
-
*/
|
|
688
|
-
|
|
689
478
|
/**
|
|
690
479
|
* The instrumentation key. Distinct from stock's
|
|
691
480
|
* `Symbol.for('@flue/opentelemetry')` so `instrument()` treats the two as
|
|
@@ -702,17 +491,10 @@ interface RuntypeFlueInstrumentationOptions extends FlueProjectionOptions {
|
|
|
702
491
|
tracer?: Tracer;
|
|
703
492
|
}
|
|
704
493
|
/**
|
|
705
|
-
* Build
|
|
706
|
-
*
|
|
707
|
-
*
|
|
708
|
-
* The returned object implements the FULL `FlueInstrumentation` contract, not
|
|
709
|
-
* just `observe`. The `interceptor` half is not optional in practice: it is
|
|
710
|
-
* what makes each span the OTel ACTIVE context around the real agent, model and
|
|
711
|
-
* tool work, so the platform's own HTTP and database spans nest inside the run
|
|
712
|
-
* instead of landing in a separate trace — and it is the only place Flue offers
|
|
713
|
-
* `executionContext.traceCarrier`, the W3C context that joins a dispatched run
|
|
714
|
-
* to the trace that started it.
|
|
494
|
+
* Build an observe/interceptor pair for Flue's instrument(). The interceptor activates spans and joins
|
|
495
|
+
* dispatched trace carriers. Configure the OTel SDK externally, and point only one instrumentation at
|
|
496
|
+
* Runtype to avoid double counting.
|
|
715
497
|
*/
|
|
716
498
|
declare function createRuntypeFlueInstrumentation(options?: RuntypeFlueInstrumentationOptions): FlueInstrumentation;
|
|
717
499
|
|
|
718
|
-
export { ADAPTER_NAME, ADAPTER_VERSION, DEFAULT_CONTENT_MAX_CHARS, type FlueContentOptions, type FlueContentRedactContext, type FlueInstrumentation, type FlueProjectionOptions, GEN_AI, GEN_AI_CONTENT, INGEST_CONTENT_ATTRIBUTE_CEILING, RUNTYPE, RUNTYPE_FLUE_INSTRUMENTATION_KEY, RUNTYPE_SCHEMA_VERSION, RUNTYPE_STOP_REASONS, RUNTYPE_TOOL_TYPES, type RuntypeFlueInstrumentationOptions, type RuntypeStopReason, type RuntypeToolType, type SpanAttributes, type SpanIntent, createRuntypeFlueInstrumentation, runtypeFlueResourceAttributes };
|
|
500
|
+
export { ADAPTER_NAME, ADAPTER_VERSION, DEFAULT_CONTENT_MAX_CHARS, type FlueContentMessage, type FlueContentOptions, type FlueContentRedactContext, type FlueContentSetting, type FlueInstrumentation, type FlueMessageContentKind, type FlueProjectionOptions, GEN_AI, GEN_AI_CONTENT, INGEST_CONTENT_ATTRIBUTE_CEILING, RUNTYPE, RUNTYPE_FLUE_INSTRUMENTATION_KEY, RUNTYPE_SCHEMA_VERSION, RUNTYPE_STOP_REASONS, RUNTYPE_TOOL_TYPES, type RuntypeFlueInstrumentationOptions, type RuntypeStopReason, type RuntypeToolType, type SpanAttributes, type SpanIntent, createRuntypeFlueInstrumentation, runtypeFlueResourceAttributes };
|