@aigne/transport 0.2.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,34 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.3.1](https://github.com/AIGNE-io/aigne-framework/compare/transport-v0.3.0...transport-v0.3.1) (2025-05-30)
4
+
5
+
6
+ ### Dependencies
7
+
8
+ * The following workspace dependencies were updated
9
+ * dependencies
10
+ * @aigne/openai bumped to 0.2.2
11
+ * devDependencies
12
+ * @aigne/core bumped to 1.18.1
13
+ * @aigne/test-utils bumped to 0.3.3
14
+
15
+ ## [0.3.0](https://github.com/AIGNE-io/aigne-framework/compare/transport-v0.2.0...transport-v0.3.0) (2025-05-29)
16
+
17
+
18
+ ### Features
19
+
20
+ * add memory agents support for client agent ([#139](https://github.com/AIGNE-io/aigne-framework/issues/139)) ([57044fa](https://github.com/AIGNE-io/aigne-framework/commit/57044fa87b8abcba395cd05f941d6d312ab65764))
21
+
22
+
23
+ ### Dependencies
24
+
25
+ * The following workspace dependencies were updated
26
+ * dependencies
27
+ * @aigne/openai bumped to 0.2.1
28
+ * devDependencies
29
+ * @aigne/core bumped to 1.18.0
30
+ * @aigne/test-utils bumped to 0.3.2
31
+
3
32
  ## [0.2.0](https://github.com/AIGNE-io/aigne-framework/compare/transport-v0.1.0...transport-v0.2.0) (2025-05-25)
4
33
 
5
34
 
@@ -0,0 +1,20 @@
1
+ import { Agent, type AgentInvokeOptions, type AgentOptions, type AgentProcessResult, type AgentResponse, type AgentResponseStream, type Message } from "@aigne/core";
2
+ import type { MemoryAgent } from "@aigne/core/memory/memory.js";
3
+ import type { PromiseOrValue } from "@aigne/core/utils/type-utils.js";
4
+ import type { AIGNEHTTPClient } from "./client.js";
5
+ export interface ClientAgentOptions<I extends Message = Message, O extends Message = Message> extends Required<Pick<AgentOptions<I, O>, "name">> {
6
+ memory?: MemoryAgent | MemoryAgent[];
7
+ }
8
+ export declare class ClientAgent<I extends Message = Message, O extends Message = Message> extends Agent<I, O> {
9
+ client: AIGNEHTTPClient;
10
+ constructor(client: AIGNEHTTPClient, options: ClientAgentOptions<I, O>);
11
+ invoke(input: string | I, options?: Partial<AgentInvokeOptions> & {
12
+ streaming?: false;
13
+ }): Promise<O>;
14
+ invoke(input: string | I, options: Partial<AgentInvokeOptions> & {
15
+ streaming: true;
16
+ }): Promise<AgentResponseStream<O>>;
17
+ invoke(input: string | I, options?: Partial<AgentInvokeOptions>): Promise<AgentResponse<O>>;
18
+ process(_input: I, _options: AgentInvokeOptions): PromiseOrValue<AgentProcessResult<O>>;
19
+ postprocess(input: I, output: O, options: AgentInvokeOptions): Promise<void>;
20
+ }
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ClientAgent = void 0;
4
+ const core_1 = require("@aigne/core");
5
+ const stream_utils_js_1 = require("@aigne/core/utils/stream-utils.js");
6
+ class ClientAgent extends core_1.Agent {
7
+ client;
8
+ constructor(client, options) {
9
+ super(options);
10
+ this.client = client;
11
+ }
12
+ async invoke(input, options) {
13
+ const memories = await this.retrieveMemories({ search: input }, { ...options, context: this.client });
14
+ const result = await this.client._invoke(this.name, input, {
15
+ ...options,
16
+ returnActiveAgent: false,
17
+ memories,
18
+ });
19
+ if (!(result instanceof ReadableStream)) {
20
+ await this.postprocess((0, core_1.createMessage)(input), result, {
21
+ ...options,
22
+ context: this.client,
23
+ });
24
+ return result;
25
+ }
26
+ return (0, stream_utils_js_1.onAgentResponseStreamEnd)(result, async (result) => {
27
+ await this.postprocess((0, core_1.createMessage)(input), result, {
28
+ ...options,
29
+ context: this.client,
30
+ });
31
+ });
32
+ }
33
+ process(_input, _options) {
34
+ throw new Error("Method not implemented.");
35
+ }
36
+ async postprocess(input, output, options) {
37
+ await this.recordMemories({
38
+ content: [
39
+ { role: "user", content: input },
40
+ { role: "agent", content: (0, core_1.replaceTransferAgentToName)(output), source: this.name },
41
+ ],
42
+ }, options);
43
+ }
44
+ }
45
+ exports.ClientAgent = ClientAgent;
@@ -1,7 +1,6 @@
1
- /**
2
- * Client module used to interact with the AIGNE framework.
3
- */
4
- import type { AgentInvokeOptions, AgentResponse, AgentResponseStream, Message } from "@aigne/core";
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
+ import type { Args, Listener } from "@aigne/core/utils/typed-event-emtter.js";
3
+ import { ClientAgent, type ClientAgentOptions } from "./client-agent.js";
5
4
  /**
6
5
  * Configuration options for the AIGNEHTTPClient.
7
6
  */
@@ -16,7 +15,7 @@ export interface AIGNEHTTPClientOptions {
16
15
  * Options for invoking an agent through the AIGNEHTTPClient.
17
16
  * Extends the standard AgentInvokeOptions with client-specific options.
18
17
  */
19
- export interface AIGNEHTTPClientInvokeOptions extends Omit<AgentInvokeOptions, "context"> {
18
+ export interface AIGNEHTTPClientInvokeOptions extends InvokeOptions {
20
19
  /**
21
20
  * Additional fetch API options to customize the HTTP request.
22
21
  * These options will be merged with the default options used by the client.
@@ -36,7 +35,7 @@ export interface AIGNEHTTPClientInvokeOptions extends Omit<AgentInvokeOptions, "
36
35
  * Here's an example of how to use AIGNEClient with streaming response:
37
36
  * {@includeCode ../../test/http-client/http-client.test.ts#example-aigne-client-streaming}
38
37
  */
39
- export declare class AIGNEHTTPClient {
38
+ export declare class AIGNEHTTPClient<U extends UserContext = UserContext> implements Context<U> {
40
39
  options: AIGNEHTTPClientOptions;
41
40
  /**
42
41
  * Creates a new AIGNEClient instance.
@@ -44,6 +43,42 @@ export declare class AIGNEHTTPClient {
44
43
  * @param options - Configuration options for connecting to the AIGNE server
45
44
  */
46
45
  constructor(options: AIGNEHTTPClientOptions);
46
+ usage: ContextUsage;
47
+ userContext: U;
48
+ invoke<I extends Message, O extends Message>(agent: Agent<I, O> | string): UserAgent<I, O>;
49
+ invoke<I extends Message, O extends Message>(agent: Agent<I, O> | string, message: I | string, options: AIGNEHTTPClientInvokeOptions & {
50
+ returnActiveAgent: true;
51
+ streaming?: false;
52
+ }): Promise<[O, Agent]>;
53
+ invoke<I extends Message, O extends Message>(agent: Agent<I, O> | string, message: I | string, options: AIGNEHTTPClientInvokeOptions & {
54
+ returnActiveAgent: true;
55
+ streaming: true;
56
+ }): Promise<[AgentResponseStream<O>, Promise<Agent>]>;
57
+ invoke<I extends Message, O extends Message>(agent: Agent<I, O> | string, message: I | string, options?: AIGNEHTTPClientInvokeOptions & {
58
+ returnActiveAgent?: false;
59
+ streaming?: false;
60
+ }): Promise<O>;
61
+ invoke<I extends Message, O extends Message>(agent: Agent<I, O> | string, message: I | string, options: AIGNEHTTPClientInvokeOptions & {
62
+ returnActiveAgent?: false;
63
+ streaming: true;
64
+ }): Promise<AgentResponseStream<O>>;
65
+ invoke<I extends Message, O extends Message>(agent: Agent<I, O> | string, message: I | string, options: AIGNEHTTPClientInvokeOptions & {
66
+ returnActiveAgent?: false;
67
+ }): Promise<O | AgentResponseStream<O>>;
68
+ invoke<I extends Message, O extends Message>(agent: Agent<I, O> | string, message?: I | string, options?: AIGNEHTTPClientInvokeOptions): UserAgent<I, O> | Promise<AgentResponse<O> | [AgentResponse<O>, Agent]>;
69
+ publish(_topic: string | string[], _payload: Omit<MessagePayload, "context"> | Message | string, _options?: InvokeOptions): void;
70
+ subscribe(topic: string | string[], listener?: undefined): Promise<MessagePayload>;
71
+ subscribe(topic: string | string[], listener: MessageQueueListener): Unsubscribe;
72
+ subscribe(topic: string | string[], listener?: MessageQueueListener): Unsubscribe | Promise<MessagePayload>;
73
+ subscribe(topic: string | string[], listener?: MessageQueueListener): Unsubscribe | Promise<MessagePayload>;
74
+ unsubscribe(_topic: string | string[], _listener: MessageQueueListener): void;
75
+ newContext(_options?: {
76
+ reset?: boolean;
77
+ }): Context;
78
+ emit<K extends keyof ContextEventMap>(_eventName: K, ..._args: Args<K, ContextEmitEventMap>): boolean;
79
+ on<K extends keyof ContextEventMap>(_eventName: K, _listener: Listener<K, ContextEventMap>): this;
80
+ once<K extends keyof ContextEventMap>(_eventName: K, _listener: Listener<K, ContextEventMap>): this;
81
+ off<K extends keyof ContextEventMap>(_eventName: K, _listener: Listener<K, ContextEventMap>): this;
47
82
  /**
48
83
  * Invokes an agent in non-streaming mode and returns the complete response.
49
84
  *
@@ -56,7 +91,7 @@ export declare class AIGNEHTTPClient {
56
91
  * Here's a simple example of how to use AIGNEClient:
57
92
  * {@includeCode ../../test/http-client/http-client.test.ts#example-aigne-client-simple}
58
93
  */
59
- invoke<I extends Message, O extends Message>(agent: string, input: string | I, options?: AIGNEHTTPClientInvokeOptions & {
94
+ _invoke<I extends Message, O extends Message>(agent: string, input: string | I, options?: AIGNEHTTPClientInvokeOptions & {
60
95
  streaming?: false;
61
96
  }): Promise<O>;
62
97
  /**
@@ -71,7 +106,7 @@ export declare class AIGNEHTTPClient {
71
106
  * Here's an example of how to use AIGNEClient with streaming response:
72
107
  * {@includeCode ../../test/http-client/http-client.test.ts#example-aigne-client-streaming}
73
108
  */
74
- invoke<I extends Message, O extends Message>(agent: string, input: string | I, options: AIGNEHTTPClientInvokeOptions & {
109
+ _invoke<I extends Message, O extends Message>(agent: string, input: string | I, options: AIGNEHTTPClientInvokeOptions & {
75
110
  streaming: true;
76
111
  }): Promise<AgentResponseStream<O>>;
77
112
  /**
@@ -82,7 +117,7 @@ export declare class AIGNEHTTPClient {
82
117
  * @param options - Options for the invocation
83
118
  * @returns Either a complete response or a response stream depending on the streaming option
84
119
  */
85
- invoke<I extends Message, O extends Message>(agent: string, input: string | I, options?: AIGNEHTTPClientInvokeOptions): Promise<AgentResponse<O>>;
120
+ _invoke<I extends Message, O extends Message>(agent: string, input: string | I, options?: AIGNEHTTPClientInvokeOptions): Promise<AgentResponse<O>>;
86
121
  /**
87
122
  * Enhanced fetch method that handles error responses from the AIGNE server.
88
123
  * This method wraps the standard fetch API to provide better error handling and reporting.
@@ -94,4 +129,5 @@ export declare class AIGNEHTTPClient {
94
129
  * @private
95
130
  */
96
131
  fetch(...args: Parameters<typeof globalThis.fetch>): Promise<Response>;
132
+ getAgent<I extends Message = Message, O extends Message = Message>(options: ClientAgentOptions<I, O>): Promise<ClientAgent<I, O>>;
97
133
  }
@@ -1,11 +1,10 @@
1
1
  "use strict";
2
- /**
3
- * Client module used to interact with the AIGNE framework.
4
- */
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
3
  exports.AIGNEHTTPClient = void 0;
4
+ const core_1 = require("@aigne/core");
7
5
  const event_stream_js_1 = require("@aigne/core/utils/event-stream.js");
8
6
  const type_utils_js_1 = require("@aigne/core/utils/type-utils.js");
7
+ const client_agent_js_1 = require("./client-agent.js");
9
8
  /**
10
9
  * Http client for interacting with a remote AIGNE server.
11
10
  * AIGNEHTTPClient provides a client-side interface that matches the AIGNE API,
@@ -29,7 +28,41 @@ class AIGNEHTTPClient {
29
28
  constructor(options) {
30
29
  this.options = options;
31
30
  }
32
- async invoke(agent, input, options) {
31
+ usage = (0, core_1.newEmptyContextUsage)();
32
+ userContext = {};
33
+ invoke(agent, message, options) {
34
+ if (options?.returnActiveAgent)
35
+ throw new Error("Method not implemented.");
36
+ if (!message)
37
+ throw new Error("Message is required for invoking an agent");
38
+ const a = typeof agent === "string" ? this.getAgent({ name: agent }) : Promise.resolve(agent);
39
+ return a.then((agent) => agent.invoke(message, options));
40
+ }
41
+ publish(_topic, _payload, _options) {
42
+ throw new Error("Method not implemented.");
43
+ }
44
+ subscribe(_topic, _listener) {
45
+ throw new Error("Method not implemented.");
46
+ }
47
+ unsubscribe(_topic, _listener) {
48
+ throw new Error("Method not implemented.");
49
+ }
50
+ newContext(_options) {
51
+ throw new Error("Method not implemented.");
52
+ }
53
+ emit(_eventName, ..._args) {
54
+ throw new Error("Method not implemented.");
55
+ }
56
+ on(_eventName, _listener) {
57
+ throw new Error("Method not implemented.");
58
+ }
59
+ once(_eventName, _listener) {
60
+ throw new Error("Method not implemented.");
61
+ }
62
+ off(_eventName, _listener) {
63
+ throw new Error("Method not implemented.");
64
+ }
65
+ async _invoke(agent, input, options) {
33
66
  // Send the agent invocation request to the AIGNE server
34
67
  const response = await this.fetch(this.options.url, {
35
68
  ...options?.fetchOptions,
@@ -83,5 +116,8 @@ class AIGNEHTTPClient {
83
116
  }
84
117
  return result;
85
118
  }
119
+ async getAgent(options) {
120
+ return new client_agent_js_1.ClientAgent(this, options);
121
+ }
86
122
  }
87
123
  exports.AIGNEHTTPClient = AIGNEHTTPClient;
@@ -1,5 +1,5 @@
1
1
  import { IncomingMessage, ServerResponse } from "node:http";
2
- import type { AIGNE, UserContext } from "@aigne/core";
2
+ import type { AIGNE, AgentInvokeOptions, UserContext } from "@aigne/core";
3
3
  import { z } from "zod";
4
4
  /**
5
5
  * Schema for validating agent invocation payloads.
@@ -11,27 +11,63 @@ export declare const invokePayloadSchema: z.ZodObject<{
11
11
  agent: z.ZodString;
12
12
  input: z.ZodUnion<[z.ZodString, z.ZodRecord<z.ZodString, z.ZodUnknown>]>;
13
13
  options: z.ZodEffects<z.ZodOptional<z.ZodNullable<z.ZodObject<{
14
- streaming: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
14
+ streaming: z.ZodEffects<z.ZodOptional<z.ZodNullable<z.ZodBoolean>>, boolean | undefined, boolean | null | undefined>;
15
+ userContext: z.ZodEffects<z.ZodOptional<z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>>, Record<string, unknown> | undefined, Record<string, unknown> | null | undefined>;
16
+ memories: z.ZodEffects<z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodObject<{
17
+ content: z.ZodType<object, z.ZodTypeDef, object>;
18
+ }, "strip", z.ZodTypeAny, {
19
+ content: object;
20
+ }, {
21
+ content: object;
22
+ }>, "many">>>, {
23
+ content: object;
24
+ }[] | undefined, {
25
+ content: object;
26
+ }[] | null | undefined>;
15
27
  }, "strip", z.ZodTypeAny, {
16
- streaming?: boolean | null | undefined;
28
+ streaming?: boolean | undefined;
29
+ userContext?: Record<string, unknown> | undefined;
30
+ memories?: {
31
+ content: object;
32
+ }[] | undefined;
17
33
  }, {
18
34
  streaming?: boolean | null | undefined;
35
+ userContext?: Record<string, unknown> | null | undefined;
36
+ memories?: {
37
+ content: object;
38
+ }[] | null | undefined;
19
39
  }>>>, {
20
- streaming?: boolean | null | undefined;
40
+ streaming?: boolean | undefined;
41
+ userContext?: Record<string, unknown> | undefined;
42
+ memories?: {
43
+ content: object;
44
+ }[] | undefined;
21
45
  } | undefined, {
22
46
  streaming?: boolean | null | undefined;
47
+ userContext?: Record<string, unknown> | null | undefined;
48
+ memories?: {
49
+ content: object;
50
+ }[] | null | undefined;
23
51
  } | null | undefined>;
24
52
  }, "strip", z.ZodTypeAny, {
25
53
  agent: string;
26
54
  input: string | Record<string, unknown>;
27
55
  options?: {
28
- streaming?: boolean | null | undefined;
56
+ streaming?: boolean | undefined;
57
+ userContext?: Record<string, unknown> | undefined;
58
+ memories?: {
59
+ content: object;
60
+ }[] | undefined;
29
61
  } | undefined;
30
62
  }, {
31
63
  agent: string;
32
64
  input: string | Record<string, unknown>;
33
65
  options?: {
34
66
  streaming?: boolean | null | undefined;
67
+ userContext?: Record<string, unknown> | null | undefined;
68
+ memories?: {
69
+ content: object;
70
+ }[] | null | undefined;
35
71
  } | null | undefined;
36
72
  }>;
37
73
  /**
@@ -50,8 +86,7 @@ export interface AIGNEHTTPServerOptions {
50
86
  */
51
87
  maximumBodySize?: string;
52
88
  }
53
- export interface AIGNEHTTPServerInvokeOptions<U extends UserContext = UserContext> {
54
- userContext?: U;
89
+ export interface AIGNEHTTPServerInvokeOptions<U extends UserContext = UserContext> extends Pick<AgentInvokeOptions<U>, "userContext" | "memories"> {
55
90
  }
56
91
  /**
57
92
  * AIGNEHTTPServer provides HTTP API access to AIGNE capabilities.
@@ -116,10 +151,11 @@ export declare class AIGNEHTTPServer {
116
151
  * with either streaming or non-streaming response handling.
117
152
  *
118
153
  * @param request - The parsed or raw request to process
154
+ * @param options - Additional options for the invocation, such as user context and memories
119
155
  * @returns A standard Response object with the invocation result
120
156
  * @private
121
157
  */
122
- _invoke(request: Record<string, unknown> | Request | IncomingMessage, { userContext }?: AIGNEHTTPServerInvokeOptions): Promise<Response>;
158
+ _invoke(request: Record<string, unknown> | Request | IncomingMessage, options?: AIGNEHTTPServerInvokeOptions): Promise<Response>;
123
159
  /**
124
160
  * Prepares and normalizes the input from various request types.
125
161
  * Handles different request formats (Node.js IncomingMessage, Fetch API Request,
@@ -28,7 +28,20 @@ exports.invokePayloadSchema = zod_1.z.object({
28
28
  agent: zod_1.z.string(),
29
29
  input: zod_1.z.union([zod_1.z.string(), zod_1.z.record(zod_1.z.string(), zod_1.z.unknown())]),
30
30
  options: zod_1.z
31
- .object({ streaming: zod_1.z.boolean().nullish() })
31
+ .object({
32
+ streaming: zod_1.z
33
+ .boolean()
34
+ .nullish()
35
+ .transform((v) => v ?? undefined),
36
+ userContext: zod_1.z
37
+ .record(zod_1.z.string(), zod_1.z.unknown())
38
+ .nullish()
39
+ .transform((v) => v ?? undefined),
40
+ memories: zod_1.z
41
+ .array(zod_1.z.object({ content: zod_1.z.custom() }))
42
+ .nullish()
43
+ .transform((v) => v ?? undefined),
44
+ })
32
45
  .nullish()
33
46
  .transform((v) => v ?? undefined),
34
47
  });
@@ -61,7 +74,10 @@ class AIGNEHTTPServer {
61
74
  }
62
75
  async invoke(request, response, options) {
63
76
  const opts = !(response instanceof node_http_1.ServerResponse) ? options || response : options;
64
- const result = await this._invoke(request, { userContext: opts?.userContext });
77
+ const result = await this._invoke(request, {
78
+ userContext: opts?.userContext,
79
+ memories: opts?.memories,
80
+ });
65
81
  if (response instanceof node_http_1.ServerResponse) {
66
82
  await this._writeResponse(result, response);
67
83
  return;
@@ -74,24 +90,33 @@ class AIGNEHTTPServer {
74
90
  * with either streaming or non-streaming response handling.
75
91
  *
76
92
  * @param request - The parsed or raw request to process
93
+ * @param options - Additional options for the invocation, such as user context and memories
77
94
  * @returns A standard Response object with the invocation result
78
95
  * @private
79
96
  */
80
- async _invoke(request, { userContext } = {}) {
97
+ async _invoke(request, options = {}) {
81
98
  const { engine } = this;
82
99
  try {
83
100
  const payload = await this._prepareInput(request);
84
- const { agent: agentName, input, options: { streaming } = {}, } = (0, type_utils_js_1.tryOrThrow)(() => (0, type_utils_js_1.checkArguments)(`Invoke agent ${payload.agent}`, exports.invokePayloadSchema, payload), (error) => new error_js_1.ServerError(400, error.message));
101
+ const { agent: agentName, input, options: { streaming, ...opts } = {}, } = (0, type_utils_js_1.tryOrThrow)(() => (0, type_utils_js_1.checkArguments)(`Invoke agent ${payload.agent}`, exports.invokePayloadSchema, payload), (error) => new error_js_1.ServerError(400, error.message));
85
102
  const agent = engine.agents[agentName];
86
103
  if (!agent)
87
104
  throw new error_js_1.ServerError(404, `Agent ${agentName} not found`);
105
+ const mergedOptions = {
106
+ userContext: { ...opts.userContext, ...options.userContext },
107
+ memories: [...(opts.memories ?? []), ...(options.memories ?? [])],
108
+ };
88
109
  if (!streaming) {
89
- const result = await engine.invoke(agent, input, { userContext });
110
+ const result = await engine.invoke(agent, input, mergedOptions);
90
111
  return new Response(JSON.stringify(result), {
91
112
  headers: { "Content-Type": "application/json" },
92
113
  });
93
114
  }
94
- const stream = await engine.invoke(agent, input, { userContext, streaming: true });
115
+ const stream = await engine.invoke(agent, input, {
116
+ ...mergedOptions,
117
+ returnActiveAgent: false,
118
+ streaming: true,
119
+ });
95
120
  return new Response(new event_stream_js_1.AgentResponseStreamSSE(stream), {
96
121
  headers: {
97
122
  "Content-Type": "text/event-stream",
@@ -0,0 +1,20 @@
1
+ import { Agent, type AgentInvokeOptions, type AgentOptions, type AgentProcessResult, type AgentResponse, type AgentResponseStream, type Message } from "@aigne/core";
2
+ import type { MemoryAgent } from "@aigne/core/memory/memory.js";
3
+ import type { PromiseOrValue } from "@aigne/core/utils/type-utils.js";
4
+ import type { AIGNEHTTPClient } from "./client.js";
5
+ export interface ClientAgentOptions<I extends Message = Message, O extends Message = Message> extends Required<Pick<AgentOptions<I, O>, "name">> {
6
+ memory?: MemoryAgent | MemoryAgent[];
7
+ }
8
+ export declare class ClientAgent<I extends Message = Message, O extends Message = Message> extends Agent<I, O> {
9
+ client: AIGNEHTTPClient;
10
+ constructor(client: AIGNEHTTPClient, options: ClientAgentOptions<I, O>);
11
+ invoke(input: string | I, options?: Partial<AgentInvokeOptions> & {
12
+ streaming?: false;
13
+ }): Promise<O>;
14
+ invoke(input: string | I, options: Partial<AgentInvokeOptions> & {
15
+ streaming: true;
16
+ }): Promise<AgentResponseStream<O>>;
17
+ invoke(input: string | I, options?: Partial<AgentInvokeOptions>): Promise<AgentResponse<O>>;
18
+ process(_input: I, _options: AgentInvokeOptions): PromiseOrValue<AgentProcessResult<O>>;
19
+ postprocess(input: I, output: O, options: AgentInvokeOptions): Promise<void>;
20
+ }
@@ -1,7 +1,6 @@
1
- /**
2
- * Client module used to interact with the AIGNE framework.
3
- */
4
- import type { AgentInvokeOptions, AgentResponse, AgentResponseStream, Message } from "@aigne/core";
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
+ import type { Args, Listener } from "@aigne/core/utils/typed-event-emtter.js";
3
+ import { ClientAgent, type ClientAgentOptions } from "./client-agent.js";
5
4
  /**
6
5
  * Configuration options for the AIGNEHTTPClient.
7
6
  */
@@ -16,7 +15,7 @@ export interface AIGNEHTTPClientOptions {
16
15
  * Options for invoking an agent through the AIGNEHTTPClient.
17
16
  * Extends the standard AgentInvokeOptions with client-specific options.
18
17
  */
19
- export interface AIGNEHTTPClientInvokeOptions extends Omit<AgentInvokeOptions, "context"> {
18
+ export interface AIGNEHTTPClientInvokeOptions extends InvokeOptions {
20
19
  /**
21
20
  * Additional fetch API options to customize the HTTP request.
22
21
  * These options will be merged with the default options used by the client.
@@ -36,7 +35,7 @@ export interface AIGNEHTTPClientInvokeOptions extends Omit<AgentInvokeOptions, "
36
35
  * Here's an example of how to use AIGNEClient with streaming response:
37
36
  * {@includeCode ../../test/http-client/http-client.test.ts#example-aigne-client-streaming}
38
37
  */
39
- export declare class AIGNEHTTPClient {
38
+ export declare class AIGNEHTTPClient<U extends UserContext = UserContext> implements Context<U> {
40
39
  options: AIGNEHTTPClientOptions;
41
40
  /**
42
41
  * Creates a new AIGNEClient instance.
@@ -44,6 +43,42 @@ export declare class AIGNEHTTPClient {
44
43
  * @param options - Configuration options for connecting to the AIGNE server
45
44
  */
46
45
  constructor(options: AIGNEHTTPClientOptions);
46
+ usage: ContextUsage;
47
+ userContext: U;
48
+ invoke<I extends Message, O extends Message>(agent: Agent<I, O> | string): UserAgent<I, O>;
49
+ invoke<I extends Message, O extends Message>(agent: Agent<I, O> | string, message: I | string, options: AIGNEHTTPClientInvokeOptions & {
50
+ returnActiveAgent: true;
51
+ streaming?: false;
52
+ }): Promise<[O, Agent]>;
53
+ invoke<I extends Message, O extends Message>(agent: Agent<I, O> | string, message: I | string, options: AIGNEHTTPClientInvokeOptions & {
54
+ returnActiveAgent: true;
55
+ streaming: true;
56
+ }): Promise<[AgentResponseStream<O>, Promise<Agent>]>;
57
+ invoke<I extends Message, O extends Message>(agent: Agent<I, O> | string, message: I | string, options?: AIGNEHTTPClientInvokeOptions & {
58
+ returnActiveAgent?: false;
59
+ streaming?: false;
60
+ }): Promise<O>;
61
+ invoke<I extends Message, O extends Message>(agent: Agent<I, O> | string, message: I | string, options: AIGNEHTTPClientInvokeOptions & {
62
+ returnActiveAgent?: false;
63
+ streaming: true;
64
+ }): Promise<AgentResponseStream<O>>;
65
+ invoke<I extends Message, O extends Message>(agent: Agent<I, O> | string, message: I | string, options: AIGNEHTTPClientInvokeOptions & {
66
+ returnActiveAgent?: false;
67
+ }): Promise<O | AgentResponseStream<O>>;
68
+ invoke<I extends Message, O extends Message>(agent: Agent<I, O> | string, message?: I | string, options?: AIGNEHTTPClientInvokeOptions): UserAgent<I, O> | Promise<AgentResponse<O> | [AgentResponse<O>, Agent]>;
69
+ publish(_topic: string | string[], _payload: Omit<MessagePayload, "context"> | Message | string, _options?: InvokeOptions): void;
70
+ subscribe(topic: string | string[], listener?: undefined): Promise<MessagePayload>;
71
+ subscribe(topic: string | string[], listener: MessageQueueListener): Unsubscribe;
72
+ subscribe(topic: string | string[], listener?: MessageQueueListener): Unsubscribe | Promise<MessagePayload>;
73
+ subscribe(topic: string | string[], listener?: MessageQueueListener): Unsubscribe | Promise<MessagePayload>;
74
+ unsubscribe(_topic: string | string[], _listener: MessageQueueListener): void;
75
+ newContext(_options?: {
76
+ reset?: boolean;
77
+ }): Context;
78
+ emit<K extends keyof ContextEventMap>(_eventName: K, ..._args: Args<K, ContextEmitEventMap>): boolean;
79
+ on<K extends keyof ContextEventMap>(_eventName: K, _listener: Listener<K, ContextEventMap>): this;
80
+ once<K extends keyof ContextEventMap>(_eventName: K, _listener: Listener<K, ContextEventMap>): this;
81
+ off<K extends keyof ContextEventMap>(_eventName: K, _listener: Listener<K, ContextEventMap>): this;
47
82
  /**
48
83
  * Invokes an agent in non-streaming mode and returns the complete response.
49
84
  *
@@ -56,7 +91,7 @@ export declare class AIGNEHTTPClient {
56
91
  * Here's a simple example of how to use AIGNEClient:
57
92
  * {@includeCode ../../test/http-client/http-client.test.ts#example-aigne-client-simple}
58
93
  */
59
- invoke<I extends Message, O extends Message>(agent: string, input: string | I, options?: AIGNEHTTPClientInvokeOptions & {
94
+ _invoke<I extends Message, O extends Message>(agent: string, input: string | I, options?: AIGNEHTTPClientInvokeOptions & {
60
95
  streaming?: false;
61
96
  }): Promise<O>;
62
97
  /**
@@ -71,7 +106,7 @@ export declare class AIGNEHTTPClient {
71
106
  * Here's an example of how to use AIGNEClient with streaming response:
72
107
  * {@includeCode ../../test/http-client/http-client.test.ts#example-aigne-client-streaming}
73
108
  */
74
- invoke<I extends Message, O extends Message>(agent: string, input: string | I, options: AIGNEHTTPClientInvokeOptions & {
109
+ _invoke<I extends Message, O extends Message>(agent: string, input: string | I, options: AIGNEHTTPClientInvokeOptions & {
75
110
  streaming: true;
76
111
  }): Promise<AgentResponseStream<O>>;
77
112
  /**
@@ -82,7 +117,7 @@ export declare class AIGNEHTTPClient {
82
117
  * @param options - Options for the invocation
83
118
  * @returns Either a complete response or a response stream depending on the streaming option
84
119
  */
85
- invoke<I extends Message, O extends Message>(agent: string, input: string | I, options?: AIGNEHTTPClientInvokeOptions): Promise<AgentResponse<O>>;
120
+ _invoke<I extends Message, O extends Message>(agent: string, input: string | I, options?: AIGNEHTTPClientInvokeOptions): Promise<AgentResponse<O>>;
86
121
  /**
87
122
  * Enhanced fetch method that handles error responses from the AIGNE server.
88
123
  * This method wraps the standard fetch API to provide better error handling and reporting.
@@ -94,4 +129,5 @@ export declare class AIGNEHTTPClient {
94
129
  * @private
95
130
  */
96
131
  fetch(...args: Parameters<typeof globalThis.fetch>): Promise<Response>;
132
+ getAgent<I extends Message = Message, O extends Message = Message>(options: ClientAgentOptions<I, O>): Promise<ClientAgent<I, O>>;
97
133
  }
@@ -1,5 +1,5 @@
1
1
  import { IncomingMessage, ServerResponse } from "node:http";
2
- import type { AIGNE, UserContext } from "@aigne/core";
2
+ import type { AIGNE, AgentInvokeOptions, UserContext } from "@aigne/core";
3
3
  import { z } from "zod";
4
4
  /**
5
5
  * Schema for validating agent invocation payloads.
@@ -11,27 +11,63 @@ export declare const invokePayloadSchema: z.ZodObject<{
11
11
  agent: z.ZodString;
12
12
  input: z.ZodUnion<[z.ZodString, z.ZodRecord<z.ZodString, z.ZodUnknown>]>;
13
13
  options: z.ZodEffects<z.ZodOptional<z.ZodNullable<z.ZodObject<{
14
- streaming: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
14
+ streaming: z.ZodEffects<z.ZodOptional<z.ZodNullable<z.ZodBoolean>>, boolean | undefined, boolean | null | undefined>;
15
+ userContext: z.ZodEffects<z.ZodOptional<z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>>, Record<string, unknown> | undefined, Record<string, unknown> | null | undefined>;
16
+ memories: z.ZodEffects<z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodObject<{
17
+ content: z.ZodType<object, z.ZodTypeDef, object>;
18
+ }, "strip", z.ZodTypeAny, {
19
+ content: object;
20
+ }, {
21
+ content: object;
22
+ }>, "many">>>, {
23
+ content: object;
24
+ }[] | undefined, {
25
+ content: object;
26
+ }[] | null | undefined>;
15
27
  }, "strip", z.ZodTypeAny, {
16
- streaming?: boolean | null | undefined;
28
+ streaming?: boolean | undefined;
29
+ userContext?: Record<string, unknown> | undefined;
30
+ memories?: {
31
+ content: object;
32
+ }[] | undefined;
17
33
  }, {
18
34
  streaming?: boolean | null | undefined;
35
+ userContext?: Record<string, unknown> | null | undefined;
36
+ memories?: {
37
+ content: object;
38
+ }[] | null | undefined;
19
39
  }>>>, {
20
- streaming?: boolean | null | undefined;
40
+ streaming?: boolean | undefined;
41
+ userContext?: Record<string, unknown> | undefined;
42
+ memories?: {
43
+ content: object;
44
+ }[] | undefined;
21
45
  } | undefined, {
22
46
  streaming?: boolean | null | undefined;
47
+ userContext?: Record<string, unknown> | null | undefined;
48
+ memories?: {
49
+ content: object;
50
+ }[] | null | undefined;
23
51
  } | null | undefined>;
24
52
  }, "strip", z.ZodTypeAny, {
25
53
  agent: string;
26
54
  input: string | Record<string, unknown>;
27
55
  options?: {
28
- streaming?: boolean | null | undefined;
56
+ streaming?: boolean | undefined;
57
+ userContext?: Record<string, unknown> | undefined;
58
+ memories?: {
59
+ content: object;
60
+ }[] | undefined;
29
61
  } | undefined;
30
62
  }, {
31
63
  agent: string;
32
64
  input: string | Record<string, unknown>;
33
65
  options?: {
34
66
  streaming?: boolean | null | undefined;
67
+ userContext?: Record<string, unknown> | null | undefined;
68
+ memories?: {
69
+ content: object;
70
+ }[] | null | undefined;
35
71
  } | null | undefined;
36
72
  }>;
37
73
  /**
@@ -50,8 +86,7 @@ export interface AIGNEHTTPServerOptions {
50
86
  */
51
87
  maximumBodySize?: string;
52
88
  }
53
- export interface AIGNEHTTPServerInvokeOptions<U extends UserContext = UserContext> {
54
- userContext?: U;
89
+ export interface AIGNEHTTPServerInvokeOptions<U extends UserContext = UserContext> extends Pick<AgentInvokeOptions<U>, "userContext" | "memories"> {
55
90
  }
56
91
  /**
57
92
  * AIGNEHTTPServer provides HTTP API access to AIGNE capabilities.
@@ -116,10 +151,11 @@ export declare class AIGNEHTTPServer {
116
151
  * with either streaming or non-streaming response handling.
117
152
  *
118
153
  * @param request - The parsed or raw request to process
154
+ * @param options - Additional options for the invocation, such as user context and memories
119
155
  * @returns A standard Response object with the invocation result
120
156
  * @private
121
157
  */
122
- _invoke(request: Record<string, unknown> | Request | IncomingMessage, { userContext }?: AIGNEHTTPServerInvokeOptions): Promise<Response>;
158
+ _invoke(request: Record<string, unknown> | Request | IncomingMessage, options?: AIGNEHTTPServerInvokeOptions): Promise<Response>;
123
159
  /**
124
160
  * Prepares and normalizes the input from various request types.
125
161
  * Handles different request formats (Node.js IncomingMessage, Fetch API Request,
@@ -0,0 +1,20 @@
1
+ import { Agent, type AgentInvokeOptions, type AgentOptions, type AgentProcessResult, type AgentResponse, type AgentResponseStream, type Message } from "@aigne/core";
2
+ import type { MemoryAgent } from "@aigne/core/memory/memory.js";
3
+ import type { PromiseOrValue } from "@aigne/core/utils/type-utils.js";
4
+ import type { AIGNEHTTPClient } from "./client.js";
5
+ export interface ClientAgentOptions<I extends Message = Message, O extends Message = Message> extends Required<Pick<AgentOptions<I, O>, "name">> {
6
+ memory?: MemoryAgent | MemoryAgent[];
7
+ }
8
+ export declare class ClientAgent<I extends Message = Message, O extends Message = Message> extends Agent<I, O> {
9
+ client: AIGNEHTTPClient;
10
+ constructor(client: AIGNEHTTPClient, options: ClientAgentOptions<I, O>);
11
+ invoke(input: string | I, options?: Partial<AgentInvokeOptions> & {
12
+ streaming?: false;
13
+ }): Promise<O>;
14
+ invoke(input: string | I, options: Partial<AgentInvokeOptions> & {
15
+ streaming: true;
16
+ }): Promise<AgentResponseStream<O>>;
17
+ invoke(input: string | I, options?: Partial<AgentInvokeOptions>): Promise<AgentResponse<O>>;
18
+ process(_input: I, _options: AgentInvokeOptions): PromiseOrValue<AgentProcessResult<O>>;
19
+ postprocess(input: I, output: O, options: AgentInvokeOptions): Promise<void>;
20
+ }
@@ -0,0 +1,41 @@
1
+ import { Agent, createMessage, replaceTransferAgentToName, } from "@aigne/core";
2
+ import { onAgentResponseStreamEnd } from "@aigne/core/utils/stream-utils.js";
3
+ export class ClientAgent extends Agent {
4
+ client;
5
+ constructor(client, options) {
6
+ super(options);
7
+ this.client = client;
8
+ }
9
+ async invoke(input, options) {
10
+ const memories = await this.retrieveMemories({ search: input }, { ...options, context: this.client });
11
+ const result = await this.client._invoke(this.name, input, {
12
+ ...options,
13
+ returnActiveAgent: false,
14
+ memories,
15
+ });
16
+ if (!(result instanceof ReadableStream)) {
17
+ await this.postprocess(createMessage(input), result, {
18
+ ...options,
19
+ context: this.client,
20
+ });
21
+ return result;
22
+ }
23
+ return onAgentResponseStreamEnd(result, async (result) => {
24
+ await this.postprocess(createMessage(input), result, {
25
+ ...options,
26
+ context: this.client,
27
+ });
28
+ });
29
+ }
30
+ process(_input, _options) {
31
+ throw new Error("Method not implemented.");
32
+ }
33
+ async postprocess(input, output, options) {
34
+ await this.recordMemories({
35
+ content: [
36
+ { role: "user", content: input },
37
+ { role: "agent", content: replaceTransferAgentToName(output), source: this.name },
38
+ ],
39
+ }, options);
40
+ }
41
+ }
@@ -1,7 +1,6 @@
1
- /**
2
- * Client module used to interact with the AIGNE framework.
3
- */
4
- import type { AgentInvokeOptions, AgentResponse, AgentResponseStream, Message } from "@aigne/core";
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
+ import type { Args, Listener } from "@aigne/core/utils/typed-event-emtter.js";
3
+ import { ClientAgent, type ClientAgentOptions } from "./client-agent.js";
5
4
  /**
6
5
  * Configuration options for the AIGNEHTTPClient.
7
6
  */
@@ -16,7 +15,7 @@ export interface AIGNEHTTPClientOptions {
16
15
  * Options for invoking an agent through the AIGNEHTTPClient.
17
16
  * Extends the standard AgentInvokeOptions with client-specific options.
18
17
  */
19
- export interface AIGNEHTTPClientInvokeOptions extends Omit<AgentInvokeOptions, "context"> {
18
+ export interface AIGNEHTTPClientInvokeOptions extends InvokeOptions {
20
19
  /**
21
20
  * Additional fetch API options to customize the HTTP request.
22
21
  * These options will be merged with the default options used by the client.
@@ -36,7 +35,7 @@ export interface AIGNEHTTPClientInvokeOptions extends Omit<AgentInvokeOptions, "
36
35
  * Here's an example of how to use AIGNEClient with streaming response:
37
36
  * {@includeCode ../../test/http-client/http-client.test.ts#example-aigne-client-streaming}
38
37
  */
39
- export declare class AIGNEHTTPClient {
38
+ export declare class AIGNEHTTPClient<U extends UserContext = UserContext> implements Context<U> {
40
39
  options: AIGNEHTTPClientOptions;
41
40
  /**
42
41
  * Creates a new AIGNEClient instance.
@@ -44,6 +43,42 @@ export declare class AIGNEHTTPClient {
44
43
  * @param options - Configuration options for connecting to the AIGNE server
45
44
  */
46
45
  constructor(options: AIGNEHTTPClientOptions);
46
+ usage: ContextUsage;
47
+ userContext: U;
48
+ invoke<I extends Message, O extends Message>(agent: Agent<I, O> | string): UserAgent<I, O>;
49
+ invoke<I extends Message, O extends Message>(agent: Agent<I, O> | string, message: I | string, options: AIGNEHTTPClientInvokeOptions & {
50
+ returnActiveAgent: true;
51
+ streaming?: false;
52
+ }): Promise<[O, Agent]>;
53
+ invoke<I extends Message, O extends Message>(agent: Agent<I, O> | string, message: I | string, options: AIGNEHTTPClientInvokeOptions & {
54
+ returnActiveAgent: true;
55
+ streaming: true;
56
+ }): Promise<[AgentResponseStream<O>, Promise<Agent>]>;
57
+ invoke<I extends Message, O extends Message>(agent: Agent<I, O> | string, message: I | string, options?: AIGNEHTTPClientInvokeOptions & {
58
+ returnActiveAgent?: false;
59
+ streaming?: false;
60
+ }): Promise<O>;
61
+ invoke<I extends Message, O extends Message>(agent: Agent<I, O> | string, message: I | string, options: AIGNEHTTPClientInvokeOptions & {
62
+ returnActiveAgent?: false;
63
+ streaming: true;
64
+ }): Promise<AgentResponseStream<O>>;
65
+ invoke<I extends Message, O extends Message>(agent: Agent<I, O> | string, message: I | string, options: AIGNEHTTPClientInvokeOptions & {
66
+ returnActiveAgent?: false;
67
+ }): Promise<O | AgentResponseStream<O>>;
68
+ invoke<I extends Message, O extends Message>(agent: Agent<I, O> | string, message?: I | string, options?: AIGNEHTTPClientInvokeOptions): UserAgent<I, O> | Promise<AgentResponse<O> | [AgentResponse<O>, Agent]>;
69
+ publish(_topic: string | string[], _payload: Omit<MessagePayload, "context"> | Message | string, _options?: InvokeOptions): void;
70
+ subscribe(topic: string | string[], listener?: undefined): Promise<MessagePayload>;
71
+ subscribe(topic: string | string[], listener: MessageQueueListener): Unsubscribe;
72
+ subscribe(topic: string | string[], listener?: MessageQueueListener): Unsubscribe | Promise<MessagePayload>;
73
+ subscribe(topic: string | string[], listener?: MessageQueueListener): Unsubscribe | Promise<MessagePayload>;
74
+ unsubscribe(_topic: string | string[], _listener: MessageQueueListener): void;
75
+ newContext(_options?: {
76
+ reset?: boolean;
77
+ }): Context;
78
+ emit<K extends keyof ContextEventMap>(_eventName: K, ..._args: Args<K, ContextEmitEventMap>): boolean;
79
+ on<K extends keyof ContextEventMap>(_eventName: K, _listener: Listener<K, ContextEventMap>): this;
80
+ once<K extends keyof ContextEventMap>(_eventName: K, _listener: Listener<K, ContextEventMap>): this;
81
+ off<K extends keyof ContextEventMap>(_eventName: K, _listener: Listener<K, ContextEventMap>): this;
47
82
  /**
48
83
  * Invokes an agent in non-streaming mode and returns the complete response.
49
84
  *
@@ -56,7 +91,7 @@ export declare class AIGNEHTTPClient {
56
91
  * Here's a simple example of how to use AIGNEClient:
57
92
  * {@includeCode ../../test/http-client/http-client.test.ts#example-aigne-client-simple}
58
93
  */
59
- invoke<I extends Message, O extends Message>(agent: string, input: string | I, options?: AIGNEHTTPClientInvokeOptions & {
94
+ _invoke<I extends Message, O extends Message>(agent: string, input: string | I, options?: AIGNEHTTPClientInvokeOptions & {
60
95
  streaming?: false;
61
96
  }): Promise<O>;
62
97
  /**
@@ -71,7 +106,7 @@ export declare class AIGNEHTTPClient {
71
106
  * Here's an example of how to use AIGNEClient with streaming response:
72
107
  * {@includeCode ../../test/http-client/http-client.test.ts#example-aigne-client-streaming}
73
108
  */
74
- invoke<I extends Message, O extends Message>(agent: string, input: string | I, options: AIGNEHTTPClientInvokeOptions & {
109
+ _invoke<I extends Message, O extends Message>(agent: string, input: string | I, options: AIGNEHTTPClientInvokeOptions & {
75
110
  streaming: true;
76
111
  }): Promise<AgentResponseStream<O>>;
77
112
  /**
@@ -82,7 +117,7 @@ export declare class AIGNEHTTPClient {
82
117
  * @param options - Options for the invocation
83
118
  * @returns Either a complete response or a response stream depending on the streaming option
84
119
  */
85
- invoke<I extends Message, O extends Message>(agent: string, input: string | I, options?: AIGNEHTTPClientInvokeOptions): Promise<AgentResponse<O>>;
120
+ _invoke<I extends Message, O extends Message>(agent: string, input: string | I, options?: AIGNEHTTPClientInvokeOptions): Promise<AgentResponse<O>>;
86
121
  /**
87
122
  * Enhanced fetch method that handles error responses from the AIGNE server.
88
123
  * This method wraps the standard fetch API to provide better error handling and reporting.
@@ -94,4 +129,5 @@ export declare class AIGNEHTTPClient {
94
129
  * @private
95
130
  */
96
131
  fetch(...args: Parameters<typeof globalThis.fetch>): Promise<Response>;
132
+ getAgent<I extends Message = Message, O extends Message = Message>(options: ClientAgentOptions<I, O>): Promise<ClientAgent<I, O>>;
97
133
  }
@@ -1,8 +1,7 @@
1
- /**
2
- * Client module used to interact with the AIGNE framework.
3
- */
1
+ import { newEmptyContextUsage, } from "@aigne/core";
4
2
  import { AgentResponseStreamParser, EventStreamParser } from "@aigne/core/utils/event-stream.js";
5
3
  import { tryOrThrow } from "@aigne/core/utils/type-utils.js";
4
+ import { ClientAgent } from "./client-agent.js";
6
5
  /**
7
6
  * Http client for interacting with a remote AIGNE server.
8
7
  * AIGNEHTTPClient provides a client-side interface that matches the AIGNE API,
@@ -26,7 +25,41 @@ export class AIGNEHTTPClient {
26
25
  constructor(options) {
27
26
  this.options = options;
28
27
  }
29
- async invoke(agent, input, options) {
28
+ usage = newEmptyContextUsage();
29
+ userContext = {};
30
+ invoke(agent, message, options) {
31
+ if (options?.returnActiveAgent)
32
+ throw new Error("Method not implemented.");
33
+ if (!message)
34
+ throw new Error("Message is required for invoking an agent");
35
+ const a = typeof agent === "string" ? this.getAgent({ name: agent }) : Promise.resolve(agent);
36
+ return a.then((agent) => agent.invoke(message, options));
37
+ }
38
+ publish(_topic, _payload, _options) {
39
+ throw new Error("Method not implemented.");
40
+ }
41
+ subscribe(_topic, _listener) {
42
+ throw new Error("Method not implemented.");
43
+ }
44
+ unsubscribe(_topic, _listener) {
45
+ throw new Error("Method not implemented.");
46
+ }
47
+ newContext(_options) {
48
+ throw new Error("Method not implemented.");
49
+ }
50
+ emit(_eventName, ..._args) {
51
+ throw new Error("Method not implemented.");
52
+ }
53
+ on(_eventName, _listener) {
54
+ throw new Error("Method not implemented.");
55
+ }
56
+ once(_eventName, _listener) {
57
+ throw new Error("Method not implemented.");
58
+ }
59
+ off(_eventName, _listener) {
60
+ throw new Error("Method not implemented.");
61
+ }
62
+ async _invoke(agent, input, options) {
30
63
  // Send the agent invocation request to the AIGNE server
31
64
  const response = await this.fetch(this.options.url, {
32
65
  ...options?.fetchOptions,
@@ -80,4 +113,7 @@ export class AIGNEHTTPClient {
80
113
  }
81
114
  return result;
82
115
  }
116
+ async getAgent(options) {
117
+ return new ClientAgent(this, options);
118
+ }
83
119
  }
@@ -1,5 +1,5 @@
1
1
  import { IncomingMessage, ServerResponse } from "node:http";
2
- import type { AIGNE, UserContext } from "@aigne/core";
2
+ import type { AIGNE, AgentInvokeOptions, UserContext } from "@aigne/core";
3
3
  import { z } from "zod";
4
4
  /**
5
5
  * Schema for validating agent invocation payloads.
@@ -11,27 +11,63 @@ export declare const invokePayloadSchema: z.ZodObject<{
11
11
  agent: z.ZodString;
12
12
  input: z.ZodUnion<[z.ZodString, z.ZodRecord<z.ZodString, z.ZodUnknown>]>;
13
13
  options: z.ZodEffects<z.ZodOptional<z.ZodNullable<z.ZodObject<{
14
- streaming: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
14
+ streaming: z.ZodEffects<z.ZodOptional<z.ZodNullable<z.ZodBoolean>>, boolean | undefined, boolean | null | undefined>;
15
+ userContext: z.ZodEffects<z.ZodOptional<z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>>, Record<string, unknown> | undefined, Record<string, unknown> | null | undefined>;
16
+ memories: z.ZodEffects<z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodObject<{
17
+ content: z.ZodType<object, z.ZodTypeDef, object>;
18
+ }, "strip", z.ZodTypeAny, {
19
+ content: object;
20
+ }, {
21
+ content: object;
22
+ }>, "many">>>, {
23
+ content: object;
24
+ }[] | undefined, {
25
+ content: object;
26
+ }[] | null | undefined>;
15
27
  }, "strip", z.ZodTypeAny, {
16
- streaming?: boolean | null | undefined;
28
+ streaming?: boolean | undefined;
29
+ userContext?: Record<string, unknown> | undefined;
30
+ memories?: {
31
+ content: object;
32
+ }[] | undefined;
17
33
  }, {
18
34
  streaming?: boolean | null | undefined;
35
+ userContext?: Record<string, unknown> | null | undefined;
36
+ memories?: {
37
+ content: object;
38
+ }[] | null | undefined;
19
39
  }>>>, {
20
- streaming?: boolean | null | undefined;
40
+ streaming?: boolean | undefined;
41
+ userContext?: Record<string, unknown> | undefined;
42
+ memories?: {
43
+ content: object;
44
+ }[] | undefined;
21
45
  } | undefined, {
22
46
  streaming?: boolean | null | undefined;
47
+ userContext?: Record<string, unknown> | null | undefined;
48
+ memories?: {
49
+ content: object;
50
+ }[] | null | undefined;
23
51
  } | null | undefined>;
24
52
  }, "strip", z.ZodTypeAny, {
25
53
  agent: string;
26
54
  input: string | Record<string, unknown>;
27
55
  options?: {
28
- streaming?: boolean | null | undefined;
56
+ streaming?: boolean | undefined;
57
+ userContext?: Record<string, unknown> | undefined;
58
+ memories?: {
59
+ content: object;
60
+ }[] | undefined;
29
61
  } | undefined;
30
62
  }, {
31
63
  agent: string;
32
64
  input: string | Record<string, unknown>;
33
65
  options?: {
34
66
  streaming?: boolean | null | undefined;
67
+ userContext?: Record<string, unknown> | null | undefined;
68
+ memories?: {
69
+ content: object;
70
+ }[] | null | undefined;
35
71
  } | null | undefined;
36
72
  }>;
37
73
  /**
@@ -50,8 +86,7 @@ export interface AIGNEHTTPServerOptions {
50
86
  */
51
87
  maximumBodySize?: string;
52
88
  }
53
- export interface AIGNEHTTPServerInvokeOptions<U extends UserContext = UserContext> {
54
- userContext?: U;
89
+ export interface AIGNEHTTPServerInvokeOptions<U extends UserContext = UserContext> extends Pick<AgentInvokeOptions<U>, "userContext" | "memories"> {
55
90
  }
56
91
  /**
57
92
  * AIGNEHTTPServer provides HTTP API access to AIGNE capabilities.
@@ -116,10 +151,11 @@ export declare class AIGNEHTTPServer {
116
151
  * with either streaming or non-streaming response handling.
117
152
  *
118
153
  * @param request - The parsed or raw request to process
154
+ * @param options - Additional options for the invocation, such as user context and memories
119
155
  * @returns A standard Response object with the invocation result
120
156
  * @private
121
157
  */
122
- _invoke(request: Record<string, unknown> | Request | IncomingMessage, { userContext }?: AIGNEHTTPServerInvokeOptions): Promise<Response>;
158
+ _invoke(request: Record<string, unknown> | Request | IncomingMessage, options?: AIGNEHTTPServerInvokeOptions): Promise<Response>;
123
159
  /**
124
160
  * Prepares and normalizes the input from various request types.
125
161
  * Handles different request formats (Node.js IncomingMessage, Fetch API Request,
@@ -22,7 +22,20 @@ export const invokePayloadSchema = z.object({
22
22
  agent: z.string(),
23
23
  input: z.union([z.string(), z.record(z.string(), z.unknown())]),
24
24
  options: z
25
- .object({ streaming: z.boolean().nullish() })
25
+ .object({
26
+ streaming: z
27
+ .boolean()
28
+ .nullish()
29
+ .transform((v) => v ?? undefined),
30
+ userContext: z
31
+ .record(z.string(), z.unknown())
32
+ .nullish()
33
+ .transform((v) => v ?? undefined),
34
+ memories: z
35
+ .array(z.object({ content: z.custom() }))
36
+ .nullish()
37
+ .transform((v) => v ?? undefined),
38
+ })
26
39
  .nullish()
27
40
  .transform((v) => v ?? undefined),
28
41
  });
@@ -55,7 +68,10 @@ export class AIGNEHTTPServer {
55
68
  }
56
69
  async invoke(request, response, options) {
57
70
  const opts = !(response instanceof ServerResponse) ? options || response : options;
58
- const result = await this._invoke(request, { userContext: opts?.userContext });
71
+ const result = await this._invoke(request, {
72
+ userContext: opts?.userContext,
73
+ memories: opts?.memories,
74
+ });
59
75
  if (response instanceof ServerResponse) {
60
76
  await this._writeResponse(result, response);
61
77
  return;
@@ -68,24 +84,33 @@ export class AIGNEHTTPServer {
68
84
  * with either streaming or non-streaming response handling.
69
85
  *
70
86
  * @param request - The parsed or raw request to process
87
+ * @param options - Additional options for the invocation, such as user context and memories
71
88
  * @returns A standard Response object with the invocation result
72
89
  * @private
73
90
  */
74
- async _invoke(request, { userContext } = {}) {
91
+ async _invoke(request, options = {}) {
75
92
  const { engine } = this;
76
93
  try {
77
94
  const payload = await this._prepareInput(request);
78
- const { agent: agentName, input, options: { streaming } = {}, } = tryOrThrow(() => checkArguments(`Invoke agent ${payload.agent}`, invokePayloadSchema, payload), (error) => new ServerError(400, error.message));
95
+ const { agent: agentName, input, options: { streaming, ...opts } = {}, } = tryOrThrow(() => checkArguments(`Invoke agent ${payload.agent}`, invokePayloadSchema, payload), (error) => new ServerError(400, error.message));
79
96
  const agent = engine.agents[agentName];
80
97
  if (!agent)
81
98
  throw new ServerError(404, `Agent ${agentName} not found`);
99
+ const mergedOptions = {
100
+ userContext: { ...opts.userContext, ...options.userContext },
101
+ memories: [...(opts.memories ?? []), ...(options.memories ?? [])],
102
+ };
82
103
  if (!streaming) {
83
- const result = await engine.invoke(agent, input, { userContext });
104
+ const result = await engine.invoke(agent, input, mergedOptions);
84
105
  return new Response(JSON.stringify(result), {
85
106
  headers: { "Content-Type": "application/json" },
86
107
  });
87
108
  }
88
- const stream = await engine.invoke(agent, input, { userContext, streaming: true });
109
+ const stream = await engine.invoke(agent, input, {
110
+ ...mergedOptions,
111
+ returnActiveAgent: false,
112
+ streaming: true,
113
+ });
89
114
  return new Response(new AgentResponseStreamSSE(stream), {
90
115
  headers: {
91
116
  "Content-Type": "text/event-stream",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aigne/transport",
3
- "version": "0.2.0",
3
+ "version": "0.3.1",
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.2.0"
42
+ "@aigne/openai": "^0.2.2"
43
43
  },
44
44
  "devDependencies": {
45
45
  "@types/bun": "^1.2.12",
@@ -48,12 +48,14 @@
48
48
  "compression": "^1.8.0",
49
49
  "detect-port": "^2.1.0",
50
50
  "express": "^5.1.0",
51
+ "fast-deep-equal": "^3.1.3",
51
52
  "hono": "^4.7.10",
52
53
  "npm-run-all": "^4.1.5",
53
54
  "rimraf": "^6.0.1",
54
55
  "typescript": "^5.8.3",
55
- "@aigne/core": "^1.17.0",
56
- "@aigne/test-utils": "^0.3.1"
56
+ "uuid": "^11.1.0",
57
+ "@aigne/test-utils": "^0.3.3",
58
+ "@aigne/core": "^1.18.1"
57
59
  },
58
60
  "scripts": {
59
61
  "lint": "tsc --noEmit",