@gea-ai/agent-sdk 0.1.261007-alpha.1 → 0.1.261008-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.
@@ -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
+ }
@@ -15,6 +15,7 @@ import { decodeAgentModelProxyValue, encodeAgentModelProxyValue, } from "@gea-ai
15
15
  import { createGeaAI, modelDescriptorSchema } from "./gea-ai.js";
16
16
  import { storeToolModelOutput, resolveToolArtifacts, } from "./tool-model-output.js";
17
17
  import { mcpToolModelOutput } from "./mcp-tool-output.js";
18
+ import { AgentMediaReadError, readAgentMedia } from "./agent-media-read.js";
18
19
  export { createGeaAI } from "./gea-ai.js";
19
20
  import { mergeLlmJson, llmRuntimeRequestOptionsSchema, } from "@gea-ai/contract/llm-catalog";
20
21
  import { executeChannelAgentRun, uploadChannelInput, } from "./agent-channel-api.js";
@@ -3802,7 +3803,7 @@ async function executeAgentWorkerRequest(input, waitUntil, ownComputer, ownSessi
3802
3803
  const readImage = async (file) => {
3803
3804
  if (!artifactScope)
3804
3805
  throw new Error("Images require Agent Artifacts.");
3805
- const response = await host.fetch(`${HOST_PATH}/tools/attachments/read`, {
3806
+ const image = await readAgentMedia(() => host.fetch(`${HOST_PATH}/tools/attachments/read`, {
3806
3807
  method: "POST",
3807
3808
  headers: { "content-type": "application/json" },
3808
3809
  body: JSON.stringify({
@@ -3810,16 +3811,14 @@ async function executeAgentWorkerRequest(input, waitUntil, ownComputer, ownSessi
3810
3811
  ...(file.id ? { id: file.id } : { key: file.key }),
3811
3812
  }),
3812
3813
  signal: input.request.signal,
3813
- });
3814
- if (!response.ok)
3815
- throw new Error(`Could not read Artifact image (${response.status}).`);
3816
- const bytes = new Uint8Array(await response.arrayBuffer());
3814
+ }), "read Artifact image", input.request.signal);
3815
+ const bytes = new Uint8Array(image.data);
3817
3816
  if (bytes.byteLength > MAX_AGENT_ARTIFACT_IMAGE_BYTES)
3818
3817
  throw new Error("Prepared image exceeds the model image limit.");
3819
3818
  return {
3820
3819
  type: "file",
3821
3820
  data: { type: "data", data: bytes },
3822
- mediaType: response.headers.get("content-type") ?? file.mediaType,
3821
+ mediaType: image.mediaType ?? file.mediaType,
3823
3822
  };
3824
3823
  };
3825
3824
  const addImage = async (file) => {
@@ -4115,6 +4114,12 @@ async function executeAgentWorkerRequest(input, waitUntil, ownComputer, ownSessi
4115
4114
  const initialPrompt = await startupTracing.withSpan("agent.startup.prompt", () => preparePrompt(withTurnImages(assembleAgentWorkerContext({ context, runtimeContext }), turnImages)));
4116
4115
  const modelCancellation = new AbortController();
4117
4116
  let failure;
4117
+ const executionErrorText = (error, fallback = "Agent execution failed.") => {
4118
+ const original = failure?.error ?? error;
4119
+ return original instanceof AgentMediaReadError
4120
+ ? original.message
4121
+ : fallback;
4122
+ };
4118
4123
  let pendingMainCall;
4119
4124
  let pendingMainModel = configuredModel;
4120
4125
  let lastStepNumber = 0;
@@ -4129,7 +4134,7 @@ async function executeAgentWorkerRequest(input, waitUntil, ownComputer, ownSessi
4129
4134
  // the execution's original failure before publishing that chunk.
4130
4135
  ownSessionOutcome({
4131
4136
  status: input.request.signal.aborted ? "cancelled" : "failed",
4132
- text: "Agent execution failed.",
4137
+ text: executionErrorText(error),
4133
4138
  });
4134
4139
  recordExecutionFailure(error);
4135
4140
  };
@@ -4267,9 +4272,9 @@ async function executeAgentWorkerRequest(input, waitUntil, ownComputer, ownSessi
4267
4272
  // both the error and final usage from clients.
4268
4273
  ownSessionOutcome({
4269
4274
  status: input.request.signal.aborted ? "cancelled" : "failed",
4270
- text: responseMessage.parts
4275
+ text: executionErrorText(failure.error, responseMessage.parts
4271
4276
  .flatMap((part) => (part.type === "text" ? [part.text] : []))
4272
- .join(""),
4277
+ .join("")),
4273
4278
  });
4274
4279
  return;
4275
4280
  }
@@ -4645,7 +4650,13 @@ async function executeAgentWorkerRequest(input, waitUntil, ownComputer, ownSessi
4645
4650
  throw failure.error;
4646
4651
  },
4647
4652
  async prepareModel(request) {
4648
- const prepared = await preparePrompt(withTurnImages(assembleAgentWorkerContext({ context, runtimeContext }), turnImages));
4653
+ const prepared = await preparePrompt(withTurnImages(assembleAgentWorkerContext({ context, runtimeContext }), turnImages)).catch((error) => {
4654
+ // Core serializes host exceptions through WASM. Preserve this safe,
4655
+ // typed media failure before that boundary loses its identity.
4656
+ if (error instanceof AgentMediaReadError)
4657
+ fail(error);
4658
+ throw error;
4659
+ });
4649
4660
  const prompt = [...prepared.instructions, ...prepared.messages];
4650
4661
  modelPrompt = prompt;
4651
4662
  const decoratedTools = addCacheControlToToolList(request.tools.map((tool) => ({
@@ -4742,6 +4753,7 @@ async function executeAgentWorkerRequest(input, waitUntil, ownComputer, ownSessi
4742
4753
  async execute({ writer }) {
4743
4754
  for await (const chunk of projectAgentCoreEvents(tracked, {
4744
4755
  messageId,
4756
+ onError: executionErrorText,
4745
4757
  approvals: pending?.pendingStep.approvals,
4746
4758
  tools,
4747
4759
  messageMetadata: {
@@ -4842,6 +4854,7 @@ async function executeAgentWorkerRequest(input, waitUntil, ownComputer, ownSessi
4842
4854
  : stepCountIs(Number.POSITIVE_INFINITY),
4843
4855
  });
4844
4856
  stream = result.toUIMessageStream({
4857
+ onError: (error) => executionErrorText(error, "An error occurred."),
4845
4858
  generateMessageId: () => payload.responseMessageId,
4846
4859
  originalMessages: payload.originalMessages,
4847
4860
  sendReasoning: true,
@@ -4948,7 +4961,7 @@ async function executeAgentWorkerRequest(input, waitUntil, ownComputer, ownSessi
4948
4961
  !input.request.signal.aborted) {
4949
4962
  events.push({
4950
4963
  type: "error",
4951
- errorText: "Agent execution failed.",
4964
+ errorText: executionErrorText(failure?.error),
4952
4965
  });
4953
4966
  streamedError = true;
4954
4967
  }
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";
@@ -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
- /** Explicitly makes a main Agent in the same Worker available to the owning Agent. */
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 = Omit<z.input<typeof remoteAgentDeclarationSchema>, "type">;
452
- /** Invoke a fixed Agent ID. Omitted invocationAuthority uses a protected Project key; oauth requires an existing target installation. Environment defaults to the Host environment. */
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. */
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
- /** Explicitly makes a main Agent in the same Worker available to the owning Agent. */
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
- return remoteAgentDeclarationSchema.parse({ ...input, type: "remote" });
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() {
@@ -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 response = await fetch(part.data.url, { signal });
33
- if (!response.ok)
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.261007-alpha.1";
1
+ export declare const agentSdkVersion = "0.1.261008-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.261007-alpha.1";
2
+ export const agentSdkVersion = "0.1.261008-alpha.0";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gea-ai/agent-sdk",
3
- "version": "0.1.261007-alpha.1",
3
+ "version": "0.1.261008-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.261007-alpha.1",
122
+ "@gea-ai/contract": "0.1.261008-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",