@witqq/agent-sdk 0.8.0 → 0.9.0

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.
Files changed (113) hide show
  1. package/dist/{agent-DxY68NZL.d.cts → agent-C6H2CgJA.d.cts} +2 -0
  2. package/dist/{agent-CW9XbmG_.d.ts → agent-F7oB6eKp.d.ts} +2 -0
  3. package/dist/backends/claude.cjs.map +1 -1
  4. package/dist/backends/claude.d.cts +2 -2
  5. package/dist/backends/claude.d.ts +2 -2
  6. package/dist/backends/claude.js.map +1 -1
  7. package/dist/backends/copilot.cjs +8 -15
  8. package/dist/backends/copilot.cjs.map +1 -1
  9. package/dist/backends/copilot.d.cts +2 -2
  10. package/dist/backends/copilot.d.ts +2 -2
  11. package/dist/backends/copilot.js +8 -15
  12. package/dist/backends/copilot.js.map +1 -1
  13. package/dist/backends/mock-llm.cjs +719 -0
  14. package/dist/backends/mock-llm.cjs.map +1 -0
  15. package/dist/backends/mock-llm.d.cts +37 -0
  16. package/dist/backends/mock-llm.d.ts +37 -0
  17. package/dist/backends/mock-llm.js +717 -0
  18. package/dist/backends/mock-llm.js.map +1 -0
  19. package/dist/backends/vercel-ai.cjs +8 -1
  20. package/dist/backends/vercel-ai.cjs.map +1 -1
  21. package/dist/backends/vercel-ai.d.cts +2 -2
  22. package/dist/backends/vercel-ai.d.ts +2 -2
  23. package/dist/backends/vercel-ai.js +8 -1
  24. package/dist/backends/vercel-ai.js.map +1 -1
  25. package/dist/backends-Cno0gZjy.d.cts +114 -0
  26. package/dist/backends-Cno0gZjy.d.ts +114 -0
  27. package/dist/chat/accumulator.cjs.map +1 -1
  28. package/dist/chat/accumulator.d.cts +2 -2
  29. package/dist/chat/accumulator.d.ts +2 -2
  30. package/dist/chat/accumulator.js.map +1 -1
  31. package/dist/chat/backends.cjs +350 -77
  32. package/dist/chat/backends.cjs.map +1 -1
  33. package/dist/chat/backends.d.cts +7 -7
  34. package/dist/chat/backends.d.ts +7 -7
  35. package/dist/chat/backends.js +349 -78
  36. package/dist/chat/backends.js.map +1 -1
  37. package/dist/chat/context.d.cts +2 -2
  38. package/dist/chat/context.d.ts +2 -2
  39. package/dist/chat/core.cjs +35 -25
  40. package/dist/chat/core.cjs.map +1 -1
  41. package/dist/chat/core.d.cts +15 -5
  42. package/dist/chat/core.d.ts +15 -5
  43. package/dist/chat/core.js +35 -26
  44. package/dist/chat/core.js.map +1 -1
  45. package/dist/chat/events.d.cts +2 -2
  46. package/dist/chat/events.d.ts +2 -2
  47. package/dist/chat/index.cjs +418 -122
  48. package/dist/chat/index.cjs.map +1 -1
  49. package/dist/chat/index.d.cts +7 -7
  50. package/dist/chat/index.d.ts +7 -7
  51. package/dist/chat/index.js +418 -124
  52. package/dist/chat/index.js.map +1 -1
  53. package/dist/chat/react.cjs +216 -12
  54. package/dist/chat/react.cjs.map +1 -1
  55. package/dist/chat/react.d.cts +78 -4
  56. package/dist/chat/react.d.ts +78 -4
  57. package/dist/chat/react.js +215 -13
  58. package/dist/chat/react.js.map +1 -1
  59. package/dist/chat/runtime.cjs +6 -2
  60. package/dist/chat/runtime.cjs.map +1 -1
  61. package/dist/chat/runtime.d.cts +2 -2
  62. package/dist/chat/runtime.d.ts +2 -2
  63. package/dist/chat/runtime.js +6 -2
  64. package/dist/chat/runtime.js.map +1 -1
  65. package/dist/chat/server.cjs +15 -5
  66. package/dist/chat/server.cjs.map +1 -1
  67. package/dist/chat/server.d.cts +3 -3
  68. package/dist/chat/server.d.ts +3 -3
  69. package/dist/chat/server.js +15 -5
  70. package/dist/chat/server.js.map +1 -1
  71. package/dist/chat/sessions.cjs +39 -23
  72. package/dist/chat/sessions.cjs.map +1 -1
  73. package/dist/chat/sessions.d.cts +2 -2
  74. package/dist/chat/sessions.d.ts +2 -2
  75. package/dist/chat/sessions.js +40 -24
  76. package/dist/chat/sessions.js.map +1 -1
  77. package/dist/chat/sqlite.cjs +95 -0
  78. package/dist/chat/sqlite.cjs.map +1 -1
  79. package/dist/chat/sqlite.d.cts +39 -3
  80. package/dist/chat/sqlite.d.ts +39 -3
  81. package/dist/chat/sqlite.js +93 -1
  82. package/dist/chat/sqlite.js.map +1 -1
  83. package/dist/chat/state.d.cts +2 -2
  84. package/dist/chat/state.d.ts +2 -2
  85. package/dist/chat/storage.cjs +39 -23
  86. package/dist/chat/storage.cjs.map +1 -1
  87. package/dist/chat/storage.d.cts +7 -3
  88. package/dist/chat/storage.d.ts +7 -3
  89. package/dist/chat/storage.js +40 -24
  90. package/dist/chat/storage.js.map +1 -1
  91. package/dist/{in-process-transport-C1JnJGVR.d.ts → in-process-transport-7EIit9Xk.d.ts} +51 -17
  92. package/dist/{in-process-transport-C7DSqPyX.d.cts → in-process-transport-Ct9YcX8I.d.cts} +51 -17
  93. package/dist/index.cjs +14 -14
  94. package/dist/index.cjs.map +1 -1
  95. package/dist/index.d.cts +4 -2
  96. package/dist/index.d.ts +4 -2
  97. package/dist/index.js +13 -13
  98. package/dist/index.js.map +1 -1
  99. package/dist/testing.cjs +724 -0
  100. package/dist/testing.cjs.map +1 -1
  101. package/dist/testing.d.cts +14 -2
  102. package/dist/testing.d.ts +14 -2
  103. package/dist/testing.js +724 -0
  104. package/dist/testing.js.map +1 -1
  105. package/dist/{transport-Cdh3M0tS.d.cts → transport-DLWCN18G.d.cts} +1 -1
  106. package/dist/{transport-Ciap4PWK.d.ts → transport-DsuS-GeM.d.ts} +1 -1
  107. package/dist/{types-ajANVzf7.d.ts → types-DgtI1hzh.d.ts} +2 -1
  108. package/dist/{types-DRgd_9R7.d.cts → types-DkSXALKg.d.cts} +2 -1
  109. package/package.json +18 -7
  110. package/LICENSE +0 -21
  111. package/README.md +0 -1054
  112. package/dist/backends-BSrsBYFn.d.cts +0 -39
  113. package/dist/backends-BSrsBYFn.d.ts +0 -39
@@ -1,5 +1,5 @@
1
- import { c as ChatMessage } from '../types-DRgd_9R7.cjs';
2
- import '../agent-DxY68NZL.cjs';
1
+ import { c as ChatMessage } from '../types-DkSXALKg.cjs';
2
+ import '../agent-C6H2CgJA.cjs';
3
3
  import 'zod';
4
4
  import '../errors-C-so0M4t.cjs';
5
5
  import '../types-4vbcmPTp.cjs';
@@ -1,5 +1,5 @@
1
- import { c as ChatMessage } from '../types-ajANVzf7.js';
2
- import '../agent-CW9XbmG_.js';
1
+ import { c as ChatMessage } from '../types-DgtI1hzh.js';
2
+ import '../agent-F7oB6eKp.js';
3
3
  import 'zod';
4
4
  import '../errors-C-so0M4t.js';
5
5
  import '../types-BxggH0Yh.js';
@@ -76,30 +76,30 @@ function isFilePart(value) {
76
76
  const obj = value;
77
77
  return obj.type === "file" && typeof obj.name === "string" && typeof obj.mimeType === "string";
78
78
  }
79
+ var VALID_CHAT_EVENT_TYPES = /* @__PURE__ */ new Set([
80
+ "message:start",
81
+ "message:delta",
82
+ "message:complete",
83
+ "tool:start",
84
+ "tool:complete",
85
+ "thinking:start",
86
+ "thinking:delta",
87
+ "thinking:end",
88
+ "permission:request",
89
+ "permission:response",
90
+ "usage",
91
+ "session:created",
92
+ "session:updated",
93
+ "error",
94
+ "typing:start",
95
+ "typing:end",
96
+ "heartbeat",
97
+ "done"
98
+ ]);
79
99
  function isChatEvent(value) {
80
100
  if (typeof value !== "object" || value === null) return false;
81
101
  const obj = value;
82
- const validTypes = [
83
- "message:start",
84
- "message:delta",
85
- "message:complete",
86
- "tool:start",
87
- "tool:complete",
88
- "thinking:start",
89
- "thinking:delta",
90
- "thinking:end",
91
- "permission:request",
92
- "permission:response",
93
- "usage",
94
- "session:created",
95
- "session:updated",
96
- "error",
97
- "typing:start",
98
- "typing:end",
99
- "heartbeat",
100
- "done"
101
- ];
102
- return validTypes.includes(obj.type);
102
+ return VALID_CHAT_EVENT_TYPES.has(obj.type);
103
103
  }
