@runtypelabs/cloudflare-agents 0.1.1
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/LICENSE +21 -0
- package/README.md +92 -0
- package/dist/chunk-BuRpWjxB.mjs +42 -0
- package/dist/chunk-DBVUQIKL.cjs +53 -0
- package/dist/durable-object.cjs +892 -0
- package/dist/durable-object.d.cts +114 -0
- package/dist/durable-object.d.ts +114 -0
- package/dist/durable-object.mjs +891 -0
- package/dist/index.cjs +344 -0
- package/dist/index.d.cts +13 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.mjs +339 -0
- package/dist/observer-DnEMHl8z.d.cts +121 -0
- package/dist/observer-DnEMHl8z.d.ts +121 -0
- package/package.json +56 -0
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
import { n as operationSpanId, t as createRunIdentity } from "./chunk-BuRpWjxB.mjs";
|
|
2
|
+
//#region src/content.ts
|
|
3
|
+
const MAX_CONTENT_BYTES = 32768;
|
|
4
|
+
function diagnose$1(policy, code) {
|
|
5
|
+
try {
|
|
6
|
+
policy.onDiagnostic?.(code);
|
|
7
|
+
} catch {
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
function isEnabled(policy, kind) {
|
|
12
|
+
if (kind === "instructions") return policy.instructions ?? policy.messages ?? false;
|
|
13
|
+
if (kind === "error") return policy.errors ?? false;
|
|
14
|
+
return policy[kind] ?? false;
|
|
15
|
+
}
|
|
16
|
+
/** Applies privacy policy before a content value can enter telemetry storage. */
|
|
17
|
+
function captureContent(policy, kind, value) {
|
|
18
|
+
if (!isEnabled(policy, kind) || value === void 0) return void 0;
|
|
19
|
+
const limit = policy.maxBytes ?? MAX_CONTENT_BYTES;
|
|
20
|
+
if (!Number.isSafeInteger(limit) || limit < 1 || limit > MAX_CONTENT_BYTES) {
|
|
21
|
+
diagnose$1(policy, "content_invalid");
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
let detached;
|
|
25
|
+
try {
|
|
26
|
+
detached = JSON.parse(JSON.stringify(value));
|
|
27
|
+
} catch {
|
|
28
|
+
diagnose$1(policy, "content_invalid");
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
let redacted;
|
|
32
|
+
try {
|
|
33
|
+
redacted = policy.redact ? policy.redact(kind, detached) : detached;
|
|
34
|
+
} catch {
|
|
35
|
+
diagnose$1(policy, "content_redaction_failed");
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
if (redacted === void 0) return void 0;
|
|
39
|
+
try {
|
|
40
|
+
const serialized = JSON.stringify(redacted);
|
|
41
|
+
if (serialized === void 0) {
|
|
42
|
+
diagnose$1(policy, "content_invalid");
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
if (new TextEncoder().encode(serialized).byteLength > limit) {
|
|
46
|
+
diagnose$1(policy, "content_too_large");
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
return JSON.parse(serialized);
|
|
50
|
+
} catch {
|
|
51
|
+
diagnose$1(policy, "content_invalid");
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
//#endregion
|
|
56
|
+
//#region src/observer.ts
|
|
57
|
+
/** Adds bounded observation callbacks without reading or replacing the response stream. */
|
|
58
|
+
async function observeStreamTextOptions(options, observation) {
|
|
59
|
+
const destination = observation.observer;
|
|
60
|
+
let deliveryFailed = false;
|
|
61
|
+
observation = {
|
|
62
|
+
...observation,
|
|
63
|
+
turn: { ...observation.turn },
|
|
64
|
+
observer: {
|
|
65
|
+
onDiagnostic: destination.onDiagnostic,
|
|
66
|
+
async emit(event) {
|
|
67
|
+
const terminal = event.kind === "finished" || event.kind === "aborted" || event.kind === "errored";
|
|
68
|
+
const outgoing = deliveryFailed && terminal ? {
|
|
69
|
+
kind: "incomplete",
|
|
70
|
+
turn: event.turn,
|
|
71
|
+
reason: "observation_delivery_failed"
|
|
72
|
+
} : event;
|
|
73
|
+
try {
|
|
74
|
+
await destination.emit(outgoing);
|
|
75
|
+
} catch (error) {
|
|
76
|
+
deliveryFailed = true;
|
|
77
|
+
throw error;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
await emit(observation.observer, {
|
|
83
|
+
kind: "accepted",
|
|
84
|
+
turn: observation.turn
|
|
85
|
+
});
|
|
86
|
+
if (observation.turn.continuation) await emit(observation.observer, {
|
|
87
|
+
kind: "unsupported",
|
|
88
|
+
turn: observation.turn,
|
|
89
|
+
reason: "continuation"
|
|
90
|
+
});
|
|
91
|
+
const pendingToolCalls = /* @__PURE__ */ new Set();
|
|
92
|
+
const completedServerToolCalls = /* @__PURE__ */ new Set();
|
|
93
|
+
let lastToolError;
|
|
94
|
+
return {
|
|
95
|
+
...options,
|
|
96
|
+
experimental_onStart: options.experimental_onStart,
|
|
97
|
+
experimental_onStepStart: wrap(options.experimental_onStepStart, async (event) => {
|
|
98
|
+
await emitModelInput(observation, event, event.stepNumber);
|
|
99
|
+
}),
|
|
100
|
+
experimental_onToolCallStart: wrap(options.experimental_onToolCallStart, async (event) => {
|
|
101
|
+
await emit(observation.observer, {
|
|
102
|
+
kind: "tool_started",
|
|
103
|
+
turn: observation.turn,
|
|
104
|
+
stepNumber: event.stepNumber,
|
|
105
|
+
...model(event.model) ? { model: model(event.model) } : {},
|
|
106
|
+
toolCall: toolCall(observation, event.toolCall)
|
|
107
|
+
});
|
|
108
|
+
}),
|
|
109
|
+
experimental_onToolCallFinish: wrap(options.experimental_onToolCallFinish, async (event) => {
|
|
110
|
+
const id = toolCallId(event.toolCall);
|
|
111
|
+
if (id) completedServerToolCalls.add(id);
|
|
112
|
+
const output = event.success ? captureContent(observation.content, "tools", event.output) : void 0;
|
|
113
|
+
const error = event.success ? void 0 : captureError(observation.content, event.error);
|
|
114
|
+
if (!event.success) lastToolError = error;
|
|
115
|
+
const outcome = event.success ? output === void 0 ? {} : { output } : error === void 0 ? {} : { error };
|
|
116
|
+
await emit(observation.observer, {
|
|
117
|
+
kind: "tool_finished",
|
|
118
|
+
turn: observation.turn,
|
|
119
|
+
stepNumber: event.stepNumber,
|
|
120
|
+
...model(event.model) ? { model: model(event.model) } : {},
|
|
121
|
+
toolCall: toolCall(observation, event.toolCall),
|
|
122
|
+
durationMs: boundedDuration(event.durationMs),
|
|
123
|
+
success: event.success,
|
|
124
|
+
...outcome
|
|
125
|
+
});
|
|
126
|
+
}),
|
|
127
|
+
onStepFinish: wrap(options.onStepFinish, async (event) => {
|
|
128
|
+
updatePendingToolCalls(pendingToolCalls, event);
|
|
129
|
+
for (const id of completedServerToolCalls) pendingToolCalls.delete(id);
|
|
130
|
+
await emit(observation.observer, modelStep(observation, event));
|
|
131
|
+
}),
|
|
132
|
+
onFinish: wrap(options.onFinish, async (event) => {
|
|
133
|
+
if (observation.turn.continuation) return;
|
|
134
|
+
for (const id of completedServerToolCalls) pendingToolCalls.delete(id);
|
|
135
|
+
const terminalToolError = event.finishReason === "tool-calls" && event.content.some((part) => part.type === "tool-error");
|
|
136
|
+
if (event.finishReason === "error" || terminalToolError) {
|
|
137
|
+
await emit(observation.observer, {
|
|
138
|
+
kind: "errored",
|
|
139
|
+
turn: observation.turn,
|
|
140
|
+
...lastToolError === void 0 ? {} : { error: lastToolError }
|
|
141
|
+
});
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
if (pendingToolCalls.size > 0) {
|
|
145
|
+
await emit(observation.observer, {
|
|
146
|
+
kind: "unsupported",
|
|
147
|
+
turn: observation.turn,
|
|
148
|
+
reason: "unresolved_tool_calls"
|
|
149
|
+
});
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
await emit(observation.observer, {
|
|
153
|
+
kind: "finished",
|
|
154
|
+
turn: observation.turn
|
|
155
|
+
});
|
|
156
|
+
}),
|
|
157
|
+
onAbort: wrap(options.onAbort, async () => {
|
|
158
|
+
await emit(observation.observer, {
|
|
159
|
+
kind: "aborted",
|
|
160
|
+
turn: observation.turn
|
|
161
|
+
});
|
|
162
|
+
}),
|
|
163
|
+
onError: wrap(options.onError, async (event) => {
|
|
164
|
+
const error = captureError(observation.content, event.error);
|
|
165
|
+
await emit(observation.observer, {
|
|
166
|
+
kind: "errored",
|
|
167
|
+
turn: observation.turn,
|
|
168
|
+
...error === void 0 ? {} : { error }
|
|
169
|
+
});
|
|
170
|
+
})
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
function wrap(existing, observe) {
|
|
174
|
+
return async (event) => {
|
|
175
|
+
await existing?.(event);
|
|
176
|
+
try {
|
|
177
|
+
await observe(event);
|
|
178
|
+
} catch {
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
async function emit(observer, event) {
|
|
184
|
+
try {
|
|
185
|
+
await observer.emit(event);
|
|
186
|
+
} catch {
|
|
187
|
+
diagnose(observer, "observer_emit_failed");
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
function diagnose(observer, code) {
|
|
191
|
+
try {
|
|
192
|
+
observer.onDiagnostic?.(code);
|
|
193
|
+
} catch {
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
function emitModelInput(observation, event, stepNumber) {
|
|
198
|
+
const system = captureContent(observation.content, "instructions", event.system);
|
|
199
|
+
const messages = captureMessages(observation.content, event.messages);
|
|
200
|
+
return emit(observation.observer, {
|
|
201
|
+
kind: "model_input",
|
|
202
|
+
turn: observation.turn,
|
|
203
|
+
stepNumber,
|
|
204
|
+
model: model(event.model) ?? {
|
|
205
|
+
provider: "",
|
|
206
|
+
modelId: ""
|
|
207
|
+
},
|
|
208
|
+
...system === void 0 ? {} : { system },
|
|
209
|
+
...messages === void 0 ? {} : { messages }
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
function modelStep(observation, event) {
|
|
213
|
+
const output = captureContent(observation.content, "messages", event.text);
|
|
214
|
+
const toolCalls = toolsEnabled(observation.content) ? captureContent(observation.content, "tools", event.toolCalls) : void 0;
|
|
215
|
+
const toolResults = toolsEnabled(observation.content) ? captureContent(observation.content, "tools", event.toolResults) : void 0;
|
|
216
|
+
const finishReason = boundedString(event.finishReason);
|
|
217
|
+
return {
|
|
218
|
+
kind: "model_step",
|
|
219
|
+
turn: observation.turn,
|
|
220
|
+
stepNumber: event.stepNumber,
|
|
221
|
+
model: model(event.model) ?? {
|
|
222
|
+
provider: "",
|
|
223
|
+
modelId: ""
|
|
224
|
+
},
|
|
225
|
+
...output === void 0 ? {} : { output },
|
|
226
|
+
...toolCalls === void 0 ? {} : { toolCalls },
|
|
227
|
+
...toolResults === void 0 ? {} : { toolResults },
|
|
228
|
+
...finishReason === void 0 ? {} : { finishReason },
|
|
229
|
+
usage: usage(event.usage)
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
function updatePendingToolCalls(pendingToolCalls, event) {
|
|
233
|
+
for (const call of event.toolCalls) {
|
|
234
|
+
const id = toolCallId(call);
|
|
235
|
+
if (id) pendingToolCalls.add(id);
|
|
236
|
+
}
|
|
237
|
+
for (const result of event.toolResults) {
|
|
238
|
+
const id = toolCallId(result);
|
|
239
|
+
if (id) pendingToolCalls.delete(id);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
function toolCallId(value) {
|
|
243
|
+
if (!value || typeof value !== "object") return void 0;
|
|
244
|
+
return boundedString(value.toolCallId);
|
|
245
|
+
}
|
|
246
|
+
function captureMessages(policy, messages) {
|
|
247
|
+
if (!Array.isArray(messages)) return captureContent(policy, "messages", messages);
|
|
248
|
+
const captured = messages.flatMap((message) => {
|
|
249
|
+
const value = captureMessage(policy, message);
|
|
250
|
+
return value === void 0 ? [] : [value];
|
|
251
|
+
});
|
|
252
|
+
return captured.length === 0 ? void 0 : captured;
|
|
253
|
+
}
|
|
254
|
+
function captureMessage(policy, message) {
|
|
255
|
+
const kind = messageKind(message);
|
|
256
|
+
if (kind !== "messages") return captureContent(policy, kind, message);
|
|
257
|
+
if (!message || typeof message !== "object") return captureContent(policy, "messages", message);
|
|
258
|
+
const content = message.content;
|
|
259
|
+
if (!Array.isArray(content)) return captureContent(policy, "messages", message);
|
|
260
|
+
const capturedContent = content.flatMap((part) => {
|
|
261
|
+
const value = captureContent(policy, partKind(part), part);
|
|
262
|
+
return value === void 0 ? [] : [value];
|
|
263
|
+
});
|
|
264
|
+
if (capturedContent.length === 0) return void 0;
|
|
265
|
+
return captureContent(policy, "messages", {
|
|
266
|
+
...message,
|
|
267
|
+
content: capturedContent
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
function messageKind(message) {
|
|
271
|
+
if (!message || typeof message !== "object") return "messages";
|
|
272
|
+
const role = message.role;
|
|
273
|
+
if (role === "system" || role === "developer") return "instructions";
|
|
274
|
+
return role === "tool" ? "tools" : "messages";
|
|
275
|
+
}
|
|
276
|
+
function partKind(part) {
|
|
277
|
+
if (!part || typeof part !== "object") return "messages";
|
|
278
|
+
const type = part.type;
|
|
279
|
+
return typeof type === "string" && type.startsWith("tool-") ? "tools" : "messages";
|
|
280
|
+
}
|
|
281
|
+
function toolsEnabled(policy) {
|
|
282
|
+
return policy.tools === true;
|
|
283
|
+
}
|
|
284
|
+
function toolCall(observation, value) {
|
|
285
|
+
if (!value || typeof value !== "object") {
|
|
286
|
+
diagnose(observation.observer, "invalid_sdk_event");
|
|
287
|
+
return {};
|
|
288
|
+
}
|
|
289
|
+
const call = value;
|
|
290
|
+
const toolCallId = boundedString(call.toolCallId);
|
|
291
|
+
const toolName = boundedString(call.toolName);
|
|
292
|
+
const input = captureContent(observation.content, "tools", call.input);
|
|
293
|
+
return {
|
|
294
|
+
...toolCallId === void 0 ? {} : { toolCallId },
|
|
295
|
+
...toolName === void 0 ? {} : { toolName },
|
|
296
|
+
...input === void 0 ? {} : { input }
|
|
297
|
+
};
|
|
298
|
+
}
|
|
299
|
+
function model(value) {
|
|
300
|
+
if (!value || typeof value !== "object") return void 0;
|
|
301
|
+
const candidate = value;
|
|
302
|
+
const provider = boundedString(candidate.provider);
|
|
303
|
+
const modelId = boundedString(candidate.modelId);
|
|
304
|
+
return provider && modelId ? {
|
|
305
|
+
provider,
|
|
306
|
+
modelId
|
|
307
|
+
} : void 0;
|
|
308
|
+
}
|
|
309
|
+
function captureError(policy, error) {
|
|
310
|
+
if (error instanceof Error) return captureContent(policy, "error", {
|
|
311
|
+
name: error.name,
|
|
312
|
+
message: error.message
|
|
313
|
+
});
|
|
314
|
+
return captureContent(policy, "error", error);
|
|
315
|
+
}
|
|
316
|
+
function boundedString(value) {
|
|
317
|
+
return typeof value === "string" && value.length > 0 && value.length <= 512 ? value : void 0;
|
|
318
|
+
}
|
|
319
|
+
function boundedDuration(value) {
|
|
320
|
+
return typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : 0;
|
|
321
|
+
}
|
|
322
|
+
function usage(value) {
|
|
323
|
+
if (!value || typeof value !== "object") return {};
|
|
324
|
+
return Object.fromEntries(Object.entries(value).filter(([, amount]) => typeof amount === "number" && Number.isFinite(amount) && amount >= 0));
|
|
325
|
+
}
|
|
326
|
+
//#endregion
|
|
327
|
+
//#region src/durable-observer.ts
|
|
328
|
+
/** Bridges a companion Durable Object receipt to the observer's delivery diagnostic. */
|
|
329
|
+
function createDurableObserver(sink, onDiagnostic) {
|
|
330
|
+
return {
|
|
331
|
+
onDiagnostic,
|
|
332
|
+
async emit(observation) {
|
|
333
|
+
if (!(await sink.observe(observation)).accepted) throw new Error("Durable adapter observation was not accepted");
|
|
334
|
+
}
|
|
335
|
+
};
|
|
336
|
+
}
|
|
337
|
+
//#endregion
|
|
338
|
+
export { captureContent, createDurableObserver, createRunIdentity, observeStreamTextOptions, operationSpanId };
|
|
339
|
+
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { streamText } from "ai";
|
|
2
|
+
//#region src/identity.d.ts
|
|
3
|
+
interface SubmissionIdentity {
|
|
4
|
+
agentId: string;
|
|
5
|
+
submissionId: string;
|
|
6
|
+
conversationId: string;
|
|
7
|
+
}
|
|
8
|
+
interface RunIdentity extends SubmissionIdentity {
|
|
9
|
+
traceId: string;
|
|
10
|
+
rootSpanId: string;
|
|
11
|
+
}
|
|
12
|
+
/** Stable producer identity, independent of native traces and export partitioning. */
|
|
13
|
+
declare function createRunIdentity(input: SubmissionIdentity): Promise<RunIdentity>;
|
|
14
|
+
/** The same operation is encoded with the same span ID on every delivery attempt. */
|
|
15
|
+
declare function operationSpanId(traceId: string, operationId: string): Promise<string>;
|
|
16
|
+
//#endregion
|
|
17
|
+
//#region src/content.d.ts
|
|
18
|
+
type ContentKind = 'messages' | 'instructions' | 'tools' | 'error';
|
|
19
|
+
type CapturedJson = null | boolean | number | string | CapturedJson[] | {
|
|
20
|
+
[key: string]: CapturedJson;
|
|
21
|
+
};
|
|
22
|
+
type ContentDiagnostic = 'content_invalid' | 'content_redaction_failed' | 'content_too_large';
|
|
23
|
+
interface ContentPolicy {
|
|
24
|
+
messages?: boolean;
|
|
25
|
+
/** Instructions follow message capture unless explicitly disabled. */
|
|
26
|
+
instructions?: boolean;
|
|
27
|
+
tools?: boolean;
|
|
28
|
+
errors?: boolean;
|
|
29
|
+
/** Maximum UTF-8 bytes per captured content field, capped at 32 KiB. */
|
|
30
|
+
maxBytes?: number;
|
|
31
|
+
/** Receives a detached copy. Return undefined to omit the field. */
|
|
32
|
+
redact?: (kind: ContentKind, value: CapturedJson) => CapturedJson | undefined;
|
|
33
|
+
onDiagnostic?: (code: ContentDiagnostic) => void;
|
|
34
|
+
}
|
|
35
|
+
/** Applies privacy policy before a content value can enter telemetry storage. */
|
|
36
|
+
declare function captureContent(policy: ContentPolicy, kind: ContentKind, value: unknown): CapturedJson | undefined;
|
|
37
|
+
//#endregion
|
|
38
|
+
//#region src/observer.d.ts
|
|
39
|
+
interface AdapterTurn {
|
|
40
|
+
submissionId: string;
|
|
41
|
+
conversationId: string;
|
|
42
|
+
exchangeId: string;
|
|
43
|
+
continuation: boolean;
|
|
44
|
+
}
|
|
45
|
+
type ObserverDiagnostic = 'observer_emit_failed' | 'invalid_sdk_event';
|
|
46
|
+
interface AdapterObserver {
|
|
47
|
+
emit(observation: AdapterObservation): void | Promise<void>;
|
|
48
|
+
onDiagnostic?: (code: ObserverDiagnostic) => void;
|
|
49
|
+
}
|
|
50
|
+
interface AdapterObservationBase {
|
|
51
|
+
turn: AdapterTurn;
|
|
52
|
+
}
|
|
53
|
+
interface AdapterAcceptedObservation extends AdapterObservationBase {
|
|
54
|
+
kind: 'accepted';
|
|
55
|
+
}
|
|
56
|
+
interface AdapterModelInputObservation extends AdapterObservationBase {
|
|
57
|
+
kind: 'model_input';
|
|
58
|
+
stepNumber: number | undefined;
|
|
59
|
+
model: AdapterModel;
|
|
60
|
+
system?: CapturedJson;
|
|
61
|
+
messages?: CapturedJson;
|
|
62
|
+
}
|
|
63
|
+
interface AdapterModelStepObservation extends AdapterObservationBase {
|
|
64
|
+
kind: 'model_step';
|
|
65
|
+
stepNumber: number;
|
|
66
|
+
model: AdapterModel;
|
|
67
|
+
output?: CapturedJson;
|
|
68
|
+
toolCalls?: CapturedJson;
|
|
69
|
+
toolResults?: CapturedJson;
|
|
70
|
+
finishReason?: string;
|
|
71
|
+
usage: Record<string, number>;
|
|
72
|
+
}
|
|
73
|
+
interface AdapterToolStartedObservation extends AdapterObservationBase {
|
|
74
|
+
kind: 'tool_started';
|
|
75
|
+
stepNumber: number | undefined;
|
|
76
|
+
model?: AdapterModel;
|
|
77
|
+
toolCall: AdapterToolCall;
|
|
78
|
+
}
|
|
79
|
+
interface AdapterToolFinishedObservation extends AdapterObservationBase {
|
|
80
|
+
kind: 'tool_finished';
|
|
81
|
+
stepNumber: number | undefined;
|
|
82
|
+
model?: AdapterModel;
|
|
83
|
+
toolCall: AdapterToolCall;
|
|
84
|
+
durationMs: number;
|
|
85
|
+
success: boolean;
|
|
86
|
+
output?: CapturedJson;
|
|
87
|
+
error?: CapturedJson;
|
|
88
|
+
}
|
|
89
|
+
interface AdapterTerminalObservation extends AdapterObservationBase {
|
|
90
|
+
kind: 'finished' | 'aborted' | 'errored';
|
|
91
|
+
error?: CapturedJson;
|
|
92
|
+
}
|
|
93
|
+
interface AdapterUnsupportedObservation extends AdapterObservationBase {
|
|
94
|
+
kind: 'unsupported';
|
|
95
|
+
reason: 'continuation' | 'unresolved_tool_calls';
|
|
96
|
+
}
|
|
97
|
+
interface AdapterIncompleteObservation extends AdapterObservationBase {
|
|
98
|
+
kind: 'incomplete';
|
|
99
|
+
reason: 'observation_delivery_failed';
|
|
100
|
+
}
|
|
101
|
+
type AdapterObservation = AdapterAcceptedObservation | AdapterModelInputObservation | AdapterModelStepObservation | AdapterToolStartedObservation | AdapterToolFinishedObservation | AdapterTerminalObservation | AdapterUnsupportedObservation | AdapterIncompleteObservation;
|
|
102
|
+
interface AdapterModel {
|
|
103
|
+
provider: string;
|
|
104
|
+
modelId: string;
|
|
105
|
+
}
|
|
106
|
+
interface AdapterToolCall {
|
|
107
|
+
toolCallId?: string;
|
|
108
|
+
toolName?: string;
|
|
109
|
+
input?: CapturedJson;
|
|
110
|
+
}
|
|
111
|
+
type StreamTextOptions = Parameters<typeof streamText>[0];
|
|
112
|
+
interface ObserveStreamTextOptions {
|
|
113
|
+
content: ContentPolicy;
|
|
114
|
+
observer: AdapterObserver;
|
|
115
|
+
turn: AdapterTurn;
|
|
116
|
+
}
|
|
117
|
+
/** Adds bounded observation callbacks without reading or replacing the response stream. */
|
|
118
|
+
declare function observeStreamTextOptions<Options extends StreamTextOptions>(options: Options, observation: ObserveStreamTextOptions): Promise<Options>;
|
|
119
|
+
//#endregion
|
|
120
|
+
export { operationSpanId as _, AdapterToolStartedObservation as a, observeStreamTextOptions as c, ContentKind as d, ContentPolicy as f, createRunIdentity as g, SubmissionIdentity as h, AdapterObserver as i, CapturedJson as l, RunIdentity as m, AdapterModelStepObservation as n, AdapterTurn as o, captureContent as p, AdapterObservation as r, ObserveStreamTextOptions as s, AdapterModelInputObservation as t, ContentDiagnostic as u };
|
|
121
|
+
export {}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { streamText } from "ai";
|
|
2
|
+
//#region src/identity.d.ts
|
|
3
|
+
interface SubmissionIdentity {
|
|
4
|
+
agentId: string;
|
|
5
|
+
submissionId: string;
|
|
6
|
+
conversationId: string;
|
|
7
|
+
}
|
|
8
|
+
interface RunIdentity extends SubmissionIdentity {
|
|
9
|
+
traceId: string;
|
|
10
|
+
rootSpanId: string;
|
|
11
|
+
}
|
|
12
|
+
/** Stable producer identity, independent of native traces and export partitioning. */
|
|
13
|
+
declare function createRunIdentity(input: SubmissionIdentity): Promise<RunIdentity>;
|
|
14
|
+
/** The same operation is encoded with the same span ID on every delivery attempt. */
|
|
15
|
+
declare function operationSpanId(traceId: string, operationId: string): Promise<string>;
|
|
16
|
+
//#endregion
|
|
17
|
+
//#region src/content.d.ts
|
|
18
|
+
type ContentKind = 'messages' | 'instructions' | 'tools' | 'error';
|
|
19
|
+
type CapturedJson = null | boolean | number | string | CapturedJson[] | {
|
|
20
|
+
[key: string]: CapturedJson;
|
|
21
|
+
};
|
|
22
|
+
type ContentDiagnostic = 'content_invalid' | 'content_redaction_failed' | 'content_too_large';
|
|
23
|
+
interface ContentPolicy {
|
|
24
|
+
messages?: boolean;
|
|
25
|
+
/** Instructions follow message capture unless explicitly disabled. */
|
|
26
|
+
instructions?: boolean;
|
|
27
|
+
tools?: boolean;
|
|
28
|
+
errors?: boolean;
|
|
29
|
+
/** Maximum UTF-8 bytes per captured content field, capped at 32 KiB. */
|
|
30
|
+
maxBytes?: number;
|
|
31
|
+
/** Receives a detached copy. Return undefined to omit the field. */
|
|
32
|
+
redact?: (kind: ContentKind, value: CapturedJson) => CapturedJson | undefined;
|
|
33
|
+
onDiagnostic?: (code: ContentDiagnostic) => void;
|
|
34
|
+
}
|
|
35
|
+
/** Applies privacy policy before a content value can enter telemetry storage. */
|
|
36
|
+
declare function captureContent(policy: ContentPolicy, kind: ContentKind, value: unknown): CapturedJson | undefined;
|
|
37
|
+
//#endregion
|
|
38
|
+
//#region src/observer.d.ts
|
|
39
|
+
interface AdapterTurn {
|
|
40
|
+
submissionId: string;
|
|
41
|
+
conversationId: string;
|
|
42
|
+
exchangeId: string;
|
|
43
|
+
continuation: boolean;
|
|
44
|
+
}
|
|
45
|
+
type ObserverDiagnostic = 'observer_emit_failed' | 'invalid_sdk_event';
|
|
46
|
+
interface AdapterObserver {
|
|
47
|
+
emit(observation: AdapterObservation): void | Promise<void>;
|
|
48
|
+
onDiagnostic?: (code: ObserverDiagnostic) => void;
|
|
49
|
+
}
|
|
50
|
+
interface AdapterObservationBase {
|
|
51
|
+
turn: AdapterTurn;
|
|
52
|
+
}
|
|
53
|
+
interface AdapterAcceptedObservation extends AdapterObservationBase {
|
|
54
|
+
kind: 'accepted';
|
|
55
|
+
}
|
|
56
|
+
interface AdapterModelInputObservation extends AdapterObservationBase {
|
|
57
|
+
kind: 'model_input';
|
|
58
|
+
stepNumber: number | undefined;
|
|
59
|
+
model: AdapterModel;
|
|
60
|
+
system?: CapturedJson;
|
|
61
|
+
messages?: CapturedJson;
|
|
62
|
+
}
|
|
63
|
+
interface AdapterModelStepObservation extends AdapterObservationBase {
|
|
64
|
+
kind: 'model_step';
|
|
65
|
+
stepNumber: number;
|
|
66
|
+
model: AdapterModel;
|
|
67
|
+
output?: CapturedJson;
|
|
68
|
+
toolCalls?: CapturedJson;
|
|
69
|
+
toolResults?: CapturedJson;
|
|
70
|
+
finishReason?: string;
|
|
71
|
+
usage: Record<string, number>;
|
|
72
|
+
}
|
|
73
|
+
interface AdapterToolStartedObservation extends AdapterObservationBase {
|
|
74
|
+
kind: 'tool_started';
|
|
75
|
+
stepNumber: number | undefined;
|
|
76
|
+
model?: AdapterModel;
|
|
77
|
+
toolCall: AdapterToolCall;
|
|
78
|
+
}
|
|
79
|
+
interface AdapterToolFinishedObservation extends AdapterObservationBase {
|
|
80
|
+
kind: 'tool_finished';
|
|
81
|
+
stepNumber: number | undefined;
|
|
82
|
+
model?: AdapterModel;
|
|
83
|
+
toolCall: AdapterToolCall;
|
|
84
|
+
durationMs: number;
|
|
85
|
+
success: boolean;
|
|
86
|
+
output?: CapturedJson;
|
|
87
|
+
error?: CapturedJson;
|
|
88
|
+
}
|
|
89
|
+
interface AdapterTerminalObservation extends AdapterObservationBase {
|
|
90
|
+
kind: 'finished' | 'aborted' | 'errored';
|
|
91
|
+
error?: CapturedJson;
|
|
92
|
+
}
|
|
93
|
+
interface AdapterUnsupportedObservation extends AdapterObservationBase {
|
|
94
|
+
kind: 'unsupported';
|
|
95
|
+
reason: 'continuation' | 'unresolved_tool_calls';
|
|
96
|
+
}
|
|
97
|
+
interface AdapterIncompleteObservation extends AdapterObservationBase {
|
|
98
|
+
kind: 'incomplete';
|
|
99
|
+
reason: 'observation_delivery_failed';
|
|
100
|
+
}
|
|
101
|
+
type AdapterObservation = AdapterAcceptedObservation | AdapterModelInputObservation | AdapterModelStepObservation | AdapterToolStartedObservation | AdapterToolFinishedObservation | AdapterTerminalObservation | AdapterUnsupportedObservation | AdapterIncompleteObservation;
|
|
102
|
+
interface AdapterModel {
|
|
103
|
+
provider: string;
|
|
104
|
+
modelId: string;
|
|
105
|
+
}
|
|
106
|
+
interface AdapterToolCall {
|
|
107
|
+
toolCallId?: string;
|
|
108
|
+
toolName?: string;
|
|
109
|
+
input?: CapturedJson;
|
|
110
|
+
}
|
|
111
|
+
type StreamTextOptions = Parameters<typeof streamText>[0];
|
|
112
|
+
interface ObserveStreamTextOptions {
|
|
113
|
+
content: ContentPolicy;
|
|
114
|
+
observer: AdapterObserver;
|
|
115
|
+
turn: AdapterTurn;
|
|
116
|
+
}
|
|
117
|
+
/** Adds bounded observation callbacks without reading or replacing the response stream. */
|
|
118
|
+
declare function observeStreamTextOptions<Options extends StreamTextOptions>(options: Options, observation: ObserveStreamTextOptions): Promise<Options>;
|
|
119
|
+
//#endregion
|
|
120
|
+
export { operationSpanId as _, AdapterToolStartedObservation as a, observeStreamTextOptions as c, ContentKind as d, ContentPolicy as f, createRunIdentity as g, SubmissionIdentity as h, AdapterObserver as i, CapturedJson as l, RunIdentity as m, AdapterModelStepObservation as n, AdapterTurn as o, captureContent as p, AdapterObservation as r, ObserveStreamTextOptions as s, AdapterModelInputObservation as t, ContentDiagnostic as u };
|
|
121
|
+
export {}
|
package/package.json
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@runtypelabs/cloudflare-agents",
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"description": "Durable application telemetry for Cloudflare Agents SDK runs in Runtype.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.cjs",
|
|
7
|
+
"module": "./dist/index.mjs",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"import": {
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"default": "./dist/index.mjs"
|
|
14
|
+
},
|
|
15
|
+
"require": {
|
|
16
|
+
"types": "./dist/index.d.cts",
|
|
17
|
+
"default": "./dist/index.cjs"
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"./durable-object": {
|
|
21
|
+
"types": "./dist/durable-object.d.ts",
|
|
22
|
+
"import": "./dist/durable-object.mjs"
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"files": [
|
|
26
|
+
"dist",
|
|
27
|
+
"README.md",
|
|
28
|
+
"LICENSE"
|
|
29
|
+
],
|
|
30
|
+
"devDependencies": {
|
|
31
|
+
"@cloudflare/workers-types": "^5.20260804.1",
|
|
32
|
+
"ai": "6.0.277",
|
|
33
|
+
"tsdown": "^0.23.0",
|
|
34
|
+
"typescript": "^6.0.3",
|
|
35
|
+
"vitest": "^5.0.2"
|
|
36
|
+
},
|
|
37
|
+
"peerDependencies": {
|
|
38
|
+
"ai": "6.0.277"
|
|
39
|
+
},
|
|
40
|
+
"publishConfig": {
|
|
41
|
+
"access": "public"
|
|
42
|
+
},
|
|
43
|
+
"sideEffects": false,
|
|
44
|
+
"license": "MIT",
|
|
45
|
+
"repository": {
|
|
46
|
+
"type": "git",
|
|
47
|
+
"url": "https://github.com/runtypelabs/core",
|
|
48
|
+
"directory": "packages/cloudflare-agents"
|
|
49
|
+
},
|
|
50
|
+
"scripts": {
|
|
51
|
+
"build": "tsdown",
|
|
52
|
+
"typecheck": "tsgo --noEmit && tsgo --noEmit -p tsconfig.tests.json",
|
|
53
|
+
"test": "vitest run",
|
|
54
|
+
"lint": "eslint . --max-warnings 0"
|
|
55
|
+
}
|
|
56
|
+
}
|