@ash-cloud/ash-ui 0.2.4 → 0.2.5

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.cts CHANGED
@@ -1059,6 +1059,7 @@ interface StreamEvent {
1059
1059
  text?: string;
1060
1060
  /** Message content array (for 'message' events) */
1061
1061
  content?: unknown;
1062
+ requestId?: string;
1062
1063
  toolId?: string;
1063
1064
  toolName?: string;
1064
1065
  input?: unknown;
@@ -1071,6 +1072,8 @@ interface StreamEvent {
1071
1072
  result?: string;
1072
1073
  totalCost?: number;
1073
1074
  totalTokens?: number;
1075
+ stop_reason?: string;
1076
+ stop_sequence?: string;
1074
1077
  /** SSE event ID (sequence number from relay) for reconnection */
1075
1078
  id?: string;
1076
1079
  entry?: {
@@ -1081,6 +1084,12 @@ interface StreamEvent {
1081
1084
  data?: Record<string, unknown>;
1082
1085
  };
1083
1086
  }
1087
+ interface ToolPermissionRequest {
1088
+ requestId: string;
1089
+ sessionId: string;
1090
+ toolName: string;
1091
+ input?: unknown;
1092
+ }
1084
1093
  /**
1085
1094
  * Async generator that yields StreamEvent objects
1086
1095
  */
@@ -1204,6 +1213,15 @@ interface UseAgentChatOptions {
1204
1213
  * Callback for sandbox log events
1205
1214
  */
1206
1215
  onSandboxLog?: (entry: NonNullable<StreamEvent['entry']>) => void;
1216
+ /**
1217
+ * Callback to approve/deny tool usage requests.
1218
+ * When provided, tool permission events will be resolved automatically.
1219
+ */
1220
+ canUseTool?: (request: ToolPermissionRequest) => boolean | Promise<boolean>;
1221
+ /**
1222
+ * Function to resolve a tool permission request (sends the decision to the server).
1223
+ */
1224
+ resolveToolPermission?: (request: ToolPermissionRequest, allow: boolean) => Promise<void>;
1207
1225
  /**
1208
1226
  * Callback when reconnection is attempted
1209
1227
  */
@@ -1409,6 +1427,15 @@ interface UseChatOptions {
1409
1427
  * Callback when a tool is called
1410
1428
  */
1411
1429
  onToolCall?: (handler: ToolCallHandler) => void;
1430
+ /**
1431
+ * Callback to approve/deny tool usage requests.
1432
+ * When provided, tool permission events will be resolved automatically.
1433
+ */
1434
+ canUseTool?: (request: ToolPermissionRequest) => boolean | Promise<boolean>;
1435
+ /**
1436
+ * Function to resolve a tool permission request (sends the decision to the server).
1437
+ */
1438
+ resolveToolPermission?: (request: ToolPermissionRequest, allow: boolean) => Promise<void>;
1412
1439
  /**
1413
1440
  * Callback when streaming finishes
1414
1441
  */
package/dist/index.d.ts CHANGED
@@ -1059,6 +1059,7 @@ interface StreamEvent {
1059
1059
  text?: string;
1060
1060
  /** Message content array (for 'message' events) */
1061
1061
  content?: unknown;
1062
+ requestId?: string;
1062
1063
  toolId?: string;
1063
1064
  toolName?: string;
1064
1065
  input?: unknown;
@@ -1071,6 +1072,8 @@ interface StreamEvent {
1071
1072
  result?: string;
1072
1073
  totalCost?: number;
1073
1074
  totalTokens?: number;
1075
+ stop_reason?: string;
1076
+ stop_sequence?: string;
1074
1077
  /** SSE event ID (sequence number from relay) for reconnection */
1075
1078
  id?: string;
1076
1079
  entry?: {
@@ -1081,6 +1084,12 @@ interface StreamEvent {
1081
1084
  data?: Record<string, unknown>;
1082
1085
  };
1083
1086
  }
1087
+ interface ToolPermissionRequest {
1088
+ requestId: string;
1089
+ sessionId: string;
1090
+ toolName: string;
1091
+ input?: unknown;
1092
+ }
1084
1093
  /**
1085
1094
  * Async generator that yields StreamEvent objects
1086
1095
  */
@@ -1204,6 +1213,15 @@ interface UseAgentChatOptions {
1204
1213
  * Callback for sandbox log events
1205
1214
  */
1206
1215
  onSandboxLog?: (entry: NonNullable<StreamEvent['entry']>) => void;
1216
+ /**
1217
+ * Callback to approve/deny tool usage requests.
1218
+ * When provided, tool permission events will be resolved automatically.
1219
+ */
1220
+ canUseTool?: (request: ToolPermissionRequest) => boolean | Promise<boolean>;
1221
+ /**
1222
+ * Function to resolve a tool permission request (sends the decision to the server).
1223
+ */
1224
+ resolveToolPermission?: (request: ToolPermissionRequest, allow: boolean) => Promise<void>;
1207
1225
  /**
1208
1226
  * Callback when reconnection is attempted
1209
1227
  */
@@ -1409,6 +1427,15 @@ interface UseChatOptions {
1409
1427
  * Callback when a tool is called
1410
1428
  */
1411
1429
  onToolCall?: (handler: ToolCallHandler) => void;
1430
+ /**
1431
+ * Callback to approve/deny tool usage requests.
1432
+ * When provided, tool permission events will be resolved automatically.
1433
+ */
1434
+ canUseTool?: (request: ToolPermissionRequest) => boolean | Promise<boolean>;
1435
+ /**
1436
+ * Function to resolve a tool permission request (sends the decision to the server).
1437
+ */
1438
+ resolveToolPermission?: (request: ToolPermissionRequest, allow: boolean) => Promise<void>;
1412
1439
  /**
1413
1440
  * Callback when streaming finishes
1414
1441
  */
package/dist/index.js CHANGED
@@ -3664,6 +3664,8 @@ function useAgentChat(options) {
3664
3664
  onSessionEnd,
3665
3665
  onError,
3666
3666
  onSandboxLog,
3667
+ canUseTool,
3668
+ resolveToolPermission,
3667
3669
  onReconnect,
3668
3670
  maxReconnectAttempts = 3,
3669
3671
  reconnectBaseDelay = 1e3,
@@ -3697,6 +3699,23 @@ function useAgentChat(options) {
3697
3699
  const emitStreamingEntries = useCallback((newEntries) => {
3698
3700
  setStreamingEntries([...newEntries]);
3699
3701
  }, []);
3702
+ const handleToolPermission = useCallback(async (event) => {
3703
+ if (event.type !== "tool_permission") return;
3704
+ if (!canUseTool) return;
3705
+ if (!event.requestId || !event.sessionId || !event.toolName) return;
3706
+ const request = {
3707
+ requestId: event.requestId,
3708
+ sessionId: event.sessionId,
3709
+ toolName: event.toolName,
3710
+ input: event.input
3711
+ };
3712
+ const allow = await canUseTool(request);
3713
+ if (!resolveToolPermission) {
3714
+ console.warn("[useAgentChat] resolveToolPermission not provided for tool permission response");
3715
+ return;
3716
+ }
3717
+ await resolveToolPermission(request, allow);
3718
+ }, [canUseTool, resolveToolPermission]);
3700
3719
  const createTextEntry = useCallback((id, content) => ({
3701
3720
  id,
3702
3721
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
@@ -3855,6 +3874,7 @@ function useAgentChat(options) {
3855
3874
  for await (const event of stream) {
3856
3875
  if (controller.signal.aborted) break;
3857
3876
  eventCountRef.current++;
3877
+ await handleToolPermission(event);
3858
3878
  localStreamingEntries = processEvent(event, localStreamingEntries);
3859
3879
  emitStreamingEntries(localStreamingEntries);
3860
3880
  if (event.type === "complete" || event.type === "session_end" || event.type === "error") {
@@ -3888,7 +3908,7 @@ function useAgentChat(options) {
3888
3908
  }
3889
3909
  return false;
3890
3910
  }
3891
- }, [subscribeToSession, maxReconnectAttempts, reconnectBaseDelay, onReconnect, processEvent, emitStreamingEntries]);
3911
+ }, [subscribeToSession, maxReconnectAttempts, reconnectBaseDelay, onReconnect, processEvent, emitStreamingEntries, handleToolPermission]);
3892
3912
  const send = useCallback(async (prompt) => {
3893
3913
  if (isStreaming) return;
3894
3914
  let finalPrompt = prompt;
@@ -3967,6 +3987,7 @@ function useAgentChat(options) {
3967
3987
  console.error("[useAgentChat] onEvent error:", err);
3968
3988
  }
3969
3989
  }
3990
+ await handleToolPermission(event);
3970
3991
  let processedEvent = event;
3971
3992
  if (middleware?.length) {
3972
3993
  processedEvent = await applyEventMiddleware(middleware, event);
@@ -4016,7 +4037,7 @@ function useAgentChat(options) {
4016
4037
  abortControllerRef.current = null;
4017
4038
  resetStreamingState();
4018
4039
  }
4019
- }, [isStreaming, sessionId, historyEntries, streamingEntries, createStream, subscribeToSession, processEvent, emitStreamingEntries, resetStreamingState, onError, attemptReconnect, onBeforeSend, onEvent, middleware]);
4040
+ }, [isStreaming, sessionId, historyEntries, streamingEntries, createStream, subscribeToSession, processEvent, emitStreamingEntries, resetStreamingState, onError, attemptReconnect, onBeforeSend, onEvent, middleware, handleToolPermission]);
4020
4041
  const stop = useCallback(() => {
4021
4042
  reconnectAttemptsRef.current = maxReconnectAttempts + 1;
4022
4043
  setIsReconnecting(false);
@@ -4067,6 +4088,8 @@ function useChat(options) {
4067
4088
  initialSessionId,
4068
4089
  initialMessages = [],
4069
4090
  onToolCall,
4091
+ canUseTool,
4092
+ resolveToolPermission,
4070
4093
  onFinish,
4071
4094
  onError,
4072
4095
  onSessionStart,
@@ -4101,6 +4124,23 @@ function useChat(options) {
4101
4124
  return prev;
4102
4125
  });
4103
4126
  }, []);
4127
+ const handleToolPermission = useCallback(async (event) => {
4128
+ if (event.type !== "tool_permission") return;
4129
+ if (!canUseTool) return;
4130
+ if (!event.requestId || !event.sessionId || !event.toolName) return;
4131
+ const request = {
4132
+ requestId: event.requestId,
4133
+ sessionId: event.sessionId,
4134
+ toolName: event.toolName,
4135
+ input: event.input
4136
+ };
4137
+ const allow = await canUseTool(request);
4138
+ if (!resolveToolPermission) {
4139
+ console.warn("[useChat] resolveToolPermission not provided for tool permission response");
4140
+ return;
4141
+ }
4142
+ await resolveToolPermission(request, allow);
4143
+ }, [canUseTool, resolveToolPermission]);
4104
4144
  const processEvent = useCallback((event) => {
4105
4145
  switch (event.type) {
4106
4146
  case "session_start":
@@ -4220,6 +4260,7 @@ function useChat(options) {
4220
4260
  const stream = createStream(finalPrompt, sessionIdRef.current || void 0, streamOptions);
4221
4261
  for await (const event of stream) {
4222
4262
  if (controller.signal.aborted) break;
4263
+ await handleToolPermission(event);
4223
4264
  let processedEvent = event;
4224
4265
  if (middleware?.length) {
4225
4266
  processedEvent = await applyEventMiddleware(middleware, event);
@@ -4249,7 +4290,7 @@ function useChat(options) {
4249
4290
  abortControllerRef.current = null;
4250
4291
  currentAssistantMessageRef.current = null;
4251
4292
  }
4252
- }, [isLoading, createStream, processEvent, middleware, onError]);
4293
+ }, [isLoading, createStream, processEvent, middleware, onError, handleToolPermission]);
4253
4294
  const stop = useCallback(() => {
4254
4295
  reconnectAttemptsRef.current = maxReconnectAttempts + 1;
4255
4296
  setIsReconnecting(false);