agentxjs 2.9.0-dev-20260317033749 → 2.9.0-dev-20260317042246

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/dist/index.d.ts CHANGED
@@ -3,7 +3,7 @@ import { AgentXPlatform } from '@agentxjs/core/runtime';
3
3
  import { UserContentPart, Message } from '@agentxjs/core/agent';
4
4
  import { AgentXError } from '@agentxjs/core/error';
5
5
  export { AgentXError, AgentXErrorCategory, AgentXErrorCode, AgentXErrorContext } from '@agentxjs/core/error';
6
- import { Unsubscribe, BusEvent, EventBus, BusEventHandler } from '@agentxjs/core/event';
6
+ import { BusEvent, EventBus, BusEventHandler, Unsubscribe } from '@agentxjs/core/event';
7
7
  import { LLMProtocol, LLMProviderRecord } from '@agentxjs/core/persistence';
8
8
  export { Capability, Context, ContextProvider } from '@agentxjs/core/context';
9
9
 
@@ -206,99 +206,67 @@ declare const initialMetrics: PresentationMetrics;
206
206
  declare const initialPresentationState: PresentationState;
207
207
 
208
208
  /**
209
- * Presentation Class
210
- *
211
- * High-level API for UI integration.
212
- * Wraps AgentX client and provides presentation state management.
213
- */
214
-
215
- /**
216
- * Presentation update handler
217
- */
218
- type PresentationUpdateHandler = (state: PresentationState) => void;
219
- /**
220
- * Presentation error handler
209
+ * Workspace — file tree + operations, unified.
221
210
  */
222
- type PresentationErrorHandler = (error: Error) => void;
211
+ interface Workspace {
212
+ /** Current file tree (real-time updates) */
213
+ readonly files: readonly FileTreeEntry[];
214
+ /** Read file content */
215
+ read(path: string): Promise<string>;
216
+ /** Write content to file */
217
+ write(path: string, content: string): Promise<void>;
218
+ /** List directory entries */
219
+ list(path?: string): Promise<FileTreeEntry[]>;
220
+ }
223
221
  /**
224
- * Presentation options
222
+ * Options for creating a Presentation
225
223
  */
226
224
  interface PresentationOptions {
227
- /**
228
- * Called on every state update
229
- */
230
- onUpdate?: PresentationUpdateHandler;
231
- /**
232
- * Called on errors
233
- */
234
- onError?: PresentationErrorHandler;
225
+ /** Called on every state change (legacy — prefer subscribe) */
226
+ onUpdate?: (state: PresentationState) => void;
235
227
  }