104
104
 
105
105
  // src/chat/bridge.ts
@@ -163,8 +163,9 @@ function agentEventToChatEvent(event, messageId) {
163
163
  case "ask_user":
164
164
  case "ask_user_response":
165
165
  case "session_info":
166
- case "done":
167
166
  return null;
167
+ case "done":
168
+ return { type: "done", finalOutput: event.finalOutput ?? void 0, finishReason: event.finishReason };
168
169
  default:
169
170
  return null;
170
171
  }
@@ -210,21 +211,29 @@ function chatEventToAgentEvent(event) {
210
211
 
211
212
  // src/chat/conversion.ts
212
213
  function toAgentMessage(message) {
214
+ return toAgentMessages(message)[0];
215
+ }
216
+ function toAgentMessages(message) {
213
217
  const textContent = getMessageText(message);
214
218
  const toolCallParts = getMessageToolCalls(message);
215
219
  switch (message.role) {
216
220
  case "user":
217
- return { role: "user", content: textContent };
221
+ return [{ role: "user", content: textContent }];
218
222
  case "assistant": {
219
223
  const toolCalls = toolCallParts.length > 0 ? toolCallParts.map((p) => ({ id: p.toolCallId, name: p.name, args: p.args })) : void 0;
220
- return {
224
+ const assistantMsg = {
221
225
  role: "assistant",
222
226
  content: textContent,
223
227
  toolCalls
224
228
  };
229
+ const toolResults = extractToolResults(message);
230
+ if (toolResults.length > 0) {
231
+ return [assistantMsg, { role: "tool", toolResults }];
232
+ }
233
+ return [assistantMsg];
225
234
  }
226
235
  case "system":
227
- return { role: "system", content: textContent };
236
+ return [{ role: "system", content: textContent }];
228
237
  }
229
238
  }
230
239
  function fromAgentMessage(message, id) {
@@ -300,6 +309,7 @@ exports.isSourcePart = isSourcePart;
300
309
  exports.isTextPart = isTextPart;
301
310
  exports.isToolCallPart = isToolCallPart;
302
311
  exports.toAgentMessage = toAgentMessage;
312
+ exports.toAgentMessages = toAgentMessages;
303
313
  exports.toChatId = toChatId;
304
314
  //# sourceMappingURL=core.cjs.map
305
315
  //# sourceMappingURL=core.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/chat/types.ts","../../src/chat/chat-utils.ts","../../src/chat/guards.ts","../../src/chat/bridge.ts","../../src/chat/conversion.ts"],"names":[],"mappings":"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","file":"core.cjs","sourcesContent":["/**\n * @witqq/agent-sdk — Chat domain types\n *\n * All type definitions and interfaces for the chat layer.\n * Pure types + ChatId generation (tightly coupled to branded type).\n */\n\nimport type { UsageData, ToolDefinition, ErrorCode } from \"../types.js\";\nimport type { AuthToken } from \"../auth/types.js\";\n\n// ─── Unique ID ─────────────────────────────────────────────────\n\n/** Branded type for unique identifiers */\nexport type ChatId = string & { readonly __brand: \"ChatId\" };\n\n/**\n * Generate a new unique ChatId (crypto.randomUUID-based)\n * @returns Branded ChatId string\n */\nexport function createChatId(): ChatId {\n return crypto.randomUUID() as ChatId;\n}\n\n/** UUID v4 pattern for ChatId validation */\nconst UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;\n\n/**\n * Cast a string to ChatId with UUID format validation.\n * Use this instead of manual `as ChatId` type assertions.\n *\n * @param value - String to validate and cast\n * @returns Branded ChatId\n * @throws {TypeError} If value is not a valid UUID v4 format\n */\nexport function toChatId(value: string): ChatId {\n if (!UUID_RE.test(value)) {\n throw new TypeError(`Invalid ChatId: \"${value}\" is not a valid UUID`);\n }\n return value as ChatId;\n}\n\n/**\n * Accepts either a plain string or branded ChatId for API convenience.\n * Use this in public API signatures so consumers don't need `as ChatId` casts.\n */\nexport type ChatIdLike = string | ChatId;\n\n// ─── Status Types ──────────────────────────────────────────────\n\n/** Lifecycle status of a message part (text, reasoning, etc.) */\nexport type PartStatus = \"pending\" | \"streaming\" | \"complete\" | \"error\";\n/** Lifecycle status of a tool call within a message */\nexport type ToolCallStatus = \"pending\" | \"running\" | \"requires_approval\" | \"complete\" | \"error\" | \"denied\";\n/** Lifecycle status of an entire message */\nexport type MessageStatus = \"pending\" | \"streaming\" | \"complete\" | \"error\" | \"cancelled\";\n/** Lifecycle status of a chat session */\nexport type SessionStatus = \"active\";\n/** Lifecycle status of the chat runtime */\nexport type RuntimeStatus = \"idle\" | \"streaming\" | \"error\" | \"disposed\";\n\n// ─── Message Parts (union) ─────────────────────────────────────\n\n/** Plain text content part */\nexport interface TextPart { type: \"text\"; text: string; status: PartStatus; }\n/** Model reasoning/thinking content part */\nexport interface ReasoningPart { type: \"reasoning\"; text: string; status: PartStatus; }\n/** Tool invocation part with call ID, arguments, optional result */\nexport interface ToolCallPart { type: \"tool_call\"; toolCallId: string; name: string; args: unknown; result?: unknown; status: ToolCallStatus; error?: string; }\n/** Source reference part (URL citation) */\nexport interface SourcePart { type: \"source\"; url: string; title?: string; status: PartStatus; }\n/** File attachment part (base64-encoded data) */\nexport interface FilePart { type: \"file\"; name: string; mimeType: string; data: string; status: PartStatus; }\n/** Union of all message part types */\nexport type MessagePart = TextPart | ReasoningPart | ToolCallPart | SourcePart | FilePart;\n\n// ─── Chat Message ──────────────────────────────────────────────\n\n/** Role of message author */\nexport type ChatRole = \"user\" | \"assistant\" | \"system\";\n\n/** Metadata attached to messages — useful preset for the TMetadata generic */\nexport interface ChatMessageMetadata {\n model?: string;\n backend?: string;\n usage?: UsageData;\n isSummary?: boolean;\n estimatedTokens?: number;\n custom?: Record<string, unknown>;\n}\n\n/** Message status */\nexport type ChatMessageStatus = MessageStatus;\n\n/** A single chat message — the fundamental unit of conversation */\nexport interface ChatMessage<TMetadata = unknown> {\n id: ChatId;\n role: ChatRole;\n parts: MessagePart[];\n metadata?: TMetadata;\n createdAt: string;\n updatedAt?: string;\n status: MessageStatus;\n}\n\n// ─── Supporting Types ──────────────────────────────────────────\n\n// ─── Chat Session ──────────────────────────────────────────────\n\n/** Session configuration snapshot */\nexport interface ChatSessionConfig {\n model: string;\n backend: string;\n systemPrompt?: string;\n temperature?: number;\n maxTokens?: number;\n}\n\n/**\n * Session metadata tracking usage statistics and custom extensions.\n *\n * Updated automatically by session stores on each `addMessage()` call.\n * The generic `TCustom` parameter allows type-safe application-specific\n * metadata via the `custom` field.\n *\n * @typeParam TCustom - Shape of the `custom` field (defaults to `Record<string, unknown>`)\n */\nexport interface ChatSessionMetadata<TCustom extends Record<string, unknown> = Record<string, unknown>> {\n /** Number of messages in the session (updated by session store) */\n messageCount: number;\n /** Total token count across all messages in the session */\n totalTokens: number;\n /** Optional tags for session categorization and filtering */\n tags?: string[];\n /** Application-specific metadata — typed via the TCustom generic parameter */\n custom?: TCustom;\n}\n\n/** Chat session — a conversation with ordered messages (pure serializable data) */\nexport interface ChatSession<TCustom extends Record<string, unknown> = Record<string, unknown>> {\n id: ChatId;\n title?: string;\n messages: ChatMessage[];\n config: ChatSessionConfig;\n metadata: ChatSessionMetadata<TCustom>;\n status: SessionStatus;\n createdAt: string;\n updatedAt: string;\n backendSessionId?: string;\n}\n\n/**\n * Reactive wrapper around ChatSession — provides subscribe/getSnapshot for\n * React useSyncExternalStore integration and lastMessage convenience getter.\n * Session stores may optionally return ObservableSession instances.\n */\nexport interface ObservableSession<TCustom extends Record<string, unknown> = Record<string, unknown>>\n extends ChatSession<TCustom> {\n /** Subscribe to session changes (for React useSyncExternalStore) */\n subscribe(callback: () => void): () => void;\n /** Get immutable snapshot of session state (for React useSyncExternalStore) */\n getSnapshot(): ChatSession<TCustom>;\n /** Last message in the session */\n readonly lastMessage: ChatMessage | undefined;\n}\n\n/** Lightweight session info for listing (without full message array) */\nexport interface SessionInfo {\n id: ChatId;\n title?: string;\n status: SessionStatus;\n messageCount: number;\n lastMessage?: ChatMessage;\n createdAt: string;\n updatedAt: string;\n}\n\n// ─── Chat Events ───────────────────────────────────────────────\n\n/** Events emitted during chat operation */\nexport type ChatEvent =\n | { type: \"message:start\"; messageId: ChatId; role: ChatRole }\n | { type: \"message:delta\"; messageId: ChatId; text: string }\n | { type: \"message:complete\"; messageId: ChatId; message: ChatMessage }\n | {\n type: \"tool:start\";\n messageId: ChatId;\n toolCallId: string;\n toolName: string;\n args: Record<string, unknown>;\n }\n | {\n type: \"tool:complete\";\n messageId: ChatId;\n toolCallId: string;\n toolName: string;\n result: unknown;\n isError?: boolean;\n }\n | { type: \"thinking:start\"; messageId: ChatId }\n | { type: \"thinking:delta\"; messageId: ChatId; text: string }\n | { type: \"thinking:end\"; messageId: ChatId }\n | {\n type: \"permission:request\";\n messageId: ChatId;\n toolName: string;\n toolArgs: Record<string, unknown>;\n }\n | {\n type: \"permission:response\";\n messageId: ChatId;\n toolName: string;\n allowed: boolean;\n }\n | {\n type: \"usage\";\n promptTokens: number;\n completionTokens: number;\n model?: string;\n }\n | { type: \"session:created\"; sessionId: ChatId }\n | { type: \"session:updated\"; sessionId: ChatId }\n | {\n type: \"error\";\n error: string;\n recoverable: boolean;\n code?: ErrorCode;\n messageId?: ChatId;\n }\n | { type: \"typing:start\" }\n | { type: \"typing:end\" }\n | { type: \"heartbeat\" }\n | { type: \"done\"; finalOutput?: string };\n\n/** All possible ChatEvent type strings */\nexport type ChatEventType = ChatEvent[\"type\"];\n\n// ─── Chat Middleware ───────────────────────────────────────────\n\n/** Context passed to ChatMiddleware hooks */\nexport interface ChatMiddlewareContext {\n sessionId: ChatId;\n signal: AbortSignal;\n}\n\n/** Runtime-level middleware for the send/receive lifecycle.\n * Different from EventMiddleware which operates at the event bus level. */\nexport interface ChatMiddleware {\n /** Transform message before sending to backend. Return null to reject the send. */\n onBeforeSend?(message: ChatMessage, context: ChatMiddlewareContext): ChatMessage | null | Promise<ChatMessage | null>;\n /** Transform/intercept stream events */\n onEvent?(event: ChatEvent, context: ChatMiddlewareContext): ChatEvent | null | Promise<ChatEvent | null>;\n /** Transform completed message after receiving from backend */\n onAfterReceive?(message: ChatMessage, context: ChatMiddlewareContext): ChatMessage | Promise<ChatMessage>;\n /** Intercept errors — return null to suppress, return error to propagate */\n onError?(error: Error, context: ChatMiddlewareContext): Error | null | Promise<Error | null>;\n}\n\n// ─── Chat Provider Abstraction ─────────────────────────────────\n\n/** Options for sending a message to a provider */\nexport interface SendMessageOptions {\n signal?: AbortSignal;\n /** Model to use for this request. Required for server-side runtime.send(). */\n model?: string;\n /** Per-call system prompt override (forwarded to the backend agent) */\n systemPrompt?: string;\n context?: Record<string, unknown>;\n /** Additional tools to include in this request */\n tools?: ToolDefinition[];\n}\n\n/** Options for runtime.send() — requires backend routing info */\nexport interface RuntimeSendOptions {\n /** Backend to route this request to (key in backends map) */\n backend: string;\n /** Authentication credentials for the backend factory */\n credentials: AuthToken;\n /** Model to use for this request */\n model: string;\n /** Per-call system prompt override (forwarded to the backend agent) */\n systemPrompt?: string;\n /** Abort signal */\n signal?: AbortSignal;\n /** Request-scoped context */\n context?: Record<string, unknown>;\n /** Additional tools */\n tools?: ToolDefinition[];\n}\n\n/**\n * @deprecated IChatProvider has been inlined into IChatBackend.\n * Import IChatBackend from \"@witqq/agent-sdk/chat/backends\" instead.\n * Kept as type alias for backward compatibility.\n */\nexport type IChatProvider = import(\"./backends/types.js\").IChatBackend;\n\n// ─── Factory Functions ─────────────────────────────────────────\n\n/**\n * Create a simple text ChatMessage.\n *\n * @param text - Message text content\n * @param role - Message role (default: \"user\")\n * @returns A complete ChatMessage with a single TextPart\n */\nexport function createTextMessage(text: string, role: ChatRole = \"user\"): ChatMessage {\n return {\n id: createChatId(),\n role,\n parts: [{ type: \"text\", text, status: \"complete\" }],\n createdAt: new Date().toISOString(),\n status: \"complete\",\n };\n}\n\n/** Type guard: checks if a session has reactive API (subscribe/getSnapshot) */\nexport function isObservableSession<TCustom extends Record<string, unknown> = Record<string, unknown>>(\n session: ChatSession<TCustom>,\n): session is ObservableSession<TCustom> {\n return \"subscribe\" in session && typeof (session as ObservableSession<TCustom>).subscribe === \"function\"\n && \"getSnapshot\" in session && typeof (session as ObservableSession<TCustom>).getSnapshot === \"function\";\n}\n","/**\n * @witqq/agent-sdk — Chat utility functions\n */\n\nimport type { ChatMessage, TextPart, ToolCallPart, ReasoningPart } from \"./types.js\";\nexport { createChatId, toChatId } from \"./types.js\";\n\n/**\n * Join all TextPart texts in a message\n */\nexport function getMessageText(message: ChatMessage): string {\n return message.parts\n .filter((p): p is TextPart => p.type === \"text\")\n .map((p) => p.text)\n .join(\"\");\n}\n\n/**\n * Filter all ToolCallParts from a message\n */\nexport function getMessageToolCalls(message: ChatMessage): ToolCallPart[] {\n return message.parts.filter((p): p is ToolCallPart => p.type === \"tool_call\");\n}\n\n/**\n * Join all ReasoningPart texts in a message\n */\nexport function getMessageReasoning(message: ChatMessage): string {\n return message.parts\n .filter((p): p is ReasoningPart => p.type === \"reasoning\")\n .map((p) => p.text)\n .join(\"\");\n}\n","/**\n * @witqq/agent-sdk — Chat type guards\n */\n\nimport type {\n ChatMessage,\n ChatSession,\n MessagePart,\n TextPart,\n ToolCallPart,\n ReasoningPart,\n SourcePart,\n FilePart,\n ChatEvent,\n ChatEventType,\n} from \"./types.js\";\n\n/** Check if a value is a ChatMessage */\nexport function isChatMessage(value: unknown): value is ChatMessage {\n if (typeof value !== \"object\" || value === null) return false;\n const obj = value as Record<string, unknown>;\n return (\n typeof obj.id === \"string\" &&\n typeof obj.role === \"string\" &&\n (obj.role === \"user\" || obj.role === \"assistant\" || obj.role === \"system\") &&\n Array.isArray(obj.parts) &&\n typeof obj.createdAt === \"string\" &&\n typeof obj.status === \"string\"\n );\n}\n\n/** Check if a value is a ChatSession */\nexport function isChatSession(value: unknown): value is ChatSession {\n if (typeof value !== \"object\" || value === null) return false;\n const obj = value as Record<string, unknown>;\n return (\n typeof obj.id === \"string\" &&\n Array.isArray(obj.messages) &&\n typeof obj.config === \"object\" &&\n obj.config !== null &&\n typeof obj.createdAt === \"string\" &&\n typeof obj.updatedAt === \"string\" &&\n typeof obj.status === \"string\"\n );\n}\n\n/** Check if a value is a MessagePart */\nexport function isMessagePart(value: unknown): value is MessagePart {\n if (typeof value !== \"object\" || value === null) return false;\n const obj = value as Record<string, unknown>;\n return (\n typeof obj.type === \"string\" &&\n (obj.type === \"text\" || obj.type === \"reasoning\" || obj.type === \"tool_call\" || obj.type === \"source\" || obj.type === \"file\")\n );\n}\n\n/** Check if a value is a TextPart */\nexport function isTextPart(value: unknown): value is TextPart {\n if (typeof value !== \"object\" || value === null) return false;\n const obj = value as Record<string, unknown>;\n return obj.type === \"text\" && typeof obj.text === \"string\";\n}\n\n/** Check if a value is a ToolCallPart */\nexport function isToolCallPart(value: unknown): value is ToolCallPart {\n if (typeof value !== \"object\" || value === null) return false;\n const obj = value as Record<string, unknown>;\n return obj.type === \"tool_call\" && typeof obj.toolCallId === \"string\" && typeof obj.name === \"string\";\n}\n\n/** Check if a value is a ReasoningPart */\nexport function isReasoningPart(value: unknown): value is ReasoningPart {\n if (typeof value !== \"object\" || value === null) return false;\n const obj = value as Record<string, unknown>;\n return obj.type === \"reasoning\" && typeof obj.text === \"string\";\n}\n\n/** Check if a value is a SourcePart */\nexport function isSourcePart(value: unknown): value is SourcePart {\n if (typeof value !== \"object\" || value === null) return false;\n const obj = value as Record<string, unknown>;\n return obj.type === \"source\" && typeof obj.url === \"string\";\n}\n\n/** Check if a value is a FilePart */\nexport function isFilePart(value: unknown): value is FilePart {\n if (typeof value !== \"object\" || value === null) return false;\n const obj = value as Record<string, unknown>;\n return obj.type === \"file\" && typeof obj.name === \"string\" && typeof obj.mimeType === \"string\";\n}\n\n/** Check if a value is a ChatEvent */\nexport function isChatEvent(value: unknown): value is ChatEvent {\n if (typeof value !== \"object\" || value === null) return false;\n const obj = value as Record<string, unknown>;\n const validTypes: ChatEventType[] = [\n \"message:start\", \"message:delta\", \"message:complete\",\n \"tool:start\", \"tool:complete\",\n \"thinking:start\", \"thinking:delta\", \"thinking:end\",\n \"permission:request\", \"permission:response\",\n \"usage\", \"session:created\", \"session:updated\",\n \"error\", \"typing:start\", \"typing:end\", \"heartbeat\", \"done\",\n ];\n return validTypes.includes(obj.type as ChatEventType);\n}\n","/**\n * @witqq/agent-sdk — AgentEvent ↔ ChatEvent bridge\n */\n\nimport type { AgentEvent, JSONValue } from \"../types.js\";\nimport type { ChatId, ChatEvent } from \"./types.js\";\n\n/**\n * Map a single AgentEvent to a ChatEvent (or null if no mapping)\n */\nexport function agentEventToChatEvent(\n event: AgentEvent,\n messageId: ChatId,\n): ChatEvent | null {\n switch (event.type) {\n case \"text_delta\":\n return { type: \"message:delta\", messageId, text: event.text };\n case \"thinking_start\":\n return { type: \"thinking:start\", messageId };\n case \"thinking_delta\":\n return { type: \"thinking:delta\", messageId, text: event.text };\n case \"thinking_end\":\n return { type: \"thinking:end\", messageId };\n case \"tool_call_start\":\n return {\n type: \"tool:start\",\n messageId,\n toolCallId: event.toolCallId,\n toolName: event.toolName,\n args: event.args as Record<string, unknown>,\n };\n case \"tool_call_end\":\n return {\n type: \"tool:complete\",\n messageId,\n toolCallId: event.toolCallId,\n toolName: event.toolName,\n result: event.result,\n };\n case \"permission_request\":\n return {\n type: \"permission:request\",\n messageId,\n toolName: event.request.toolName,\n toolArgs: event.request.toolArgs,\n };\n case \"permission_response\":\n return {\n type: \"permission:response\",\n messageId,\n toolName: event.toolName,\n allowed: event.decision.allowed,\n };\n case \"usage_update\":\n return {\n type: \"usage\",\n promptTokens: event.promptTokens,\n completionTokens: event.completionTokens,\n model: event.model,\n };\n case \"error\":\n return {\n type: \"error\",\n error: event.error,\n recoverable: event.recoverable,\n code: event.code,\n messageId,\n };\n case \"heartbeat\":\n return { type: \"heartbeat\" };\n case \"ask_user\":\n case \"ask_user_response\":\n case \"session_info\":\n case \"done\":\n return null;\n default:\n return null;\n }\n}\n\n/**\n * Convert AgentEvent async iterable to ChatEvent async iterable\n */\nexport async function* adaptAgentEvents(\n events: AsyncIterable<AgentEvent>,\n messageId: ChatId,\n): AsyncIterable<ChatEvent> {\n for await (const event of events) {\n const chatEvent = agentEventToChatEvent(event, messageId);\n if (chatEvent !== null) {\n yield chatEvent;\n }\n }\n}\n\n/**\n * Map a ChatEvent back to an AgentEvent for accumulator consumption.\n * Returns null for events that don't map to accumulator-relevant AgentEvents.\n */\nexport function chatEventToAgentEvent(event: ChatEvent): AgentEvent | null {\n switch (event.type) {\n case \"message:delta\":\n return { type: \"text_delta\", text: event.text };\n case \"thinking:start\":\n return { type: \"thinking_start\" };\n case \"thinking:delta\":\n return { type: \"thinking_delta\", text: event.text };\n case \"thinking:end\":\n return { type: \"thinking_end\" };\n case \"tool:start\":\n return {\n type: \"tool_call_start\",\n toolCallId: event.toolCallId,\n toolName: event.toolName,\n args: event.args as JSONValue,\n };\n case \"tool:complete\":\n return {\n type: \"tool_call_end\",\n toolCallId: event.toolCallId,\n toolName: event.toolName,\n result: event.result as JSONValue,\n };\n case \"error\":\n return { type: \"error\", error: event.error, recoverable: event.recoverable, code: event.code };\n default:\n return null;\n }\n}\n","/**\n * @witqq/agent-sdk — ChatMessage ↔ agent-sdk Message conversion\n */\n\nimport type { Message, ToolCall, ToolResult, JSONValue } from \"../types.js\";\nimport type { ChatId, ChatMessage, ChatRole, MessagePart } from \"./types.js\";\nimport { createChatId, getMessageText, getMessageToolCalls } from \"./chat-utils.js\";\n\n/**\n * Convert a ChatMessage to agent-sdk Message format\n */\nexport function toAgentMessage(message: ChatMessage): Message {\n const textContent = getMessageText(message);\n const toolCallParts = getMessageToolCalls(message);\n\n switch (message.role) {\n case \"user\":\n return { role: \"user\", content: textContent };\n case \"assistant\": {\n const toolCalls: ToolCall[] | undefined = toolCallParts.length > 0\n ? toolCallParts.map((p) => ({ id: p.toolCallId, name: p.name, args: p.args as JSONValue }))\n : undefined;\n return {\n role: \"assistant\",\n content: textContent,\n toolCalls,\n };\n }\n case \"system\":\n return { role: \"system\", content: textContent };\n }\n}\n\n/**\n * Convert an agent-sdk Message to ChatMessage\n */\nexport function fromAgentMessage(message: Message, id?: ChatId): ChatMessage {\n const chatId = id ?? createChatId();\n const now = new Date().toISOString();\n\n const parts: MessagePart[] = [];\n\n const textContent =\n typeof message.content === \"string\"\n ? message.content\n : Array.isArray(message.content)\n ? message.content\n .filter((part) => part.type === \"text\")\n .map((part) => part.text)\n .join(\"\\n\")\n : (message.content ?? \"\");\n\n if (textContent) {\n parts.push({ type: \"text\", text: textContent, status: \"complete\" });\n }\n\n if (message.role === \"assistant\" && message.toolCalls) {\n for (const tc of message.toolCalls) {\n parts.push({\n type: \"tool_call\",\n toolCallId: tc.id,\n name: tc.name,\n args: tc.args,\n status: \"complete\",\n });\n }\n }\n\n if (message.role === \"tool\" && message.toolResults) {\n for (const tr of message.toolResults) {\n parts.push({\n type: \"tool_call\",\n toolCallId: tr.toolCallId,\n name: tr.name,\n args: {},\n result: tr.result,\n status: \"complete\",\n });\n }\n }\n\n if (parts.length === 0) {\n parts.push({ type: \"text\", text: \"\", status: \"complete\" });\n }\n\n const role: ChatRole = message.role === \"tool\" ? \"assistant\" : message.role;\n\n return {\n id: chatId,\n role,\n parts,\n createdAt: now,\n status: \"complete\",\n };\n}\n\n/**\n * Extract ToolResults from ToolCallParts that have results\n */\nexport function extractToolResults(message: ChatMessage): ToolResult[] {\n return getMessageToolCalls(message)\n .filter((p) => p.result !== undefined)\n .map((p) => ({\n toolCallId: p.toolCallId,\n name: p.name,\n result: p.result as JSONValue,\n isError: p.status === \"error\" ? true : undefined,\n }));\n}\n"]}
1
+ {"version":3,"sources":["../../src/chat/types.ts","../../src/chat/chat-utils.ts","../../src/chat/guards.ts","../../src/chat/bridge.ts","../../src/chat/conversion.ts"],"names":[],"mappings":"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","file":"core.cjs","sourcesContent":["/**\n * @witqq/agent-sdk — Chat domain types\n *\n * All type definitions and interfaces for the chat layer.\n * Pure types + ChatId generation (tightly coupled to branded type).\n */\n\nimport type { UsageData, ToolDefinition, ErrorCode } from \"../types.js\";\nimport type { AuthToken } from \"../auth/types.js\";\n\n// ─── Unique ID ─────────────────────────────────────────────────\n\n/** Branded type for unique identifiers */\nexport type ChatId = string & { readonly __brand: \"ChatId\" };\n\n/**\n * Generate a new unique ChatId (crypto.randomUUID-based)\n * @returns Branded ChatId string\n */\nexport function createChatId(): ChatId {\n return crypto.randomUUID() as ChatId;\n}\n\n/** UUID v4 pattern for ChatId validation */\nconst UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;\n\n/**\n * Cast a string to ChatId with UUID format validation.\n * Use this instead of manual `as ChatId` type assertions.\n *\n * @param value - String to validate and cast\n * @returns Branded ChatId\n * @throws {TypeError} If value is not a valid UUID v4 format\n */\nexport function toChatId(value: string): ChatId {\n if (!UUID_RE.test(value)) {\n throw new TypeError(`Invalid ChatId: \"${value}\" is not a valid UUID`);\n }\n return value as ChatId;\n}\n\n/**\n * Accepts either a plain string or branded ChatId for API convenience.\n * Use this in public API signatures so consumers don't need `as ChatId` casts.\n */\nexport type ChatIdLike = string | ChatId;\n\n// ─── Status Types ──────────────────────────────────────────────\n\n/** Lifecycle status of a message part (text, reasoning, etc.) */\nexport type PartStatus = \"pending\" | \"streaming\" | \"complete\" | \"error\";\n/** Lifecycle status of a tool call within a message */\nexport type ToolCallStatus = \"pending\" | \"running\" | \"requires_approval\" | \"complete\" | \"error\" | \"denied\";\n/** Lifecycle status of an entire message */\nexport type MessageStatus = \"pending\" | \"streaming\" | \"complete\" | \"error\" | \"cancelled\";\n/** Lifecycle status of a chat session */\nexport type SessionStatus = \"active\";\n/** Lifecycle status of the chat runtime */\nexport type RuntimeStatus = \"idle\" | \"streaming\" | \"error\" | \"disposed\";\n\n// ─── Message Parts (union) ─────────────────────────────────────\n\n/** Plain text content part */\nexport interface TextPart { type: \"text\"; text: string; status: PartStatus; }\n/** Model reasoning/thinking content part */\nexport interface ReasoningPart { type: \"reasoning\"; text: string; status: PartStatus; }\n/** Tool invocation part with call ID, arguments, optional result */\nexport interface ToolCallPart { type: \"tool_call\"; toolCallId: string; name: string; args: unknown; result?: unknown; status: ToolCallStatus; error?: string; }\n/** Source reference part (URL citation) */\nexport interface SourcePart { type: \"source\"; url: string; title?: string; status: PartStatus; }\n/** File attachment part (base64-encoded data) */\nexport interface FilePart { type: \"file\"; name: string; mimeType: string; data: string; status: PartStatus; }\n/** Union of all message part types */\nexport type MessagePart = TextPart | ReasoningPart | ToolCallPart | SourcePart | FilePart;\n\n// ─── Chat Message ──────────────────────────────────────────────\n\n/** Role of message author */\nexport type ChatRole = \"user\" | \"assistant\" | \"system\";\n\n/** Metadata attached to messages — useful preset for the TMetadata generic */\nexport interface ChatMessageMetadata {\n model?: string;\n backend?: string;\n usage?: UsageData;\n isSummary?: boolean;\n estimatedTokens?: number;\n custom?: Record<string, unknown>;\n}\n\n/** Message status */\nexport type ChatMessageStatus = MessageStatus;\n\n/** A single chat message — the fundamental unit of conversation */\nexport interface ChatMessage<TMetadata = unknown> {\n id: ChatId;\n role: ChatRole;\n parts: MessagePart[];\n metadata?: TMetadata;\n createdAt: string;\n updatedAt?: string;\n status: MessageStatus;\n}\n\n// ─── Supporting Types ──────────────────────────────────────────\n\n// ─── Chat Session ──────────────────────────────────────────────\n\n/** Session configuration snapshot */\nexport interface ChatSessionConfig {\n model: string;\n backend: string;\n systemPrompt?: string;\n temperature?: number;\n maxTokens?: number;\n}\n\n/**\n * Session metadata tracking usage statistics and custom extensions.\n *\n * Updated automatically by session stores on each `addMessage()` call.\n * The generic `TCustom` parameter allows type-safe application-specific\n * metadata via the `custom` field.\n *\n * @typeParam TCustom - Shape of the `custom` field (defaults to `Record<string, unknown>`)\n */\nexport interface ChatSessionMetadata<TCustom extends Record<string, unknown> = Record<string, unknown>> {\n /** Number of messages in the session (updated by session store) */\n messageCount: number;\n /** Total token count across all messages in the session */\n totalTokens: number;\n /** Optional tags for session categorization and filtering */\n tags?: string[];\n /** Application-specific metadata — typed via the TCustom generic parameter */\n custom?: TCustom;\n}\n\n/** Chat session — a conversation with ordered messages (pure serializable data) */\nexport interface ChatSession<TCustom extends Record<string, unknown> = Record<string, unknown>> {\n id: ChatId;\n title?: string;\n messages: ChatMessage[];\n config: ChatSessionConfig;\n metadata: ChatSessionMetadata<TCustom>;\n status: SessionStatus;\n createdAt: string;\n updatedAt: string;\n backendSessionId?: string;\n}\n\n/**\n * Reactive wrapper around ChatSession — provides subscribe/getSnapshot for\n * React useSyncExternalStore integration and lastMessage convenience getter.\n * Session stores may optionally return ObservableSession instances.\n */\nexport interface ObservableSession<TCustom extends Record<string, unknown> = Record<string, unknown>>\n extends ChatSession<TCustom> {\n /** Subscribe to session changes (for React useSyncExternalStore) */\n subscribe(callback: () => void): () => void;\n /** Get immutable snapshot of session state (for React useSyncExternalStore) */\n getSnapshot(): ChatSession<TCustom>;\n /** Last message in the session */\n readonly lastMessage: ChatMessage | undefined;\n}\n\n/** Lightweight session info for listing (without full message array) */\nexport interface SessionInfo {\n id: ChatId;\n title?: string;\n status: SessionStatus;\n messageCount: number;\n lastMessage?: ChatMessage;\n createdAt: string;\n updatedAt: string;\n}\n\n// ─── Chat Events ───────────────────────────────────────────────\n\n/** Events emitted during chat operation */\nexport type ChatEvent =\n | { type: \"message:start\"; messageId: ChatId; role: ChatRole }\n | { type: \"message:delta\"; messageId: ChatId; text: string }\n | { type: \"message:complete\"; messageId: ChatId; message: ChatMessage }\n | {\n type: \"tool:start\";\n messageId: ChatId;\n toolCallId: string;\n toolName: string;\n args: Record<string, unknown>;\n }\n | {\n type: \"tool:complete\";\n messageId: ChatId;\n toolCallId: string;\n toolName: string;\n result: unknown;\n isError?: boolean;\n }\n | { type: \"thinking:start\"; messageId: ChatId }\n | { type: \"thinking:delta\"; messageId: ChatId; text: string }\n | { type: \"thinking:end\"; messageId: ChatId }\n | {\n type: \"permission:request\";\n messageId: ChatId;\n toolName: string;\n toolArgs: Record<string, unknown>;\n }\n | {\n type: \"permission:response\";\n messageId: ChatId;\n toolName: string;\n allowed: boolean;\n }\n | {\n type: \"usage\";\n promptTokens: number;\n completionTokens: number;\n model?: string;\n }\n | { type: \"session:created\"; sessionId: ChatId }\n | { type: \"session:updated\"; sessionId: ChatId }\n | {\n type: \"error\";\n error: string;\n recoverable: boolean;\n code?: ErrorCode;\n messageId?: ChatId;\n }\n | { type: \"typing:start\" }\n | { type: \"typing:end\" }\n | { type: \"heartbeat\" }\n | { type: \"done\"; finalOutput?: string; finishReason?: string };\n\n/** All possible ChatEvent type strings */\nexport type ChatEventType = ChatEvent[\"type\"];\n\n// ─── Chat Middleware ───────────────────────────────────────────\n\n/** Context passed to ChatMiddleware hooks */\nexport interface ChatMiddlewareContext {\n sessionId: ChatId;\n signal: AbortSignal;\n}\n\n/** Runtime-level middleware for the send/receive lifecycle.\n * Different from EventMiddleware which operates at the event bus level. */\nexport interface ChatMiddleware {\n /** Transform message before sending to backend. Return null to reject the send. */\n onBeforeSend?(message: ChatMessage, context: ChatMiddlewareContext): ChatMessage | null | Promise<ChatMessage | null>;\n /** Transform/intercept stream events */\n onEvent?(event: ChatEvent, context: ChatMiddlewareContext): ChatEvent | null | Promise<ChatEvent | null>;\n /** Transform completed message after receiving from backend */\n onAfterReceive?(message: ChatMessage, context: ChatMiddlewareContext): ChatMessage | Promise<ChatMessage>;\n /** Intercept errors — return null to suppress, return error to propagate */\n onError?(error: Error, context: ChatMiddlewareContext): Error | null | Promise<Error | null>;\n}\n\n// ─── Chat Provider Abstraction ─────────────────────────────────\n\n/** Options for sending a message to a provider */\nexport interface SendMessageOptions {\n signal?: AbortSignal;\n /** Model to use for this request. Required for server-side runtime.send(). */\n model?: string;\n /** Per-call system prompt override (forwarded to the backend agent) */\n systemPrompt?: string;\n context?: Record<string, unknown>;\n /** Additional tools to include in this request */\n tools?: ToolDefinition[];\n}\n\n/** Options for runtime.send() — requires backend routing info */\nexport interface RuntimeSendOptions {\n /** Backend to route this request to (key in backends map) */\n backend: string;\n /** Authentication credentials for the backend factory */\n credentials: AuthToken;\n /** Model to use for this request */\n model: string;\n /** Per-call system prompt override (forwarded to the backend agent) */\n systemPrompt?: string;\n /** Abort signal */\n signal?: AbortSignal;\n /** Request-scoped context */\n context?: Record<string, unknown>;\n /** Additional tools */\n tools?: ToolDefinition[];\n}\n\n/**\n * @deprecated IChatProvider has been inlined into IChatBackend.\n * Import IChatBackend from \"@witqq/agent-sdk/chat/backends\" instead.\n * Kept as type alias for backward compatibility.\n */\nexport type IChatProvider = import(\"./backends/types.js\").IChatBackend;\n\n// ─── Factory Functions ─────────────────────────────────────────\n\n/**\n * Create a simple text ChatMessage.\n *\n * @param text - Message text content\n * @param role - Message role (default: \"user\")\n * @returns A complete ChatMessage with a single TextPart\n */\nexport function createTextMessage(text: string, role: ChatRole = \"user\"): ChatMessage {\n return {\n id: createChatId(),\n role,\n parts: [{ type: \"text\", text, status: \"complete\" }],\n createdAt: new Date().toISOString(),\n status: \"complete\",\n };\n}\n\n/** Type guard: checks if a session has reactive API (subscribe/getSnapshot) */\nexport function isObservableSession<TCustom extends Record<string, unknown> = Record<string, unknown>>(\n session: ChatSession<TCustom>,\n): session is ObservableSession<TCustom> {\n return \"subscribe\" in session && typeof (session as ObservableSession<TCustom>).subscribe === \"function\"\n && \"getSnapshot\" in session && typeof (session as ObservableSession<TCustom>).getSnapshot === \"function\";\n}\n","/**\n * @witqq/agent-sdk — Chat utility functions\n */\n\nimport type { ChatMessage, TextPart, ToolCallPart, ReasoningPart } from \"./types.js\";\nexport { createChatId, toChatId } from \"./types.js\";\n\n/**\n * Join all TextPart texts in a message\n */\nexport function getMessageText(message: ChatMessage): string {\n return message.parts\n .filter((p): p is TextPart => p.type === \"text\")\n .map((p) => p.text)\n .join(\"\");\n}\n\n/**\n * Filter all ToolCallParts from a message\n */\nexport function getMessageToolCalls(message: ChatMessage): ToolCallPart[] {\n return message.parts.filter((p): p is ToolCallPart => p.type === \"tool_call\");\n}\n\n/**\n * Join all ReasoningPart texts in a message\n */\nexport function getMessageReasoning(message: ChatMessage): string {\n return message.parts\n .filter((p): p is ReasoningPart => p.type === \"reasoning\")\n .map((p) => p.text)\n .join(\"\");\n}\n","/**\n * @witqq/agent-sdk — Chat type guards\n */\n\nimport type {\n ChatMessage,\n ChatSession,\n MessagePart,\n TextPart,\n ToolCallPart,\n ReasoningPart,\n SourcePart,\n FilePart,\n ChatEvent,\n} from \"./types.js\";\n\n/** Check if a value is a ChatMessage */\nexport function isChatMessage(value: unknown): value is ChatMessage {\n if (typeof value !== \"object\" || value === null) return false;\n const obj = value as Record<string, unknown>;\n return (\n typeof obj.id === \"string\" &&\n typeof obj.role === \"string\" &&\n (obj.role === \"user\" || obj.role === \"assistant\" || obj.role === \"system\") &&\n Array.isArray(obj.parts) &&\n typeof obj.createdAt === \"string\" &&\n typeof obj.status === \"string\"\n );\n}\n\n/** Check if a value is a ChatSession */\nexport function isChatSession(value: unknown): value is ChatSession {\n if (typeof value !== \"object\" || value === null) return false;\n const obj = value as Record<string, unknown>;\n return (\n typeof obj.id === \"string\" &&\n Array.isArray(obj.messages) &&\n typeof obj.config === \"object\" &&\n obj.config !== null &&\n typeof obj.createdAt === \"string\" &&\n typeof obj.updatedAt === \"string\" &&\n typeof obj.status === \"string\"\n );\n}\n\n/** Check if a value is a MessagePart */\nexport function isMessagePart(value: unknown): value is MessagePart {\n if (typeof value !== \"object\" || value === null) return false;\n const obj = value as Record<string, unknown>;\n return (\n typeof obj.type === \"string\" &&\n (obj.type === \"text\" || obj.type === \"reasoning\" || obj.type === \"tool_call\" || obj.type === \"source\" || obj.type === \"file\")\n );\n}\n\n/** Check if a value is a TextPart */\nexport function isTextPart(value: unknown): value is TextPart {\n if (typeof value !== \"object\" || value === null) return false;\n const obj = value as Record<string, unknown>;\n return obj.type === \"text\" && typeof obj.text === \"string\";\n}\n\n/** Check if a value is a ToolCallPart */\nexport function isToolCallPart(value: unknown): value is ToolCallPart {\n if (typeof value !== \"object\" || value === null) return false;\n const obj = value as Record<string, unknown>;\n return obj.type === \"tool_call\" && typeof obj.toolCallId === \"string\" && typeof obj.name === \"string\";\n}\n\n/** Check if a value is a ReasoningPart */\nexport function isReasoningPart(value: unknown): value is ReasoningPart {\n if (typeof value !== \"object\" || value === null) return false;\n const obj = value as Record<string, unknown>;\n return obj.type === \"reasoning\" && typeof obj.text === \"string\";\n}\n\n/** Check if a value is a SourcePart */\nexport function isSourcePart(value: unknown): value is SourcePart {\n if (typeof value !== \"object\" || value === null) return false;\n const obj = value as Record<string, unknown>;\n return obj.type === \"source\" && typeof obj.url === \"string\";\n}\n\n/** Check if a value is a FilePart */\nexport function isFilePart(value: unknown): value is FilePart {\n if (typeof value !== \"object\" || value === null) return false;\n const obj = value as Record<string, unknown>;\n return obj.type === \"file\" && typeof obj.name === \"string\" && typeof obj.mimeType === \"string\";\n}\n\nconst VALID_CHAT_EVENT_TYPES: ReadonlySet<string> = new Set([\n \"message:start\", \"message:delta\", \"message:complete\",\n \"tool:start\", \"tool:complete\",\n \"thinking:start\", \"thinking:delta\", \"thinking:end\",\n \"permission:request\", \"permission:response\",\n \"usage\", \"session:created\", \"session:updated\",\n \"error\", \"typing:start\", \"typing:end\", \"heartbeat\", \"done\",\n]);\n\n/** Check if a value is a ChatEvent */\nexport function isChatEvent(value: unknown): value is ChatEvent {\n if (typeof value !== \"object\" || value === null) return false;\n const obj = value as Record<string, unknown>;\n return VALID_CHAT_EVENT_TYPES.has(obj.type as string);\n}\n","/**\n * @witqq/agent-sdk — AgentEvent ↔ ChatEvent bridge\n */\n\nimport type { AgentEvent, JSONValue } from \"../types.js\";\nimport type { ChatId, ChatEvent } from \"./types.js\";\n\n/**\n * Map a single AgentEvent to a ChatEvent (or null if no mapping)\n */\nexport function agentEventToChatEvent(\n event: AgentEvent,\n messageId: ChatId,\n): ChatEvent | null {\n switch (event.type) {\n case \"text_delta\":\n return { type: \"message:delta\", messageId, text: event.text };\n case \"thinking_start\":\n return { type: \"thinking:start\", messageId };\n case \"thinking_delta\":\n return { type: \"thinking:delta\", messageId, text: event.text };\n case \"thinking_end\":\n return { type: \"thinking:end\", messageId };\n case \"tool_call_start\":\n return {\n type: \"tool:start\",\n messageId,\n toolCallId: event.toolCallId,\n toolName: event.toolName,\n args: event.args as Record<string, unknown>,\n };\n case \"tool_call_end\":\n return {\n type: \"tool:complete\",\n messageId,\n toolCallId: event.toolCallId,\n toolName: event.toolName,\n result: event.result,\n };\n case \"permission_request\":\n return {\n type: \"permission:request\",\n messageId,\n toolName: event.request.toolName,\n toolArgs: event.request.toolArgs,\n };\n case \"permission_response\":\n return {\n type: \"permission:response\",\n messageId,\n toolName: event.toolName,\n allowed: event.decision.allowed,\n };\n case \"usage_update\":\n return {\n type: \"usage\",\n promptTokens: event.promptTokens,\n completionTokens: event.completionTokens,\n model: event.model,\n };\n case \"error\":\n return {\n type: \"error\",\n error: event.error,\n recoverable: event.recoverable,\n code: event.code,\n messageId,\n };\n case \"heartbeat\":\n return { type: \"heartbeat\" };\n case \"ask_user\":\n case \"ask_user_response\":\n case \"session_info\":\n return null;\n case \"done\":\n return { type: \"done\", finalOutput: event.finalOutput ?? undefined, finishReason: event.finishReason };\n default:\n return null;\n }\n}\n\n/**\n * Convert AgentEvent async iterable to ChatEvent async iterable\n */\nexport async function* adaptAgentEvents(\n events: AsyncIterable<AgentEvent>,\n messageId: ChatId,\n): AsyncIterable<ChatEvent> {\n for await (const event of events) {\n const chatEvent = agentEventToChatEvent(event, messageId);\n if (chatEvent !== null) {\n yield chatEvent;\n }\n }\n}\n\n/**\n * Map a ChatEvent back to an AgentEvent for accumulator consumption.\n * Returns null for events that don't map to accumulator-relevant AgentEvents.\n */\nexport function chatEventToAgentEvent(event: ChatEvent): AgentEvent | null {\n switch (event.type) {\n case \"message:delta\":\n return { type: \"text_delta\", text: event.text };\n case \"thinking:start\":\n return { type: \"thinking_start\" };\n case \"thinking:delta\":\n return { type: \"thinking_delta\", text: event.text };\n case \"thinking:end\":\n return { type: \"thinking_end\" };\n case \"tool:start\":\n return {\n type: \"tool_call_start\",\n toolCallId: event.toolCallId,\n toolName: event.toolName,\n args: event.args as JSONValue,\n };\n case \"tool:complete\":\n return {\n type: \"tool_call_end\",\n toolCallId: event.toolCallId,\n toolName: event.toolName,\n result: event.result as JSONValue,\n };\n case \"error\":\n return { type: \"error\", error: event.error, recoverable: event.recoverable, code: event.code };\n default:\n return null;\n }\n}\n","/**\n * @witqq/agent-sdk — ChatMessage ↔ agent-sdk Message conversion\n */\n\nimport type { Message, ToolCall, ToolResult, JSONValue } from \"../types.js\";\nimport type { ChatId, ChatMessage, ChatRole, MessagePart } from \"./types.js\";\nimport { createChatId, getMessageText, getMessageToolCalls } from \"./chat-utils.js\";\n\n/**\n * Convert a ChatMessage to agent-sdk Message format.\n * @deprecated Use toAgentMessages() which correctly handles tool results.\n * This function drops tool results for assistant messages with completed tool calls.\n */\nexport function toAgentMessage(message: ChatMessage): Message {\n return toAgentMessages(message)[0];\n}\n\n/**\n * Convert a ChatMessage to one or more agent-sdk Messages.\n * For assistant messages with completed tool calls, emits both:\n * 1. {role: \"assistant\", toolCalls: [...]} — the tool invocation\n * 2. {role: \"tool\", toolResults: [...]} — the tool results\n * This preserves tool results when replaying conversation history to backends.\n */\nexport function toAgentMessages(message: ChatMessage): Message[] {\n const textContent = getMessageText(message);\n const toolCallParts = getMessageToolCalls(message);\n\n switch (message.role) {\n case \"user\":\n return [{ role: \"user\", content: textContent }];\n case \"assistant\": {\n const toolCalls: ToolCall[] | undefined = toolCallParts.length > 0\n ? toolCallParts.map((p) => ({ id: p.toolCallId, name: p.name, args: p.args as JSONValue }))\n : undefined;\n const assistantMsg: Message = {\n role: \"assistant\",\n content: textContent,\n toolCalls,\n };\n\n // Emit tool results as a separate message if any tool calls have results\n const toolResults = extractToolResults(message);\n if (toolResults.length > 0) {\n return [assistantMsg, { role: \"tool\", toolResults }];\n }\n\n return [assistantMsg];\n }\n case \"system\":\n return [{ role: \"system\", content: textContent }];\n }\n}\n\n/**\n * Convert an agent-sdk Message to ChatMessage\n */\nexport function fromAgentMessage(message: Message, id?: ChatId): ChatMessage {\n const chatId = id ?? createChatId();\n const now = new Date().toISOString();\n\n const parts: MessagePart[] = [];\n\n const textContent =\n typeof message.content === \"string\"\n ? message.content\n : Array.isArray(message.content)\n ? message.content\n .filter((part) => part.type === \"text\")\n .map((part) => part.text)\n .join(\"\\n\")\n : (message.content ?? \"\");\n\n if (textContent) {\n parts.push({ type: \"text\", text: textContent, status: \"complete\" });\n }\n\n if (message.role === \"assistant\" && message.toolCalls) {\n for (const tc of message.toolCalls) {\n parts.push({\n type: \"tool_call\",\n toolCallId: tc.id,\n name: tc.name,\n args: tc.args,\n status: \"complete\",\n });\n }\n }\n\n if (message.role === \"tool\" && message.toolResults) {\n for (const tr of message.toolResults) {\n parts.push({\n type: \"tool_call\",\n toolCallId: tr.toolCallId,\n name: tr.name,\n args: {},\n result: tr.result,\n status: \"complete\",\n });\n }\n }\n\n if (parts.length === 0) {\n parts.push({ type: \"text\", text: \"\", status: \"complete\" });\n }\n\n const role: ChatRole = message.role === \"tool\" ? \"assistant\" : message.role;\n\n return {\n id: chatId,\n role,\n parts,\n createdAt: now,\n status: \"complete\",\n };\n}\n\n/**\n * Extract ToolResults from ToolCallParts that have results\n */\nexport function extractToolResults(message: ChatMessage): ToolResult[] {\n return getMessageToolCalls(message)\n .filter((p) => p.result !== undefined)\n .map((p) => ({\n toolCallId: p.toolCallId,\n name: p.name,\n result: p.result as JSONValue,\n isError: p.status === \"error\" ? true : undefined,\n }));\n}\n"]}
@@ -1,6 +1,6 @@
1
- import { c as ChatMessage, v as ToolCallPart, a as ChatEvent, g as ChatSession, F as FilePart, p as MessagePart, q as ReasoningPart, t as SourcePart, u as TextPart, b as ChatId } from '../types-DRgd_9R7.cjs';
2
- export { C as ChatEventType, f as ChatIdLike, k as ChatMessageMetadata, l as ChatMessageStatus, e as ChatMiddleware, m as ChatMiddlewareContext, n as ChatRole, j as ChatSessionConfig, A as ChatSessionMetadata, o as IChatProvider, M as MessageStatus, O as ObservableSession, P as PartStatus, h as RuntimeSendOptions, R as RuntimeStatus, S as SendMessageOptions, r as SessionInfo, s as SessionStatus, T as ToolCallStatus, w as createChatId, x as createTextMessage, y as isObservableSession, z as toChatId } from '../types-DRgd_9R7.cjs';
3
- import { A as AgentEvent, d as Message, e as ToolResult } from '../agent-DxY68NZL.cjs';
1
+ import { c as ChatMessage, v as ToolCallPart, a as ChatEvent, g as ChatSession, F as FilePart, p as MessagePart, q as ReasoningPart, t as SourcePart, u as TextPart, b as ChatId } from '../types-DkSXALKg.cjs';
2
+ export { C as ChatEventType, f as ChatIdLike, k as ChatMessageMetadata, l as ChatMessageStatus, e as ChatMiddleware, m as ChatMiddlewareContext, n as ChatRole, j as ChatSessionConfig, A as ChatSessionMetadata, o as IChatProvider, M as MessageStatus, O as ObservableSession, P as PartStatus, h as RuntimeSendOptions, R as RuntimeStatus, S as SendMessageOptions, r as SessionInfo, s as SessionStatus, T as ToolCallStatus, w as createChatId, x as createTextMessage, y as isObservableSession, z as toChatId } from '../types-DkSXALKg.cjs';
3
+ import { A as AgentEvent, d as Message, e as ToolResult } from '../agent-C6H2CgJA.cjs';
4
4
  import '../errors-C-so0M4t.cjs';
5
5
  import '../types-4vbcmPTp.cjs';
6
6
  import '../errors-CmVvczxZ.cjs';
@@ -69,9 +69,19 @@ declare function chatEventToAgentEvent(event: ChatEvent): AgentEvent | null;
69
69
  */
70
70
 
71
71
  /**
72
- * Convert a ChatMessage to agent-sdk Message format
72
+ * Convert a ChatMessage to agent-sdk Message format.
73
+ * @deprecated Use toAgentMessages() which correctly handles tool results.
74
+ * This function drops tool results for assistant messages with completed tool calls.
73
75
  */
74
76
  declare function toAgentMessage(message: ChatMessage): Message;
77
+ /**
78
+ * Convert a ChatMessage to one or more agent-sdk Messages.
79
+ * For assistant messages with completed tool calls, emits both:
80
+ * 1. {role: "assistant", toolCalls: [...]} — the tool invocation
81
+ * 2. {role: "tool", toolResults: [...]} — the tool results
82
+ * This preserves tool results when replaying conversation history to backends.
83
+ */
84
+ declare function toAgentMessages(message: ChatMessage): Message[];
75
85
  /**
76
86
  * Convert an agent-sdk Message to ChatMessage
77
87
  */
@@ -81,4 +91,4 @@ declare function fromAgentMessage(message: Message, id?: ChatId): ChatMessage;
81
91
  */
82
92
  declare function extractToolResults(message: ChatMessage): ToolResult[];
83
93
 
84
- export { ChatEvent, ChatId, ChatMessage, ChatSession, FilePart, MessagePart, ReasoningPart, SourcePart, TextPart, ToolCallPart, adaptAgentEvents, agentEventToChatEvent, chatEventToAgentEvent, extractToolResults, fromAgentMessage, getMessageReasoning, getMessageText, getMessageToolCalls, isChatEvent, isChatMessage, isChatSession, isFilePart, isMessagePart, isReasoningPart, isSourcePart, isTextPart, isToolCallPart, toAgentMessage };
94
+ export { ChatEvent, ChatId, ChatMessage, ChatSession, FilePart, MessagePart, ReasoningPart, SourcePart, TextPart, ToolCallPart, adaptAgentEvents, agentEventToChatEvent, chatEventToAgentEvent, extractToolResults, fromAgentMessage, getMessageReasoning, getMessageText, getMessageToolCalls, isChatEvent, isChatMessage, isChatSession, isFilePart, isMessagePart, isReasoningPart, isSourcePart, isTextPart, isToolCallPart, toAgentMessage, toAgentMessages };
@@ -1,6 +1,6 @@
1
- import { c as ChatMessage, v as ToolCallPart, a as ChatEvent, g as ChatSession, F as FilePart, p as MessagePart, q as ReasoningPart, t as SourcePart, u as TextPart, b as ChatId } from '../types-ajANVzf7.js';
2
- export { C as ChatEventType, f as ChatIdLike, k as ChatMessageMetadata, l as ChatMessageStatus, e as ChatMiddleware, m as ChatMiddlewareContext, n as ChatRole, j as ChatSessionConfig, A as ChatSessionMetadata, o as IChatProvider, M as MessageStatus, O as ObservableSession, P as PartStatus, h as RuntimeSendOptions, R as RuntimeStatus, S as SendMessageOptions, r as SessionInfo, s as SessionStatus, T as ToolCallStatus, w as createChatId, x as createTextMessage, y as isObservableSession, z as toChatId } from '../types-ajANVzf7.js';
3
- import { A as AgentEvent, d as Message, e as ToolResult } from '../agent-CW9XbmG_.js';
1
+ import { c as ChatMessage, v as ToolCallPart, a as ChatEvent, g as ChatSession, F as FilePart, p as MessagePart, q as ReasoningPart, t as SourcePart, u as TextPart, b as ChatId } from '../types-DgtI1hzh.js';
2
+ export { C as ChatEventType, f as ChatIdLike, k as ChatMessageMetadata, l as ChatMessageStatus, e as ChatMiddleware, m as ChatMiddlewareContext, n as ChatRole, j as ChatSessionConfig, A as ChatSessionMetadata, o as IChatProvider, M as MessageStatus, O as ObservableSession, P as PartStatus, h as RuntimeSendOptions, R as RuntimeStatus, S as SendMessageOptions, r as SessionInfo, s as SessionStatus, T as ToolCallStatus, w as createChatId, x as createTextMessage, y as isObservableSession, z as toChatId } from '../types-DgtI1hzh.js';
3
+ import { A as AgentEvent, d as Message, e as ToolResult } from '../agent-F7oB6eKp.js';
4
4
  import '../errors-C-so0M4t.js';
5
5
  import '../types-BxggH0Yh.js';
6
6
  import '../errors-CmVvczxZ.js';
@@ -69,9 +69,19 @@ declare function chatEventToAgentEvent(event: ChatEvent): AgentEvent | null;
69
69
  */
70
70
 
71
71
  /**
72
- * Convert a ChatMessage to agent-sdk Message format
72
+ * Convert a ChatMessage to agent-sdk Message format.
73
+ * @deprecated Use toAgentMessages() which correctly handles tool results.
74
+ * This function drops tool results for assistant messages with completed tool calls.
73
75
  */
74
76
  declare function toAgentMessage(message: ChatMessage): Message;
77
+ /**
78
+ * Convert a ChatMessage to one or more agent-sdk Messages.
79
+ * For assistant messages with completed tool calls, emits both:
80
+ * 1. {role: "assistant", toolCalls: [...]} — the tool invocation
81
+ * 2. {role: "tool", toolResults: [...]} — the tool results
82
+ * This preserves tool results when replaying conversation history to backends.
83
+ */
84
+ declare function toAgentMessages(message: ChatMessage): Message[];
75
85
  /**
76
86
  * Convert an agent-sdk Message to ChatMessage
77
87
  */
@@ -81,4 +91,4 @@ declare function fromAgentMessage(message: Message, id?: ChatId): ChatMessage;
81
91
  */
82
92
  declare function extractToolResults(message: ChatMessage): ToolResult[];
83
93
 
84
- export { ChatEvent, ChatId, ChatMessage, ChatSession, FilePart, MessagePart, ReasoningPart, SourcePart, TextPart, ToolCallPart, adaptAgentEvents, agentEventToChatEvent, chatEventToAgentEvent, extractToolResults, fromAgentMessage, getMessageReasoning, getMessageText, getMessageToolCalls, isChatEvent, isChatMessage, isChatSession, isFilePart, isMessagePart, isReasoningPart, isSourcePart, isTextPart, isToolCallPart, toAgentMessage };
94
+ export { ChatEvent, ChatId, ChatMessage, ChatSession, FilePart, MessagePart, ReasoningPart, SourcePart, TextPart, ToolCallPart, adaptAgentEvents, agentEventToChatEvent, chatEventToAgentEvent, extractToolResults, fromAgentMessage, getMessageReasoning, getMessageText, getMessageToolCalls, isChatEvent, isChatMessage, isChatSession, isFilePart, isMessagePart, isReasoningPart, isSourcePart, isTextPart, isToolCallPart, toAgentMessage, toAgentMessages };
package/dist/chat/core.js CHANGED
@@ -74,30 +74,30 @@ function isFilePart(value) {
74
74
  const obj = value;
75
75
  return obj.type === "file" && typeof obj.name === "string" && typeof obj.mimeType === "string";
76
76
  }
77
+ var VALID_CHAT_EVENT_TYPES = /* @__PURE__ */ new Set([
78
+ "message:start",
79
+ "message:delta",
80
+ "message:complete",
81
+ "tool:start",
82
+ "tool:complete",
83
+ "thinking:start",
84
+ "thinking:delta",
85
+ "thinking:end",
86
+ "permission:request",
87
+ "permission:response",
88
+ "usage",
89
+ "session:created",
90
+ "session:updated",
91
+ "error",
92
+ "typing:start",
93
+ "typing:end",
94
+ "heartbeat",
95
+ "done"
96
+ ]);
77
97
  function isChatEvent(value) {
78
98
  if (typeof value !== "object" || value === null) return false;
79
99
  const obj = value;
80
- const validTypes = [
81
- "message:start",
82
- "message:delta",
83
- "message:complete",
84
- "tool:start",
85
- "tool:complete",
86
- "thinking:start",
87
- "thinking:delta",
88
- "thinking:end",
89
- "permission:request",
90
- "permission:response",
91
- "usage",
92
- "session:created",
93
- "session:updated",
94
- "error",
95
- "typing:start",
96
- "typing:end",
97
- "heartbeat",
98
- "done"
99
- ];
100
- return validTypes.includes(obj.type);
100
+ return VALID_CHAT_EVENT_TYPES.has(obj.type);
101
101
  }
102
102
 
103
103
  // src/chat/bridge.ts
@@ -161,8 +161,9 @@ function agentEventToChatEvent(event, messageId) {
161
161
  case "ask_user":
162
162
  case "ask_user_response":
163
163
  case "session_info":
164
- case "done":
165
164
  return null;
165
+ case "done":
166
+ return { type: "done", finalOutput: event.finalOutput ?? void 0, finishReason: event.finishReason };
166
167
  default:
167
168
  return null;
168
169
  }
@@ -208,21 +209,29 @@ function chatEventToAgentEvent(event) {
208
209
 
209
210
  // src/chat/conversion.ts
210
211
  function toAgentMessage(message) {
212
+ return toAgentMessages(message)[0];
213
+ }
214
+ function toAgentMessages(message) {
211
215
  const textContent = getMessageText(message);
212
216
  const toolCallParts = getMessageToolCalls(message);
213
217
  switch (message.role) {
214
218
  case "user":
215
- return { role: "user", content: textContent };
219
+ return [{ role: "user", content: textContent }];
216
220
  case "assistant": {
217
221
  const toolCalls = toolCallParts.length > 0 ? toolCallParts.map((p) => ({ id: p.toolCallId, name: p.name, args: p.args })) : void 0;
218
- return {
222
+ const assistantMsg = {
219
223
  role: "assistant",
220
224
  content: textContent,
221
225
  toolCalls
222
226
  };
227
+ const toolResults = extractToolResults(message);
228
+ if (toolResults.length > 0) {
229
+ return [assistantMsg, { role: "tool", toolResults }];
230
+ }
231
+ return [assistantMsg];
223
232
  }
224
233
  case "system":
225
- return { role: "system", content: textContent };
234
+ return [{ role: "system", content: textContent }];
226
235
  }
227
236
  }
228
237
  function fromAgentMessage(message, id) {
@@ -277,6 +286,6 @@ function extractToolResults(message) {
277
286
  }));
278
287
  }
279
288
 
280
- export { adaptAgentEvents, agentEventToChatEvent, chatEventToAgentEvent, createChatId, createTextMessage, extractToolResults, fromAgentMessage, getMessageReasoning, getMessageText, getMessageToolCalls, isChatEvent, isChatMessage, isChatSession, isFilePart, isMessagePart, isObservableSession, isReasoningPart, isSourcePart, isTextPart, isToolCallPart, toAgentMessage, toChatId };
289
+ export { adaptAgentEvents, agentEventToChatEvent, chatEventToAgentEvent, createChatId, createTextMessage, extractToolResults, fromAgentMessage, getMessageReasoning, getMessageText, getMessageToolCalls, isChatEvent, isChatMessage, isChatSession, isFilePart, isMessagePart, isObservableSession, isReasoningPart, isSourcePart, isTextPart, isToolCallPart, toAgentMessage, toAgentMessages, toChatId };
281
290
  //# sourceMappingURL=core.js.map
282
291
  //# sourceMappingURL=core.js.map