@telemetry-dev/pi 0.1.0 → 0.1.2
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 +34 -25
- package/dist/{extension-CZQ_PvAB.d.mts → extension-DhhRAe5R.d.mts} +9 -4
- package/dist/{extension-DLbX-piL.mjs → extension-V9WCbPBU.mjs} +38 -6
- package/dist/index.d.mts +1 -1
- package/dist/index.mjs +1 -1
- package/dist/register.d.mts +1 -1
- package/dist/register.mjs +1 -1
- package/package.json +2 -2
- package/src/config.ts +2 -1
- package/src/extension.ts +45 -8
package/README.md
CHANGED
|
@@ -54,45 +54,54 @@ options.
|
|
|
54
54
|
|
|
55
55
|
## Trace shape
|
|
56
56
|
|
|
57
|
-
A typical
|
|
57
|
+
A typical session produces this hierarchy:
|
|
58
58
|
|
|
59
59
|
```text
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
│
|
|
64
|
-
└──
|
|
60
|
+
session
|
|
61
|
+
└── invoke_agent
|
|
62
|
+
├── chat {model} (assistant message)
|
|
63
|
+
│ ├── execute_tool {toolName} (tool calls from that message)
|
|
64
|
+
│ └── execute_tool {toolName}
|
|
65
|
+
└── chat {model} (final assistant message)
|
|
65
66
|
```
|
|
66
67
|
|
|
67
|
-
- one `
|
|
68
|
-
- one
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
call id, arguments, result, and error state;
|
|
68
|
+
- one `session` wrapper span for the full pi session;
|
|
69
|
+
- one `invoke_agent` span for each prompt, with the prompt and the final assistant content;
|
|
70
|
+
- one nested `chat {model}` span for each completed assistant message, with the provider, models,
|
|
71
|
+
response id, finish reason, usage, pi cost, provider request, and all returned content blocks;
|
|
72
|
+
- one `execute_tool {toolName}` span for each tool execution, under the `chat` span that issued the
|
|
73
|
+
call. If no message matches the tool call id, the span is under the `invoke_agent` span. The span
|
|
74
|
+
includes the tool call id, arguments, result, and error state;
|
|
74
75
|
- lifecycle logs for sessions, turns, compaction, and model changes.
|
|
75
76
|
|
|
76
|
-
|
|
77
|
-
`gen_ai.conversation.id`. This keeps `/new`, `/resume`, `/fork`, and `/reload`
|
|
78
|
-
|
|
79
|
-
`eventName`.
|
|
77
|
+
Each span and log reads `ctx.sessionManager.getSessionId()` when its event occurs. The span or log
|
|
78
|
+
records the value as `gen_ai.conversation.id`. This keeps `/new`, `/resume`, `/fork`, and `/reload`
|
|
79
|
+
events with the new session. Logs also have `gen_ai.agent.name` and the pi event type as `eventName`.
|
|
80
80
|
|
|
81
|
-
`agent_end`
|
|
82
|
-
|
|
83
|
-
It
|
|
81
|
+
`agent_end` records the last run result and starts an asynchronous flush. `agent_settled` closes
|
|
82
|
+
unfinished tool spans and the prompt span. `session_shutdown` closes an unfinished prompt and the
|
|
83
|
+
session span, then waits for the final flush. It does not shut down the SDK during a pi session change.
|
|
84
84
|
|
|
85
85
|
## Content capture
|
|
86
86
|
|
|
87
|
-
|
|
88
|
-
`
|
|
89
|
-
|
|
87
|
+
The prompt includes its image blocks. Chat input records the provider-formatted request from
|
|
88
|
+
`before_provider_request`, after all `context` handlers and pi's model-message conversion.
|
|
89
|
+
This conversion removes `!!` shell output and custom-message `details` from the model input.
|
|
90
|
+
System instructions come from the effective `ctx.getSystemPrompt()` at the request boundary, after all
|
|
91
|
+
`before_agent_start` handlers. Chat output contains all returned content blocks. The integration also
|
|
92
|
+
records tool arguments and tool results.
|
|
90
93
|
|
|
91
|
-
|
|
92
|
-
|
|
94
|
+
These values obey the telemetry.dev SDK `captureInput` and `captureOutput` settings, which default to
|
|
95
|
+
`true`. Use `mask` to remove values before capture. Use `maxAttributeLength` to limit serialized
|
|
96
|
+
attributes.
|
|
93
97
|
|
|
94
98
|
## Limitations
|
|
95
99
|
|
|
100
|
+
- Chat input uses each provider's request shape, not pi's raw session messages. Pi's public hooks do
|
|
101
|
+
not expose the final wire payload. A later `before_provider_request` handler can replace the request
|
|
102
|
+
after capture. Custom providers must call pi's `onPayload` callback for request and system
|
|
103
|
+
instruction capture. Without that callback, those fields are absent. Prompt, output, and tool
|
|
104
|
+
capture still work.
|
|
96
105
|
- Pi does not expose per-request TTFT or duration fields. Chat duration is measured from
|
|
97
106
|
`message_start` to `message_end` using local wall-clock time, and TTFT is not recorded.
|
|
98
107
|
- `tool_call` and `tool_result` are intentionally not intercepted. In pi, an uncaught `tool_call`
|
|
@@ -7,7 +7,7 @@ import { ClientOverrides, TelemetryOptions } from "@telemetry-dev/sdk";
|
|
|
7
7
|
* integration never touches the global provider — every span is created
|
|
8
8
|
* through the SDK's own tracer with explicit parenting.
|
|
9
9
|
*/
|
|
10
|
-
type TelemetryDevPiOptions = Omit<TelemetryOptions, "registerGlobal">;
|
|
10
|
+
type TelemetryDevPiOptions = Omit<TelemetryOptions, "registerGlobal" | "sdkName">;
|
|
11
11
|
//#endregion
|
|
12
12
|
//#region src/extension.d.ts
|
|
13
13
|
/** Options for {@link telemetryDevExtension}. */
|
|
@@ -31,6 +31,8 @@ interface TelemetryDevExtensionContext {
|
|
|
31
31
|
sessionManager: {
|
|
32
32
|
getSessionId(): string | undefined;
|
|
33
33
|
};
|
|
34
|
+
/** Effective system prompt after all before_agent_start handlers. */
|
|
35
|
+
getSystemPrompt(): string;
|
|
34
36
|
}
|
|
35
37
|
/**
|
|
36
38
|
* Structural stand-in for the host `ExtensionAPI` passed to extension
|
|
@@ -46,9 +48,12 @@ type TelemetryDevExtension = (pi: TelemetryDevExtensionHost) => void;
|
|
|
46
48
|
* Creates a pi extension factory that exports agent loops, model calls, tool
|
|
47
49
|
* executions, and lifecycle logs to telemetry.dev.
|
|
48
50
|
*
|
|
49
|
-
* Trace shape per
|
|
50
|
-
*
|
|
51
|
-
*
|
|
51
|
+
* Trace shape: one trace per pi session with a `session` root span. Each user
|
|
52
|
+
* prompt is an `invoke_agent` child, with one `chat {model}` child span per
|
|
53
|
+
* assistant message and one `execute_tool {tool}` child span per tool
|
|
54
|
+
* execution. Payloads include the prompt and its images, the provider-formatted
|
|
55
|
+
* request, and every returned content block (thinking, text, tool calls).
|
|
56
|
+
* Logs join the same session through `gen_ai.conversation.id`.
|
|
52
57
|
*/
|
|
53
58
|
declare function telemetryDevExtension(options?: TelemetryDevExtensionOptions, overrides?: ClientOverrides): TelemetryDevExtension;
|
|
54
59
|
//#endregion
|
|
@@ -8,6 +8,7 @@ function ensureInit(options = {}, overrides) {
|
|
|
8
8
|
init({
|
|
9
9
|
...options,
|
|
10
10
|
serviceName: options.serviceName ?? process.env.OTEL_SERVICE_NAME ?? "pi",
|
|
11
|
+
sdkName: "@telemetry-dev/pi",
|
|
11
12
|
registerGlobal: false
|
|
12
13
|
}, overrides);
|
|
13
14
|
}
|
|
@@ -70,9 +71,12 @@ function failureError(name, message) {
|
|
|
70
71
|
* Creates a pi extension factory that exports agent loops, model calls, tool
|
|
71
72
|
* executions, and lifecycle logs to telemetry.dev.
|
|
72
73
|
*
|
|
73
|
-
* Trace shape per
|
|
74
|
-
*
|
|
75
|
-
*
|
|
74
|
+
* Trace shape: one trace per pi session with a `session` root span. Each user
|
|
75
|
+
* prompt is an `invoke_agent` child, with one `chat {model}` child span per
|
|
76
|
+
* assistant message and one `execute_tool {tool}` child span per tool
|
|
77
|
+
* execution. Payloads include the prompt and its images, the provider-formatted
|
|
78
|
+
* request, and every returned content block (thinking, text, tool calls).
|
|
79
|
+
* Logs join the same session through `gen_ai.conversation.id`.
|
|
76
80
|
*/
|
|
77
81
|
function telemetryDevExtension(options = {}, overrides) {
|
|
78
82
|
const { agentName = "pi", ...sdkOptions } = options;
|
|
@@ -87,9 +91,13 @@ function telemetryDevExtension(options = {}, overrides) {
|
|
|
87
91
|
function register(event, handler) {
|
|
88
92
|
pi.on(event, handler);
|
|
89
93
|
}
|
|
94
|
+
/** Root of the one trace per pi session; every prompt span nests under it. */
|
|
95
|
+
let sessionSpan;
|
|
90
96
|
let agentSpan;
|
|
91
97
|
let assistantStartedAt;
|
|
92
98
|
let pendingPrompt;
|
|
99
|
+
let systemPrompt;
|
|
100
|
+
let request;
|
|
93
101
|
/** Latest agent_end outcome, applied to the prompt span when the run settles. */
|
|
94
102
|
let lastRunResult;
|
|
95
103
|
/** Chat span that issued each pending tool call, so tool spans nest under it. */
|
|
@@ -125,6 +133,10 @@ function telemetryDevExtension(options = {}, overrides) {
|
|
|
125
133
|
agentSpan?.end(fields);
|
|
126
134
|
agentSpan = void 0;
|
|
127
135
|
}
|
|
136
|
+
function endSessionSpan() {
|
|
137
|
+
sessionSpan?.end();
|
|
138
|
+
sessionSpan = void 0;
|
|
139
|
+
}
|
|
128
140
|
function on(event, handler) {
|
|
129
141
|
register(event, (payload, ctx) => {
|
|
130
142
|
try {
|
|
@@ -136,15 +148,29 @@ function telemetryDevExtension(options = {}, overrides) {
|
|
|
136
148
|
}
|
|
137
149
|
register("before_agent_start", (event) => {
|
|
138
150
|
try {
|
|
139
|
-
|
|
151
|
+
const prompt = event.prompt?.constructor === String ? event.prompt : void 0;
|
|
152
|
+
pendingPrompt = Array.isArray(event.images) && event.images.length > 0 ? [{
|
|
153
|
+
type: "text",
|
|
154
|
+
text: prompt ?? ""
|
|
155
|
+
}, ...event.images] : prompt;
|
|
140
156
|
} catch (error) {
|
|
141
157
|
reportError(onError, error);
|
|
142
158
|
}
|
|
143
159
|
});
|
|
160
|
+
on("before_provider_request", (event, ctx) => {
|
|
161
|
+
request = event.payload;
|
|
162
|
+
systemPrompt = ctx.getSystemPrompt();
|
|
163
|
+
});
|
|
144
164
|
on("agent_start", (_event, ctx) => {
|
|
145
165
|
if (agentSpan) return;
|
|
166
|
+
sessionSpan ??= startSpan("session", {
|
|
167
|
+
type: "agent",
|
|
168
|
+
agentName,
|
|
169
|
+
attributes: spanAttributes(ctx)
|
|
170
|
+
});
|
|
146
171
|
agentSpan = startSpan("invoke_agent", {
|
|
147
172
|
type: "agent",
|
|
173
|
+
parent: sessionSpan,
|
|
148
174
|
agentName,
|
|
149
175
|
input: pendingPrompt,
|
|
150
176
|
attributes: spanAttributes(ctx)
|
|
@@ -161,7 +187,7 @@ function telemetryDevExtension(options = {}, overrides) {
|
|
|
161
187
|
const stopReason = stringField(lastAssistant, "stopReason");
|
|
162
188
|
const errorMessage = stringField(lastAssistant, "errorMessage");
|
|
163
189
|
lastRunResult = {
|
|
164
|
-
output:
|
|
190
|
+
output: lastAssistant?.content,
|
|
165
191
|
finishReason: stopReason,
|
|
166
192
|
error: stopReason === "error" ? failureError(stopReason, errorMessage) : void 0
|
|
167
193
|
};
|
|
@@ -196,10 +222,14 @@ function telemetryDevExtension(options = {}, overrides) {
|
|
|
196
222
|
usage: usageFields(message),
|
|
197
223
|
costUsd: numberField(asRecord(asRecord(message.usage)?.cost), "total"),
|
|
198
224
|
finishReason: stopReason,
|
|
199
|
-
|
|
225
|
+
systemInstructions: systemPrompt,
|
|
226
|
+
input: request,
|
|
227
|
+
output: message.content,
|
|
200
228
|
error: stopReason === "error" ? failureError(stopReason, errorMessage) : void 0,
|
|
201
229
|
attributes: spanAttributes(ctx)
|
|
202
230
|
});
|
|
231
|
+
request = void 0;
|
|
232
|
+
systemPrompt = void 0;
|
|
203
233
|
for (const block of Array.isArray(message.content) ? message.content : []) {
|
|
204
234
|
const record = asRecord(block);
|
|
205
235
|
if (record?.type === "toolCall" && record.id?.constructor === String) chatSpanByToolCall.set(record.id, span);
|
|
@@ -235,6 +265,7 @@ function telemetryDevExtension(options = {}, overrides) {
|
|
|
235
265
|
emit("turn_end", ctx, "debug", "Turn completed", { "pi.turn.index": event.turnIndex });
|
|
236
266
|
});
|
|
237
267
|
on("session_start", (event, ctx) => {
|
|
268
|
+
endSessionSpan();
|
|
238
269
|
const model = asRecord(ctx.model);
|
|
239
270
|
emit("session_start", ctx, "info", "Session started", {
|
|
240
271
|
"gen_ai.request.model": stringField(model, "id"),
|
|
@@ -262,6 +293,7 @@ function telemetryDevExtension(options = {}, overrides) {
|
|
|
262
293
|
endAgentSpan(lastRunResult ?? { finishReason: "incomplete" });
|
|
263
294
|
lastRunResult = void 0;
|
|
264
295
|
}
|
|
296
|
+
endSessionSpan();
|
|
265
297
|
emit("session_shutdown", ctx, "info", "Session shutdown", { "pi.session.reason": event.reason });
|
|
266
298
|
await flush();
|
|
267
299
|
} catch (error) {
|
package/dist/index.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as telemetryDevExtension, i as TelemetryDevExtensionOptions, n as TelemetryDevExtensionContext, o as TelemetryDevPiOptions, r as TelemetryDevExtensionHost, t as TelemetryDevExtension } from "./extension-
|
|
1
|
+
import { a as telemetryDevExtension, i as TelemetryDevExtensionOptions, n as TelemetryDevExtensionContext, o as TelemetryDevPiOptions, r as TelemetryDevExtensionHost, t as TelemetryDevExtension } from "./extension-DhhRAe5R.mjs";
|
|
2
2
|
export { type TelemetryDevExtension, type TelemetryDevExtensionContext, type TelemetryDevExtensionHost, type TelemetryDevExtensionOptions, type TelemetryDevPiOptions, telemetryDevExtension };
|
package/dist/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as telemetryDevExtension } from "./extension-
|
|
1
|
+
import { t as telemetryDevExtension } from "./extension-V9WCbPBU.mjs";
|
|
2
2
|
export { telemetryDevExtension };
|
package/dist/register.d.mts
CHANGED
package/dist/register.mjs
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@telemetry-dev/pi",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "Pi coding-agent telemetry integration for telemetry.dev.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"agents",
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
},
|
|
44
44
|
"dependencies": {
|
|
45
45
|
"@opentelemetry/api": "^1.9.1",
|
|
46
|
-
"@telemetry-dev/sdk": "^0.1.
|
|
46
|
+
"@telemetry-dev/sdk": "^0.1.2"
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
49
|
"@earendil-works/pi-coding-agent": "0.82.1",
|
package/src/config.ts
CHANGED
|
@@ -6,7 +6,7 @@ import { init, shutdown, type ClientOverrides, type TelemetryOptions } from "@te
|
|
|
6
6
|
* integration never touches the global provider — every span is created
|
|
7
7
|
* through the SDK's own tracer with explicit parenting.
|
|
8
8
|
*/
|
|
9
|
-
export type TelemetryDevPiOptions = Omit<TelemetryOptions, "registerGlobal">;
|
|
9
|
+
export type TelemetryDevPiOptions = Omit<TelemetryOptions, "registerGlobal" | "sdkName">;
|
|
10
10
|
|
|
11
11
|
export type { ClientOverrides };
|
|
12
12
|
|
|
@@ -20,6 +20,7 @@ export function ensureInit(options: TelemetryDevPiOptions = {}, overrides?: Clie
|
|
|
20
20
|
{
|
|
21
21
|
...options,
|
|
22
22
|
serviceName: options.serviceName ?? process.env.OTEL_SERVICE_NAME ?? "pi",
|
|
23
|
+
sdkName: "@telemetry-dev/pi",
|
|
23
24
|
// Enforce the guarantee above at runtime for untyped (plain JS) callers.
|
|
24
25
|
registerGlobal: false,
|
|
25
26
|
},
|
package/src/extension.ts
CHANGED
|
@@ -30,6 +30,8 @@ export interface TelemetryDevExtensionContext {
|
|
|
30
30
|
model: unknown;
|
|
31
31
|
/** Read-only session manager exposing the session id. */
|
|
32
32
|
sessionManager: { getSessionId(): string | undefined };
|
|
33
|
+
/** Effective system prompt after all before_agent_start handlers. */
|
|
34
|
+
getSystemPrompt(): string;
|
|
33
35
|
}
|
|
34
36
|
|
|
35
37
|
/**
|
|
@@ -116,9 +118,12 @@ function failureError(name: string, message: string | undefined): Error {
|
|
|
116
118
|
* Creates a pi extension factory that exports agent loops, model calls, tool
|
|
117
119
|
* executions, and lifecycle logs to telemetry.dev.
|
|
118
120
|
*
|
|
119
|
-
* Trace shape per
|
|
120
|
-
*
|
|
121
|
-
*
|
|
121
|
+
* Trace shape: one trace per pi session with a `session` root span. Each user
|
|
122
|
+
* prompt is an `invoke_agent` child, with one `chat {model}` child span per
|
|
123
|
+
* assistant message and one `execute_tool {tool}` child span per tool
|
|
124
|
+
* execution. Payloads include the prompt and its images, the provider-formatted
|
|
125
|
+
* request, and every returned content block (thinking, text, tool calls).
|
|
126
|
+
* Logs join the same session through `gen_ai.conversation.id`.
|
|
122
127
|
*/
|
|
123
128
|
export function telemetryDevExtension(
|
|
124
129
|
options: TelemetryDevExtensionOptions = {},
|
|
@@ -142,9 +147,13 @@ export function telemetryDevExtension(
|
|
|
142
147
|
pi.on(event as never, handler as never);
|
|
143
148
|
}
|
|
144
149
|
|
|
150
|
+
/** Root of the one trace per pi session; every prompt span nests under it. */
|
|
151
|
+
let sessionSpan: SpanHandle | undefined;
|
|
145
152
|
let agentSpan: SpanHandle | undefined;
|
|
146
153
|
let assistantStartedAt: number | undefined;
|
|
147
|
-
let pendingPrompt:
|
|
154
|
+
let pendingPrompt: JsonValue | undefined;
|
|
155
|
+
let systemPrompt: string | undefined;
|
|
156
|
+
let request: unknown;
|
|
148
157
|
/** Latest agent_end outcome, applied to the prompt span when the run settles. */
|
|
149
158
|
let lastRunResult: Parameters<SpanHandle["end"]>[0];
|
|
150
159
|
/** Chat span that issued each pending tool call, so tool spans nest under it. */
|
|
@@ -187,6 +196,11 @@ export function telemetryDevExtension(
|
|
|
187
196
|
agentSpan = undefined;
|
|
188
197
|
}
|
|
189
198
|
|
|
199
|
+
function endSessionSpan(): void {
|
|
200
|
+
sessionSpan?.end();
|
|
201
|
+
sessionSpan = undefined;
|
|
202
|
+
}
|
|
203
|
+
|
|
190
204
|
function on<Event>(
|
|
191
205
|
event: string,
|
|
192
206
|
handler: (event: Event, ctx: TelemetryDevExtensionContext) => void,
|
|
@@ -200,20 +214,36 @@ export function telemetryDevExtension(
|
|
|
200
214
|
});
|
|
201
215
|
}
|
|
202
216
|
|
|
203
|
-
register("before_agent_start", (event: { prompt?: JsonValue }) => {
|
|
217
|
+
register("before_agent_start", (event: { prompt?: JsonValue; images?: JsonValue[] }) => {
|
|
204
218
|
try {
|
|
205
|
-
|
|
219
|
+
const prompt = event.prompt?.constructor === String ? event.prompt : undefined;
|
|
220
|
+
pendingPrompt =
|
|
221
|
+
Array.isArray(event.images) && event.images.length > 0
|
|
222
|
+
? [{ type: "text", text: prompt ?? "" }, ...event.images]
|
|
223
|
+
: prompt;
|
|
206
224
|
} catch (error) {
|
|
207
225
|
reportError(onError, error);
|
|
208
226
|
}
|
|
209
227
|
});
|
|
210
228
|
|
|
229
|
+
// All context handlers and host conversion run before this hook.
|
|
230
|
+
on("before_provider_request", (event: { payload: unknown }, ctx) => {
|
|
231
|
+
request = event.payload;
|
|
232
|
+
systemPrompt = ctx.getSystemPrompt();
|
|
233
|
+
});
|
|
234
|
+
|
|
211
235
|
on("agent_start", (_event, ctx) => {
|
|
212
236
|
// Automatic retries, compaction, and queued continuations re-enter the
|
|
213
237
|
// agent loop before the run settles; keep the original prompt span open.
|
|
214
238
|
if (agentSpan) return;
|
|
239
|
+
sessionSpan ??= startSpan("session", {
|
|
240
|
+
type: "agent",
|
|
241
|
+
agentName,
|
|
242
|
+
attributes: spanAttributes(ctx),
|
|
243
|
+
});
|
|
215
244
|
agentSpan = startSpan("invoke_agent", {
|
|
216
245
|
type: "agent",
|
|
246
|
+
parent: sessionSpan,
|
|
217
247
|
agentName,
|
|
218
248
|
input: pendingPrompt,
|
|
219
249
|
attributes: spanAttributes(ctx),
|
|
@@ -234,7 +264,7 @@ export function telemetryDevExtension(
|
|
|
234
264
|
// failure and start another run before the prompt settles. Record the
|
|
235
265
|
// outcome and close the span at agent_settled.
|
|
236
266
|
lastRunResult = {
|
|
237
|
-
output:
|
|
267
|
+
output: lastAssistant?.content,
|
|
238
268
|
finishReason: stopReason,
|
|
239
269
|
error: stopReason === "error" ? failureError(stopReason, errorMessage) : undefined,
|
|
240
270
|
};
|
|
@@ -273,10 +303,14 @@ export function telemetryDevExtension(
|
|
|
273
303
|
usage: usageFields(message),
|
|
274
304
|
costUsd: numberField(asRecord(asRecord(message.usage)?.cost), "total"),
|
|
275
305
|
finishReason: stopReason,
|
|
276
|
-
|
|
306
|
+
systemInstructions: systemPrompt,
|
|
307
|
+
input: request,
|
|
308
|
+
output: message.content,
|
|
277
309
|
error: stopReason === "error" ? failureError(stopReason, errorMessage) : undefined,
|
|
278
310
|
attributes: spanAttributes(ctx),
|
|
279
311
|
});
|
|
312
|
+
request = undefined;
|
|
313
|
+
systemPrompt = undefined;
|
|
280
314
|
for (const block of Array.isArray(message.content) ? message.content : []) {
|
|
281
315
|
const record = asRecord(block);
|
|
282
316
|
if (record?.type === "toolCall" && record.id?.constructor === String) {
|
|
@@ -328,6 +362,8 @@ export function telemetryDevExtension(
|
|
|
328
362
|
});
|
|
329
363
|
|
|
330
364
|
on("session_start", (event: { reason: string; previousSessionFile?: string }, ctx) => {
|
|
365
|
+
// A new, resumed, forked, or switched session is a new trace.
|
|
366
|
+
endSessionSpan();
|
|
331
367
|
const model = asRecord(ctx.model);
|
|
332
368
|
emit("session_start", ctx, "info", "Session started", {
|
|
333
369
|
"gen_ai.request.model": stringField(model, "id"),
|
|
@@ -363,6 +399,7 @@ export function telemetryDevExtension(
|
|
|
363
399
|
endAgentSpan(lastRunResult ?? { finishReason: "incomplete" });
|
|
364
400
|
lastRunResult = undefined;
|
|
365
401
|
}
|
|
402
|
+
endSessionSpan();
|
|
366
403
|
emit("session_shutdown", ctx, "info", "Session shutdown", {
|
|
367
404
|
"pi.session.reason": event.reason,
|
|
368
405
|
});
|