@mongodb-js/agent-engine-sdk 0.11.3
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.md +201 -0
- package/README.md +20 -0
- package/dist/api/events.d.ts +39 -0
- package/dist/api/events.d.ts.map +1 -0
- package/dist/api/events.js +9 -0
- package/dist/api/v1/memory.d.ts +257 -0
- package/dist/api/v1/memory.d.ts.map +1 -0
- package/dist/api/v1/memory.js +219 -0
- package/dist/app.d.ts +27 -0
- package/dist/app.d.ts.map +1 -0
- package/dist/app.js +19 -0
- package/dist/clients/events.d.ts +11 -0
- package/dist/clients/events.d.ts.map +1 -0
- package/dist/clients/events.js +67 -0
- package/dist/clients/memory.d.ts +358 -0
- package/dist/clients/memory.d.ts.map +1 -0
- package/dist/clients/memory.js +658 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/interfaces.d.ts +111 -0
- package/dist/interfaces.d.ts.map +1 -0
- package/dist/interfaces.js +22 -0
- package/dist/models.d.ts +593 -0
- package/dist/models.d.ts.map +1 -0
- package/dist/models.js +588 -0
- package/package.json +50 -0
package/dist/models.js
ADDED
|
@@ -0,0 +1,588 @@
|
|
|
1
|
+
/** Framework-neutral types and models for the Atlas Agent Engine SDK. */
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
/** Runtime schema for the recursive `JsonValue` type. */
|
|
4
|
+
export const JsonValueSchema = z.lazy(() => z.union([
|
|
5
|
+
z.string(),
|
|
6
|
+
z.number(),
|
|
7
|
+
z.boolean(),
|
|
8
|
+
z.null(),
|
|
9
|
+
z.array(JsonValueSchema),
|
|
10
|
+
z.record(z.string(), JsonValueSchema),
|
|
11
|
+
]));
|
|
12
|
+
/** Text content block. */
|
|
13
|
+
export const TextBlockSchema = z.object({
|
|
14
|
+
type: z.literal("text").default("text"),
|
|
15
|
+
text: z.string(),
|
|
16
|
+
});
|
|
17
|
+
/** Image content block. */
|
|
18
|
+
export const ImageBlockSchema = z.object({
|
|
19
|
+
type: z.literal("image").default("image"),
|
|
20
|
+
url: z.string(),
|
|
21
|
+
mime_type: z.string().optional(),
|
|
22
|
+
});
|
|
23
|
+
/** Document/file content block. */
|
|
24
|
+
export const DocumentBlockSchema = z.object({
|
|
25
|
+
type: z.literal("document").default("document"),
|
|
26
|
+
url: z.string(),
|
|
27
|
+
mime_type: z.string().optional(),
|
|
28
|
+
filename: z.string().optional(),
|
|
29
|
+
});
|
|
30
|
+
/**
|
|
31
|
+
* Discriminated on `type` so a document block is never misparsed as an image
|
|
32
|
+
* (a plain union would match `{ url }` against `ImageBlockSchema` first and
|
|
33
|
+
* silently drop `filename`). Inputs must carry an explicit `type`.
|
|
34
|
+
*/
|
|
35
|
+
export const AnyContentBlockSchema = z.discriminatedUnion("type", [
|
|
36
|
+
TextBlockSchema,
|
|
37
|
+
ImageBlockSchema,
|
|
38
|
+
DocumentBlockSchema,
|
|
39
|
+
]);
|
|
40
|
+
/** Framework-neutral tool definition. */
|
|
41
|
+
export const ToolDefinitionSchema = z.object({
|
|
42
|
+
name: z.string(),
|
|
43
|
+
description: z.string(),
|
|
44
|
+
args_schema: z.record(z.string(), z.unknown()),
|
|
45
|
+
callable: z.custom((v) => typeof v === "function"),
|
|
46
|
+
remote: z.boolean().default(true),
|
|
47
|
+
provider_type: z.string().optional(),
|
|
48
|
+
scopes: z.array(z.string()).default([]),
|
|
49
|
+
network: z.array(z.string()).default([]),
|
|
50
|
+
timeout_seconds: z.number().int().default(30),
|
|
51
|
+
redact_fields: z.array(z.string()).default([]),
|
|
52
|
+
});
|
|
53
|
+
/** Constructs a ToolDefinition, applying Python-parity defaults (remote=true, network=[], timeout_seconds=30, redact_fields=[]). */
|
|
54
|
+
export function createToolDefinition(input) {
|
|
55
|
+
return ToolDefinitionSchema.parse(input);
|
|
56
|
+
}
|
|
57
|
+
/** Typed token-usage metadata for LLM calls. */
|
|
58
|
+
export class LLMTokenUsage {
|
|
59
|
+
inputTokens;
|
|
60
|
+
outputTokens;
|
|
61
|
+
promptTokens;
|
|
62
|
+
completionTokens;
|
|
63
|
+
totalTokens;
|
|
64
|
+
model;
|
|
65
|
+
constructor(data) {
|
|
66
|
+
this.inputTokens = data.input_tokens;
|
|
67
|
+
this.outputTokens = data.output_tokens;
|
|
68
|
+
this.promptTokens = data.prompt_tokens;
|
|
69
|
+
this.completionTokens = data.completion_tokens;
|
|
70
|
+
this.totalTokens = data.total_tokens;
|
|
71
|
+
this.model = data.model;
|
|
72
|
+
if (this.totalTokens === undefined) {
|
|
73
|
+
const prompt = this.inputTokens ?? this.promptTokens;
|
|
74
|
+
const completion = this.outputTokens ?? this.completionTokens;
|
|
75
|
+
if (prompt !== undefined && completion !== undefined) {
|
|
76
|
+
this.totalTokens = prompt + completion;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
/** Serializes to snake_case wire format so JSON.stringify round-trips through LLMTokenUsageSchema. */
|
|
81
|
+
toJSON() {
|
|
82
|
+
const result = {};
|
|
83
|
+
if (this.inputTokens !== undefined)
|
|
84
|
+
result["input_tokens"] = this.inputTokens;
|
|
85
|
+
if (this.outputTokens !== undefined)
|
|
86
|
+
result["output_tokens"] = this.outputTokens;
|
|
87
|
+
if (this.promptTokens !== undefined)
|
|
88
|
+
result["prompt_tokens"] = this.promptTokens;
|
|
89
|
+
if (this.completionTokens !== undefined)
|
|
90
|
+
result["completion_tokens"] = this.completionTokens;
|
|
91
|
+
if (this.totalTokens !== undefined)
|
|
92
|
+
result["total_tokens"] = this.totalTokens;
|
|
93
|
+
if (this.model !== undefined)
|
|
94
|
+
result["model"] = this.model;
|
|
95
|
+
return result;
|
|
96
|
+
}
|
|
97
|
+
/** Returns LangChain's expected usage-metadata keys. */
|
|
98
|
+
toLangchainUsageMetadata() {
|
|
99
|
+
const inputTokens = this.inputTokens ?? this.promptTokens ?? 0;
|
|
100
|
+
const outputTokens = this.outputTokens ?? this.completionTokens ?? 0;
|
|
101
|
+
const totalTokens = this.totalTokens ?? inputTokens + outputTokens;
|
|
102
|
+
return {
|
|
103
|
+
input_tokens: inputTokens,
|
|
104
|
+
output_tokens: outputTokens,
|
|
105
|
+
total_tokens: totalTokens,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
/** Runtime validation schema for LLMTokenUsage wire data. All fields optional, matching the class constructor. */
|
|
110
|
+
export const LLMTokenUsageSchema = z.preprocess((val) => (val instanceof LLMTokenUsage ? val.toJSON() : val), z
|
|
111
|
+
.object({
|
|
112
|
+
input_tokens: z.number().optional(),
|
|
113
|
+
output_tokens: z.number().optional(),
|
|
114
|
+
prompt_tokens: z.number().optional(),
|
|
115
|
+
completion_tokens: z.number().optional(),
|
|
116
|
+
total_tokens: z.number().optional(),
|
|
117
|
+
model: z.string().optional(),
|
|
118
|
+
})
|
|
119
|
+
.transform((data) => new LLMTokenUsage(data)));
|
|
120
|
+
/** Typed final tool call requested by an LLM. */
|
|
121
|
+
export class LLMToolCall {
|
|
122
|
+
id;
|
|
123
|
+
name;
|
|
124
|
+
args;
|
|
125
|
+
type;
|
|
126
|
+
index;
|
|
127
|
+
constructor(data) {
|
|
128
|
+
this.id = data.id;
|
|
129
|
+
this.name = data.name;
|
|
130
|
+
this.args = data.args ?? data.arguments; // accepts both 'args' and 'arguments' for cross-provider compatibility
|
|
131
|
+
this.type = data.type;
|
|
132
|
+
this.index = data.index;
|
|
133
|
+
}
|
|
134
|
+
/** Returns a LangChain-compatible tool-call dict (excludes index). */
|
|
135
|
+
toLangchainDict() {
|
|
136
|
+
const result = {};
|
|
137
|
+
if (this.id !== undefined)
|
|
138
|
+
result["id"] = this.id;
|
|
139
|
+
if (this.name !== undefined)
|
|
140
|
+
result["name"] = this.name;
|
|
141
|
+
if (this.args !== undefined)
|
|
142
|
+
result["args"] = this.args;
|
|
143
|
+
if (this.type !== undefined)
|
|
144
|
+
result["type"] = this.type;
|
|
145
|
+
return result;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
/** Runtime validation schema for LLMToolCall wire data. */
|
|
149
|
+
export const LLMToolCallSchema = z
|
|
150
|
+
.object({
|
|
151
|
+
id: z.string().optional(),
|
|
152
|
+
name: z.string().optional(),
|
|
153
|
+
args: JsonValueSchema.optional(),
|
|
154
|
+
arguments: JsonValueSchema.optional(),
|
|
155
|
+
type: z.string().optional(),
|
|
156
|
+
index: z.number().optional(),
|
|
157
|
+
})
|
|
158
|
+
.transform((data) => new LLMToolCall(data));
|
|
159
|
+
/** Serializable bound-tool schema forwarded with an LLM call. */
|
|
160
|
+
export class LLMToolSchema {
|
|
161
|
+
name;
|
|
162
|
+
description;
|
|
163
|
+
parameters;
|
|
164
|
+
type;
|
|
165
|
+
strict;
|
|
166
|
+
function;
|
|
167
|
+
constructor(data) {
|
|
168
|
+
this.name = data.name;
|
|
169
|
+
this.description = data.description;
|
|
170
|
+
this.parameters = data.parameters;
|
|
171
|
+
this.type = data.type;
|
|
172
|
+
this.strict = data.strict;
|
|
173
|
+
this.function = data.function;
|
|
174
|
+
}
|
|
175
|
+
/** Returns the schema in the shape LangChain bind_tools expects. */
|
|
176
|
+
toLangchainDict() {
|
|
177
|
+
const result = {};
|
|
178
|
+
if (this.name !== undefined)
|
|
179
|
+
result["name"] = this.name;
|
|
180
|
+
if (this.description !== undefined)
|
|
181
|
+
result["description"] = this.description;
|
|
182
|
+
if (this.parameters !== undefined)
|
|
183
|
+
result["parameters"] = this.parameters;
|
|
184
|
+
if (this.type !== undefined)
|
|
185
|
+
result["type"] = this.type;
|
|
186
|
+
if (this.strict !== undefined)
|
|
187
|
+
result["strict"] = this.strict;
|
|
188
|
+
if (this.function !== undefined)
|
|
189
|
+
result["function"] = this.function;
|
|
190
|
+
return result;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
/** Runtime validation schema for LLMToolSchema wire data. */
|
|
194
|
+
export const LLMToolSchemaValidator = z
|
|
195
|
+
.object({
|
|
196
|
+
name: z.string().optional(),
|
|
197
|
+
description: z.string().optional(),
|
|
198
|
+
parameters: JsonValueSchema.optional(),
|
|
199
|
+
type: z.string().optional(),
|
|
200
|
+
strict: z.boolean().optional(),
|
|
201
|
+
function: JsonValueSchema.optional(),
|
|
202
|
+
})
|
|
203
|
+
.transform((data) => new LLMToolSchema(data));
|
|
204
|
+
const INVOCATION_KNOWN_KEYS = new Set([
|
|
205
|
+
"max_tokens",
|
|
206
|
+
"response_format",
|
|
207
|
+
"top_p",
|
|
208
|
+
"top_k",
|
|
209
|
+
"frequency_penalty",
|
|
210
|
+
"presence_penalty",
|
|
211
|
+
"seed",
|
|
212
|
+
"timeout",
|
|
213
|
+
"parallel_tool_calls",
|
|
214
|
+
"reasoning_effort",
|
|
215
|
+
]);
|
|
216
|
+
/** Explicit provider/model options passed with an LLM invocation. */
|
|
217
|
+
export class LLMInvocationOptions {
|
|
218
|
+
maxTokens;
|
|
219
|
+
responseFormat;
|
|
220
|
+
topP;
|
|
221
|
+
topK;
|
|
222
|
+
frequencyPenalty;
|
|
223
|
+
presencePenalty;
|
|
224
|
+
seed;
|
|
225
|
+
timeout;
|
|
226
|
+
parallelToolCalls;
|
|
227
|
+
reasoningEffort;
|
|
228
|
+
/** Provider-specific kwargs not in the standard field set (e.g. temperature). Mirrors Python's extra="allow". */
|
|
229
|
+
extras;
|
|
230
|
+
constructor(data) {
|
|
231
|
+
this.maxTokens = data.max_tokens;
|
|
232
|
+
this.responseFormat = data.response_format;
|
|
233
|
+
this.topP = data.top_p;
|
|
234
|
+
this.topK = data.top_k;
|
|
235
|
+
this.frequencyPenalty = data.frequency_penalty;
|
|
236
|
+
this.presencePenalty = data.presence_penalty;
|
|
237
|
+
this.seed = data.seed;
|
|
238
|
+
this.timeout = data.timeout;
|
|
239
|
+
this.parallelToolCalls = data.parallel_tool_calls;
|
|
240
|
+
this.reasoningEffort = data.reasoning_effort;
|
|
241
|
+
this.extras = Object.fromEntries(Object.entries(data).filter(([k, v]) => !INVOCATION_KNOWN_KEYS.has(k) && v !== undefined));
|
|
242
|
+
}
|
|
243
|
+
/** Serializes to snake_case wire format so JSON.stringify round-trips through LLMInvocationOptionsSchema. */
|
|
244
|
+
toJSON() {
|
|
245
|
+
return this.toModelKwargs();
|
|
246
|
+
}
|
|
247
|
+
/** Converts to kwargs for underlying model invocation. Mirrors Python's model_dump(exclude_none=True) with extra="allow". */
|
|
248
|
+
toModelKwargs() {
|
|
249
|
+
const result = { ...this.extras };
|
|
250
|
+
if (this.maxTokens !== undefined)
|
|
251
|
+
result["max_tokens"] = this.maxTokens;
|
|
252
|
+
if (this.responseFormat !== undefined)
|
|
253
|
+
result["response_format"] = this.responseFormat;
|
|
254
|
+
if (this.topP !== undefined)
|
|
255
|
+
result["top_p"] = this.topP;
|
|
256
|
+
if (this.topK !== undefined)
|
|
257
|
+
result["top_k"] = this.topK;
|
|
258
|
+
if (this.frequencyPenalty !== undefined)
|
|
259
|
+
result["frequency_penalty"] = this.frequencyPenalty;
|
|
260
|
+
if (this.presencePenalty !== undefined)
|
|
261
|
+
result["presence_penalty"] = this.presencePenalty;
|
|
262
|
+
if (this.seed !== undefined)
|
|
263
|
+
result["seed"] = this.seed;
|
|
264
|
+
if (this.timeout !== undefined)
|
|
265
|
+
result["timeout"] = this.timeout;
|
|
266
|
+
if (this.parallelToolCalls !== undefined)
|
|
267
|
+
result["parallel_tool_calls"] = this.parallelToolCalls;
|
|
268
|
+
if (this.reasoningEffort !== undefined)
|
|
269
|
+
result["reasoning_effort"] = this.reasoningEffort;
|
|
270
|
+
return result;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
/** Runtime validation schema for LLMInvocationOptions wire data. */
|
|
274
|
+
export const LLMInvocationOptionsSchema = z.preprocess((val) => (val instanceof LLMInvocationOptions ? val.toJSON() : val), z
|
|
275
|
+
.looseObject({
|
|
276
|
+
max_tokens: z.number().optional(),
|
|
277
|
+
response_format: JsonValueSchema.optional(),
|
|
278
|
+
top_p: z.number().optional(),
|
|
279
|
+
top_k: z.number().optional(),
|
|
280
|
+
frequency_penalty: z.number().optional(),
|
|
281
|
+
presence_penalty: z.number().optional(),
|
|
282
|
+
seed: z.number().optional(),
|
|
283
|
+
timeout: z.number().optional(),
|
|
284
|
+
parallel_tool_calls: z.boolean().optional(),
|
|
285
|
+
reasoning_effort: z.string().optional(),
|
|
286
|
+
})
|
|
287
|
+
.transform((data) => new LLMInvocationOptions(data)));
|
|
288
|
+
/**
|
|
289
|
+
* Runtime validation schema for Message wire data. Parses snake_case wire
|
|
290
|
+
* fields and transforms them to the camelCase Message interface shape,
|
|
291
|
+
* matching how LLMToolCallSchema/LLMTokenUsageSchema handle the same mapping.
|
|
292
|
+
*/
|
|
293
|
+
export const MessageSchema = z
|
|
294
|
+
.looseObject({
|
|
295
|
+
role: z.enum(["user", "assistant", "tool", "system"]),
|
|
296
|
+
content: z.union([z.string(), z.array(AnyContentBlockSchema)]),
|
|
297
|
+
tool_calls: z.array(LLMToolCallSchema).optional(),
|
|
298
|
+
tool_call_id: z.string().optional(),
|
|
299
|
+
is_error: z.boolean().optional(),
|
|
300
|
+
name: z.string().optional(),
|
|
301
|
+
id: z.string().optional(),
|
|
302
|
+
additional_kwargs: z.record(z.string(), JsonValueSchema).optional(),
|
|
303
|
+
response_metadata: z.record(z.string(), JsonValueSchema).optional(),
|
|
304
|
+
})
|
|
305
|
+
.transform((data) => ({
|
|
306
|
+
role: data.role,
|
|
307
|
+
content: data.content,
|
|
308
|
+
toolCalls: data.tool_calls,
|
|
309
|
+
toolCallId: data.tool_call_id,
|
|
310
|
+
isError: data.is_error,
|
|
311
|
+
name: data.name,
|
|
312
|
+
id: data.id,
|
|
313
|
+
additionalKwargs: data.additional_kwargs,
|
|
314
|
+
responseMetadata: data.response_metadata,
|
|
315
|
+
}));
|
|
316
|
+
/**
|
|
317
|
+
* Serialize a Message to its snake_case wire shape — the camel→snake "dump"
|
|
318
|
+
* half that mirrors Python's `model_dump(by_alias=True)`. `MessageSchema` is
|
|
319
|
+
* the inverse snake→camel "parse" half.
|
|
320
|
+
*
|
|
321
|
+
* Keeping these two symmetric is what makes the representation safe: messages
|
|
322
|
+
* are camelCase internally (the `Message` interface) and snake_case on the
|
|
323
|
+
* wire, and conversion happens exactly once at each boundary. Use this when
|
|
324
|
+
* dumping an already-internal `Message`; never re-run an internal Message
|
|
325
|
+
* through `MessageSchema`, whose transform would blank the camelCase fields.
|
|
326
|
+
*/
|
|
327
|
+
export function serializeMessage(message) {
|
|
328
|
+
const out = {
|
|
329
|
+
role: message.role,
|
|
330
|
+
content: message.content,
|
|
331
|
+
};
|
|
332
|
+
if (message.toolCalls !== undefined)
|
|
333
|
+
out["tool_calls"] = message.toolCalls;
|
|
334
|
+
if (message.toolCallId !== undefined)
|
|
335
|
+
out["tool_call_id"] = message.toolCallId;
|
|
336
|
+
if (message.isError !== undefined)
|
|
337
|
+
out["is_error"] = message.isError;
|
|
338
|
+
if (message.name !== undefined)
|
|
339
|
+
out["name"] = message.name;
|
|
340
|
+
if (message.id !== undefined)
|
|
341
|
+
out["id"] = message.id;
|
|
342
|
+
if (message.additionalKwargs !== undefined)
|
|
343
|
+
out["additional_kwargs"] = message.additionalKwargs;
|
|
344
|
+
if (message.responseMetadata !== undefined)
|
|
345
|
+
out["response_metadata"] = message.responseMetadata;
|
|
346
|
+
return out;
|
|
347
|
+
}
|
|
348
|
+
const TOKEN_KEYS = new Set([
|
|
349
|
+
"input_tokens",
|
|
350
|
+
"output_tokens",
|
|
351
|
+
"prompt_tokens",
|
|
352
|
+
"completion_tokens",
|
|
353
|
+
"total_tokens",
|
|
354
|
+
"model",
|
|
355
|
+
]);
|
|
356
|
+
/** Framework-neutral LLM response. */
|
|
357
|
+
export class LLMResponse {
|
|
358
|
+
content;
|
|
359
|
+
toolCalls;
|
|
360
|
+
metadata;
|
|
361
|
+
usage;
|
|
362
|
+
id;
|
|
363
|
+
name;
|
|
364
|
+
additionalKwargs;
|
|
365
|
+
responseMetadata;
|
|
366
|
+
constructor(data) {
|
|
367
|
+
this.content = data.content;
|
|
368
|
+
this.toolCalls = data.toolCalls;
|
|
369
|
+
this.metadata = data.metadata ?? {};
|
|
370
|
+
this.usage = data.usage;
|
|
371
|
+
this.id = data.id;
|
|
372
|
+
this.name = data.name;
|
|
373
|
+
this.additionalKwargs = data.additionalKwargs;
|
|
374
|
+
this.responseMetadata = data.responseMetadata;
|
|
375
|
+
}
|
|
376
|
+
/**
|
|
377
|
+
* Constructs an LLMResponse from a raw provider dict, normalizing usage
|
|
378
|
+
* from either a top-level 'usage' key or token keys embedded in 'metadata'.
|
|
379
|
+
*/
|
|
380
|
+
static fromRaw(data) {
|
|
381
|
+
let usage;
|
|
382
|
+
if (data["usage"] != null) {
|
|
383
|
+
usage = new LLMTokenUsage(data["usage"]);
|
|
384
|
+
}
|
|
385
|
+
else {
|
|
386
|
+
const metadata = data["metadata"];
|
|
387
|
+
if (metadata != null &&
|
|
388
|
+
typeof metadata === "object" &&
|
|
389
|
+
!Array.isArray(metadata)) {
|
|
390
|
+
const meta = metadata;
|
|
391
|
+
const metaUsage = meta["usage"];
|
|
392
|
+
let usageData;
|
|
393
|
+
if (metaUsage != null &&
|
|
394
|
+
typeof metaUsage === "object" &&
|
|
395
|
+
!Array.isArray(metaUsage)) {
|
|
396
|
+
usageData = metaUsage;
|
|
397
|
+
}
|
|
398
|
+
else if (Object.keys(meta).some((k) => TOKEN_KEYS.has(k))) {
|
|
399
|
+
usageData = meta;
|
|
400
|
+
}
|
|
401
|
+
if (usageData != null) {
|
|
402
|
+
usage = new LLMTokenUsage(usageData);
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
const rawToolCalls = data["tool_calls"] ?? data["toolCalls"];
|
|
407
|
+
return new LLMResponse({
|
|
408
|
+
content: data["content"] ?? "",
|
|
409
|
+
toolCalls: Array.isArray(rawToolCalls)
|
|
410
|
+
? rawToolCalls.map((tc) => LLMToolCallSchema.parse(tc))
|
|
411
|
+
: undefined,
|
|
412
|
+
metadata: data["metadata"] ?? {},
|
|
413
|
+
usage,
|
|
414
|
+
id: data["id"],
|
|
415
|
+
name: data["name"],
|
|
416
|
+
additionalKwargs: (data["additional_kwargs"] ??
|
|
417
|
+
data["additionalKwargs"]),
|
|
418
|
+
responseMetadata: (data["response_metadata"] ??
|
|
419
|
+
data["responseMetadata"]),
|
|
420
|
+
});
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
/** Runtime validation schema for LLMResponse wire data. `content` is the only required field. */
|
|
424
|
+
export const LLMResponseSchema = z.looseObject({
|
|
425
|
+
content: z.string(),
|
|
426
|
+
tool_calls: z.array(z.unknown()).optional(),
|
|
427
|
+
metadata: z.record(z.string(), z.unknown()).optional(),
|
|
428
|
+
usage: z.record(z.string(), z.unknown()).optional(),
|
|
429
|
+
id: z.string().optional(),
|
|
430
|
+
name: z.string().optional(),
|
|
431
|
+
additional_kwargs: z.record(z.string(), z.unknown()).optional(),
|
|
432
|
+
response_metadata: z.record(z.string(), z.unknown()).optional(),
|
|
433
|
+
});
|
|
434
|
+
/** Runtime validation schema for ToolCallChunk wire data. */
|
|
435
|
+
export const ToolCallChunkSchema = z.object({
|
|
436
|
+
id: z.string().optional(),
|
|
437
|
+
name: z.string().optional(),
|
|
438
|
+
args: z.string().optional(),
|
|
439
|
+
type: z.string().optional(),
|
|
440
|
+
index: z.number().optional(),
|
|
441
|
+
});
|
|
442
|
+
/**
|
|
443
|
+
* Refines `z.unknown()` to reject the absent/`undefined` case, matching Pydantic's
|
|
444
|
+
* "required field" semantics for JsonValue-typed fields (where `null` is allowed
|
|
445
|
+
* but a missing key is not).
|
|
446
|
+
*/
|
|
447
|
+
const RequiredJsonValueSchema = z
|
|
448
|
+
.unknown()
|
|
449
|
+
.refine((v) => v !== undefined, { message: "Required" });
|
|
450
|
+
/** Runtime validation schema for AgentInput wire data. */
|
|
451
|
+
export const AgentInputSchema = z.looseObject({
|
|
452
|
+
payload: RequiredJsonValueSchema,
|
|
453
|
+
});
|
|
454
|
+
/** Runtime validation schema for AgentOutput wire data. */
|
|
455
|
+
export const AgentOutputSchema = z.looseObject({
|
|
456
|
+
response: RequiredJsonValueSchema,
|
|
457
|
+
});
|
|
458
|
+
// An SSE `event:` line is terminated by CR/LF, so a name carrying those bytes
|
|
459
|
+
// could forge extra frames in any server-sent-event serializer. NUL is rejected
|
|
460
|
+
// too as it can truncate the name in C-based parsers/log sinks. Forbid them at
|
|
461
|
+
// the schema boundary regardless of which transport later renders the name.
|
|
462
|
+
const StreamEventNameSchema = z
|
|
463
|
+
.string()
|
|
464
|
+
// Checked via includes() rather than a regex so the NUL literal doesn't
|
|
465
|
+
// trip eslint's no-control-regex rule.
|
|
466
|
+
.refine((v) => !v.includes("\r") && !v.includes("\n") && !v.includes("\u0000"), {
|
|
467
|
+
message: "Stream event name must not contain CR, LF, or NUL",
|
|
468
|
+
});
|
|
469
|
+
/** Runtime validation schema for StreamEvent wire data. */
|
|
470
|
+
export const StreamEventSchema = z.looseObject({
|
|
471
|
+
data: RequiredJsonValueSchema,
|
|
472
|
+
event: StreamEventNameSchema.optional(),
|
|
473
|
+
});
|
|
474
|
+
/**
|
|
475
|
+
* Per-session summary sourced from framework-specific persistence.
|
|
476
|
+
*
|
|
477
|
+
* Returned by the AER's session-enrichment endpoint. The platform layer
|
|
478
|
+
* (OE) merges this with its own tenant fields (user_id, project_id,
|
|
479
|
+
* workspace_id, visibility) when assembling the public sessions list.
|
|
480
|
+
*
|
|
481
|
+
* Mirrors Python's `SessionSummary` in `agent_engine_sdk/models.py`.
|
|
482
|
+
*/
|
|
483
|
+
export const SessionSummarySchema = z.object({
|
|
484
|
+
/** Identifier of the session. */
|
|
485
|
+
session_id: z.string(),
|
|
486
|
+
/** ISO 8601 timestamp of the most recent activity; empty when unavailable. */
|
|
487
|
+
last_activity: z.string(),
|
|
488
|
+
/** ISO 8601 timestamp when the session was first persisted; empty when unavailable. */
|
|
489
|
+
created_at: z.string(),
|
|
490
|
+
/**
|
|
491
|
+
* Number of messages in the session — the same count the session messages
|
|
492
|
+
* endpoint returns.
|
|
493
|
+
*/
|
|
494
|
+
message_count: z.number().int(),
|
|
495
|
+
/**
|
|
496
|
+
* Truncated first human-authored message (up to 80 chars). Empty when no
|
|
497
|
+
* human message has been persisted.
|
|
498
|
+
*/
|
|
499
|
+
first_message_preview: z.string().default(""),
|
|
500
|
+
});
|
|
501
|
+
/** Response for the AER's session-summary enrichment endpoint. */
|
|
502
|
+
export const SessionsSummaryResponseSchema = z.object({
|
|
503
|
+
/**
|
|
504
|
+
* One summary per requested session_id that has framework-side
|
|
505
|
+
* persistence. Sessions without persistence are omitted.
|
|
506
|
+
*/
|
|
507
|
+
sessions: z.array(SessionSummarySchema),
|
|
508
|
+
});
|
|
509
|
+
/**
|
|
510
|
+
* A single message in a session's conversation history.
|
|
511
|
+
*
|
|
512
|
+
* `role` uses the same vocabulary as `Message` ("user", "assistant",
|
|
513
|
+
* "tool", "system"). `name` carries the tool name on tool messages.
|
|
514
|
+
*
|
|
515
|
+
* Mirrors Python's `SessionMessage` in `agent_engine_sdk/models.py`.
|
|
516
|
+
*/
|
|
517
|
+
export const SessionMessageSchema = z.object({
|
|
518
|
+
/**
|
|
519
|
+
* Stable identifier — the framework's id when available, otherwise a
|
|
520
|
+
* synthetic id derived from session_id + position.
|
|
521
|
+
*/
|
|
522
|
+
id: z.string(),
|
|
523
|
+
/**
|
|
524
|
+
* Platform role: "user", "assistant", "tool", or "system".
|
|
525
|
+
* Unknown framework types pass through unchanged.
|
|
526
|
+
*/
|
|
527
|
+
role: z.string(),
|
|
528
|
+
/** Flat-string content. Multimodal content is collapsed to its text portions only. */
|
|
529
|
+
content: z.string(),
|
|
530
|
+
/**
|
|
531
|
+
* ISO 8601 persistence-boundary timestamp. Native checkpoint projections use
|
|
532
|
+
* the first checkpoint where the message appeared; durable workflow projections
|
|
533
|
+
* use the committed snapshot boundary; empty when unavailable.
|
|
534
|
+
*/
|
|
535
|
+
timestamp: z.string(),
|
|
536
|
+
/** Identifier of the session this message belongs to. */
|
|
537
|
+
session_id: z.string(),
|
|
538
|
+
/** Tool name on tool messages, empty otherwise. */
|
|
539
|
+
name: z.string().default(""),
|
|
540
|
+
/**
|
|
541
|
+
* Tool calls requested by an assistant message. Each carries a stable `id`
|
|
542
|
+
* that the matching tool result echoes back via `tool_call_id`.
|
|
543
|
+
*/
|
|
544
|
+
tool_calls: z.array(LLMToolCallSchema).nullable().default(null),
|
|
545
|
+
/**
|
|
546
|
+
* On a tool message, the id of the assistant tool call this message is the
|
|
547
|
+
* result of. Empty/absent on non-tool messages.
|
|
548
|
+
*/
|
|
549
|
+
tool_call_id: z.string().nullable().default(null),
|
|
550
|
+
/**
|
|
551
|
+
* Framework message metadata that should remain attached to the message,
|
|
552
|
+
* including generic UI artifact metadata.
|
|
553
|
+
*/
|
|
554
|
+
additional_kwargs: z.record(z.string(), z.unknown()).nullable().default(null),
|
|
555
|
+
});
|
|
556
|
+
/** Response for the AER's session-messages endpoint. */
|
|
557
|
+
export const SessionMessagesResponseSchema = z.object({
|
|
558
|
+
/**
|
|
559
|
+
* Decoded conversation history in chronological order. Empty when the
|
|
560
|
+
* session has no persisted messages.
|
|
561
|
+
*/
|
|
562
|
+
messages: z.array(SessionMessageSchema),
|
|
563
|
+
});
|
|
564
|
+
/** Parses an ISO datetime string into a Date. Rejects unparseable input. */
|
|
565
|
+
export const DateFromStringSchema = z.string().transform((s, ctx) => {
|
|
566
|
+
const d = new Date(s);
|
|
567
|
+
if (Number.isNaN(d.getTime())) {
|
|
568
|
+
ctx.addIssue({ code: "custom", message: `Invalid datetime string: ${s}` });
|
|
569
|
+
return z.NEVER;
|
|
570
|
+
}
|
|
571
|
+
return d;
|
|
572
|
+
});
|
|
573
|
+
/** Reference to a branch and its fork point. */
|
|
574
|
+
export const BranchRefSchema = z.looseObject({
|
|
575
|
+
name: z.string(),
|
|
576
|
+
root_event_id: z.string(),
|
|
577
|
+
});
|
|
578
|
+
/** Platform event — the storage envelope. Payloads are opaque. */
|
|
579
|
+
export const EventSchema = z.looseObject({
|
|
580
|
+
event_id: z.string(),
|
|
581
|
+
session_id: z.string(),
|
|
582
|
+
parent_event_id: z.string().optional(),
|
|
583
|
+
actor_id: z.string(),
|
|
584
|
+
payload: z.unknown().transform((v) => v),
|
|
585
|
+
metadata: z.record(z.string(), z.string()).optional(),
|
|
586
|
+
branch: BranchRefSchema.optional(),
|
|
587
|
+
timestamp: DateFromStringSchema,
|
|
588
|
+
});
|
package/package.json
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@mongodb-js/agent-engine-sdk",
|
|
3
|
+
"version": "0.11.3",
|
|
4
|
+
"license": "Apache-2.0",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "https://github.com/10gen/agentic-platform.git",
|
|
8
|
+
"directory": "client-libraries/packages/javascript/packages/agent-engine-sdk"
|
|
9
|
+
},
|
|
10
|
+
"description": "Core TypeScript protocols and models for the Atlas Agent Engine SDK",
|
|
11
|
+
"type": "module",
|
|
12
|
+
"packageManager": "npm@11.14.1",
|
|
13
|
+
"engines": {
|
|
14
|
+
"node": ">=24",
|
|
15
|
+
"npm": ">=11.10.0"
|
|
16
|
+
},
|
|
17
|
+
"main": "./dist/index.js",
|
|
18
|
+
"types": "./dist/index.d.ts",
|
|
19
|
+
"exports": {
|
|
20
|
+
".": {
|
|
21
|
+
"import": "./dist/index.js",
|
|
22
|
+
"types": "./dist/index.d.ts"
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"files": [
|
|
26
|
+
"dist",
|
|
27
|
+
"README.md",
|
|
28
|
+
"LICENSE.md"
|
|
29
|
+
],
|
|
30
|
+
"scripts": {
|
|
31
|
+
"build": "tsc",
|
|
32
|
+
"typecheck": "tsc --noEmit",
|
|
33
|
+
"test": "vitest run",
|
|
34
|
+
"test:watch": "vitest",
|
|
35
|
+
"lint": "eslint \"src/**/*.ts\" \"tests/**/*.ts\""
|
|
36
|
+
},
|
|
37
|
+
"devDependencies": {
|
|
38
|
+
"@eslint/js": "^10.0.1",
|
|
39
|
+
"eslint": "^10.4.0",
|
|
40
|
+
"typescript": "^5.5.0",
|
|
41
|
+
"typescript-eslint": "^8.59.3",
|
|
42
|
+
"vitest": "^4.1.6"
|
|
43
|
+
},
|
|
44
|
+
"dependencies": {
|
|
45
|
+
"zod": "^4.4.3"
|
|
46
|
+
},
|
|
47
|
+
"publishConfig": {
|
|
48
|
+
"registry": "https://registry.npmjs.org"
|
|
49
|
+
}
|
|
50
|
+
}
|