236
- /**
237
- * Presentation - UI-friendly wrapper for AgentX
238
- */
239
228
  declare class Presentation {
240
- private agentx;
241
- private instanceId;
242
- private state;
243
- private updateHandlers;
244
- private errorHandlers;
245
- private eventUnsubscribe;
246
- /**
247
- * Workspace operations — read, write, list files in the agent's workspace.
248
- * null when the agent has no workspace.
249
- */
250
- readonly workspace: PresentationWorkspace | null;
229
+ private _agentx;
230
+ private _instanceId;
231
+ private _state;
232
+ private _listeners;
233
+ private _legacyHandlers;
234
+ private _eventUnsubscribe;
235
+ private _workspaceOps;
251
236
  constructor(agentx: AgentX, instanceId: string, options?: PresentationOptions, initialConversations?: Conversation[], workspace?: PresentationWorkspace | null);
252
- /**
253
- * Get current state
254
- */
255
- getState(): PresentationState;
256
- /**
257
- * Subscribe to state updates
258
- */
259
- onUpdate(handler: PresentationUpdateHandler): Unsubscribe;
260
- /**
261
- * Subscribe to errors
237
+ /** All conversations (user, assistant, error) */
238
+ get conversations(): readonly Conversation[];
239
+ /** Current agent status */
240
+ get status(): PresentationState["status"];
241
+ /** WebSocket connection state */
242
+ get connection(): ConnectionState;
243
+ /** Token usage and context metrics */
244
+ get metrics(): PresentationMetrics;
245
+ /** Workspace — file tree + operations. null if agent has no workspace. */
246
+ get workspace(): Workspace | null;
247
+ /**
248
+ * Subscribe to state changes.
249
+ * Compatible with React's useSyncExternalStore.
250
+ * Does NOT call listener immediately.
251
+ *
252
+ * @returns Unsubscribe function
262
253
  */
263
- onError(handler: PresentationErrorHandler): Unsubscribe;
254
+ subscribe(listener: () => void): () => void;
264
255
  /**
265
- * Send a message (text or content parts with files/images)
256
+ * Get state snapshot.
257
+ * Compatible with React's useSyncExternalStore.
266
258
  */
259
+ getSnapshot(): PresentationState;
260
+ /** Send a message */
267
261
  send(content: string | UserContentPart[]): Promise<void>;
268
- /**
269
- * Interrupt current response
270
- */
262
+ /** Interrupt current response */
271
263
  interrupt(): Promise<void>;
272
- /**
273
- * Rewind conversation to a specific index.
274
- *
275
- * Calls runtime.rewind — a system-level operation that:
276
- * 1. Truncates session messages
277
- * 2. Resets circuit breaker
278
- * 3. Emits rewind event → reducer updates state
279
- *
280
- * @param index - conversation index to rewind to (0-based, removes this index and after)
281
- */
264
+ /** Rewind conversation to a specific index (removes index and everything after) */
282
265
  rewind(index: number): Promise<void>;
283
- /**
284
- * Edit a user message and resend.
285
- * Rewinds to the message, replaces it, and sends the new content.
286
- *
287
- * @param index - conversation index of the user message to edit (0-based)
288
- * @param content - new content to send
289
- */
290
- editAndResend(index: number, content: string | UserContentPart[]): Promise<void>;
291
- /**
292
- * Reset state
293
- */
294
- reset(): void;
295
- /**
296
- * Dispose and cleanup
297
- */
266
+ /** Dispose and cleanup all subscriptions */
298
267
  dispose(): void;
299
- private subscribeToEvents;
300
- private notify;
301
- private notifyError;
268
+ private _subscribeToEvents;
269
+ private _notify;
302
270
  }
303
271
 
304
272
  /**
@@ -840,4 +808,4 @@ interface PlatformConfig {
840
808
  */
841
809
  declare function createAgentX(config?: PlatformConfig): AgentXBuilder;
842
810
 
