@aigne/transport 0.9.6 → 0.10.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,53 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.10.2](https://github.com/AIGNE-io/aigne-framework/compare/transport-v0.10.1...transport-v0.10.2) (2025-07-17)
4
+
5
+
6
+ ### Dependencies
7
+
8
+ * The following workspace dependencies were updated
9
+ * dependencies
10
+ * @aigne/openai bumped to 0.10.2
11
+ * devDependencies
12
+ * @aigne/agent-library bumped to 1.21.2
13
+ * @aigne/core bumped to 1.36.0
14
+ * @aigne/test-utils bumped to 0.5.10
15
+ * @aigne/default-memory bumped to 1.0.2
16
+
17
+ ## [0.10.1](https://github.com/AIGNE-io/aigne-framework/compare/transport-v0.10.0...transport-v0.10.1) (2025-07-17)
18
+
19
+
20
+ ### Dependencies
21
+
22
+ * The following workspace dependencies were updated
23
+ * dependencies
24
+ * @aigne/openai bumped to 0.10.1
25
+ * devDependencies
26
+ * @aigne/agent-library bumped to 1.21.1
27
+ * @aigne/core bumped to 1.35.0
28
+ * @aigne/test-utils bumped to 0.5.9
29
+ * @aigne/default-memory bumped to 1.0.1
30
+
31
+ ## [0.10.0](https://github.com/AIGNE-io/aigne-framework/compare/transport-v0.9.6...transport-v0.10.0) (2025-07-15)
32
+
33
+
34
+ ### Features
35
+
36
+ * **memory:** support did space memory adapter ([#229](https://github.com/AIGNE-io/aigne-framework/issues/229)) ([6f69b64](https://github.com/AIGNE-io/aigne-framework/commit/6f69b64e98b963db9d6ab5357306b445385eaa68))
37
+ * **model:** support aigne-hub model adapter ([#253](https://github.com/AIGNE-io/aigne-framework/issues/253)) ([4b33f8d](https://github.com/AIGNE-io/aigne-framework/commit/4b33f8d1a819f52357db81d502c56b55eaa0669f))
38
+
39
+
40
+ ### Dependencies
41
+
42
+ * The following workspace dependencies were updated
43
+ * dependencies
44
+ * @aigne/openai bumped to 0.10.0
45
+ * devDependencies
46
+ * @aigne/agent-library bumped to 1.21.0
47
+ * @aigne/core bumped to 1.34.0
48
+ * @aigne/test-utils bumped to 0.5.8
49
+ * @aigne/default-memory bumped to 1.0.0
50
+
3
51
  ## [0.9.6](https://github.com/AIGNE-io/aigne-framework/compare/transport-v0.9.5...transport-v0.9.6) (2025-07-14)
4
52
 
5
53
 
@@ -0,0 +1,92 @@
1
+ import type { AgentResponse, AgentResponseStream, ChatModelOptions, InvokeOptions, Message } from "@aigne/core";
2
+ import type { OpenAIChatModelOptions } from "@aigne/openai";
3
+ /**
4
+ * Options for invoking an agent through the BaseClient.
5
+ * Extends the standard AgentInvokeOptions with client-specific options.
6
+ */
7
+ export interface BaseClientInvokeOptions extends InvokeOptions {
8
+ /**
9
+ * Additional fetch API options to customize the HTTP request.
10
+ * These options will be merged with the default options used by the client.
11
+ */
12
+ fetchOptions?: Partial<RequestInit>;
13
+ }
14
+ export interface BaseClientOptions {
15
+ url: string;
16
+ accessKey?: string;
17
+ model?: string;
18
+ modelOptions?: ChatModelOptions;
19
+ clientOptions?: OpenAIChatModelOptions["clientOptions"];
20
+ }
21
+ /**
22
+ * Http client for interacting with a remote AIGNE server.
23
+ * BaseClient provides a client-side interface that matches the AIGNE API,
24
+ * allowing applications to invoke agents and receive responses from a remote AIGNE instance.
25
+ *
26
+ * @example
27
+ * Here's a simple example of how to use AIGNEClient:
28
+ * {@includeCode ../../test/http-client/http-client.test.ts#example-aigne-client-simple}
29
+ *
30
+ * @example
31
+ * Here's an example of how to use AIGNEClient with streaming response:
32
+ * {@includeCode ../../test/http-client/http-client.test.ts#example-aigne-client-streaming}
33
+ */
34
+ export declare class BaseClient {
35
+ options: BaseClientOptions;
36
+ /**
37
+ * Creates a new AIGNEClient instance.
38
+ *
39
+ * @param options - Configuration options for connecting to the AIGNE server
40
+ */
41
+ constructor(options: BaseClientOptions);
42
+ /**
43
+ * Invokes an agent in non-streaming mode and returns the complete response.
44
+ *
45
+ * @param agent - Name of the agent to invoke
46
+ * @param input - Input message for the agent
47
+ * @param options - Options with streaming mode explicitly set to false or omitted
48
+ * @returns The complete agent response
49
+ *
50
+ * @example
51
+ * Here's a simple example of how to use AIGNEClient:
52
+ * {@includeCode ../../test/http-client/http-client.test.ts#example-aigne-client-simple}
53
+ */
54
+ __invoke<I extends Message, O extends Message>(agent?: string, input?: string | I, options?: BaseClientInvokeOptions & {
55
+ streaming?: false;
56
+ }): Promise<O>;
57
+ /**
58
+ * Invokes an agent with streaming mode enabled and returns a stream of response chunks.
59
+ *
60
+ * @param agent - Name of the agent to invoke
61
+ * @param input - Input message for the agent
62
+ * @param options - Options with streaming mode explicitly set to true
63
+ * @returns A stream of agent response chunks
64
+ *
65
+ * @example
66
+ * Here's an example of how to use AIGNEClient with streaming response:
67
+ * {@includeCode ../../test/http-client/http-client.test.ts#example-aigne-client-streaming}
68
+ */
69
+ __invoke<I extends Message, O extends Message>(agent?: string, input?: string | I, options?: BaseClientInvokeOptions & {
70
+ streaming: true;
71
+ }): Promise<AgentResponseStream<O>>;
72
+ /**
73
+ * Invokes an agent with the given input and options.
74
+ *
75
+ * @param agent - Name of the agent to invoke
76
+ * @param input - Input message for the agent
77
+ * @param options - Options for the invocation
78
+ * @returns Either a complete response or a response stream depending on the streaming option
79
+ */
80
+ __invoke<I extends Message, O extends Message>(agent?: string, input?: string | I, options?: BaseClientInvokeOptions): Promise<AgentResponse<O>>;
81
+ /**
82
+ * Enhanced fetch method that handles error responses from the AIGNE server.
83
+ * This method wraps the standard fetch API to provide better error handling and reporting.
84
+ *
85
+ * @param args - Standard fetch API arguments (url and options)
86
+ * @returns A Response object if the request was successful
87
+ * @throws Error with detailed information if the request failed
88
+ *
89
+ * @private
90
+ */
91
+ fetch(...args: Parameters<typeof globalThis.fetch>): Promise<Response>;
92
+ }
@@ -0,0 +1,101 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BaseClient = void 0;
4
+ const event_stream_js_1 = require("@aigne/core/utils/event-stream.js");
5
+ const type_utils_js_1 = require("@aigne/core/utils/type-utils.js");
6
+ const constants_js_1 = require("../constants.js");
7
+ /**
8
+ * Http client for interacting with a remote AIGNE server.
9
+ * BaseClient provides a client-side interface that matches the AIGNE API,
10
+ * allowing applications to invoke agents and receive responses from a remote AIGNE instance.
11
+ *
12
+ * @example
13
+ * Here's a simple example of how to use AIGNEClient:
14
+ * {@includeCode ../../test/http-client/http-client.test.ts#example-aigne-client-simple}
15
+ *
16
+ * @example
17
+ * Here's an example of how to use AIGNEClient with streaming response:
18
+ * {@includeCode ../../test/http-client/http-client.test.ts#example-aigne-client-streaming}
19
+ */
20
+ class BaseClient {
21
+ options;
22
+ /**
23
+ * Creates a new AIGNEClient instance.
24
+ *
25
+ * @param options - Configuration options for connecting to the AIGNE server
26
+ */
27
+ constructor(options) {
28
+ this.options = options;
29
+ }
30
+ async __invoke(agent, input, options) {
31
+ const model = this.options.modelOptions?.model ?? this.options.model;
32
+ const headers = {
33
+ "Content-Type": "application/json",
34
+ ...options?.fetchOptions?.headers,
35
+ };
36
+ if (this.options?.accessKey) {
37
+ headers["Authorization"] = `Bearer ${this.options.accessKey}`;
38
+ }
39
+ const body = {
40
+ model,
41
+ input,
42
+ agent: agent ?? constants_js_1.ChatModelName,
43
+ options: options && {
44
+ ...(0, type_utils_js_1.omit)(options, "context"),
45
+ userContext: { ...options.userContext },
46
+ memories: [...(options.memories ?? [])],
47
+ modelOptions: this.options.modelOptions,
48
+ clientOptions: this.options.clientOptions,
49
+ },
50
+ };
51
+ const response = await this.fetch(this.options.url, {
52
+ ...options?.fetchOptions,
53
+ method: "POST",
54
+ headers: headers,
55
+ body: JSON.stringify(body),
56
+ });
57
+ // For non-streaming responses, simply parse the JSON response and return it
58
+ if (!options?.streaming) {
59
+ return await response.json();
60
+ }
61
+ // For streaming responses, set up the streaming pipeline
62
+ const stream = response.body;
63
+ if (!stream)
64
+ throw new Error("Response body is not a stream");
65
+ // Process the stream through a series of transforms:
66
+ // 1. Convert bytes to text
67
+ // 2. Parse SSE format into structured events
68
+ // 3. Convert events into a standardized agent response stream
69
+ return stream
70
+ .pipeThrough(new TextDecoderStream())
71
+ .pipeThrough(new event_stream_js_1.EventStreamParser())
72
+ .pipeThrough(new event_stream_js_1.AgentResponseStreamParser());
73
+ }
74
+ /**
75
+ * Enhanced fetch method that handles error responses from the AIGNE server.
76
+ * This method wraps the standard fetch API to provide better error handling and reporting.
77
+ *
78
+ * @param args - Standard fetch API arguments (url and options)
79
+ * @returns A Response object if the request was successful
80
+ * @throws Error with detailed information if the request failed
81
+ *
82
+ * @private
83
+ */
84
+ async fetch(...args) {
85
+ const result = await globalThis.fetch(...args);
86
+ if (!result.ok) {
87
+ let message;
88
+ try {
89
+ const text = await result.text();
90
+ const json = (0, type_utils_js_1.tryOrThrow)(() => JSON.parse(text));
91
+ message = json?.error?.message || text;
92
+ }
93
+ catch {
94
+ // ignore
95
+ }
96
+ throw new Error(`Failed to fetch url ${args[0]} with status ${result.status}: ${message}`);
97
+ }
98
+ return result;
99
+ }
100
+ }
101
+ exports.BaseClient = BaseClient;
@@ -1,27 +1,18 @@
1
1
  import { type Agent, type AgentResponse, type AgentResponseStream, type Context, type ContextEmitEventMap, type ContextEventMap, type ContextUsage, type InvokeOptions, type Message, type MessagePayload, type MessageQueueListener, type Unsubscribe, type UserAgent, type UserContext } from "@aigne/core";
2
2
  import type { Args, Listener } from "@aigne/core/utils/typed-event-emitter.js";
3
+ import { BaseClient, type BaseClientInvokeOptions, type BaseClientOptions } from "./base-client.js";
3
4
  import { ClientAgent, type ClientAgentOptions } from "./client-agent.js";
4
5
  import { ClientChatModel } from "./client-chat-model.js";
5
6
  /**
6
7
  * Configuration options for the AIGNEHTTPClient.
7
8
  */
8
- export interface AIGNEHTTPClientOptions {
9
- /**
10
- * The URL of the AIGNE server to connect to.
11
- * This should point to the base endpoint where the AIGNEServer is hosted.
12
- */
13
- url: string;
9
+ export interface AIGNEHTTPClientOptions extends BaseClientOptions {
14
10
  }
15
11
  /**
16
12
  * Options for invoking an agent through the AIGNEHTTPClient.
17
13
  * Extends the standard AgentInvokeOptions with client-specific options.
18
14
  */
19
- export interface AIGNEHTTPClientInvokeOptions extends InvokeOptions {
20
- /**
21
- * Additional fetch API options to customize the HTTP request.
22
- * These options will be merged with the default options used by the client.
23
- */
24
- fetchOptions?: Partial<RequestInit>;
15
+ export interface AIGNEHTTPClientInvokeOptions extends BaseClientInvokeOptions {
25
16
  }
26
17
  /**
27
18
  * Http client for interacting with a remote AIGNE server.
@@ -36,7 +27,7 @@ export interface AIGNEHTTPClientInvokeOptions extends InvokeOptions {
36
27
  * Here's an example of how to use AIGNEClient with streaming response:
37
28
  * {@includeCode ../../test/http-client/http-client.test.ts#example-aigne-client-streaming}
38
29
  */
39
- export declare class AIGNEHTTPClient<U extends UserContext = UserContext> implements Context<U> {
30
+ export declare class AIGNEHTTPClient<U extends UserContext = UserContext> extends BaseClient implements Context<U> {
40
31
  options: AIGNEHTTPClientOptions;
41
32
  /**
42
33
  * Creates a new AIGNEClient instance.
@@ -123,16 +114,5 @@ export declare class AIGNEHTTPClient<U extends UserContext = UserContext> implem
123
114
  * @returns Either a complete response or a response stream depending on the streaming option
124
115
  */
125
116
  _invoke<I extends Message, O extends Message>(agent: string, input: string | I, options?: AIGNEHTTPClientInvokeOptions): Promise<AgentResponse<O>>;
126
- /**
127
- * Enhanced fetch method that handles error responses from the AIGNE server.
128
- * This method wraps the standard fetch API to provide better error handling and reporting.
129
- *
130
- * @param args - Standard fetch API arguments (url and options)
131
- * @returns A Response object if the request was successful
132
- * @throws Error with detailed information if the request failed
133
- *
134
- * @private
135
- */
136
- fetch(...args: Parameters<typeof globalThis.fetch>): Promise<Response>;
137
117
  getAgent<I extends Message = Message, O extends Message = Message>(options: ClientAgentOptions<I, O>): Promise<ClientAgent<I, O>>;
138
118
  }
@@ -2,9 +2,9 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.AIGNEHTTPClient = void 0;
4
4
  const core_1 = require("@aigne/core");
5
- const event_stream_js_1 = require("@aigne/core/utils/event-stream.js");
6
5
  const type_utils_js_1 = require("@aigne/core/utils/type-utils.js");
7
6
  const uuid_1 = require("uuid");
7
+ const base_client_js_1 = require("./base-client.js");
8
8
  const client_agent_js_1 = require("./client-agent.js");
9
9
  const client_chat_model_js_1 = require("./client-chat-model.js");
10
10
  /**
@@ -20,7 +20,7 @@ const client_chat_model_js_1 = require("./client-chat-model.js");
20
20
  * Here's an example of how to use AIGNEClient with streaming response:
21
21
  * {@includeCode ../../test/http-client/http-client.test.ts#example-aigne-client-streaming}
22
22
  */
23
- class AIGNEHTTPClient {
23
+ class AIGNEHTTPClient extends base_client_js_1.BaseClient {
24
24
  options;
25
25
  /**
26
26
  * Creates a new AIGNEClient instance.
@@ -28,6 +28,7 @@ class AIGNEHTTPClient {
28
28
  * @param options - Configuration options for connecting to the AIGNE server
29
29
  */
30
30
  constructor(options) {
31
+ super(options);
31
32
  this.options = options;
32
33
  }
33
34
  id = (0, uuid_1.v7)();
@@ -81,67 +82,12 @@ class AIGNEHTTPClient {
81
82
  console.error("Method not implemented.");
82
83
  return this;
83
84
  }
84
- async _invoke(agent, input, options) {
85
- // Send the agent invocation request to the AIGNE server
86
- const response = await this.fetch(this.options.url, {
87
- ...options?.fetchOptions,
88
- method: "POST",
89
- headers: {
90
- "Content-Type": "application/json",
91
- ...options?.fetchOptions?.headers,
92
- },
93
- body: JSON.stringify({
94
- agent,
95
- input,
96
- options: options && {
97
- ...(0, type_utils_js_1.omit)(options, "context"),
98
- userContext: { ...this.userContext, ...options.userContext },
99
- memories: [...this.memories, ...(options.memories ?? [])],
100
- },
101
- }),
85
+ async _invoke(agent, input, options = {}) {
86
+ return this.__invoke(agent, input, {
87
+ ...(0, type_utils_js_1.omit)(options, "context"),
88
+ userContext: { ...this.userContext, ...options.userContext },
89
+ memories: [...this.memories, ...(options.memories ?? [])],
102
90
  });
103
- // For non-streaming responses, simply parse the JSON response and return it
104
- if (!options?.streaming) {
105
- return await response.json();
106
- }
107
- // For streaming responses, set up the streaming pipeline
108
- const stream = response.body;
109
- if (!stream)
110
- throw new Error("Response body is not a stream");
111
- // Process the stream through a series of transforms:
112
- // 1. Convert bytes to text
113
- // 2. Parse SSE format into structured events
114
- // 3. Convert events into a standardized agent response stream
115
- return stream
116
- .pipeThrough(new TextDecoderStream())
117
- .pipeThrough(new event_stream_js_1.EventStreamParser())
118
- .pipeThrough(new event_stream_js_1.AgentResponseStreamParser());
119
- }
120
- /**
121
- * Enhanced fetch method that handles error responses from the AIGNE server.
122
- * This method wraps the standard fetch API to provide better error handling and reporting.
123
- *
124
- * @param args - Standard fetch API arguments (url and options)
125
- * @returns A Response object if the request was successful
126
- * @throws Error with detailed information if the request failed
127
- *
128
- * @private
129
- */
130
- async fetch(...args) {
131
- const result = await globalThis.fetch(...args);
132
- if (!result.ok) {
133
- let message;
134
- try {
135
- const text = await result.text();
136
- const json = (0, type_utils_js_1.tryOrThrow)(() => JSON.parse(text));
137
- message = json?.error?.message || text;
138
- }
139
- catch {
140
- // ignore
141
- }
142
- throw new Error(`Failed to fetch url ${args[0]} with status ${result.status}: ${message}`);
143
- }
144
- return result;
145
91
  }
146
92
  async getAgent(options) {
147
93
  return new client_agent_js_1.ClientAgent(this, options);
@@ -1,5 +1,6 @@
1
1
  import { IncomingMessage, ServerResponse } from "node:http";
2
2
  import type { AIGNE, InvokeOptions, UserContext } from "@aigne/core";
3
+ import type { PromiseOrValue } from "@aigne/core/utils/type-utils.js";
3
4
  import { z } from "zod";
4
5
  /**
5
6
  * Schema for validating agent invocation payloads.
@@ -26,55 +27,55 @@ export declare const invokePayloadSchema: z.ZodObject<{
26
27
  content: object;
27
28
  }[] | null | undefined>;
28
29
  }, "strip", z.ZodTypeAny, {
29
- memories?: {
30
- content: object;
31
- }[] | undefined;
32
30
  streaming?: boolean | undefined;
33
31
  returnProgressChunks?: boolean | undefined;
34
32
  userContext?: Record<string, unknown> | undefined;
35
- }, {
36
33
  memories?: {
37
34
  content: object;
38
- }[] | null | undefined;
35
+ }[] | undefined;
36
+ }, {
39
37
  streaming?: boolean | null | undefined;
40
38
  returnProgressChunks?: boolean | null | undefined;
41
39
  userContext?: Record<string, unknown> | null | undefined;
42
- }>>>, {
43
40
  memories?: {
44
41
  content: object;
45
- }[] | undefined;
42
+ }[] | null | undefined;
43
+ }>>>, {
46
44
  streaming?: boolean | undefined;
47
45
  returnProgressChunks?: boolean | undefined;
48
46
  userContext?: Record<string, unknown> | undefined;
49
- } | undefined, {
50
47
  memories?: {
51
48
  content: object;
52
- }[] | null | undefined;
49
+ }[] | undefined;
50
+ } | undefined, {
53
51
  streaming?: boolean | null | undefined;
54
52
  returnProgressChunks?: boolean | null | undefined;
55
53
  userContext?: Record<string, unknown> | null | undefined;
54
+ memories?: {
55
+ content: object;
56
+ }[] | null | undefined;
56
57
  } | null | undefined>;
57
58
  }, "strip", z.ZodTypeAny, {
58
- agent: string;
59
59
  input: Record<string, unknown>;
60
+ agent: string;
60
61
  options?: {
61
- memories?: {
62
- content: object;
63
- }[] | undefined;
64
62
  streaming?: boolean | undefined;
65
63
  returnProgressChunks?: boolean | undefined;
66
64
  userContext?: Record<string, unknown> | undefined;
65
+ memories?: {
66
+ content: object;
67
+ }[] | undefined;
67
68
  } | undefined;
68
69
  }, {
69
- agent: string;
70
70
  input: Record<string, unknown>;
71
+ agent: string;
71
72
  options?: {
72
- memories?: {
73
- content: object;
74
- }[] | null | undefined;
75
73
  streaming?: boolean | null | undefined;
76
74
  returnProgressChunks?: boolean | null | undefined;
77
75
  userContext?: Record<string, unknown> | null | undefined;
76
+ memories?: {
77
+ content: object;
78
+ }[] | null | undefined;
78
79
  } | null | undefined;
79
80
  }>;
80
81
  /**
@@ -94,6 +95,7 @@ export interface AIGNEHTTPServerOptions {
94
95
  maximumBodySize?: string;
95
96
  }
96
97
  export interface AIGNEHTTPServerInvokeOptions<U extends UserContext = UserContext> extends Pick<InvokeOptions<U>, "returnProgressChunks" | "userContext" | "memories"> {
98
+ callback?: (result: Record<string, unknown>) => PromiseOrValue<void>;
97
99
  }
98
100
  /**
99
101
  * AIGNEHTTPServer provides HTTP API access to AIGNE capabilities.
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.AIGNEHTTPServer = exports.invokePayloadSchema = void 0;
7
7
  const node_http_1 = require("node:http");
8
8
  const event_stream_js_1 = require("@aigne/core/utils/event-stream.js");
9
+ const stream_utils_js_1 = require("@aigne/core/utils/stream-utils.js");
9
10
  const type_utils_js_1 = require("@aigne/core/utils/type-utils.js");
10
11
  const content_type_1 = __importDefault(require("content-type"));
11
12
  const raw_body_1 = __importDefault(require("raw-body"));
@@ -82,6 +83,7 @@ class AIGNEHTTPServer {
82
83
  const result = await this._invoke(request, {
83
84
  userContext: opts?.userContext,
84
85
  memories: opts?.memories,
86
+ callback: opts?.callback,
85
87
  });
86
88
  if (response instanceof node_http_1.ServerResponse) {
87
89
  await this._writeResponse(result, response);
@@ -114,6 +116,7 @@ class AIGNEHTTPServer {
114
116
  };
115
117
  if (!streaming) {
116
118
  const result = await aigne.invoke(agent, input, mergedOptions);
119
+ options.callback?.(result);
117
120
  return new Response(JSON.stringify(result), {
118
121
  headers: { "Content-Type": "application/json" },
119
122
  });
@@ -123,7 +126,12 @@ class AIGNEHTTPServer {
123
126
  returnActiveAgent: false,
124
127
  streaming: true,
125
128
  });
126
- return new Response(new event_stream_js_1.AgentResponseStreamSSE(stream), {
129
+ const newStream = (0, stream_utils_js_1.onAgentResponseStreamEnd)(stream, {
130
+ onResult: async (result) => {
131
+ options.callback?.(result);
132
+ },
133
+ });
134
+ return new Response(new event_stream_js_1.AgentResponseStreamSSE(newStream), {
127
135
  headers: {
128
136
  "Content-Type": "text/event-stream",
129
137
  "Cache-Control": "no-cache",
@@ -1 +1,3 @@
1
- {"type": "commonjs"}
1
+ {
2
+ "type": "commonjs"
3
+ }
@@ -0,0 +1,92 @@
1
+ import type { AgentResponse, AgentResponseStream, ChatModelOptions, InvokeOptions, Message } from "@aigne/core";
2
+ import type { OpenAIChatModelOptions } from "@aigne/openai";
3
+ /**
4
+ * Options for invoking an agent through the BaseClient.
5
+ * Extends the standard AgentInvokeOptions with client-specific options.
6
+ */
7
+ export interface BaseClientInvokeOptions extends InvokeOptions {
8
+ /**
9
+ * Additional fetch API options to customize the HTTP request.
10
+ * These options will be merged with the default options used by the client.
11
+ */
12
+ fetchOptions?: Partial<RequestInit>;
13
+ }
14
+ export interface BaseClientOptions {
15
+ url: string;
16
+ accessKey?: string;
17
+ model?: string;
18
+ modelOptions?: ChatModelOptions;
19
+ clientOptions?: OpenAIChatModelOptions["clientOptions"];
20
+ }
21
+ /**
22
+ * Http client for interacting with a remote AIGNE server.
23
+ * BaseClient provides a client-side interface that matches the AIGNE API,
24
+ * allowing applications to invoke agents and receive responses from a remote AIGNE instance.
25
+ *
26
+ * @example
27
+ * Here's a simple example of how to use AIGNEClient:
28
+ * {@includeCode ../../test/http-client/http-client.test.ts#example-aigne-client-simple}
29
+ *
30
+ * @example
31
+ * Here's an example of how to use AIGNEClient with streaming response:
32
+ * {@includeCode ../../test/http-client/http-client.test.ts#example-aigne-client-streaming}
33
+ */
34
+ export declare class BaseClient {
35
+ options: BaseClientOptions;
36
+ /**
37
+ * Creates a new AIGNEClient instance.
38
+ *
39
+ * @param options - Configuration options for connecting to the AIGNE server
40
+ */
41
+ constructor(options: BaseClientOptions);
42
+ /**
43
+ * Invokes an agent in non-streaming mode and returns the complete response.
44
+ *
45
+ * @param agent - Name of the agent to invoke
46
+ * @param input - Input message for the agent
47
+ * @param options - Options with streaming mode explicitly set to false or omitted
48
+ * @returns The complete agent response
49
+ *
50
+ * @example
51
+ * Here's a simple example of how to use AIGNEClient:
52
+ * {@includeCode ../../test/http-client/http-client.test.ts#example-aigne-client-simple}
53
+ */
54
+ __invoke<I extends Message, O extends Message>(agent?: string, input?: string | I, options?: BaseClientInvokeOptions & {
55
+ streaming?: false;
56
+ }): Promise<O>;
57
+ /**
58
+ * Invokes an agent with streaming mode enabled and returns a stream of response chunks.
59
+ *
60
+ * @param agent - Name of the agent to invoke
61
+ * @param input - Input message for the agent
62
+ * @param options - Options with streaming mode explicitly set to true
63
+ * @returns A stream of agent response chunks
64
+ *
65
+ * @example
66
+ * Here's an example of how to use AIGNEClient with streaming response:
67
+ * {@includeCode ../../test/http-client/http-client.test.ts#example-aigne-client-streaming}
68
+ */
69
+ __invoke<I extends Message, O extends Message>(agent?: string, input?: string | I, options?: BaseClientInvokeOptions & {
70
+ streaming: true;
71
+ }): Promise<AgentResponseStream<O>>;
72
+ /**
73
+ * Invokes an agent with the given input and options.
74
+ *
75
+ * @param agent - Name of the agent to invoke
76
+ * @param input - Input message for the agent
77
+ * @param options - Options for the invocation
78
+ * @returns Either a complete response or a response stream depending on the streaming option
79
+ */
80
+ __invoke<I extends Message, O extends Message>(agent?: string, input?: string | I, options?: BaseClientInvokeOptions): Promise<AgentResponse<O>>;
81
+ /**
82
+ * Enhanced fetch method that handles error responses from the AIGNE server.
83
+ * This method wraps the standard fetch API to provide better error handling and reporting.
84
+ *
85
+ * @param args - Standard fetch API arguments (url and options)
86
+ * @returns A Response object if the request was successful
87
+ * @throws Error with detailed information if the request failed
88
+ *
89
+ * @private
90
+ */
91
+ fetch(...args: Parameters<typeof globalThis.fetch>): Promise<Response>;
92
+ }
@@ -1,27 +1,18 @@
1
1
  import { type Agent, type AgentResponse, type AgentResponseStream, type Context, type ContextEmitEventMap, type ContextEventMap, type ContextUsage, type InvokeOptions, type Message, type MessagePayload, type MessageQueueListener, type Unsubscribe, type UserAgent, type UserContext } from "@aigne/core";
2
2
  import type { Args, Listener } from "@aigne/core/utils/typed-event-emitter.js";
3
+ import { BaseClient, type BaseClientInvokeOptions, type BaseClientOptions } from "./base-client.js";
3
4
  import { ClientAgent, type ClientAgentOptions } from "./client-agent.js";
4
5
  import { ClientChatModel } from "./client-chat-model.js";
5
6
  /**
6
7
  * Configuration options for the AIGNEHTTPClient.
7
8
  */
8
- export interface AIGNEHTTPClientOptions {
9
- /**
10
- * The URL of the AIGNE server to connect to.
11
- * This should point to the base endpoint where the AIGNEServer is hosted.
12
- */
13
- url: string;
9
+ export interface AIGNEHTTPClientOptions extends BaseClientOptions {
14
10
  }
15
11
  /**
16
12
  * Options for invoking an agent through the AIGNEHTTPClient.
17
13
  * Extends the standard AgentInvokeOptions with client-specific options.
18
14
  */
19
- export interface AIGNEHTTPClientInvokeOptions extends InvokeOptions {
20
- /**
21
- * Additional fetch API options to customize the HTTP request.
22
- * These options will be merged with the default options used by the client.
23
- */
24
- fetchOptions?: Partial<RequestInit>;
15
+ export interface AIGNEHTTPClientInvokeOptions extends BaseClientInvokeOptions {
25
16
  }
26
17
  /**
27
18
  * Http client for interacting with a remote AIGNE server.
@@ -36,7 +27,7 @@ export interface AIGNEHTTPClientInvokeOptions extends InvokeOptions {
36
27
  * Here's an example of how to use AIGNEClient with streaming response:
37
28
  * {@includeCode ../../test/http-client/http-client.test.ts#example-aigne-client-streaming}
38
29
  */
39
- export declare class AIGNEHTTPClient<U extends UserContext = UserContext> implements Context<U> {
30
+ export declare class AIGNEHTTPClient<U extends UserContext = UserContext> extends BaseClient implements Context<U> {
40
31
  options: AIGNEHTTPClientOptions;
41
32
  /**
42
33
  * Creates a new AIGNEClient instance.
@@ -123,16 +114,5 @@ export declare class AIGNEHTTPClient<U extends UserContext = UserContext> implem
123
114
  * @returns Either a complete response or a response stream depending on the streaming option
124
115
  */
125
116
  _invoke<I extends Message, O extends Message>(agent: string, input: string | I, options?: AIGNEHTTPClientInvokeOptions): Promise<AgentResponse<O>>;
126
- /**
127
- * Enhanced fetch method that handles error responses from the AIGNE server.
128
- * This method wraps the standard fetch API to provide better error handling and reporting.
129
- *
130
- * @param args - Standard fetch API arguments (url and options)
131
- * @returns A Response object if the request was successful
132
- * @throws Error with detailed information if the request failed
133
- *
134
- * @private
135
- */
136
- fetch(...args: Parameters<typeof globalThis.fetch>): Promise<Response>;
137
117
  getAgent<I extends Message = Message, O extends Message = Message>(options: ClientAgentOptions<I, O>): Promise<ClientAgent<I, O>>;
138
118
  }
@@ -1,5 +1,6 @@
1
1
  import { IncomingMessage, ServerResponse } from "node:http";
2
2
  import type { AIGNE, InvokeOptions, UserContext } from "@aigne/core";
3
+ import type { PromiseOrValue } from "@aigne/core/utils/type-utils.js";
3
4
  import { z } from "zod";
4
5
  /**
5
6
  * Schema for validating agent invocation payloads.
@@ -26,55 +27,55 @@ export declare const invokePayloadSchema: z.ZodObject<{
26
27
  content: object;
27
28
  }[] | null | undefined>;
28
29
  }, "strip", z.ZodTypeAny, {
29
- memories?: {
30
- content: object;
31
- }[] | undefined;
32
30
  streaming?: boolean | undefined;
33
31
  returnProgressChunks?: boolean | undefined;
34
32
  userContext?: Record<string, unknown> | undefined;
35
- }, {
36
33
  memories?: {
37
34
  content: object;
38
- }[] | null | undefined;
35
+ }[] | undefined;
36
+ }, {
39
37
  streaming?: boolean | null | undefined;
40
38
  returnProgressChunks?: boolean | null | undefined;
41
39
  userContext?: Record<string, unknown> | null | undefined;
42
- }>>>, {
43
40
  memories?: {
44
41
  content: object;
45
- }[] | undefined;
42
+ }[] | null | undefined;
43
+ }>>>, {
46
44
  streaming?: boolean | undefined;
47
45
  returnProgressChunks?: boolean | undefined;
48
46
  userContext?: Record<string, unknown> | undefined;
49
- } | undefined, {
50
47
  memories?: {
51
48
  content: object;
52
- }[] | null | undefined;
49
+ }[] | undefined;
50
+ } | undefined, {
53
51
  streaming?: boolean | null | undefined;
54
52
  returnProgressChunks?: boolean | null | undefined;
55
53
  userContext?: Record<string, unknown> | null | undefined;
54
+ memories?: {
55
+ content: object;
56
+ }[] | null | undefined;
56
57
  } | null | undefined>;
57
58
  }, "strip", z.ZodTypeAny, {
58
- agent: string;
59
59
  input: Record<string, unknown>;
60
+ agent: string;
60
61
  options?: {
61
- memories?: {
62
- content: object;
63
- }[] | undefined;
64
62
  streaming?: boolean | undefined;
65
63
  returnProgressChunks?: boolean | undefined;
66
64
  userContext?: Record<string, unknown> | undefined;
65
+ memories?: {
66
+ content: object;
67
+ }[] | undefined;
67
68
  } | undefined;
68
69
  }, {
69
- agent: string;
70
70
  input: Record<string, unknown>;
71
+ agent: string;
71
72
  options?: {
72
- memories?: {
73
- content: object;
74
- }[] | null | undefined;
75
73
  streaming?: boolean | null | undefined;
76
74
  returnProgressChunks?: boolean | null | undefined;
77
75
  userContext?: Record<string, unknown> | null | undefined;
76
+ memories?: {
77
+ content: object;
78
+ }[] | null | undefined;
78
79
  } | null | undefined;
79
80
  }>;
80
81
  /**
@@ -94,6 +95,7 @@ export interface AIGNEHTTPServerOptions {
94
95
  maximumBodySize?: string;
95
96
  }
96
97
  export interface AIGNEHTTPServerInvokeOptions<U extends UserContext = UserContext> extends Pick<InvokeOptions<U>, "returnProgressChunks" | "userContext" | "memories"> {
98
+ callback?: (result: Record<string, unknown>) => PromiseOrValue<void>;
97
99
  }
98
100
  /**
99
101
  * AIGNEHTTPServer provides HTTP API access to AIGNE capabilities.
@@ -0,0 +1,92 @@
1
+ import type { AgentResponse, AgentResponseStream, ChatModelOptions, InvokeOptions, Message } from "@aigne/core";
2
+ import type { OpenAIChatModelOptions } from "@aigne/openai";
3
+ /**
4
+ * Options for invoking an agent through the BaseClient.
5
+ * Extends the standard AgentInvokeOptions with client-specific options.
6
+ */
7
+ export interface BaseClientInvokeOptions extends InvokeOptions {
8
+ /**
9
+ * Additional fetch API options to customize the HTTP request.
10
+ * These options will be merged with the default options used by the client.
11
+ */
12
+ fetchOptions?: Partial<RequestInit>;
13
+ }
14
+ export interface BaseClientOptions {
15
+ url: string;
16
+ accessKey?: string;
17
+ model?: string;
18
+ modelOptions?: ChatModelOptions;
19
+ clientOptions?: OpenAIChatModelOptions["clientOptions"];
20
+ }
21
+ /**
22
+ * Http client for interacting with a remote AIGNE server.
23
+ * BaseClient provides a client-side interface that matches the AIGNE API,
24
+ * allowing applications to invoke agents and receive responses from a remote AIGNE instance.
25
+ *
26
+ * @example
27
+ * Here's a simple example of how to use AIGNEClient:
28
+ * {@includeCode ../../test/http-client/http-client.test.ts#example-aigne-client-simple}
29
+ *
30
+ * @example
31
+ * Here's an example of how to use AIGNEClient with streaming response:
32
+ * {@includeCode ../../test/http-client/http-client.test.ts#example-aigne-client-streaming}
33
+ */
34
+ export declare class BaseClient {
35
+ options: BaseClientOptions;
36
+ /**
37
+ * Creates a new AIGNEClient instance.
38
+ *
39
+ * @param options - Configuration options for connecting to the AIGNE server
40
+ */
41
+ constructor(options: BaseClientOptions);
42
+ /**
43
+ * Invokes an agent in non-streaming mode and returns the complete response.
44
+ *
45
+ * @param agent - Name of the agent to invoke
46
+ * @param input - Input message for the agent
47
+ * @param options - Options with streaming mode explicitly set to false or omitted
48
+ * @returns The complete agent response
49
+ *
50
+ * @example
51
+ * Here's a simple example of how to use AIGNEClient:
52
+ * {@includeCode ../../test/http-client/http-client.test.ts#example-aigne-client-simple}
53
+ */
54
+ __invoke<I extends Message, O extends Message>(agent?: string, input?: string | I, options?: BaseClientInvokeOptions & {
55
+ streaming?: false;
56
+ }): Promise<O>;
57
+ /**
58
+ * Invokes an agent with streaming mode enabled and returns a stream of response chunks.
59
+ *
60
+ * @param agent - Name of the agent to invoke
61
+ * @param input - Input message for the agent
62
+ * @param options - Options with streaming mode explicitly set to true
63
+ * @returns A stream of agent response chunks
64
+ *
65
+ * @example
66
+ * Here's an example of how to use AIGNEClient with streaming response:
67
+ * {@includeCode ../../test/http-client/http-client.test.ts#example-aigne-client-streaming}
68
+ */
69
+ __invoke<I extends Message, O extends Message>(agent?: string, input?: string | I, options?: BaseClientInvokeOptions & {
70
+ streaming: true;
71
+ }): Promise<AgentResponseStream<O>>;
72
+ /**
73
+ * Invokes an agent with the given input and options.
74
+ *
75
+ * @param agent - Name of the agent to invoke
76
+ * @param input - Input message for the agent
77
+ * @param options - Options for the invocation
78
+ * @returns Either a complete response or a response stream depending on the streaming option
79
+ */
80
+ __invoke<I extends Message, O extends Message>(agent?: string, input?: string | I, options?: BaseClientInvokeOptions): Promise<AgentResponse<O>>;
81
+ /**
82
+ * Enhanced fetch method that handles error responses from the AIGNE server.
83
+ * This method wraps the standard fetch API to provide better error handling and reporting.
84
+ *
85
+ * @param args - Standard fetch API arguments (url and options)
86
+ * @returns A Response object if the request was successful
87
+ * @throws Error with detailed information if the request failed
88
+ *
89
+ * @private
90
+ */
91
+ fetch(...args: Parameters<typeof globalThis.fetch>): Promise<Response>;
92
+ }
@@ -0,0 +1,97 @@
1
+ import { AgentResponseStreamParser, EventStreamParser } from "@aigne/core/utils/event-stream.js";
2
+ import { omit, tryOrThrow } from "@aigne/core/utils/type-utils.js";
3
+ import { ChatModelName } from "../constants.js";
4
+ /**
5
+ * Http client for interacting with a remote AIGNE server.
6
+ * BaseClient provides a client-side interface that matches the AIGNE API,
7
+ * allowing applications to invoke agents and receive responses from a remote AIGNE instance.
8
+ *
9
+ * @example
10
+ * Here's a simple example of how to use AIGNEClient:
11
+ * {@includeCode ../../test/http-client/http-client.test.ts#example-aigne-client-simple}
12
+ *
13
+ * @example
14
+ * Here's an example of how to use AIGNEClient with streaming response:
15
+ * {@includeCode ../../test/http-client/http-client.test.ts#example-aigne-client-streaming}
16
+ */
17
+ export class BaseClient {
18
+ options;
19
+ /**
20
+ * Creates a new AIGNEClient instance.
21
+ *
22
+ * @param options - Configuration options for connecting to the AIGNE server
23
+ */
24
+ constructor(options) {
25
+ this.options = options;
26
+ }
27
+ async __invoke(agent, input, options) {
28
+ const model = this.options.modelOptions?.model ?? this.options.model;
29
+ const headers = {
30
+ "Content-Type": "application/json",
31
+ ...options?.fetchOptions?.headers,
32
+ };
33
+ if (this.options?.accessKey) {
34
+ headers["Authorization"] = `Bearer ${this.options.accessKey}`;
35
+ }
36
+ const body = {
37
+ model,
38
+ input,
39
+ agent: agent ?? ChatModelName,
40
+ options: options && {
41
+ ...omit(options, "context"),
42
+ userContext: { ...options.userContext },
43
+ memories: [...(options.memories ?? [])],
44
+ modelOptions: this.options.modelOptions,
45
+ clientOptions: this.options.clientOptions,
46
+ },
47
+ };
48
+ const response = await this.fetch(this.options.url, {
49
+ ...options?.fetchOptions,
50
+ method: "POST",
51
+ headers: headers,
52
+ body: JSON.stringify(body),
53
+ });
54
+ // For non-streaming responses, simply parse the JSON response and return it
55
+ if (!options?.streaming) {
56
+ return await response.json();
57
+ }
58
+ // For streaming responses, set up the streaming pipeline
59
+ const stream = response.body;
60
+ if (!stream)
61
+ throw new Error("Response body is not a stream");
62
+ // Process the stream through a series of transforms:
63
+ // 1. Convert bytes to text
64
+ // 2. Parse SSE format into structured events
65
+ // 3. Convert events into a standardized agent response stream
66
+ return stream
67
+ .pipeThrough(new TextDecoderStream())
68
+ .pipeThrough(new EventStreamParser())
69
+ .pipeThrough(new AgentResponseStreamParser());
70
+ }
71
+ /**
72
+ * Enhanced fetch method that handles error responses from the AIGNE server.
73
+ * This method wraps the standard fetch API to provide better error handling and reporting.
74
+ *
75
+ * @param args - Standard fetch API arguments (url and options)
76
+ * @returns A Response object if the request was successful
77
+ * @throws Error with detailed information if the request failed
78
+ *
79
+ * @private
80
+ */
81
+ async fetch(...args) {
82
+ const result = await globalThis.fetch(...args);
83
+ if (!result.ok) {
84
+ let message;
85
+ try {
86
+ const text = await result.text();
87
+ const json = tryOrThrow(() => JSON.parse(text));
88
+ message = json?.error?.message || text;
89
+ }
90
+ catch {
91
+ // ignore
92
+ }
93
+ throw new Error(`Failed to fetch url ${args[0]} with status ${result.status}: ${message}`);
94
+ }
95
+ return result;
96
+ }
97
+ }
@@ -1,27 +1,18 @@
1
1
  import { type Agent, type AgentResponse, type AgentResponseStream, type Context, type ContextEmitEventMap, type ContextEventMap, type ContextUsage, type InvokeOptions, type Message, type MessagePayload, type MessageQueueListener, type Unsubscribe, type UserAgent, type UserContext } from "@aigne/core";
2
2
  import type { Args, Listener } from "@aigne/core/utils/typed-event-emitter.js";
3
+ import { BaseClient, type BaseClientInvokeOptions, type BaseClientOptions } from "./base-client.js";
3
4
  import { ClientAgent, type ClientAgentOptions } from "./client-agent.js";
4
5
  import { ClientChatModel } from "./client-chat-model.js";
5
6
  /**
6
7
  * Configuration options for the AIGNEHTTPClient.
7
8
  */
8
- export interface AIGNEHTTPClientOptions {
9
- /**
10
- * The URL of the AIGNE server to connect to.
11
- * This should point to the base endpoint where the AIGNEServer is hosted.
12
- */
13
- url: string;
9
+ export interface AIGNEHTTPClientOptions extends BaseClientOptions {
14
10
  }
15
11
  /**
16
12
  * Options for invoking an agent through the AIGNEHTTPClient.
17
13
  * Extends the standard AgentInvokeOptions with client-specific options.
18
14
  */
19
- export interface AIGNEHTTPClientInvokeOptions extends InvokeOptions {
20
- /**
21
- * Additional fetch API options to customize the HTTP request.
22
- * These options will be merged with the default options used by the client.
23
- */
24
- fetchOptions?: Partial<RequestInit>;
15
+ export interface AIGNEHTTPClientInvokeOptions extends BaseClientInvokeOptions {
25
16
  }
26
17
  /**
27
18
  * Http client for interacting with a remote AIGNE server.
@@ -36,7 +27,7 @@ export interface AIGNEHTTPClientInvokeOptions extends InvokeOptions {
36
27
  * Here's an example of how to use AIGNEClient with streaming response:
37
28
  * {@includeCode ../../test/http-client/http-client.test.ts#example-aigne-client-streaming}
38
29
  */
39
- export declare class AIGNEHTTPClient<U extends UserContext = UserContext> implements Context<U> {
30
+ export declare class AIGNEHTTPClient<U extends UserContext = UserContext> extends BaseClient implements Context<U> {
40
31
  options: AIGNEHTTPClientOptions;
41
32
  /**
42
33
  * Creates a new AIGNEClient instance.
@@ -123,16 +114,5 @@ export declare class AIGNEHTTPClient<U extends UserContext = UserContext> implem
123
114
  * @returns Either a complete response or a response stream depending on the streaming option
124
115
  */
125
116
  _invoke<I extends Message, O extends Message>(agent: string, input: string | I, options?: AIGNEHTTPClientInvokeOptions): Promise<AgentResponse<O>>;
126
- /**
127
- * Enhanced fetch method that handles error responses from the AIGNE server.
128
- * This method wraps the standard fetch API to provide better error handling and reporting.
129
- *
130
- * @param args - Standard fetch API arguments (url and options)
131
- * @returns A Response object if the request was successful
132
- * @throws Error with detailed information if the request failed
133
- *
134
- * @private
135
- */
136
- fetch(...args: Parameters<typeof globalThis.fetch>): Promise<Response>;
137
117
  getAgent<I extends Message = Message, O extends Message = Message>(options: ClientAgentOptions<I, O>): Promise<ClientAgent<I, O>>;
138
118
  }
@@ -1,7 +1,7 @@
1
1
  import { newEmptyContextUsage, } from "@aigne/core";
2
- import { AgentResponseStreamParser, EventStreamParser } from "@aigne/core/utils/event-stream.js";
3
- import { omit, tryOrThrow } from "@aigne/core/utils/type-utils.js";
2
+ import { omit } from "@aigne/core/utils/type-utils.js";
4
3
  import { v7 } from "uuid";
4
+ import { BaseClient } from "./base-client.js";
5
5
  import { ClientAgent } from "./client-agent.js";
6
6
  import { ClientChatModel } from "./client-chat-model.js";
7
7
  /**
@@ -17,7 +17,7 @@ import { ClientChatModel } from "./client-chat-model.js";
17
17
  * Here's an example of how to use AIGNEClient with streaming response:
18
18
  * {@includeCode ../../test/http-client/http-client.test.ts#example-aigne-client-streaming}
19
19
  */
20
- export class AIGNEHTTPClient {
20
+ export class AIGNEHTTPClient extends BaseClient {
21
21
  options;
22
22
  /**
23
23
  * Creates a new AIGNEClient instance.
@@ -25,6 +25,7 @@ export class AIGNEHTTPClient {
25
25
  * @param options - Configuration options for connecting to the AIGNE server
26
26
  */
27
27
  constructor(options) {
28
+ super(options);
28
29
  this.options = options;
29
30
  }
30
31
  id = v7();
@@ -78,67 +79,12 @@ export class AIGNEHTTPClient {
78
79
  console.error("Method not implemented.");
79
80
  return this;
80
81
  }
81
- async _invoke(agent, input, options) {
82
- // Send the agent invocation request to the AIGNE server
83
- const response = await this.fetch(this.options.url, {
84
- ...options?.fetchOptions,
85
- method: "POST",
86
- headers: {
87
- "Content-Type": "application/json",
88
- ...options?.fetchOptions?.headers,
89
- },
90
- body: JSON.stringify({
91
- agent,
92
- input,
93
- options: options && {
94
- ...omit(options, "context"),
95
- userContext: { ...this.userContext, ...options.userContext },
96
- memories: [...this.memories, ...(options.memories ?? [])],
97
- },
98
- }),
82
+ async _invoke(agent, input, options = {}) {
83
+ return this.__invoke(agent, input, {
84
+ ...omit(options, "context"),
85
+ userContext: { ...this.userContext, ...options.userContext },
86
+ memories: [...this.memories, ...(options.memories ?? [])],
99
87
  });
100
- // For non-streaming responses, simply parse the JSON response and return it
101
- if (!options?.streaming) {
102
- return await response.json();
103
- }
104
- // For streaming responses, set up the streaming pipeline
105
- const stream = response.body;
106
- if (!stream)
107
- throw new Error("Response body is not a stream");
108
- // Process the stream through a series of transforms:
109
- // 1. Convert bytes to text
110
- // 2. Parse SSE format into structured events
111
- // 3. Convert events into a standardized agent response stream
112
- return stream
113
- .pipeThrough(new TextDecoderStream())
114
- .pipeThrough(new EventStreamParser())
115
- .pipeThrough(new AgentResponseStreamParser());
116
- }
117
- /**
118
- * Enhanced fetch method that handles error responses from the AIGNE server.
119
- * This method wraps the standard fetch API to provide better error handling and reporting.
120
- *
121
- * @param args - Standard fetch API arguments (url and options)
122
- * @returns A Response object if the request was successful
123
- * @throws Error with detailed information if the request failed
124
- *
125
- * @private
126
- */
127
- async fetch(...args) {
128
- const result = await globalThis.fetch(...args);
129
- if (!result.ok) {
130
- let message;
131
- try {
132
- const text = await result.text();
133
- const json = tryOrThrow(() => JSON.parse(text));
134
- message = json?.error?.message || text;
135
- }
136
- catch {
137
- // ignore
138
- }
139
- throw new Error(`Failed to fetch url ${args[0]} with status ${result.status}: ${message}`);
140
- }
141
- return result;
142
88
  }
143
89
  async getAgent(options) {
144
90
  return new ClientAgent(this, options);
@@ -1,5 +1,6 @@
1
1
  import { IncomingMessage, ServerResponse } from "node:http";
2
2
  import type { AIGNE, InvokeOptions, UserContext } from "@aigne/core";
3
+ import type { PromiseOrValue } from "@aigne/core/utils/type-utils.js";
3
4
  import { z } from "zod";
4
5
  /**
5
6
  * Schema for validating agent invocation payloads.
@@ -26,55 +27,55 @@ export declare const invokePayloadSchema: z.ZodObject<{
26
27
  content: object;
27
28
  }[] | null | undefined>;
28
29
  }, "strip", z.ZodTypeAny, {
29
- memories?: {
30
- content: object;
31
- }[] | undefined;
32
30
  streaming?: boolean | undefined;
33
31
  returnProgressChunks?: boolean | undefined;
34
32
  userContext?: Record<string, unknown> | undefined;
35
- }, {
36
33
  memories?: {
37
34
  content: object;
38
- }[] | null | undefined;
35
+ }[] | undefined;
36
+ }, {
39
37
  streaming?: boolean | null | undefined;
40
38
  returnProgressChunks?: boolean | null | undefined;
41
39
  userContext?: Record<string, unknown> | null | undefined;
42
- }>>>, {
43
40
  memories?: {
44
41
  content: object;
45
- }[] | undefined;
42
+ }[] | null | undefined;
43
+ }>>>, {
46
44
  streaming?: boolean | undefined;
47
45
  returnProgressChunks?: boolean | undefined;
48
46
  userContext?: Record<string, unknown> | undefined;
49
- } | undefined, {
50
47
  memories?: {
51
48
  content: object;
52
- }[] | null | undefined;
49
+ }[] | undefined;
50
+ } | undefined, {
53
51
  streaming?: boolean | null | undefined;
54
52
  returnProgressChunks?: boolean | null | undefined;
55
53
  userContext?: Record<string, unknown> | null | undefined;
54
+ memories?: {
55
+ content: object;
56
+ }[] | null | undefined;
56
57
  } | null | undefined>;
57
58
  }, "strip", z.ZodTypeAny, {
58
- agent: string;
59
59
  input: Record<string, unknown>;
60
+ agent: string;
60
61
  options?: {
61
- memories?: {
62
- content: object;
63
- }[] | undefined;
64
62
  streaming?: boolean | undefined;
65
63
  returnProgressChunks?: boolean | undefined;
66
64
  userContext?: Record<string, unknown> | undefined;
65
+ memories?: {
66
+ content: object;
67
+ }[] | undefined;
67
68
  } | undefined;
68
69
  }, {
69
- agent: string;
70
70
  input: Record<string, unknown>;
71
+ agent: string;
71
72
  options?: {
72
- memories?: {
73
- content: object;
74
- }[] | null | undefined;
75
73
  streaming?: boolean | null | undefined;
76
74
  returnProgressChunks?: boolean | null | undefined;
77
75
  userContext?: Record<string, unknown> | null | undefined;
76
+ memories?: {
77
+ content: object;
78
+ }[] | null | undefined;
78
79
  } | null | undefined;
79
80
  }>;
80
81
  /**
@@ -94,6 +95,7 @@ export interface AIGNEHTTPServerOptions {
94
95
  maximumBodySize?: string;
95
96
  }
96
97
  export interface AIGNEHTTPServerInvokeOptions<U extends UserContext = UserContext> extends Pick<InvokeOptions<U>, "returnProgressChunks" | "userContext" | "memories"> {
98
+ callback?: (result: Record<string, unknown>) => PromiseOrValue<void>;
97
99
  }
98
100
  /**
99
101
  * AIGNEHTTPServer provides HTTP API access to AIGNE capabilities.
@@ -1,5 +1,6 @@
1
1
  import { IncomingMessage, ServerResponse } from "node:http";
2
2
  import { AgentResponseStreamSSE } from "@aigne/core/utils/event-stream.js";
3
+ import { onAgentResponseStreamEnd } from "@aigne/core/utils/stream-utils.js";
3
4
  import { checkArguments, isRecord, tryOrThrow } from "@aigne/core/utils/type-utils.js";
4
5
  import contentType from "content-type";
5
6
  import getRawBody from "raw-body";
@@ -76,6 +77,7 @@ export class AIGNEHTTPServer {
76
77
  const result = await this._invoke(request, {
77
78
  userContext: opts?.userContext,
78
79
  memories: opts?.memories,
80
+ callback: opts?.callback,
79
81
  });
80
82
  if (response instanceof ServerResponse) {
81
83
  await this._writeResponse(result, response);
@@ -108,6 +110,7 @@ export class AIGNEHTTPServer {
108
110
  };
109
111
  if (!streaming) {
110
112
  const result = await aigne.invoke(agent, input, mergedOptions);
113
+ options.callback?.(result);
111
114
  return new Response(JSON.stringify(result), {
112
115
  headers: { "Content-Type": "application/json" },
113
116
  });
@@ -117,7 +120,12 @@ export class AIGNEHTTPServer {
117
120
  returnActiveAgent: false,
118
121
  streaming: true,
119
122
  });
120
- return new Response(new AgentResponseStreamSSE(stream), {
123
+ const newStream = onAgentResponseStreamEnd(stream, {
124
+ onResult: async (result) => {
125
+ options.callback?.(result);
126
+ },
127
+ });
128
+ return new Response(new AgentResponseStreamSSE(newStream), {
121
129
  headers: {
122
130
  "Content-Type": "text/event-stream",
123
131
  "Cache-Control": "no-cache",
@@ -1 +1,3 @@
1
- {"type": "module"}
1
+ {
2
+ "type": "module"
3
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aigne/transport",
3
- "version": "0.9.6",
3
+ "version": "0.10.2",
4
4
  "description": "AIGNE Transport SDK providing HTTP client and server implementations for communication between AIGNE components",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -39,7 +39,7 @@
39
39
  }
40
40
  },
41
41
  "dependencies": {
42
- "@aigne/openai": "^0.9.2"
42
+ "@aigne/openai": "^0.10.2"
43
43
  },
44
44
  "devDependencies": {
45
45
  "@types/bun": "^1.2.18",
@@ -54,9 +54,10 @@
54
54
  "rimraf": "^6.0.1",
55
55
  "typescript": "^5.8.3",
56
56
  "uuid": "^11.1.0",
57
- "@aigne/agent-library": "^1.20.5",
58
- "@aigne/test-utils": "^0.5.7",
59
- "@aigne/core": "^1.33.2"
57
+ "@aigne/agent-library": "^1.21.2",
58
+ "@aigne/core": "^1.36.0",
59
+ "@aigne/default-memory": "^1.0.2",
60
+ "@aigne/test-utils": "^0.5.10"
60
61
  },
61
62
  "scripts": {
62
63
  "lint": "tsc --noEmit",
@@ -64,6 +65,6 @@
64
65
  "clean": "rimraf lib test/coverage",
65
66
  "test": "bun test",
66
67
  "test:coverage": "bun test --coverage --coverage-reporter=lcov --coverage-reporter=text",
67
- "postbuild": "echo '{\"type\": \"module\"}' > lib/esm/package.json && echo '{\"type\": \"commonjs\"}' > lib/cjs/package.json"
68
+ "postbuild": "node ../../scripts/post-build-lib.mjs"
68
69
  }
69
70
  }