agentxjs 2.5.0 → 2.6.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.
@@ -17,14 +17,14 @@ import { createLocalContainers } from "./namespaces/containers";
17
17
  import { createLocalImages } from "./namespaces/images";
18
18
  import { createLocalLLM } from "./namespaces/llm";
19
19
  import { createPresentations } from "./namespaces/presentations";
20
+ import { createLocalPrototypes } from "./namespaces/prototypes";
20
21
  import { createLocalSessions } from "./namespaces/sessions";
21
22
  import type {
22
- AgentHandle,
23
23
  AgentX,
24
- Embodiment,
25
- ImageListResponse,
26
- InstanceNamespace,
24
+ ChatNamespace,
27
25
  LLMNamespace,
26
+ PrototypeNamespace,
27
+ RuntimeNamespace,
28
28
  } from "./types";
29
29
 
30
30
  const logger = createLogger("agentx/LocalClient");
@@ -33,26 +33,31 @@ const logger = createLogger("agentx/LocalClient");
33
33
  * LocalClient - Embedded runtime implementation
34
34
  */
35
35
  export class LocalClient implements AgentX {
36
- private readonly runtime: AgentXRuntime;
36
+ private readonly _runtime: AgentXRuntime;
37
37
  private commandHandler: CommandHandler | null = null;
38
38
  private isDisposed = false;
39
39
 
40
- readonly instance: InstanceNamespace;
40
+ readonly chat: ChatNamespace;
41
+ readonly runtime: RuntimeNamespace;
41
42
  readonly provider: LLMNamespace;
43
+ readonly prototype: PrototypeNamespace;
42
44
 
43
- constructor(runtime: AgentXRuntime) {
44
- this.runtime = runtime;
45
- const platform = runtime.platform;
45
+ constructor(agentxRuntime: AgentXRuntime) {
46
+ this._runtime = agentxRuntime;
47
+ const platform = agentxRuntime.platform;
46
48
 
47
49
  const container = createLocalContainers(platform);
48
50
  const image = createLocalImages(platform);
49
- const agent = createLocalAgents(runtime);
50
- const session = createLocalSessions(runtime);
51
+ const agent = createLocalAgents(agentxRuntime);
52
+ const session = createLocalSessions(agentxRuntime);
51
53
  const llm = createLocalLLM(platform);
54
+ const prototype = createLocalPrototypes(platform);
52
55
  const present = createPresentations(this, image);
53
56
 
54
- this.instance = { container, image, agent, session, present, llm };
57
+ this.runtime = { container, image, agent, session, present, llm, prototype };
55
58
  this.provider = llm;
59
+ this.prototype = prototype;
60
+ this.chat = this.createChatNamespace();
56
61
 
57
62
  logger.info("LocalClient initialized");
58
63
  }
@@ -64,59 +69,17 @@ export class LocalClient implements AgentX {
64
69
  }
65
70
 
66
71
  get events(): EventBus {
67
- return this.runtime.platform.eventBus;
68
- }
69
-
70
- // ==================== Top-level Agent API ====================
71
-
72
- async create(params: {
73
- name?: string;
74
- description?: string;
75
- contextId?: string;
76
- embody?: Embodiment;
77
- customData?: Record<string, unknown>;
78
- }): Promise<AgentHandle> {
79
- const containerId = "default";
80
- const imgRes = await this.instance.image.create({ containerId, ...params });
81
- const agentRes = await this.instance.agent.create({ imageId: imgRes.record.imageId });
82
- return new AgentHandleImpl(
83
- {
84
- agentId: agentRes.agentId,
85
- imageId: agentRes.imageId,
86
- containerId: agentRes.containerId,
87
- sessionId: agentRes.sessionId,
88
- },
89
- this.instance
90
- );
91
- }
92
-
93
- async list(): Promise<ImageListResponse> {
94
- return this.instance.image.list();
95
- }
96
-
97
- async get(agentId: string): Promise<AgentHandle | null> {
98
- const res = await this.instance.image.get(agentId);
99
- if (!res.record) return null;
100
- const r = res.record;
101
- return new AgentHandleImpl(
102
- {
103
- agentId: r.imageId,
104
- imageId: r.imageId,
105
- containerId: r.containerId,
106
- sessionId: r.sessionId,
107
- },
108
- this.instance
109
- );
72
+ return this._runtime.platform.eventBus;
110
73
  }
111
74
 
112
75
  // ==================== Event Subscription ====================
113
76
 
114
77
  on<T extends string>(type: T, handler: BusEventHandler<BusEvent & { type: T }>): Unsubscribe {
115
- return this.runtime.platform.eventBus.on(type, handler);
78
+ return this._runtime.platform.eventBus.on(type, handler);
116
79
  }
117
80
 
118
81
  onAny(handler: BusEventHandler): Unsubscribe {
119
- return this.runtime.platform.eventBus.onAny(handler);
82
+ return this._runtime.platform.eventBus.onAny(handler);
120
83
  }
121
84
 
122
85
  subscribe(_sessionId: string): void {
@@ -126,7 +89,7 @@ export class LocalClient implements AgentX {
126
89
  // ==================== Error Handling ====================
127
90
 
128
91
  onError(handler: (error: AgentXError) => void): Unsubscribe {
129
- return this.runtime.platform.eventBus.on("agentx_error", (event) => {
92
+ return this._runtime.platform.eventBus.on("agentx_error", (event) => {
130
93
  handler(event.data as AgentXError);
131
94
  });
132
95
  }
@@ -135,7 +98,7 @@ export class LocalClient implements AgentX {
135
98
 
136
99
  async rpc<T = unknown>(method: string, params?: unknown): Promise<T> {
137
100
  if (!this.commandHandler) {
138
- this.commandHandler = new CommandHandler(this.runtime);
101
+ this.commandHandler = new CommandHandler(this._runtime);
139
102
  }
140
103
  const result = await this.commandHandler.handle(method as RpcMethod, params);
141
104
  if (result.success) {
@@ -144,6 +107,63 @@ export class LocalClient implements AgentX {
144
107
  throw new Error(result.message);
145
108
  }
146
109
 
110
+ // ==================== Private ====================
111
+
112
+ private createChatNamespace(): ChatNamespace {
113
+ const instance = this.runtime;
114
+ return {
115
+ async create(params) {
116
+ const containerId = "default";
117
+ // If prototypeId is provided, merge prototype config into params
118
+ let mergedParams = { ...params };
119
+ if (params.prototypeId) {
120
+ const protoRes = await instance.prototype.get(params.prototypeId);
121
+ if (protoRes.record) {
122
+ const proto = protoRes.record;
123
+ mergedParams = {
124
+ name: proto.name,
125
+ description: proto.description,
126
+ contextId: proto.contextId,
127
+ embody: proto.embody,
128
+ customData: proto.customData,
129
+ ...params, // inline params override prototype
130
+ };
131
+ }
132
+ }
133
+ const { prototypeId: _pid, ...imageParams } = mergedParams;
134
+ const imgRes = await instance.image.create({ containerId, ...imageParams });
135
+ const agentRes = await instance.agent.create({ imageId: imgRes.record.imageId });
136
+ return new AgentHandleImpl(
137
+ {
138
+ agentId: agentRes.agentId,
139
+ imageId: agentRes.imageId,
140
+ containerId: agentRes.containerId,
141
+ sessionId: agentRes.sessionId,
142
+ },
143
+ instance
144
+ );
145
+ },
146
+ async list() {
147
+ return instance.image.list();
148
+ },
149
+ async get(id) {
150
+ const res = await instance.image.get(id);
151
+ if (!res.record) return null;
152
+ const r = res.record;
153
+ const agentRes = await instance.agent.create({ imageId: r.imageId });
154
+ return new AgentHandleImpl(
155
+ {
156
+ agentId: agentRes.agentId,
157
+ imageId: agentRes.imageId,
158
+ containerId: agentRes.containerId,
159
+ sessionId: agentRes.sessionId,
160
+ },
161
+ instance
162
+ );
163
+ },
164
+ };
165
+ }
166
+
147
167
  // ==================== Lifecycle ====================
148
168
 
149
169
  async disconnect(): Promise<void> {
@@ -152,7 +172,7 @@ export class LocalClient implements AgentX {
152
172
 
153
173
  async dispose(): Promise<void> {
154
174
  if (this.isDisposed) return;
155
- await this.runtime.shutdown();
175
+ await this._runtime.shutdown();
156
176
  this.isDisposed = true;
157
177
  logger.info("LocalClient disposed");
158
178
  }
@@ -16,15 +16,15 @@ import { createRemoteContainers } from "./namespaces/containers";
16
16
  import { createRemoteImages } from "./namespaces/images";
17
17
  import { createRemoteLLM } from "./namespaces/llm";
18
18
  import { createPresentations } from "./namespaces/presentations";
19
+ import { createRemotePrototypes } from "./namespaces/prototypes";
19
20
  import { createRemoteSessions } from "./namespaces/sessions";
20
21
  import type {
21
- AgentHandle,
22
22
  AgentX,
23
- Embodiment,
24
- ImageListResponse,
25
- InstanceNamespace,
23
+ ChatNamespace,
26
24
  LLMNamespace,
25
+ PrototypeNamespace,
27
26
  RemoteClientConfig,
27
+ RuntimeNamespace,
28
28
  } from "./types";
29
29
 
30
30
  const logger = createLogger("agentx/RemoteClient");
@@ -37,8 +37,10 @@ export class RemoteClient implements AgentX {
37
37
  private readonly eventBus: EventBus;
38
38
  private readonly rpcClient: RpcClient;
39
39
 
40
- readonly instance: InstanceNamespace;
40
+ readonly chat: ChatNamespace;
41
+ readonly runtime: RuntimeNamespace;
41
42
  readonly provider: LLMNamespace;
43
+ readonly prototype: PrototypeNamespace;
42
44
 
43
45
  constructor(config: RemoteClientConfig) {
44
46
  this.config = config;
@@ -66,10 +68,13 @@ export class RemoteClient implements AgentX {
66
68
  const agent = createRemoteAgents(this.rpcClient);
67
69
  const session = createRemoteSessions(this.rpcClient);
68
70
  const llm = createRemoteLLM(this.rpcClient);
71
+ const prototype = createRemotePrototypes(this.rpcClient);
69
72
  const present = createPresentations(this, image);
70
73
 
71
- this.instance = { container, image, agent, session, present, llm };
74
+ this.runtime = { container, image, agent, session, present, llm, prototype };
72
75
  this.provider = llm;
76
+ this.prototype = prototype;
77
+ this.chat = this.createChatNamespace();
73
78
  }
74
79
 
75
80
  // ==================== Properties ====================
@@ -82,48 +87,6 @@ export class RemoteClient implements AgentX {
82
87
  return this.eventBus;
83
88
  }
84
89
 
85
- // ==================== Top-level Agent API ====================
86
-
87
- async create(params: {
88
- name?: string;
89
- description?: string;
90
- contextId?: string;
91
- embody?: Embodiment;
92
- customData?: Record<string, unknown>;
93
- }): Promise<AgentHandle> {
94
- const containerId = "default";
95
- const imgRes = await this.instance.image.create({ containerId, ...params });
96
- const agentRes = await this.instance.agent.create({ imageId: imgRes.record.imageId });
97
- return new AgentHandleImpl(
98
- {
99
- agentId: agentRes.agentId,
100
- imageId: agentRes.imageId,
101
- containerId: agentRes.containerId,
102
- sessionId: agentRes.sessionId,
103
- },
104
- this.instance
105
- );
106
- }
107
-
108
- async list(): Promise<ImageListResponse> {
109
- return this.instance.image.list();
110
- }
111
-
112
- async get(agentId: string): Promise<AgentHandle | null> {
113
- const res = await this.instance.image.get(agentId);
114
- if (!res.record) return null;
115
- const r = res.record;
116
- return new AgentHandleImpl(
117
- {
118
- agentId: r.imageId,
119
- imageId: r.imageId,
120
- containerId: r.containerId,
121
- sessionId: r.sessionId,
122
- },
123
- this.instance
124
- );
125
- }
126
-
127
90
  // ==================== Connection ====================
128
91
 
129
92
  async connect(): Promise<void> {
@@ -170,4 +133,61 @@ export class RemoteClient implements AgentX {
170
133
  async rpc<T = unknown>(method: string, params?: unknown): Promise<T> {
171
134
  return this.rpcClient.call<T>(method as RpcMethod, params);
172
135
  }
136
+
137
+ // ==================== Private ====================
138
+
139
+ private createChatNamespace(): ChatNamespace {
140
+ const instance = this.runtime;
141
+ return {
142
+ async create(params) {
143
+ const containerId = "default";
144
+ // If prototypeId is provided, merge prototype config into params
145
+ let mergedParams = { ...params };
146
+ if (params.prototypeId) {
147
+ const protoRes = await instance.prototype.get(params.prototypeId);
148
+ if (protoRes.record) {
149
+ const proto = protoRes.record;
150
+ mergedParams = {
151
+ name: proto.name,
152
+ description: proto.description,
153
+ contextId: proto.contextId,
154
+ embody: proto.embody,
155
+ customData: proto.customData,
156
+ ...params, // inline params override prototype
157
+ };
158
+ }
159
+ }
160
+ const { prototypeId: _pid, ...imageParams } = mergedParams;
161
+ const imgRes = await instance.image.create({ containerId, ...imageParams });
162
+ const agentRes = await instance.agent.create({ imageId: imgRes.record.imageId });
163
+ return new AgentHandleImpl(
164
+ {
165
+ agentId: agentRes.agentId,
166
+ imageId: agentRes.imageId,
167
+ containerId: agentRes.containerId,
168
+ sessionId: agentRes.sessionId,
169
+ },
170
+ instance
171
+ );
172
+ },
173
+ async list() {
174
+ return instance.image.list();
175
+ },
176
+ async get(id) {
177
+ const res = await instance.image.get(id);
178
+ if (!res.record) return null;
179
+ const r = res.record;
180
+ const agentRes = await instance.agent.create({ imageId: r.imageId });
181
+ return new AgentHandleImpl(
182
+ {
183
+ agentId: agentRes.agentId,
184
+ imageId: agentRes.imageId,
185
+ containerId: agentRes.containerId,
186
+ sessionId: agentRes.sessionId,
187
+ },
188
+ instance
189
+ );
190
+ },
191
+ };
192
+ }
173
193
  }
package/src/index.ts CHANGED
@@ -9,7 +9,7 @@
9
9
  * import { nodePlatform } from "@agentxjs/node-platform";
10
10
  *
11
11
  * const ax = createAgentX(nodePlatform({ createDriver }));
12
- * const agent = await ax.create({ name: "Aristotle", embody: { model: "claude-sonnet-4-6" } });
12
+ * const agent = await ax.chat.create({ name: "Aristotle", embody: { model: "claude-sonnet-4-6" } });
13
13
  * await agent.send("Hello!");
14
14
  * ```
15
15
  *
@@ -75,18 +75,21 @@ export function createAgentX(config?: PlatformConfig): AgentXBuilder {
75
75
  return getLocalClient().events;
76
76
  },
77
77
 
78
- get instance() {
79
- return getLocalClient().instance;
78
+ get runtime() {
79
+ return getLocalClient().runtime;
80
80
  },
81
81
 
82
82
  get provider() {
83
83
  return getLocalClient().provider;
84
84
  },
85
85
 
86
- // Top-level Agent API
87
- create: (params) => getLocalClient().create(params),
88
- list: () => getLocalClient().list(),
89
- get: (agentId) => getLocalClient().get(agentId),
86
+ get chat() {
87
+ return getLocalClient().chat;
88
+ },
89
+
90
+ get prototype() {
91
+ return getLocalClient().prototype;
92
+ },
90
93
 
91
94
  on(type, handler) {
92
95
  return getLocalClient().on(type, handler);
@@ -194,6 +197,7 @@ export type {
194
197
  AgentXBuilder,
195
198
  AgentXServer,
196
199
  BaseResponse,
200
+ ChatNamespace,
197
201
  ConnectOptions,
198
202
  ContainerCreateResponse,
199
203
  ContainerGetResponse,
@@ -206,7 +210,6 @@ export type {
206
210
  ImageListResponse,
207
211
  ImageNamespace,
208
212
  ImageRecord,
209
- InstanceNamespace,
210
213
  LLMNamespace,
211
214
  LLMProviderCreateResponse,
212
215
  LLMProviderDefaultResponse,
@@ -216,6 +219,12 @@ export type {
216
219
  MaybeAsync,
217
220
  MessageSendResponse,
218
221
  PresentationNamespace,
222
+ PrototypeCreateResponse,
223
+ PrototypeGetResponse,
224
+ PrototypeListResponse,
225
+ PrototypeNamespace,
226
+ PrototypeUpdateResponse,
227
+ RuntimeNamespace,
219
228
  ServeConfig,
220
229
  SessionNamespace,
221
230
  } from "./types";
@@ -0,0 +1,136 @@
1
+ /**
2
+ * Prototype namespace factories
3
+ */
4
+
5
+ import type { RpcClient } from "@agentxjs/core/network";
6
+ import type { AgentXPlatform } from "@agentxjs/core/runtime";
7
+ import type {
8
+ BaseResponse,
9
+ PrototypeCreateResponse,
10
+ PrototypeGetResponse,
11
+ PrototypeListResponse,
12
+ PrototypeNamespace,
13
+ PrototypeUpdateResponse,
14
+ } from "../types";
15
+
16
+ /**
17
+ * Create local prototype namespace backed by embedded runtime
18
+ */
19
+ export function createLocalPrototypes(platform: AgentXPlatform): PrototypeNamespace {
20
+ return {
21
+ async create(params): Promise<PrototypeCreateResponse> {
22
+ const repo = platform.prototypeRepository;
23
+ if (!repo) {
24
+ throw new Error("Prototype repository not available");
25
+ }
26
+
27
+ const now = Date.now();
28
+ const random = Math.random().toString(36).slice(2, 8);
29
+ const record = {
30
+ prototypeId: `proto_${now}_${random}`,
31
+ containerId: params.containerId,
32
+ name: params.name,
33
+ description: params.description,
34
+ contextId: params.contextId,
35
+ embody: params.embody,
36
+ customData: params.customData,
37
+ createdAt: now,
38
+ updatedAt: now,
39
+ };
40
+
41
+ await repo.savePrototype(record);
42
+ return { record, requestId: "" };
43
+ },
44
+
45
+ async get(prototypeId: string): Promise<PrototypeGetResponse> {
46
+ const repo = platform.prototypeRepository;
47
+ if (!repo) {
48
+ throw new Error("Prototype repository not available");
49
+ }
50
+
51
+ const record = await repo.findPrototypeById(prototypeId);
52
+ return { record, requestId: "" };
53
+ },
54
+
55
+ async list(containerId?: string): Promise<PrototypeListResponse> {
56
+ const repo = platform.prototypeRepository;
57
+ if (!repo) {
58
+ throw new Error("Prototype repository not available");
59
+ }
60
+
61
+ const records = containerId
62
+ ? await repo.findPrototypesByContainerId(containerId)
63
+ : await repo.findAllPrototypes();
64
+
65
+ return { records, requestId: "" };
66
+ },
67
+
68
+ async update(prototypeId, updates): Promise<PrototypeUpdateResponse> {
69
+ const repo = platform.prototypeRepository;
70
+ if (!repo) {
71
+ throw new Error("Prototype repository not available");
72
+ }
73
+
74
+ const existing = await repo.findPrototypeById(prototypeId);
75
+ if (!existing) {
76
+ throw new Error(`Prototype not found: ${prototypeId}`);
77
+ }
78
+
79
+ const { embody: embodyUpdates, ...otherUpdates } = updates;
80
+ const updatedRecord = {
81
+ ...existing,
82
+ ...otherUpdates,
83
+ embody: embodyUpdates ? { ...existing.embody, ...embodyUpdates } : existing.embody,
84
+ updatedAt: Date.now(),
85
+ };
86
+
87
+ await repo.savePrototype(updatedRecord);
88
+ return { record: updatedRecord, requestId: "" };
89
+ },
90
+
91
+ async delete(prototypeId: string): Promise<BaseResponse> {
92
+ const repo = platform.prototypeRepository;
93
+ if (!repo) {
94
+ throw new Error("Prototype repository not available");
95
+ }
96
+
97
+ await repo.deletePrototype(prototypeId);
98
+ return { requestId: "" };
99
+ },
100
+ };
101
+ }
102
+
103
+ /**
104
+ * Create remote prototype namespace backed by RPC client
105
+ */
106
+ export function createRemotePrototypes(rpcClient: RpcClient): PrototypeNamespace {
107
+ return {
108
+ async create(params): Promise<PrototypeCreateResponse> {
109
+ const result = await rpcClient.call<PrototypeCreateResponse>("prototype.create", params);
110
+ return { ...result, requestId: "" };
111
+ },
112
+
113
+ async get(prototypeId: string): Promise<PrototypeGetResponse> {
114
+ const result = await rpcClient.call<PrototypeGetResponse>("prototype.get", { prototypeId });
115
+ return { ...result, requestId: "" };
116
+ },
117
+
118
+ async list(containerId?: string): Promise<PrototypeListResponse> {
119
+ const result = await rpcClient.call<PrototypeListResponse>("prototype.list", { containerId });
120
+ return { ...result, requestId: "" };
121
+ },
122
+
123
+ async update(prototypeId, updates): Promise<PrototypeUpdateResponse> {
124
+ const result = await rpcClient.call<PrototypeUpdateResponse>("prototype.update", {
125
+ prototypeId,
126
+ updates,
127
+ });
128
+ return { ...result, requestId: "" };
129
+ },
130
+
131
+ async delete(prototypeId: string): Promise<BaseResponse> {
132
+ const result = await rpcClient.call<BaseResponse>("prototype.delete", { prototypeId });
133
+ return { ...result, requestId: "" };
134
+ },
135
+ };
136
+ }
@@ -110,7 +110,7 @@ export class Presentation {
110
110
 
111
111
  try {
112
112
  // Send message via agentx
113
- await this.agentx.instance.session.send(this.agentId, content);
113
+ await this.agentx.runtime.session.send(this.agentId, content);
114
114
  } catch (error) {
115
115
  this.notifyError(error instanceof Error ? error : new Error(String(error)));
116
116
  }
@@ -121,7 +121,7 @@ export class Presentation {
121
121
  */
122
122
  async interrupt(): Promise<void> {
123
123
  try {
124
- await this.agentx.instance.session.interrupt(this.agentId);
124
+ await this.agentx.runtime.session.interrupt(this.agentId);
125
125
  } catch (error) {
126
126
  this.notifyError(error instanceof Error ? error : new Error(String(error)));
127
127
  }