@gea-ai/agent-sdk 0.1.261007-alpha.1 → 0.1.261009-alpha.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/THIRD_PARTY_NOTICES.md +7 -0
- package/dist/agent-core.wasm +0 -0
- package/dist/agent-media-read.d.ts +13 -0
- package/dist/agent-media-read.js +29 -0
- package/dist/agent-session-inbox.js +12 -7
- package/dist/agent-worker-context.js +238 -8
- package/dist/agent-worker.js +40 -40
- package/dist/index.d.ts +25 -10
- package/dist/index.js +10 -4
- package/dist/tool-model-output.js +3 -4
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +2 -2
- package/third-party/anthropic-schema/LICENSE +13 -0
package/THIRD_PARTY_NOTICES.md
CHANGED
|
@@ -58,6 +58,13 @@ and packaged Worker conformance fixtures before changing the pin.
|
|
|
58
58
|
|
|
59
59
|
## Agent Core WASM
|
|
60
60
|
|
|
61
|
+
The bundled Core's Anthropic output-schema sanitizer is ported from
|
|
62
|
+
`@ai-sdk/anthropic` **4.0.67**, `src/sanitize-json-schema.ts` (Vercel AI SDK).
|
|
63
|
+
Copyright 2023 Vercel, Inc.; see
|
|
64
|
+
[license and notice](./third-party/anthropic-schema/LICENSE).
|
|
65
|
+
The Rust port retains the upstream transformation using `serde_json` values;
|
|
66
|
+
the original schema still controls final validation.
|
|
67
|
+
|
|
61
68
|
The optional Agent Core asset is built from this repository's Apache-2.0 Rust
|
|
62
69
|
crate with Rust 1.94.1. Its Cargo dependencies are pinned in
|
|
63
70
|
`crates/agent-core/Cargo.lock`; exact-version license copies and a dependency
|
package/dist/agent-core.wasm
CHANGED
|
Binary file
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
declare const AgentMediaReadError_base: import("better-result").TaggedErrorClass<"AgentMediaReadError", {
|
|
2
|
+
message: string;
|
|
3
|
+
operation: "download Tool output media" | "read Artifact image";
|
|
4
|
+
status?: number;
|
|
5
|
+
}>;
|
|
6
|
+
export declare class AgentMediaReadError extends AgentMediaReadError_base {
|
|
7
|
+
}
|
|
8
|
+
/** Translate Fetch failures at the Tool/model media boundary, without signed URLs. */
|
|
9
|
+
export declare function readAgentMedia(request: () => Promise<Response>, operation: "download Tool output media" | "read Artifact image", signal?: AbortSignal): Promise<{
|
|
10
|
+
data: ArrayBuffer;
|
|
11
|
+
mediaType: string | null;
|
|
12
|
+
}>;
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { TaggedError } from "better-result";
|
|
2
|
+
export class AgentMediaReadError extends TaggedError("AgentMediaReadError")() {
|
|
3
|
+
}
|
|
4
|
+
/** Translate Fetch failures at the Tool/model media boundary, without signed URLs. */
|
|
5
|
+
export async function readAgentMedia(request, operation, signal) {
|
|
6
|
+
try {
|
|
7
|
+
signal?.throwIfAborted();
|
|
8
|
+
const response = await request();
|
|
9
|
+
if (!response.ok)
|
|
10
|
+
throw new AgentMediaReadError({
|
|
11
|
+
operation,
|
|
12
|
+
status: response.status,
|
|
13
|
+
message: `Could not ${operation} (HTTP ${response.status}).`,
|
|
14
|
+
});
|
|
15
|
+
const data = await response.arrayBuffer();
|
|
16
|
+
return { data, mediaType: response.headers.get("content-type") };
|
|
17
|
+
}
|
|
18
|
+
catch (error) {
|
|
19
|
+
signal?.throwIfAborted();
|
|
20
|
+
if (AgentMediaReadError.is(error))
|
|
21
|
+
throw error;
|
|
22
|
+
// Fetch/body exceptions may contain credentials or signed URLs. These errors
|
|
23
|
+
// enter model feedback and traces, so retain the operation, not the raw cause.
|
|
24
|
+
throw new AgentMediaReadError({
|
|
25
|
+
operation,
|
|
26
|
+
message: `Could not ${operation} (network or response-body failure).`,
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -633,13 +633,18 @@ export async function handleAgentSessionInboxRequest(request, storage) {
|
|
|
633
633
|
canonicalAgentChannelJson(input.identity))
|
|
634
634
|
return Response.json({ error: "session_identity_conflict" }, { status: 409 });
|
|
635
635
|
if (state.execution?.id === input.executionId) {
|
|
636
|
-
if (
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
}
|
|
642
|
-
|
|
636
|
+
if (input.runId && input.runId !== state.execution.turnId)
|
|
637
|
+
return Response.json({ error: "execution_mismatch" }, { status: 409 });
|
|
638
|
+
if (path === "/v1/inbox/start" && state.started)
|
|
639
|
+
return Response.json({ error: "execution_already_started" }, {
|
|
640
|
+
status: 409,
|
|
641
|
+
headers: { "x-gea-session-execution": "already-started" },
|
|
642
|
+
});
|
|
643
|
+
if (!state.started) {
|
|
644
|
+
// An inbox claim retains the previous transport until the Host
|
|
645
|
+
// admits this execution with its current Run authority.
|
|
646
|
+
state.transport = input.transport;
|
|
647
|
+
state.started = path === "/v1/inbox/start";
|
|
643
648
|
await save(tx, state, runs);
|
|
644
649
|
}
|
|
645
650
|
return Response.json({ execution: state.execution });
|
|
@@ -66,6 +66,62 @@ function groupMessages(messages) {
|
|
|
66
66
|
}
|
|
67
67
|
return groups;
|
|
68
68
|
}
|
|
69
|
+
// Provider usage is request-wide, not per message. This deliberately estimates
|
|
70
|
+
// content only: UTF-8 bytes / 3 plus framing, without opaque reasoning signatures
|
|
71
|
+
// or base64 expansion. Media gets a fixed allowance, not an exact token count.
|
|
72
|
+
function estimateMessageTokens(message) {
|
|
73
|
+
const textTokens = (text) => Math.ceil(new TextEncoder().encode(text).length / 3);
|
|
74
|
+
const mediaTokens = 4_096;
|
|
75
|
+
if (typeof message.content === "string")
|
|
76
|
+
return 8 + textTokens(message.content);
|
|
77
|
+
return (8 +
|
|
78
|
+
message.content.reduce((total, part) => {
|
|
79
|
+
switch (part.type) {
|
|
80
|
+
case "text":
|
|
81
|
+
case "reasoning":
|
|
82
|
+
return total + 8 + textTokens(part.text);
|
|
83
|
+
case "image":
|
|
84
|
+
case "reasoning-file":
|
|
85
|
+
return total + mediaTokens;
|
|
86
|
+
case "file":
|
|
87
|
+
return (total +
|
|
88
|
+
(typeof part.data === "object" &&
|
|
89
|
+
"type" in part.data &&
|
|
90
|
+
part.data.type === "text"
|
|
91
|
+
? textTokens(part.data.text)
|
|
92
|
+
: mediaTokens));
|
|
93
|
+
case "tool-call":
|
|
94
|
+
return (total +
|
|
95
|
+
16 +
|
|
96
|
+
textTokens(part.toolName) +
|
|
97
|
+
textTokens(JSON.stringify(part.input) ?? ""));
|
|
98
|
+
case "tool-result": {
|
|
99
|
+
const output = part.output;
|
|
100
|
+
let tokens;
|
|
101
|
+
switch (output.type) {
|
|
102
|
+
case "content":
|
|
103
|
+
tokens = output.value.reduce((count, item) => count +
|
|
104
|
+
(item.type === "text"
|
|
105
|
+
? textTokens(item.text)
|
|
106
|
+
: item.type === "file" && item.data.type === "text"
|
|
107
|
+
? textTokens(item.data.text)
|
|
108
|
+
: mediaTokens), 0);
|
|
109
|
+
break;
|
|
110
|
+
case "text":
|
|
111
|
+
case "error-text":
|
|
112
|
+
tokens = textTokens(output.value);
|
|
113
|
+
break;
|
|
114
|
+
default:
|
|
115
|
+
tokens = textTokens(JSON.stringify(output));
|
|
116
|
+
}
|
|
117
|
+
return total + 16 + textTokens(part.toolName) + tokens;
|
|
118
|
+
}
|
|
119
|
+
default: {
|
|
120
|
+
return total + 8 + textTokens(JSON.stringify(part));
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}, 0));
|
|
124
|
+
}
|
|
69
125
|
function getToolOutputText(part) {
|
|
70
126
|
switch (part.output.type) {
|
|
71
127
|
case "error-text":
|
|
@@ -224,7 +280,7 @@ export async function applyAgentWorkerToolOutputOffload(input) {
|
|
|
224
280
|
return input.messages;
|
|
225
281
|
const groups = groupMessages(input.messages);
|
|
226
282
|
const firstProtectedIndex = input.protectRecentGroups
|
|
227
|
-
? Math.max(0, groups.length - input.options.preserveRecentGroups)
|
|
283
|
+
? Math.max(0, groups.length - (input.options.preserveRecentGroups ?? 5))
|
|
228
284
|
: groups.length;
|
|
229
285
|
const messages = [];
|
|
230
286
|
for (const [groupIndex, group] of groups.entries()) {
|
|
@@ -263,13 +319,135 @@ function summarySchema() {
|
|
|
263
319
|
"## Critical Exact Details\n- Preserve exact IDs, commands, paths, API names, error messages, and config values.",
|
|
264
320
|
].join("\n\n");
|
|
265
321
|
}
|
|
322
|
+
// Summary input is a textual projection, not a provider request. Keep resource
|
|
323
|
+
// references for recovery but never stringify media bytes or opaque metadata.
|
|
324
|
+
function summaryFileData(data) {
|
|
325
|
+
if (data instanceof URL) {
|
|
326
|
+
return data.protocol === "data:"
|
|
327
|
+
? { omitted: "inline media bytes" }
|
|
328
|
+
: { url: data.href };
|
|
329
|
+
}
|
|
330
|
+
if (typeof data === "string" ||
|
|
331
|
+
data instanceof ArrayBuffer ||
|
|
332
|
+
ArrayBuffer.isView(data)) {
|
|
333
|
+
return { omitted: "inline media bytes; recover from raw chat history" };
|
|
334
|
+
}
|
|
335
|
+
if ("type" in data) {
|
|
336
|
+
switch (data.type) {
|
|
337
|
+
case "text":
|
|
338
|
+
return { text: data.text };
|
|
339
|
+
case "url": {
|
|
340
|
+
const url = String(data.url);
|
|
341
|
+
return url.startsWith("data:")
|
|
342
|
+
? { omitted: "inline media bytes" }
|
|
343
|
+
: { url };
|
|
344
|
+
}
|
|
345
|
+
case "reference":
|
|
346
|
+
return { reference: data.reference };
|
|
347
|
+
case "data":
|
|
348
|
+
return { omitted: "inline media bytes; recover from raw chat history" };
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
return { reference: data };
|
|
352
|
+
}
|
|
353
|
+
function summaryContentPart(part) {
|
|
354
|
+
switch (part.type) {
|
|
355
|
+
case "text":
|
|
356
|
+
case "reasoning":
|
|
357
|
+
return { type: part.type, text: part.text };
|
|
358
|
+
case "tool-call":
|
|
359
|
+
return {
|
|
360
|
+
type: part.type,
|
|
361
|
+
toolName: part.toolName,
|
|
362
|
+
toolCallId: part.toolCallId,
|
|
363
|
+
input: part.input,
|
|
364
|
+
providerExecuted: part.providerExecuted,
|
|
365
|
+
};
|
|
366
|
+
case "tool-result": {
|
|
367
|
+
const output = part.output;
|
|
368
|
+
return {
|
|
369
|
+
type: part.type,
|
|
370
|
+
toolName: part.toolName,
|
|
371
|
+
toolCallId: part.toolCallId,
|
|
372
|
+
output: output.type === "content"
|
|
373
|
+
? { type: output.type, value: output.value.map(summaryContentPart) }
|
|
374
|
+
: output.type === "execution-denied"
|
|
375
|
+
? { type: output.type, reason: output.reason }
|
|
376
|
+
: { type: output.type, value: output.value },
|
|
377
|
+
};
|
|
378
|
+
}
|
|
379
|
+
case "file":
|
|
380
|
+
case "file-data":
|
|
381
|
+
return {
|
|
382
|
+
type: part.type,
|
|
383
|
+
mediaType: part.mediaType,
|
|
384
|
+
filename: part.filename,
|
|
385
|
+
data: summaryFileData(part.data),
|
|
386
|
+
};
|
|
387
|
+
case "image":
|
|
388
|
+
return {
|
|
389
|
+
type: part.type,
|
|
390
|
+
mediaType: part.mediaType,
|
|
391
|
+
data: summaryFileData(part.image),
|
|
392
|
+
};
|
|
393
|
+
case "image-data":
|
|
394
|
+
case "reasoning-file":
|
|
395
|
+
return {
|
|
396
|
+
type: part.type,
|
|
397
|
+
mediaType: part.mediaType,
|
|
398
|
+
data: summaryFileData(part.data),
|
|
399
|
+
};
|
|
400
|
+
case "file-url":
|
|
401
|
+
case "image-url":
|
|
402
|
+
return {
|
|
403
|
+
type: part.type,
|
|
404
|
+
mediaType: "mediaType" in part ? part.mediaType : undefined,
|
|
405
|
+
url: part.url.startsWith("data:") ? "[inline media omitted]" : part.url,
|
|
406
|
+
};
|
|
407
|
+
case "file-id":
|
|
408
|
+
case "image-file-id":
|
|
409
|
+
return { type: part.type, fileId: part.fileId };
|
|
410
|
+
case "file-reference":
|
|
411
|
+
case "image-file-reference":
|
|
412
|
+
return { type: part.type, reference: part.providerReference };
|
|
413
|
+
case "custom":
|
|
414
|
+
return {
|
|
415
|
+
type: part.type,
|
|
416
|
+
kind: "kind" in part ? part.kind : undefined,
|
|
417
|
+
omitted: "opaque provider content; recover from raw chat history",
|
|
418
|
+
};
|
|
419
|
+
case "tool-approval-request":
|
|
420
|
+
case "tool-approval-response":
|
|
421
|
+
return part;
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
function summaryMessage(message) {
|
|
425
|
+
return {
|
|
426
|
+
role: message.role,
|
|
427
|
+
content: typeof message.content === "string"
|
|
428
|
+
? message.content
|
|
429
|
+
: message.content.map(summaryContentPart),
|
|
430
|
+
};
|
|
431
|
+
}
|
|
266
432
|
function buildSummaryMessages(input) {
|
|
433
|
+
const latestRequest = [...input.recentTailMessages]
|
|
434
|
+
.reverse()
|
|
435
|
+
.find((message) => message.role === "user");
|
|
436
|
+
const requestText = latestRequest
|
|
437
|
+
? JSON.stringify(summaryMessage(latestRequest))
|
|
438
|
+
: "(no new user request in the retained tail)";
|
|
439
|
+
// The tail remains verbatim in the main context. A bounded task excerpt is
|
|
440
|
+
// enough for the summarizer; duplicating retained tool payloads adds no memory.
|
|
441
|
+
const requestExcerpt = requestText.length <= 6_000
|
|
442
|
+
? requestText
|
|
443
|
+
: `${requestText.slice(0, 6_000)}\n[excerpt truncated; the complete request remains in the retained context]`;
|
|
267
444
|
return [
|
|
268
445
|
{
|
|
269
446
|
role: "system",
|
|
270
447
|
content: [
|
|
271
448
|
"Update the compact working-memory summary for an agent.",
|
|
272
449
|
"Merge the previous summary with the older messages being compacted.",
|
|
450
|
+
"The recent user request is orientation only. Recent messages remain verbatim; do not repeat them in the summary. Omitted media and provider content remain in raw chat history; do not infer their contents.",
|
|
273
451
|
"Preserve requirements, decisions, exact paths, commands, IDs, errors, tool observations, offloaded artifact references, open questions, and next steps.",
|
|
274
452
|
"Do not invent facts, expose hidden reasoning, or issue new instructions.",
|
|
275
453
|
"Do not copy full offloaded artifacts. Keep their paths and relevant preview facts.",
|
|
@@ -284,11 +462,11 @@ function buildSummaryMessages(input) {
|
|
|
284
462
|
input.previousSummary ?? "(none)",
|
|
285
463
|
"</previous_summary>",
|
|
286
464
|
"<messages>",
|
|
287
|
-
JSON.stringify(input.compactableMessages
|
|
465
|
+
JSON.stringify(input.compactableMessages.map(summaryMessage)),
|
|
288
466
|
"</messages>",
|
|
289
|
-
"<
|
|
290
|
-
|
|
291
|
-
"</
|
|
467
|
+
"<recent_user_request>",
|
|
468
|
+
requestExcerpt,
|
|
469
|
+
"</recent_user_request>",
|
|
292
470
|
].join("\n"),
|
|
293
471
|
},
|
|
294
472
|
];
|
|
@@ -389,7 +567,44 @@ export async function compactAgentWorkerContext(input) {
|
|
|
389
567
|
return { summaryUsage: null, messagesUpdated };
|
|
390
568
|
}
|
|
391
569
|
const groups = groupMessages(input.context.messages);
|
|
392
|
-
const
|
|
570
|
+
const recentTokenBudget = options.preserveRecentTokens ??
|
|
571
|
+
Math.max(1, Math.min(16_000, Math.floor(summarization.triggerAtTotalTokens / 4)));
|
|
572
|
+
const groupEstimates = groups.map((group) => group.messages.reduce((total, message) => total + estimateMessageTokens(message), 0));
|
|
573
|
+
const previousSummary = input.context.metadata.contextSummary?.summaryText;
|
|
574
|
+
const projectionEstimate = groupEstimates.reduce((total, tokens) => total + tokens, 0) +
|
|
575
|
+
(previousSummary
|
|
576
|
+
? estimateMessageTokens(makeSummaryMessage(previousSummary))
|
|
577
|
+
: 0);
|
|
578
|
+
// Usage includes fixed prompt overhead we cannot attribute to individual messages.
|
|
579
|
+
// Allocate it conservatively across the projection instead of treating small
|
|
580
|
+
// local estimates as proof that an over-threshold request already fits.
|
|
581
|
+
const usageScale = Math.max(1, (input.context.contextSize ?? 0) / Math.max(1, projectionEstimate));
|
|
582
|
+
let splitIndex = groups.length;
|
|
583
|
+
let retainedTokens = 0;
|
|
584
|
+
while (splitIndex > 0) {
|
|
585
|
+
const groupTokens = Math.ceil(groupEstimates[splitIndex - 1] * usageScale);
|
|
586
|
+
// Always keep the newest complete group, even when it exceeds the budget.
|
|
587
|
+
if (splitIndex < groups.length &&
|
|
588
|
+
(retainedTokens + groupTokens > recentTokenBudget ||
|
|
589
|
+
(options.preserveRecentGroups !== undefined &&
|
|
590
|
+
groups.length - splitIndex >= options.preserveRecentGroups)))
|
|
591
|
+
break;
|
|
592
|
+
retainedTokens += groupTokens;
|
|
593
|
+
splitIndex--;
|
|
594
|
+
}
|
|
595
|
+
// Fixed overhead alone is not a reason to pay for summarizing a tiny history.
|
|
596
|
+
// Explicit retention limits still take precedence over this default safeguard.
|
|
597
|
+
if (options.preserveRecentTokens === undefined &&
|
|
598
|
+
options.preserveRecentGroups === undefined &&
|
|
599
|
+
groupEstimates
|
|
600
|
+
.slice(0, splitIndex)
|
|
601
|
+
.reduce((total, tokens) => total + tokens, 0) <
|
|
602
|
+
Math.max(1, Math.min(1_024, Math.floor(recentTokenBudget / 4)))) {
|
|
603
|
+
createAgentTracing().currentSpan?.setAttributes({
|
|
604
|
+
"gea.context.compaction.skip_reason": "insufficient_reduction",
|
|
605
|
+
});
|
|
606
|
+
return { summaryUsage: null, messagesUpdated };
|
|
607
|
+
}
|
|
393
608
|
const compactableMessages = groups
|
|
394
609
|
.slice(0, splitIndex)
|
|
395
610
|
.flatMap((group) => group.messages)
|
|
@@ -433,7 +648,18 @@ export async function compactAgentWorkerContext(input) {
|
|
|
433
648
|
if (part.type === "content_delta" && kinds.get(part.id) === "text")
|
|
434
649
|
summaryText += part.delta;
|
|
435
650
|
}
|
|
436
|
-
|
|
651
|
+
const completion = await result.result;
|
|
652
|
+
summaryUsage = completion.usage;
|
|
653
|
+
if (completion.finishReason !== "stop") {
|
|
654
|
+
// The provider call still counts toward usage, but an incomplete
|
|
655
|
+
// summary must not replace the previous summary or active history.
|
|
656
|
+
span.setAttributes({
|
|
657
|
+
"gea.context.compaction.outcome": "rejected",
|
|
658
|
+
"gea.context.compaction.finish_reason": completion.finishReason,
|
|
659
|
+
"gea.context.messages.output_count": input.context.messages.length,
|
|
660
|
+
});
|
|
661
|
+
return { summaryUsage, messagesUpdated };
|
|
662
|
+
}
|
|
437
663
|
if (!summaryText.trim())
|
|
438
664
|
throw new Error("Context summary was empty.");
|
|
439
665
|
const missingHeadings = REQUIRED_SUMMARY_HEADINGS.filter((heading) => !summaryText.includes(heading));
|
|
@@ -480,7 +706,11 @@ export async function compactAgentWorkerContext(input) {
|
|
|
480
706
|
"gea.context.tokens.estimate": input.context.contextSize ?? undefined,
|
|
481
707
|
"gea.context.tokens.threshold": summarization.triggerAtTotalTokens,
|
|
482
708
|
"gea.context.messages.compacted_count": compactableMessages.length,
|
|
483
|
-
"gea.context.groups.preserved":
|
|
709
|
+
"gea.context.groups.preserved": groups.length - splitIndex,
|
|
710
|
+
"gea.context.tokens.retained_estimate": retainedTokens,
|
|
711
|
+
"gea.context.tokens.usage_scale": usageScale,
|
|
712
|
+
"gea.context.tokens.retained_budget": recentTokenBudget,
|
|
713
|
+
"gea.context.tokens.retained_over_budget": retainedTokens > recentTokenBudget,
|
|
484
714
|
},
|
|
485
715
|
});
|
|
486
716
|
}
|
package/dist/agent-worker.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { contextSystemInputSchema } from "@gea-ai/contract/agent-worker-tools";
|
|
1
2
|
import { getAgentProgrammaticToolCalling, isAgentConnectorConnectionHelperExposed, } from "@gea-ai/contract/agent-packages";
|
|
2
3
|
import { AGENT_WORKER_TOOL_METADATA_HEADER, AGENT_WORKER_TOOL_METADATA_VERSION, } from "@gea-ai/contract/agent-worker-tools";
|
|
3
4
|
import { isAgentConnectorExposed } from "@gea-ai/contract/agent-packages";
|
|
@@ -15,6 +16,7 @@ import { decodeAgentModelProxyValue, encodeAgentModelProxyValue, } from "@gea-ai
|
|
|
15
16
|
import { createGeaAI, modelDescriptorSchema } from "./gea-ai.js";
|
|
16
17
|
import { storeToolModelOutput, resolveToolArtifacts, } from "./tool-model-output.js";
|
|
17
18
|
import { mcpToolModelOutput } from "./mcp-tool-output.js";
|
|
19
|
+
import { AgentMediaReadError, readAgentMedia } from "./agent-media-read.js";
|
|
18
20
|
export { createGeaAI } from "./gea-ai.js";
|
|
19
21
|
import { mergeLlmJson, llmRuntimeRequestOptionsSchema, } from "@gea-ai/contract/llm-catalog";
|
|
20
22
|
import { executeChannelAgentRun, uploadChannelInput, } from "./agent-channel-api.js";
|
|
@@ -2231,6 +2233,21 @@ function createHostBackedAgentTools(input) {
|
|
|
2231
2233
|
inputSchema: webSearchInputSchema,
|
|
2232
2234
|
});
|
|
2233
2235
|
}
|
|
2236
|
+
else if (definition.id === "context_system") {
|
|
2237
|
+
registerAgentWorkerTool(tools, "contextSystem", tool({
|
|
2238
|
+
description: "Access the current OAuth user's GEA Context resources. Call action=list to discover operations and their input schemas, then action=call with tool and arguments. Documents use Markdown; read before editing and retain contentHash for conflict checks. Requires OAuth; Project keys, custom principals and local calls are unsupported.",
|
|
2239
|
+
inputSchema: contextSystemInputSchema,
|
|
2240
|
+
toModelOutput: mcpToolModelOutput,
|
|
2241
|
+
execute: async (toolInput, options) => invokeHostTool({
|
|
2242
|
+
host: input.host,
|
|
2243
|
+
messages: options.messages,
|
|
2244
|
+
signal: options.abortSignal,
|
|
2245
|
+
toolCallId: options.toolCallId,
|
|
2246
|
+
toolInput,
|
|
2247
|
+
toolName: definition.id,
|
|
2248
|
+
}),
|
|
2249
|
+
}));
|
|
2250
|
+
}
|
|
2234
2251
|
else if (definition.id === "agent") {
|
|
2235
2252
|
// The negotiated target catalog below owns registration, including declared subagents.
|
|
2236
2253
|
}
|
|
@@ -2569,7 +2586,6 @@ async function requestSessionJson(input) {
|
|
|
2569
2586
|
method: input.method,
|
|
2570
2587
|
})),
|
|
2571
2588
|
});
|
|
2572
|
-
input.onResponse?.(response);
|
|
2573
2589
|
if (!response.ok)
|
|
2574
2590
|
throw new Error(`AgentSession rejected ${input.path} (${response.status}).`);
|
|
2575
2591
|
return input.schema.parse(await response.json());
|
|
@@ -3026,15 +3042,9 @@ async function executeAgentWorkerRequest(input, waitUntil, ownComputer, ownSessi
|
|
|
3026
3042
|
}
|
|
3027
3043
|
const mutateSession = (values) => {
|
|
3028
3044
|
const queuedAt = performance.now();
|
|
3029
|
-
const mutationSpan = trace
|
|
3030
|
-
.getTracer("gea.agent-session")
|
|
3031
|
-
.startSpan("agent.session.mutation", {
|
|
3032
|
-
attributes: { "gea.agent.run.id": payload.runId },
|
|
3033
|
-
});
|
|
3034
3045
|
const result = writeTail.then(async () => {
|
|
3035
3046
|
const startedAt = performance.now();
|
|
3036
3047
|
const queueMs = startedAt - queuedAt;
|
|
3037
|
-
const sequence = mutationSequence;
|
|
3038
3048
|
let failed = true;
|
|
3039
3049
|
try {
|
|
3040
3050
|
if (writeFailure)
|
|
@@ -3046,12 +3056,6 @@ async function executeAgentWorkerRequest(input, waitUntil, ownComputer, ownSessi
|
|
|
3046
3056
|
namespace: input.sessionNamespace,
|
|
3047
3057
|
path: "/v2/mutations",
|
|
3048
3058
|
schema: agentSessionExecutionMutationResultSchema,
|
|
3049
|
-
onResponse(response) {
|
|
3050
|
-
mutationSpan.setAttribute("http.response.status_code", response.status);
|
|
3051
|
-
const timing = response.headers.get("server-timing");
|
|
3052
|
-
if (timing)
|
|
3053
|
-
mutationSpan.setAttribute("gea.session.mutation.server_timing", timing);
|
|
3054
|
-
},
|
|
3055
3059
|
});
|
|
3056
3060
|
mutationSequence += 1;
|
|
3057
3061
|
failed = false;
|
|
@@ -3072,22 +3076,6 @@ async function executeAgentWorkerRequest(input, waitUntil, ownComputer, ownSessi
|
|
|
3072
3076
|
"gea.session.persistence.queue_ms": Math.round(persistenceTotals.queueMs),
|
|
3073
3077
|
"gea.session.persistence.request_ms": Math.round(persistenceTotals.requestMs),
|
|
3074
3078
|
});
|
|
3075
|
-
mutationSpan.setAttributes({
|
|
3076
|
-
"gea.session.mutation.sequence": sequence,
|
|
3077
|
-
"gea.session.mutation.kinds": Object.keys(values),
|
|
3078
|
-
"gea.session.mutation.event_count": values.events?.length ?? 0,
|
|
3079
|
-
"gea.session.mutation.queue_ms": Math.round(queueMs),
|
|
3080
|
-
"gea.session.mutation.request_ms": Math.round(requestMs),
|
|
3081
|
-
...(invocationTiming.lastModelFinishedAt === undefined
|
|
3082
|
-
? {}
|
|
3083
|
-
: {
|
|
3084
|
-
"gea.session.mutation.start_after_model_ms": Math.round(startedAt - invocationTiming.lastModelFinishedAt),
|
|
3085
|
-
"gea.session.mutation.end_after_model_ms": Math.round(performance.now() - invocationTiming.lastModelFinishedAt),
|
|
3086
|
-
}),
|
|
3087
|
-
});
|
|
3088
|
-
if (failed)
|
|
3089
|
-
mutationSpan.setStatus({ code: SpanStatusCode.ERROR });
|
|
3090
|
-
mutationSpan.end();
|
|
3091
3079
|
if (failed || queueMs + requestMs >= 250)
|
|
3092
3080
|
console.info("AgentSession mutation timing", {
|
|
3093
3081
|
runId: payload.runId,
|
|
@@ -3802,7 +3790,7 @@ async function executeAgentWorkerRequest(input, waitUntil, ownComputer, ownSessi
|
|
|
3802
3790
|
const readImage = async (file) => {
|
|
3803
3791
|
if (!artifactScope)
|
|
3804
3792
|
throw new Error("Images require Agent Artifacts.");
|
|
3805
|
-
const
|
|
3793
|
+
const image = await readAgentMedia(() => host.fetch(`${HOST_PATH}/tools/attachments/read`, {
|
|
3806
3794
|
method: "POST",
|
|
3807
3795
|
headers: { "content-type": "application/json" },
|
|
3808
3796
|
body: JSON.stringify({
|
|
@@ -3810,16 +3798,14 @@ async function executeAgentWorkerRequest(input, waitUntil, ownComputer, ownSessi
|
|
|
3810
3798
|
...(file.id ? { id: file.id } : { key: file.key }),
|
|
3811
3799
|
}),
|
|
3812
3800
|
signal: input.request.signal,
|
|
3813
|
-
});
|
|
3814
|
-
|
|
3815
|
-
throw new Error(`Could not read Artifact image (${response.status}).`);
|
|
3816
|
-
const bytes = new Uint8Array(await response.arrayBuffer());
|
|
3801
|
+
}), "read Artifact image", input.request.signal);
|
|
3802
|
+
const bytes = new Uint8Array(image.data);
|
|
3817
3803
|
if (bytes.byteLength > MAX_AGENT_ARTIFACT_IMAGE_BYTES)
|
|
3818
3804
|
throw new Error("Prepared image exceeds the model image limit.");
|
|
3819
3805
|
return {
|
|
3820
3806
|
type: "file",
|
|
3821
3807
|
data: { type: "data", data: bytes },
|
|
3822
|
-
mediaType:
|
|
3808
|
+
mediaType: image.mediaType ?? file.mediaType,
|
|
3823
3809
|
};
|
|
3824
3810
|
};
|
|
3825
3811
|
const addImage = async (file) => {
|
|
@@ -4115,6 +4101,12 @@ async function executeAgentWorkerRequest(input, waitUntil, ownComputer, ownSessi
|
|
|
4115
4101
|
const initialPrompt = await startupTracing.withSpan("agent.startup.prompt", () => preparePrompt(withTurnImages(assembleAgentWorkerContext({ context, runtimeContext }), turnImages)));
|
|
4116
4102
|
const modelCancellation = new AbortController();
|
|
4117
4103
|
let failure;
|
|
4104
|
+
const executionErrorText = (error, fallback = "Agent execution failed.") => {
|
|
4105
|
+
const original = failure?.error ?? error;
|
|
4106
|
+
return original instanceof AgentMediaReadError
|
|
4107
|
+
? original.message
|
|
4108
|
+
: fallback;
|
|
4109
|
+
};
|
|
4118
4110
|
let pendingMainCall;
|
|
4119
4111
|
let pendingMainModel = configuredModel;
|
|
4120
4112
|
let lastStepNumber = 0;
|
|
@@ -4129,7 +4121,7 @@ async function executeAgentWorkerRequest(input, waitUntil, ownComputer, ownSessi
|
|
|
4129
4121
|
// the execution's original failure before publishing that chunk.
|
|
4130
4122
|
ownSessionOutcome({
|
|
4131
4123
|
status: input.request.signal.aborted ? "cancelled" : "failed",
|
|
4132
|
-
text:
|
|
4124
|
+
text: executionErrorText(error),
|
|
4133
4125
|
});
|
|
4134
4126
|
recordExecutionFailure(error);
|
|
4135
4127
|
};
|
|
@@ -4267,9 +4259,9 @@ async function executeAgentWorkerRequest(input, waitUntil, ownComputer, ownSessi
|
|
|
4267
4259
|
// both the error and final usage from clients.
|
|
4268
4260
|
ownSessionOutcome({
|
|
4269
4261
|
status: input.request.signal.aborted ? "cancelled" : "failed",
|
|
4270
|
-
text: responseMessage.parts
|
|
4262
|
+
text: executionErrorText(failure.error, responseMessage.parts
|
|
4271
4263
|
.flatMap((part) => (part.type === "text" ? [part.text] : []))
|
|
4272
|
-
.join(""),
|
|
4264
|
+
.join("")),
|
|
4273
4265
|
});
|
|
4274
4266
|
return;
|
|
4275
4267
|
}
|
|
@@ -4645,7 +4637,13 @@ async function executeAgentWorkerRequest(input, waitUntil, ownComputer, ownSessi
|
|
|
4645
4637
|
throw failure.error;
|
|
4646
4638
|
},
|
|
4647
4639
|
async prepareModel(request) {
|
|
4648
|
-
const prepared = await preparePrompt(withTurnImages(assembleAgentWorkerContext({ context, runtimeContext }), turnImages))
|
|
4640
|
+
const prepared = await preparePrompt(withTurnImages(assembleAgentWorkerContext({ context, runtimeContext }), turnImages)).catch((error) => {
|
|
4641
|
+
// Core serializes host exceptions through WASM. Preserve this safe,
|
|
4642
|
+
// typed media failure before that boundary loses its identity.
|
|
4643
|
+
if (error instanceof AgentMediaReadError)
|
|
4644
|
+
fail(error);
|
|
4645
|
+
throw error;
|
|
4646
|
+
});
|
|
4649
4647
|
const prompt = [...prepared.instructions, ...prepared.messages];
|
|
4650
4648
|
modelPrompt = prompt;
|
|
4651
4649
|
const decoratedTools = addCacheControlToToolList(request.tools.map((tool) => ({
|
|
@@ -4742,6 +4740,7 @@ async function executeAgentWorkerRequest(input, waitUntil, ownComputer, ownSessi
|
|
|
4742
4740
|
async execute({ writer }) {
|
|
4743
4741
|
for await (const chunk of projectAgentCoreEvents(tracked, {
|
|
4744
4742
|
messageId,
|
|
4743
|
+
onError: executionErrorText,
|
|
4745
4744
|
approvals: pending?.pendingStep.approvals,
|
|
4746
4745
|
tools,
|
|
4747
4746
|
messageMetadata: {
|
|
@@ -4842,6 +4841,7 @@ async function executeAgentWorkerRequest(input, waitUntil, ownComputer, ownSessi
|
|
|
4842
4841
|
: stepCountIs(Number.POSITIVE_INFINITY),
|
|
4843
4842
|
});
|
|
4844
4843
|
stream = result.toUIMessageStream({
|
|
4844
|
+
onError: (error) => executionErrorText(error, "An error occurred."),
|
|
4845
4845
|
generateMessageId: () => payload.responseMessageId,
|
|
4846
4846
|
originalMessages: payload.originalMessages,
|
|
4847
4847
|
sendReasoning: true,
|
|
@@ -4948,7 +4948,7 @@ async function executeAgentWorkerRequest(input, waitUntil, ownComputer, ownSessi
|
|
|
4948
4948
|
!input.request.signal.aborted) {
|
|
4949
4949
|
events.push({
|
|
4950
4950
|
type: "error",
|
|
4951
|
-
errorText:
|
|
4951
|
+
errorText: executionErrorText(failure?.error),
|
|
4952
4952
|
});
|
|
4953
4953
|
streamedError = true;
|
|
4954
4954
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -10,7 +10,7 @@ export type { AgentEngine } from "./agent-core-engine.js";
|
|
|
10
10
|
import type { AgentTracing } from "@gea-ai/contract/agent-tracing";
|
|
11
11
|
export type { AgentTracing, AgentTraceSpan, } from "@gea-ai/contract/agent-tracing";
|
|
12
12
|
import { type AgentContextStrategy } from "./context.js";
|
|
13
|
-
import { remoteAgentDeclarationSchema, type AgentReference } from "@gea-ai/contract/agent-references";
|
|
13
|
+
import { workerAgentReferenceSchema, remoteAgentDeclarationSchema, type AgentReference } from "@gea-ai/contract/agent-references";
|
|
14
14
|
export type { AgentContextStrategy, AgentContextRuntime, AgentContextPrepareStepEvent, AgentContextStepEndEvent, AgentContextEndEvent, } from "./context.js";
|
|
15
15
|
import type { ComputerCommands } from "@gea-ai/contract/computer-commands";
|
|
16
16
|
import type { AgentArtifacts, AgentArtifactScopeResolver } from "@gea-ai/contract/studio-artifacts";
|
|
@@ -429,7 +429,7 @@ type CustomAgentToolDefinition = {
|
|
|
429
429
|
readonly type: "custom";
|
|
430
430
|
readonly [agentToolConnectorAliases]?: Readonly<Record<string, string>>;
|
|
431
431
|
};
|
|
432
|
-
type ManagedToolId = "agent" | "chat_list" | "chat_read" | "chat_send" | "web_search";
|
|
432
|
+
type ManagedToolId = "agent" | "chat_list" | "chat_read" | "chat_send" | "web_search" | "context_system";
|
|
433
433
|
export type DefinedManagedTool<TId extends ManagedToolId = ManagedToolId> = {
|
|
434
434
|
readonly id: TId;
|
|
435
435
|
readonly type: "managed";
|
|
@@ -439,7 +439,7 @@ export declare function agentTool(): DefinedManagedTool<"agent">;
|
|
|
439
439
|
export interface WorkerAgentRegistry {
|
|
440
440
|
}
|
|
441
441
|
export type WorkerAgentSlug = keyof WorkerAgentRegistry extends never ? string : Extract<keyof WorkerAgentRegistry, string>;
|
|
442
|
-
/**
|
|
442
|
+
/** @deprecated Use defineRemoteAgent({ slug, description }) instead. */
|
|
443
443
|
export declare function defineAgentReference<const TSlug extends WorkerAgentSlug>(input: {
|
|
444
444
|
slug: TSlug;
|
|
445
445
|
description: string;
|
|
@@ -448,15 +448,28 @@ export declare function defineAgentReference<const TSlug extends WorkerAgentSlug
|
|
|
448
448
|
description: string;
|
|
449
449
|
slug: TSlug;
|
|
450
450
|
};
|
|
451
|
-
export type DefineRemoteAgentInput =
|
|
452
|
-
|
|
453
|
-
export declare function defineRemoteAgent(input: DefineRemoteAgentInput): {
|
|
454
|
-
type: "remote";
|
|
455
|
-
agentId: string;
|
|
456
|
-
invocationAuthority?: "oauth" | "project_key" | undefined;
|
|
457
|
-
environment?: "local" | "preview" | "production" | undefined;
|
|
451
|
+
export type DefineRemoteAgentInput = {
|
|
452
|
+
slug: WorkerAgentSlug;
|
|
458
453
|
description: string;
|
|
454
|
+
agentId?: never;
|
|
455
|
+
environment?: never;
|
|
456
|
+
invocationAuthority?: never;
|
|
457
|
+
} | (Omit<z.input<typeof remoteAgentDeclarationSchema>, "type"> & {
|
|
458
|
+
slug?: never;
|
|
459
|
+
});
|
|
460
|
+
/** Reference a same-Worker entry by slug, or an independently admitted Agent by ID. */
|
|
461
|
+
export declare function defineRemoteAgent<const TSlug extends WorkerAgentSlug>(input: {
|
|
462
|
+
slug: TSlug;
|
|
463
|
+
description: string;
|
|
464
|
+
agentId?: never;
|
|
465
|
+
environment?: never;
|
|
466
|
+
invocationAuthority?: never;
|
|
467
|
+
}): Omit<z.output<typeof workerAgentReferenceSchema>, "slug"> & {
|
|
468
|
+
slug: TSlug;
|
|
459
469
|
};
|
|
470
|
+
export declare function defineRemoteAgent(input: Omit<z.input<typeof remoteAgentDeclarationSchema>, "type"> & {
|
|
471
|
+
slug?: never;
|
|
472
|
+
}): z.output<typeof remoteAgentDeclarationSchema>;
|
|
460
473
|
/** @deprecated Enable defineAgent({ sessionTools: true }) instead. */
|
|
461
474
|
export declare function chatList(): DefinedManagedTool<"chat_list">;
|
|
462
475
|
/** @deprecated Enable defineAgent({ sessionTools: true }) instead. */
|
|
@@ -464,6 +477,8 @@ export declare function chatRead(): DefinedManagedTool<"chat_read">;
|
|
|
464
477
|
/** @deprecated Enable defineAgent({ sessionTools: true }) instead. */
|
|
465
478
|
export declare function chatSend(): DefinedManagedTool<"chat_send">;
|
|
466
479
|
export declare function webSearch(): DefinedManagedTool<"web_search">;
|
|
480
|
+
/** Access the current OAuth user's GEA Context without a separate Connection. */
|
|
481
|
+
export declare function contextSystem(): DefinedManagedTool<"context_system">;
|
|
467
482
|
type LegacyAgentToolPreset = {
|
|
468
483
|
readonly preset: "coding" | "default";
|
|
469
484
|
readonly type: "preset";
|
package/dist/index.js
CHANGED
|
@@ -3,7 +3,7 @@ import { agentToolOutputOffloadOptionsSchema, } from "@gea-ai/contract/agent-con
|
|
|
3
3
|
import { resolveModelOptions, } from "@gea-ai/contract/model-options";
|
|
4
4
|
export { aiSdk } from "./ai-sdk.js";
|
|
5
5
|
import { describeAgentContext } from "./context.js";
|
|
6
|
-
import { workerAgentReferenceSchema, remoteAgentDeclarationSchema, } from "@gea-ai/contract/agent-references";
|
|
6
|
+
import { workerAgentReferenceSchema, remoteAgentDeclarationSchema, remoteAgentInputSchema, } from "@gea-ai/contract/agent-references";
|
|
7
7
|
import { agentConnectorAuthSchema, agentConnectorDefinitionSchema, agentConnectorGrantSchema, agentConnectorRuntimeSchema, agentEnvironmentVariableSchema, getAgentConnectorPrincipalType, agentPackageSnapshotSchema, agentSlugSchema, agentSkillSchema, agentToolSchema, GEA_AGENT_PACKAGE_SCHEMA_VERSION, } from "@gea-ai/contract/agent-packages";
|
|
8
8
|
import { agentChannelKeySchema, agentChannelPathSchema, agentCustomChannelDefinitionSchema, agentHttpChannelDefinitionSchema, canonicalAgentChannelJson, } from "@gea-ai/contract/agent-channels";
|
|
9
9
|
import { z } from "zod";
|
|
@@ -339,7 +339,7 @@ const agentToolConnectorAliases = Symbol("agentToolConnectorAliases");
|
|
|
339
339
|
export function agentTool() {
|
|
340
340
|
return { id: "agent", type: "managed" };
|
|
341
341
|
}
|
|
342
|
-
/**
|
|
342
|
+
/** @deprecated Use defineRemoteAgent({ slug, description }) instead. */
|
|
343
343
|
export function defineAgentReference(input) {
|
|
344
344
|
const reference = workerAgentReferenceSchema.parse({
|
|
345
345
|
...input,
|
|
@@ -347,9 +347,11 @@ export function defineAgentReference(input) {
|
|
|
347
347
|
});
|
|
348
348
|
return { ...reference, slug: input.slug };
|
|
349
349
|
}
|
|
350
|
-
/** Invoke a fixed Agent ID. Omitted invocationAuthority uses a protected Project key; oauth requires an existing target installation. Environment defaults to the Host environment. */
|
|
351
350
|
export function defineRemoteAgent(input) {
|
|
352
|
-
|
|
351
|
+
const reference = remoteAgentInputSchema.parse(input);
|
|
352
|
+
return "slug" in reference
|
|
353
|
+
? workerAgentReferenceSchema.parse({ ...reference, type: "worker" })
|
|
354
|
+
: remoteAgentDeclarationSchema.parse({ ...reference, type: "remote" });
|
|
353
355
|
}
|
|
354
356
|
/** @deprecated Enable defineAgent({ sessionTools: true }) instead. */
|
|
355
357
|
export function chatList() {
|
|
@@ -366,6 +368,10 @@ export function chatSend() {
|
|
|
366
368
|
export function webSearch() {
|
|
367
369
|
return { id: "web_search", type: "managed" };
|
|
368
370
|
}
|
|
371
|
+
/** Access the current OAuth user's GEA Context without a separate Connection. */
|
|
372
|
+
export function contextSystem() {
|
|
373
|
+
return { id: "context_system", type: "managed" };
|
|
374
|
+
}
|
|
369
375
|
export function defineToolSet(tools) {
|
|
370
376
|
return { tools, type: "tool-set" };
|
|
371
377
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { convertInlineFileDataToUint8Array } from "@ai-sdk/provider-utils";
|
|
2
2
|
import { z } from "zod";
|
|
3
|
+
import { readAgentMedia } from "./agent-media-read.js";
|
|
3
4
|
const uploadResultSchema = z.object({ id: z.uuid() });
|
|
4
5
|
/** Persist only immutable references in the model context, never signed URLs or bytes. */
|
|
5
6
|
export async function storeToolModelOutput(output, artifacts, signal) {
|
|
@@ -29,10 +30,8 @@ export async function storeToolModelOutput(output, artifacts, signal) {
|
|
|
29
30
|
});
|
|
30
31
|
let body;
|
|
31
32
|
if (part.data.type === "url") {
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
throw new Error(`Tool file download failed (${response.status}).`);
|
|
35
|
-
body = await response.arrayBuffer();
|
|
33
|
+
const url = part.data.url;
|
|
34
|
+
body = (await readAgentMedia(() => fetch(url, { signal }), "download Tool output media", signal)).data;
|
|
36
35
|
}
|
|
37
36
|
else {
|
|
38
37
|
const bytes = convertInlineFileDataToUint8Array(part.data);
|
package/dist/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const agentSdkVersion = "0.1.
|
|
1
|
+
export declare const agentSdkVersion = "0.1.261009-alpha.0";
|
package/dist/version.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// Generated by scripts/build-sdk-version.mjs from package.json.
|
|
2
|
-
export const agentSdkVersion = "0.1.
|
|
2
|
+
export const agentSdkVersion = "0.1.261009-alpha.0";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gea-ai/agent-sdk",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.261009-alpha.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"homepage": "https://musegea.com/developers",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -119,7 +119,7 @@
|
|
|
119
119
|
"@ai-sdk/otel": "1.0.119",
|
|
120
120
|
"@ai-sdk/provider": "4.0.19",
|
|
121
121
|
"@ai-sdk/provider-utils": "5.0.50",
|
|
122
|
-
"@gea-ai/contract": "0.1.
|
|
122
|
+
"@gea-ai/contract": "0.1.261009-alpha.0",
|
|
123
123
|
"@opentelemetry/api": "1.9.1",
|
|
124
124
|
"@opentelemetry/context-async-hooks": "2.10.0",
|
|
125
125
|
"@opentelemetry/core": "2.10.0",
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
Copyright 2023 Vercel, Inc.
|
|
2
|
+
|
|
3
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
you may not use this file except in compliance with the License.
|
|
5
|
+
You may obtain a copy of the License at
|
|
6
|
+
|
|
7
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
|
|
9
|
+
Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
See the License for the specific language governing permissions and
|
|
13
|
+
limitations under the License.
|