843
- export { type AgentConfig, type AgentHandle, type AgentX, type AgentXBuilder, type AgentXServer, type AssistantConversation, type BaseResponse, type Block, type ChatNamespace, type ConnectOptions, type Conversation, type ErrorConversation, type FileBlock, type ImageBlock, type ImageCreateResponse, type ImageGetResponse, type ImageListResponse, type ImageNamespace, type ImageRecord, type ImageUpdateResponse, type InstanceCreateResponse, type InstanceGetResponse, type InstanceInfo, type InstanceListResponse, type LLMNamespace, type LLMProviderCreateResponse, type LLMProviderDefaultResponse, type LLMProviderGetResponse, type LLMProviderListResponse, type LLMProviderUpdateResponse, type MaybeAsync, type MessageSendResponse, type PlatformConfig, Presentation, type PresentationErrorHandler, type PresentationMetrics, type PresentationNamespace, type PresentationOptions, type PresentationState, type PresentationUpdateHandler, type RuntimeNamespace, type ServeConfig, type SessionNamespace, type TextBlock, type ThinkingBlock, type ToolBlock, type UserConversation, addUserConversation, createAgentX, createInitialState, initialMetrics, initialPresentationState, messagesToConversations, presentationReducer };
811
+ export { type AgentConfig, type AgentHandle, type AgentX, type AgentXBuilder, type AgentXServer, type AssistantConversation, type BaseResponse, type Block, type ChatNamespace, type ConnectOptions, type Conversation, type ErrorConversation, type FileBlock, type FileTreeEntry, type ImageBlock, type ImageCreateResponse, type ImageGetResponse, type ImageListResponse, type ImageNamespace, type ImageRecord, type ImageUpdateResponse, type InstanceCreateResponse, type InstanceGetResponse, type InstanceInfo, type InstanceListResponse, type LLMNamespace, type LLMProviderCreateResponse, type LLMProviderDefaultResponse, type LLMProviderGetResponse, type LLMProviderListResponse, type LLMProviderUpdateResponse, type MaybeAsync, type MessageSendResponse, type PlatformConfig, Presentation, type PresentationMetrics, type PresentationNamespace, type PresentationOptions, type PresentationState, type PresentationWorkspace, type RuntimeNamespace, type ServeConfig, type SessionNamespace, type TextBlock, type ThinkingBlock, type ToolBlock, type UserConversation, type Workspace, type WorkspaceState, addUserConversation, createAgentX, createInitialState, initialMetrics, initialPresentationState, messagesToConversations, presentationReducer };
package/dist/index.js CHANGED
@@ -741,103 +741,111 @@ function messagesToConversations(messages) {
741
741
 
742
742
  // src/presentation/Presentation.ts
743
743
  var Presentation = class {
744
- agentx;
745
- instanceId;
746
- state;
747
- updateHandlers = /* @__PURE__ */ new Set();
748
- errorHandlers = /* @__PURE__ */ new Set();
749
- eventUnsubscribe = null;
750
- /**
751
- * Workspace operations — read, write, list files in the agent's workspace.
752
- * null when the agent has no workspace.
753
- */
754
- workspace;
744
+ _agentx;
745
+ _instanceId;
746
+ _state;
747
+ _listeners = /* @__PURE__ */ new Set();
748
+ _legacyHandlers = /* @__PURE__ */ new Set();
749
+ _eventUnsubscribe = null;
750
+ _workspaceOps;
755
751
  constructor(agentx, instanceId, options, initialConversations, workspace) {
756
- this.agentx = agentx;
757
- this.instanceId = instanceId;
758
- this.workspace = workspace ?? null;
759
- this.state = initialConversations?.length ? { ...initialPresentationState, conversations: initialConversations } : createInitialState();
752
+ this._agentx = agentx;
753
+ this._instanceId = instanceId;
754
+ this._workspaceOps = workspace ?? null;
755
+ this._state = initialConversations?.length ? { ...initialPresentationState, conversations: initialConversations } : createInitialState();
760
756
  if (options?.onUpdate) {
761
- this.updateHandlers.add(options.onUpdate);
757
+ this._legacyHandlers.add(options.onUpdate);
762
758
  }
763
- if (options?.onError) {
764
- this.errorHandlers.add(options.onError);
765
- }
766
- this.subscribeToEvents();
767
- if (this.workspace) {
768
- this.workspace.list(".").then((files) => {
769
- this.state = { ...this.state, workspace: { files } };
770
- this.notify();
759
+ this._subscribeToEvents();
760
+ if (this._workspaceOps) {
761
+ this._workspaceOps.list(".").then((files) => {
762
+ this._state = { ...this._state, workspace: { files } };
763
+ this._notify();
771
764
  });
772
765
  }
773
766
  }
774
- /**
775
- * Get current state
776
- */
777
- getState() {
778
- return this.state;
767
+ // ==================== State (direct properties) ====================
768
+ /** All conversations (user, assistant, error) */
769
+ get conversations() {
770
+ return this._state.conversations;
779
771
  }
780
- /**
781
- * Subscribe to state updates
782
- */
783
- onUpdate(handler) {
784
- this.updateHandlers.add(handler);
785
- handler(this.state);
786
- return () => {
787
- this.updateHandlers.delete(handler);
772
+ /** Current agent status */
773
+ get status() {
774
+ return this._state.status;
775
+ }
776
+ /** WebSocket connection state */
777
+ get connection() {
778
+ return this._state.connection;
779
+ }
780
+ /** Token usage and context metrics */
781
+ get metrics() {
782
+ return this._state.metrics;
783
+ }
784
+ /** Workspace — file tree + operations. null if agent has no workspace. */
785
+ get workspace() {
786
+ if (!this._workspaceOps) return null;
787
+ const ops = this._workspaceOps;
788
+ const wsState = this._state.workspace;
789
+ return {
790
+ get files() {
791
+ return wsState?.files ?? [];
792
+ },
793
+ read: (path) => ops.read(path),
794
+ write: (path, content) => ops.write(path, content),
795
+ list: (path) => ops.list(path)
788
796
  };
789
797
  }
798
+ // ==================== Subscribe ====================
790
799
  /**
791
- * Subscribe to errors
800
+ * Subscribe to state changes.
801
+ * Compatible with React's useSyncExternalStore.
802
+ * Does NOT call listener immediately.
803
+ *
804
+ * @returns Unsubscribe function
792
805
  */
793
- onError(handler) {
794
- this.errorHandlers.add(handler);
806
+ subscribe(listener) {
807
+ this._listeners.add(listener);
795
808
  return () => {
796
- this.errorHandlers.delete(handler);
809
+ this._listeners.delete(listener);
797
810
  };
798
811
  }
799
812
  /**
800
- * Send a message (text or content parts with files/images)
813
+ * Get state snapshot.
814
+ * Compatible with React's useSyncExternalStore.
801
815
  */
816
+ getSnapshot() {
817
+ return this._state;
818
+ }
819
+ // ==================== Actions ====================
820
+ /** Send a message */
802
821
  async send(content) {
803
- this.state = addUserConversation(this.state, content);
804
- this.notify();
822
+ this._state = addUserConversation(this._state, content);
823
+ this._notify();
805
824
  await new Promise((resolve) => setTimeout(resolve, 0));
806
825
  try {
807
- await this.agentx.runtime.session.send(this.instanceId, content);
826
+ await this._agentx.runtime.session.send(this._instanceId, content);
808
827
  } catch (error) {
809
- this.notifyError(error instanceof Error ? error : new Error(String(error)));
828
+ console.error("Presentation send error:", error);
810
829
  }
811
830
  }
812
- /**
813
- * Interrupt current response
814
- */
831
+ /** Interrupt current response */
815
832
  async interrupt() {
816
833
  try {
817
- await this.agentx.runtime.session.interrupt(this.instanceId);
834
+ await this._agentx.runtime.session.interrupt(this._instanceId);
818
835
  } catch (error) {
819
- this.notifyError(error instanceof Error ? error : new Error(String(error)));
836
+ console.error("Presentation interrupt error:", error);
820
837
  }
821
838
  }
822
- /**
823
- * Rewind conversation to a specific index.
824
- *
825
- * Calls runtime.rewind — a system-level operation that:
826
- * 1. Truncates session messages
827
- * 2. Resets circuit breaker
828
- * 3. Emits rewind event → reducer updates state
829
- *
830
- * @param index - conversation index to rewind to (0-based, removes this index and after)
831
- */
839
+ /** Rewind conversation to a specific index (removes index and everything after) */
832
840
  async rewind(index) {
833
- const conversations = this.state.conversations;
841
+ const conversations = this._state.conversations;
834
842
  if (index < 0 || index >= conversations.length) return;
835
843
  try {
836
- const messages = await this.agentx.runtime.session.getMessages(this.instanceId);
844
+ const messages = await this._agentx.runtime.session.getMessages(this._instanceId);
837
845
  if (messages.length === 0) return;
838
846
  if (index === 0) {
839
- await this.agentx.rpc("runtime.rewind", {
840
- imageId: this.instanceId,
847
+ await this._agentx.rpc("runtime.rewind", {
848
+ imageId: this._instanceId,
841
849
  messageId: messages[0].id
842
850
  });
843
851
  } else {
@@ -853,78 +861,56 @@ var Presentation = class {
853
861
  }
854
862
  }
855
863
  if (msgIndex >= 0 && msgIndex < messages.length) {
856
- await this.agentx.rpc("runtime.rewind", {
857
- imageId: this.instanceId,
864
+ await this._agentx.rpc("runtime.rewind", {
865
+ imageId: this._instanceId,
858
866
  messageId: messages[msgIndex].id
859
867
  });
860
868
  }
861
869
  }
862
870
  } catch (error) {
863
- this.notifyError(error instanceof Error ? error : new Error(String(error)));
871
+ console.error("Presentation rewind error:", error);
864
872
  }
865
873
  }
866
- /**
867
- * Edit a user message and resend.
868
- * Rewinds to the message, replaces it, and sends the new content.
869
- *
870
- * @param index - conversation index of the user message to edit (0-based)
871
- * @param content - new content to send
872
- */
873
- async editAndResend(index, content) {
874
- await this.rewind(index);
875
- await this.send(content);
876
- }
877
- /**
878
- * Reset state
879
- */
880
- reset() {
881
- this.state = createInitialState();
882
- this.notify();
883
- }
884
- /**
885
- * Dispose and cleanup
886
- */
874
+ /** Dispose and cleanup all subscriptions */
887
875
  dispose() {
888
- if (this.eventUnsubscribe) {
889
- this.eventUnsubscribe();
890
- this.eventUnsubscribe = null;
876
+ if (this._eventUnsubscribe) {
877
+ this._eventUnsubscribe();
878
+ this._eventUnsubscribe = null;
891
879
  }
892
- this.updateHandlers.clear();
893
- this.errorHandlers.clear();
880
+ this._listeners.clear();
881
+ this._legacyHandlers.clear();
894
882
  }
895
883
  // ==================== Private ====================
896
- subscribeToEvents() {
897
- this.eventUnsubscribe = this.agentx.onAny((event) => {
884
+ _subscribeToEvents() {
885
+ this._eventUnsubscribe = this._agentx.onAny((event) => {
898
886
  const eventWithContext = event;
899
887
  const eventAgentId = eventWithContext.context?.instanceId;
900
- if (eventAgentId && eventAgentId !== this.instanceId) {
888
+ if (eventAgentId && eventAgentId !== this._instanceId) {
901
889
  const eventImageId = eventWithContext.context?.imageId;
902
- if (!eventImageId || eventImageId !== this.instanceId) {
890
+ if (!eventImageId || eventImageId !== this._instanceId) {
903
891
  return;
904
892
  }
905
893
  }
906
- const newState = presentationReducer(this.state, event);
907
- if (newState !== this.state) {
908
- this.state = newState;
909
- this.notify();
894
+ const newState = presentationReducer(this._state, event);
895
+ if (newState !== this._state) {
896
+ this._state = newState;
897
+ this._notify();
910
898
  }
911
899
  });
912
900
  }
913
- notify() {
914
- for (const handler of this.updateHandlers) {
901
+ _notify() {
902
+ for (const listener of this._listeners) {
915
903
  try {
916
- handler(this.state);
904
+ listener();
917
905
  } catch (error) {
918
- console.error("Presentation update handler error:", error);
906
+ console.error("Presentation listener error:", error);
919
907
  }
920
908
  }
921
- }
922
- notifyError(error) {
923
- for (const handler of this.errorHandlers) {
909
+ for (const handler of this._legacyHandlers) {
924
910
  try {
925
- handler(error);
926
- } catch (e) {
927
- console.error("Presentation error handler error:", e);
911
+ handler(this._state);
912
+ } catch (error) {
913
+ console.error("Presentation handler error:", error);
928
914
  }
929
915
  }
930
916
  }