conversationalist 0.0.7 → 0.0.8

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 (97) hide show
  1. package/README.md +150 -90
  2. package/dist/adapters/anthropic/index.d.ts +11 -6
  3. package/dist/adapters/anthropic/index.d.ts.map +1 -1
  4. package/dist/adapters/anthropic/index.js +16 -3
  5. package/dist/adapters/anthropic/index.js.map +5 -4
  6. package/dist/adapters/gemini/index.d.ts +2 -2
  7. package/dist/adapters/gemini/index.d.ts.map +1 -1
  8. package/dist/adapters/gemini/index.js +52 -9
  9. package/dist/adapters/gemini/index.js.map +5 -4
  10. package/dist/adapters/openai/index.d.ts +32 -5
  11. package/dist/adapters/openai/index.d.ts.map +1 -1
  12. package/dist/adapters/openai/index.js +30 -8
  13. package/dist/adapters/openai/index.js.map +5 -4
  14. package/dist/context.d.ts.map +1 -1
  15. package/dist/conversation/append.d.ts +4 -4
  16. package/dist/conversation/append.d.ts.map +1 -1
  17. package/dist/conversation/create.d.ts +2 -3
  18. package/dist/conversation/create.d.ts.map +1 -1
  19. package/dist/conversation/index.d.ts +2 -2
  20. package/dist/conversation/index.d.ts.map +1 -1
  21. package/dist/conversation/modify.d.ts.map +1 -1
  22. package/dist/conversation/query.d.ts +9 -5
  23. package/dist/conversation/query.d.ts.map +1 -1
  24. package/dist/conversation/serialization.d.ts +6 -28
  25. package/dist/conversation/serialization.d.ts.map +1 -1
  26. package/dist/conversation/system-messages.d.ts +3 -3
  27. package/dist/conversation/system-messages.d.ts.map +1 -1
  28. package/dist/conversation/transform.d.ts.map +1 -1
  29. package/dist/conversation.d.ts +74 -18
  30. package/dist/conversation.d.ts.map +1 -1
  31. package/dist/export/index.d.ts +7 -0
  32. package/dist/export/index.d.ts.map +1 -0
  33. package/dist/export/index.js +3762 -0
  34. package/dist/export/index.js.map +62 -0
  35. package/dist/history.d.ts +102 -24
  36. package/dist/history.d.ts.map +1 -1
  37. package/dist/index.d.ts +7 -8
  38. package/dist/index.d.ts.map +1 -1
  39. package/dist/index.js +392 -4075
  40. package/dist/index.js.map +15 -60
  41. package/dist/markdown/index.d.ts +15 -0
  42. package/dist/markdown/index.d.ts.map +1 -0
  43. package/dist/markdown/index.js +4969 -0
  44. package/dist/markdown/index.js.map +69 -0
  45. package/dist/message.d.ts +1 -1
  46. package/dist/message.d.ts.map +1 -1
  47. package/dist/multi-modal.d.ts +3 -0
  48. package/dist/multi-modal.d.ts.map +1 -1
  49. package/dist/plugins/index.d.ts +1 -1
  50. package/dist/plugins/index.d.ts.map +1 -1
  51. package/dist/plugins/index.js +59 -0
  52. package/dist/plugins/index.js.map +10 -0
  53. package/dist/plugins/pii-redaction.d.ts +10 -1
  54. package/dist/plugins/pii-redaction.d.ts.map +1 -1
  55. package/dist/redaction/index.d.ts +2 -0
  56. package/dist/redaction/index.d.ts.map +1 -0
  57. package/dist/redaction/index.js +59 -0
  58. package/dist/redaction/index.js.map +10 -0
  59. package/dist/schemas/index.d.ts +2 -0
  60. package/dist/schemas/index.d.ts.map +1 -0
  61. package/dist/schemas/index.js +114 -0
  62. package/dist/schemas/index.js.map +10 -0
  63. package/dist/schemas.d.ts +324 -15
  64. package/dist/schemas.d.ts.map +1 -1
  65. package/dist/sort/index.d.ts +2 -0
  66. package/dist/sort/index.d.ts.map +1 -0
  67. package/dist/sort/index.js +32 -0
  68. package/dist/sort/index.js.map +10 -0
  69. package/dist/streaming.d.ts +3 -3
  70. package/dist/streaming.d.ts.map +1 -1
  71. package/dist/types.d.ts +72 -50
  72. package/dist/types.d.ts.map +1 -1
  73. package/dist/utilities/index.d.ts +1 -3
  74. package/dist/utilities/index.d.ts.map +1 -1
  75. package/dist/utilities/line-endings.d.ts +5 -0
  76. package/dist/utilities/line-endings.d.ts.map +1 -0
  77. package/dist/utilities/markdown.d.ts +1 -1
  78. package/dist/utilities/markdown.d.ts.map +1 -1
  79. package/dist/utilities/message-store.d.ts +6 -0
  80. package/dist/utilities/message-store.d.ts.map +1 -0
  81. package/dist/utilities/message.d.ts +9 -3
  82. package/dist/utilities/message.d.ts.map +1 -1
  83. package/dist/utilities/tool-calls.d.ts +4 -4
  84. package/dist/utilities/tool-calls.d.ts.map +1 -1
  85. package/dist/utilities/tool-results.d.ts +10 -0
  86. package/dist/utilities/tool-results.d.ts.map +1 -0
  87. package/dist/utilities/transient.d.ts +2 -2
  88. package/dist/utilities/transient.d.ts.map +1 -1
  89. package/dist/utilities.d.ts +3 -5
  90. package/dist/utilities.d.ts.map +1 -1
  91. package/dist/versioning/index.d.ts +3 -0
  92. package/dist/versioning/index.d.ts.map +1 -0
  93. package/dist/versioning/index.js +58 -0
  94. package/dist/versioning/index.js.map +11 -0
  95. package/dist/with-conversation.d.ts +8 -8
  96. package/dist/with-conversation.d.ts.map +1 -1
  97. package/package.json +26 -1
@@ -1,4 +1,46 @@
1
+ // src/utilities/message-store.ts
2
+ function getOrderedMessages(conversation) {
3
+ const ordered = [];
4
+ for (const id of conversation.ids) {
5
+ const message = conversation.messages[id];
6
+ if (message) {
7
+ ordered.push(message);
8
+ }
9
+ }
10
+ return ordered;
11
+ }
12
+
1
13
  // src/adapters/gemini/index.ts
14
+ var DEFAULT_FILE_MIME_TYPE = "application/octet-stream";
15
+ var MIME_TYPE_BY_EXTENSION = {
16
+ bmp: "image/bmp",
17
+ gif: "image/gif",
18
+ heic: "image/heic",
19
+ heif: "image/heif",
20
+ jpeg: "image/jpeg",
21
+ jpg: "image/jpeg",
22
+ png: "image/png",
23
+ svg: "image/svg+xml",
24
+ webp: "image/webp"
25
+ };
26
+ function inferMimeType(url) {
27
+ const trimmed = url.split("#")[0]?.split("?")[0] ?? "";
28
+ const dotIndex = trimmed.lastIndexOf(".");
29
+ if (dotIndex === -1) {
30
+ return;
31
+ }
32
+ const extension = trimmed.slice(dotIndex + 1).toLowerCase();
33
+ return MIME_TYPE_BY_EXTENSION[extension];
34
+ }
35
+ function resolveMimeType(url, explicit) {
36
+ return explicit ?? inferMimeType(url) ?? DEFAULT_FILE_MIME_TYPE;
37
+ }
38
+ function normalizeGeminiResponse(content) {
39
+ if (content !== null && typeof content === "object") {
40
+ return content;
41
+ }
42
+ return { result: content };
43
+ }
2
44
  function toGeminiParts(content) {
3
45
  if (typeof content === "string") {
4
46
  return content ? [{ text: content }] : [];
@@ -22,10 +64,10 @@ function toGeminiParts(content) {
22
64
  });
23
65
  }
24
66
  } else {
25
- const fileData = { fileUri: url };
26
- if (part.mimeType !== undefined) {
27
- fileData.mimeType = part.mimeType;
28
- }
67
+ const fileData = {
68
+ fileUri: url,
69
+ mimeType: resolveMimeType(url, part.mimeType)
70
+ };
29
71
  parts.push({ fileData });
30
72
  }
31
73
  }
@@ -54,7 +96,7 @@ function toFunctionResponsePart(toolResult, functionName) {
54
96
  return {
55
97
  functionResponse: {
56
98
  name: functionName,
57
- response: toolResult.content
99
+ response: normalizeGeminiResponse(toolResult.content)
58
100
  }
59
101
  };
60
102
  }
@@ -76,9 +118,10 @@ function extractSystemInstruction(messages) {
76
118
  };
77
119
  }
78
120
  function toGeminiMessages(conversation) {
79
- const systemInstruction = extractSystemInstruction(conversation.messages);
121
+ const ordered = getOrderedMessages(conversation);
122
+ const systemInstruction = extractSystemInstruction(ordered);
80
123
  const toolCallNames = new Map;
81
- for (const message of conversation.messages) {
124
+ for (const message of ordered) {
82
125
  if (message.role === "tool-use" && message.toolCall) {
83
126
  toolCallNames.set(message.toolCall.id, message.toolCall.name);
84
127
  }
@@ -96,7 +139,7 @@ function toGeminiMessages(conversation) {
96
139
  }
97
140
  currentRole = null;
98
141
  };
99
- for (const message of conversation.messages) {
142
+ for (const message of ordered) {
100
143
  if (message.hidden)
101
144
  continue;
102
145
  if (message.role === "system" || message.role === "developer") {
@@ -145,4 +188,4 @@ export {
145
188
  toGeminiMessages
146
189
  };
147
190
 
148
- //# debugId=0C64ADAD8EC3A21464756E2164756E21
191
+ //# debugId=88465330F0A95D8664756E2164756E21
@@ -1,10 +1,11 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../../../src/adapters/gemini/index.ts"],
3
+ "sources": ["../../../src/utilities/message-store.ts", "../../../src/adapters/gemini/index.ts"],
4
4
  "sourcesContent": [
5
- "import type { MultiModalContent } from '@lasercat/homogenaize';\n\nimport type { Conversation, Message, ToolCall, ToolResult } from '../../types';\n\n/**\n * Gemini text part.\n */\nexport interface GeminiTextPart {\n text: string;\n}\n\n/**\n * Gemini inline data part (for images).\n */\nexport interface GeminiInlineDataPart {\n inlineData: {\n mimeType: string;\n data: string;\n };\n}\n\n/**\n * Gemini file data part (for URLs).\n */\nexport interface GeminiFileDataPart {\n fileData: {\n mimeType?: string;\n fileUri: string;\n };\n}\n\n/**\n * Gemini function call part.\n */\nexport interface GeminiFunctionCallPart {\n functionCall: {\n name: string;\n args: Record<string, unknown>;\n };\n}\n\n/**\n * Gemini function response part.\n */\nexport interface GeminiFunctionResponsePart {\n functionResponse: {\n name: string;\n response: unknown;\n };\n}\n\n/**\n * Gemini content part union type.\n */\nexport type GeminiPart =\n | GeminiTextPart\n | GeminiInlineDataPart\n | GeminiFileDataPart\n | GeminiFunctionCallPart\n | GeminiFunctionResponsePart;\n\n/**\n * Gemini content (message) format.\n */\nexport interface GeminiContent {\n role: 'user' | 'model';\n parts: GeminiPart[];\n}\n\n/**\n * Result of converting a conversation to Gemini format.\n */\nexport interface GeminiConversation {\n systemInstruction?: GeminiContent;\n contents: GeminiContent[];\n}\n\n/**\n * Converts internal multi-modal content to Gemini parts.\n */\nfunction toGeminiParts(content: string | ReadonlyArray<MultiModalContent>): GeminiPart[] {\n if (typeof content === 'string') {\n return content ? [{ text: content }] : [];\n }\n\n const parts: GeminiPart[] = [];\n for (const part of content) {\n if (part.type === 'text') {\n if (part.text) {\n parts.push({ text: part.text });\n }\n } else if (part.type === 'image') {\n const url = part.url ?? '';\n if (url.startsWith('data:')) {\n // Base64 data URL\n const matches = url.match(/^data:([^;]+);base64,(.+)$/);\n if (matches) {\n parts.push({\n inlineData: {\n mimeType: matches[1]!,\n data: matches[2]!,\n },\n });\n }\n } else {\n // File URI\n const fileData: GeminiFileDataPart['fileData'] = { fileUri: url };\n if (part.mimeType !== undefined) {\n fileData.mimeType = part.mimeType;\n }\n parts.push({ fileData });\n }\n }\n }\n\n return parts;\n}\n\n/**\n * Converts an internal ToolCall to Gemini functionCall part.\n */\nfunction toFunctionCallPart(toolCall: ToolCall): GeminiFunctionCallPart {\n let args: Record<string, unknown>;\n if (typeof toolCall.arguments === 'string') {\n try {\n args = JSON.parse(toolCall.arguments) as Record<string, unknown>;\n } catch {\n args = { _raw: toolCall.arguments };\n }\n } else {\n args = toolCall.arguments as Record<string, unknown>;\n }\n\n return {\n functionCall: {\n name: toolCall.name,\n args,\n },\n };\n}\n\n/**\n * Converts an internal ToolResult to Gemini functionResponse part.\n * Note: Gemini needs the function name, which we track via a map from the conversation.\n */\nfunction toFunctionResponsePart(\n toolResult: ToolResult,\n functionName: string,\n): GeminiFunctionResponsePart {\n return {\n functionResponse: {\n name: functionName,\n response: toolResult.content,\n },\n };\n}\n\n/**\n * Collects system message content from a conversation for Gemini's systemInstruction.\n */\nfunction extractSystemInstruction(\n messages: ReadonlyArray<Message>,\n): GeminiContent | undefined {\n const systemMessages = messages.filter(\n (m) => (m.role === 'system' || m.role === 'developer') && !m.hidden,\n );\n\n if (systemMessages.length === 0) {\n return undefined;\n }\n\n const parts: GeminiPart[] = [];\n for (const msg of systemMessages) {\n parts.push(...toGeminiParts(msg.content));\n }\n\n if (parts.length === 0) {\n return undefined;\n }\n\n return {\n role: 'user', // systemInstruction uses 'user' role in Gemini\n parts,\n };\n}\n\n/**\n * Converts a conversation to Google Gemini API format.\n * System messages are extracted to `systemInstruction`.\n * Tool calls become functionCall parts, tool results become functionResponse parts.\n *\n * @example\n * ```ts\n * import { toGeminiMessages } from 'conversationalist/gemini';\n *\n * const { systemInstruction, contents } = toGeminiMessages(conversation);\n * const response = await genAI.getGenerativeModel({ model: 'gemini-pro' }).generateContent({\n * systemInstruction,\n * contents,\n * });\n * ```\n */\nexport function toGeminiMessages(conversation: Conversation): GeminiConversation {\n const systemInstruction = extractSystemInstruction(conversation.messages);\n\n // Build a map of tool call IDs to function names for tool results\n const toolCallNames = new Map<string, string>();\n for (const message of conversation.messages) {\n if (message.role === 'tool-use' && message.toolCall) {\n toolCallNames.set(message.toolCall.id, message.toolCall.name);\n }\n }\n\n const contents: GeminiContent[] = [];\n\n // Track pending parts to merge consecutive same-role messages\n let currentRole: 'user' | 'model' | null = null;\n let currentParts: GeminiPart[] = [];\n\n const flushCurrent = () => {\n if (currentRole && currentParts.length > 0) {\n contents.push({\n role: currentRole,\n parts: currentParts,\n });\n currentParts = [];\n }\n currentRole = null;\n };\n\n for (const message of conversation.messages) {\n if (message.hidden) continue;\n\n // Skip system messages (already extracted)\n if (message.role === 'system' || message.role === 'developer') {\n continue;\n }\n\n // Skip snapshots\n if (message.role === 'snapshot') {\n continue;\n }\n\n let targetRole: 'user' | 'model';\n let parts: GeminiPart[] = [];\n\n if (message.role === 'user') {\n targetRole = 'user';\n parts = toGeminiParts(message.content);\n } else if (message.role === 'assistant') {\n targetRole = 'model';\n parts = toGeminiParts(message.content);\n } else if (message.role === 'tool-use' && message.toolCall) {\n targetRole = 'model';\n parts = [toFunctionCallPart(message.toolCall)];\n } else if (message.role === 'tool-result' && message.toolResult) {\n targetRole = 'user';\n const functionName = toolCallNames.get(message.toolResult.callId) ?? 'unknown';\n parts = [toFunctionResponsePart(message.toolResult, functionName)];\n } else {\n continue;\n }\n\n if (parts.length === 0) {\n continue;\n }\n\n // Merge with current or start new\n if (currentRole === targetRole) {\n currentParts.push(...parts);\n } else {\n flushCurrent();\n currentRole = targetRole;\n currentParts = parts;\n }\n }\n\n flushCurrent();\n\n const result: GeminiConversation = { contents };\n if (systemInstruction !== undefined) {\n result.systemInstruction = systemInstruction;\n }\n return result;\n}\n"
5
+ "import type { Conversation, Message } from '../types';\n\nexport function getOrderedMessages(conversation: Conversation): Message[] {\n const ordered: Message[] = [];\n for (const id of conversation.ids) {\n const message = conversation.messages[id];\n if (message) {\n ordered.push(message);\n }\n }\n return ordered;\n}\n\nexport function toIdRecord<T extends { id: string }>(\n items: readonly T[],\n): Record<string, T> {\n const record: Record<string, T> = {};\n for (const item of items) {\n record[item.id] = item;\n }\n return record;\n}\n",
6
+ "import type { MultiModalContent } from '@lasercat/homogenaize';\n\nimport type { Conversation, Message, ToolCall, ToolResult } from '../../types';\nimport { getOrderedMessages } from '../../utilities/message-store';\n\n/**\n * Gemini text part.\n */\nexport interface GeminiTextPart {\n text: string;\n}\n\n/**\n * Gemini inline data part (for images).\n */\nexport interface GeminiInlineDataPart {\n inlineData: {\n mimeType: string;\n data: string;\n };\n}\n\n/**\n * Gemini file data part (for URLs).\n */\nexport interface GeminiFileDataPart {\n fileData: {\n mimeType: string;\n fileUri: string;\n };\n}\n\n/**\n * Gemini function call part.\n */\nexport interface GeminiFunctionCallPart {\n functionCall: {\n name: string;\n args: Record<string, unknown>;\n };\n}\n\n/**\n * Gemini function response part.\n */\nexport interface GeminiFunctionResponsePart {\n functionResponse: {\n name: string;\n response: Record<string, unknown>;\n };\n}\n\n/**\n * Gemini content part union type.\n */\nexport type GeminiPart =\n | GeminiTextPart\n | GeminiInlineDataPart\n | GeminiFileDataPart\n | GeminiFunctionCallPart\n | GeminiFunctionResponsePart;\n\n/**\n * Gemini content (message) format.\n */\nexport interface GeminiContent {\n role: 'user' | 'model';\n parts: GeminiPart[];\n}\n\n/**\n * Result of converting a conversation to Gemini format.\n */\nexport interface GeminiConversation {\n systemInstruction?: GeminiContent;\n contents: GeminiContent[];\n}\n\nconst DEFAULT_FILE_MIME_TYPE = 'application/octet-stream';\n\nconst MIME_TYPE_BY_EXTENSION: Record<string, string> = {\n bmp: 'image/bmp',\n gif: 'image/gif',\n heic: 'image/heic',\n heif: 'image/heif',\n jpeg: 'image/jpeg',\n jpg: 'image/jpeg',\n png: 'image/png',\n svg: 'image/svg+xml',\n webp: 'image/webp',\n};\n\nfunction inferMimeType(url: string): string | undefined {\n const trimmed = url.split('#')[0]?.split('?')[0] ?? '';\n const dotIndex = trimmed.lastIndexOf('.');\n if (dotIndex === -1) {\n return undefined;\n }\n const extension = trimmed.slice(dotIndex + 1).toLowerCase();\n return MIME_TYPE_BY_EXTENSION[extension];\n}\n\nfunction resolveMimeType(url: string, explicit?: string): string {\n return explicit ?? inferMimeType(url) ?? DEFAULT_FILE_MIME_TYPE;\n}\n\nfunction normalizeGeminiResponse(content: unknown): Record<string, unknown> {\n if (content !== null && typeof content === 'object') {\n return content as Record<string, unknown>;\n }\n return { result: content };\n}\n\n/**\n * Converts internal multi-modal content to Gemini parts.\n */\nfunction toGeminiParts(content: string | ReadonlyArray<MultiModalContent>): GeminiPart[] {\n if (typeof content === 'string') {\n return content ? [{ text: content }] : [];\n }\n\n const parts: GeminiPart[] = [];\n for (const part of content) {\n if (part.type === 'text') {\n if (part.text) {\n parts.push({ text: part.text });\n }\n } else if (part.type === 'image') {\n const url = part.url ?? '';\n if (url.startsWith('data:')) {\n // Base64 data URL\n const matches = url.match(/^data:([^;]+);base64,(.+)$/);\n if (matches) {\n parts.push({\n inlineData: {\n mimeType: matches[1]!,\n data: matches[2]!,\n },\n });\n }\n } else {\n // File URI\n const fileData: GeminiFileDataPart['fileData'] = {\n fileUri: url,\n mimeType: resolveMimeType(url, part.mimeType),\n };\n parts.push({ fileData });\n }\n }\n }\n\n return parts;\n}\n\n/**\n * Converts an internal ToolCall to Gemini functionCall part.\n */\nfunction toFunctionCallPart(toolCall: ToolCall): GeminiFunctionCallPart {\n let args: Record<string, unknown>;\n if (typeof toolCall.arguments === 'string') {\n try {\n args = JSON.parse(toolCall.arguments) as Record<string, unknown>;\n } catch {\n args = { _raw: toolCall.arguments };\n }\n } else {\n args = toolCall.arguments as Record<string, unknown>;\n }\n\n return {\n functionCall: {\n name: toolCall.name,\n args,\n },\n };\n}\n\n/**\n * Converts an internal ToolResult to Gemini functionResponse part.\n * Note: Gemini needs the function name, which we track via a map from the conversation.\n */\nfunction toFunctionResponsePart(\n toolResult: ToolResult,\n functionName: string,\n): GeminiFunctionResponsePart {\n return {\n functionResponse: {\n name: functionName,\n response: normalizeGeminiResponse(toolResult.content),\n },\n };\n}\n\n/**\n * Collects system message content from a conversation for Gemini's systemInstruction.\n */\nfunction extractSystemInstruction(\n messages: ReadonlyArray<Message>,\n): GeminiContent | undefined {\n const systemMessages = messages.filter(\n (m) => (m.role === 'system' || m.role === 'developer') && !m.hidden,\n );\n\n if (systemMessages.length === 0) {\n return undefined;\n }\n\n const parts: GeminiPart[] = [];\n for (const msg of systemMessages) {\n parts.push(...toGeminiParts(msg.content));\n }\n\n if (parts.length === 0) {\n return undefined;\n }\n\n return {\n role: 'user', // systemInstruction uses 'user' role in Gemini\n parts,\n };\n}\n\n/**\n * Converts a conversation to Google Gemini API format.\n * System messages are extracted to `systemInstruction`.\n * Tool calls become functionCall parts, tool results become functionResponse parts.\n *\n * @example\n * ```ts\n * import { toGeminiMessages } from 'conversationalist/gemini';\n *\n * const { systemInstruction, contents } = toGeminiMessages(conversation);\n * const response = await genAI.getGenerativeModel({ model: 'gemini-pro' }).generateContent({\n * systemInstruction,\n * contents,\n * });\n * ```\n */\nexport function toGeminiMessages(conversation: Conversation): GeminiConversation {\n const ordered = getOrderedMessages(conversation);\n const systemInstruction = extractSystemInstruction(ordered);\n\n // Build a map of tool call IDs to function names for tool results\n const toolCallNames = new Map<string, string>();\n for (const message of ordered) {\n if (message.role === 'tool-use' && message.toolCall) {\n toolCallNames.set(message.toolCall.id, message.toolCall.name);\n }\n }\n\n const contents: GeminiContent[] = [];\n\n // Track pending parts to merge consecutive same-role messages\n let currentRole: 'user' | 'model' | null = null;\n let currentParts: GeminiPart[] = [];\n\n const flushCurrent = () => {\n if (currentRole && currentParts.length > 0) {\n contents.push({\n role: currentRole,\n parts: currentParts,\n });\n currentParts = [];\n }\n currentRole = null;\n };\n\n for (const message of ordered) {\n if (message.hidden) continue;\n\n // Skip system messages (already extracted)\n if (message.role === 'system' || message.role === 'developer') {\n continue;\n }\n\n // Skip snapshots\n if (message.role === 'snapshot') {\n continue;\n }\n\n let targetRole: 'user' | 'model';\n let parts: GeminiPart[] = [];\n\n if (message.role === 'user') {\n targetRole = 'user';\n parts = toGeminiParts(message.content);\n } else if (message.role === 'assistant') {\n targetRole = 'model';\n parts = toGeminiParts(message.content);\n } else if (message.role === 'tool-use' && message.toolCall) {\n targetRole = 'model';\n parts = [toFunctionCallPart(message.toolCall)];\n } else if (message.role === 'tool-result' && message.toolResult) {\n targetRole = 'user';\n const functionName = toolCallNames.get(message.toolResult.callId) ?? 'unknown';\n parts = [toFunctionResponsePart(message.toolResult, functionName)];\n } else {\n continue;\n }\n\n if (parts.length === 0) {\n continue;\n }\n\n // Merge with current or start new\n if (currentRole === targetRole) {\n currentParts.push(...parts);\n } else {\n flushCurrent();\n currentRole = targetRole;\n currentParts = parts;\n }\n }\n\n flushCurrent();\n\n const result: GeminiConversation = { contents };\n if (systemInstruction !== undefined) {\n result.systemInstruction = systemInstruction;\n }\n return result;\n}\n"
6
7
  ],
7
- "mappings": ";AAgFA,SAAS,aAAa,CAAC,SAAkE;AAAA,EACvF,IAAI,OAAO,YAAY,UAAU;AAAA,IAC/B,OAAO,UAAU,CAAC,EAAE,MAAM,QAAQ,CAAC,IAAI,CAAC;AAAA,EAC1C;AAAA,EAEA,MAAM,QAAsB,CAAC;AAAA,EAC7B,WAAW,QAAQ,SAAS;AAAA,IAC1B,IAAI,KAAK,SAAS,QAAQ;AAAA,MACxB,IAAI,KAAK,MAAM;AAAA,QACb,MAAM,KAAK,EAAE,MAAM,KAAK,KAAK,CAAC;AAAA,MAChC;AAAA,IACF,EAAO,SAAI,KAAK,SAAS,SAAS;AAAA,MAChC,MAAM,MAAM,KAAK,OAAO;AAAA,MACxB,IAAI,IAAI,WAAW,OAAO,GAAG;AAAA,QAE3B,MAAM,UAAU,IAAI,MAAM,4BAA4B;AAAA,QACtD,IAAI,SAAS;AAAA,UACX,MAAM,KAAK;AAAA,YACT,YAAY;AAAA,cACV,UAAU,QAAQ;AAAA,cAClB,MAAM,QAAQ;AAAA,YAChB;AAAA,UACF,CAAC;AAAA,QACH;AAAA,MACF,EAAO;AAAA,QAEL,MAAM,WAA2C,EAAE,SAAS,IAAI;AAAA,QAChE,IAAI,KAAK,aAAa,WAAW;AAAA,UAC/B,SAAS,WAAW,KAAK;AAAA,QAC3B;AAAA,QACA,MAAM,KAAK,EAAE,SAAS,CAAC;AAAA;AAAA,IAE3B;AAAA,EACF;AAAA,EAEA,OAAO;AAAA;AAMT,SAAS,kBAAkB,CAAC,UAA4C;AAAA,EACtE,IAAI;AAAA,EACJ,IAAI,OAAO,SAAS,cAAc,UAAU;AAAA,IAC1C,IAAI;AAAA,MACF,OAAO,KAAK,MAAM,SAAS,SAAS;AAAA,MACpC,MAAM;AAAA,MACN,OAAO,EAAE,MAAM,SAAS,UAAU;AAAA;AAAA,EAEtC,EAAO;AAAA,IACL,OAAO,SAAS;AAAA;AAAA,EAGlB,OAAO;AAAA,IACL,cAAc;AAAA,MACZ,MAAM,SAAS;AAAA,MACf;AAAA,IACF;AAAA,EACF;AAAA;AAOF,SAAS,sBAAsB,CAC7B,YACA,cAC4B;AAAA,EAC5B,OAAO;AAAA,IACL,kBAAkB;AAAA,MAChB,MAAM;AAAA,MACN,UAAU,WAAW;AAAA,IACvB;AAAA,EACF;AAAA;AAMF,SAAS,wBAAwB,CAC/B,UAC2B;AAAA,EAC3B,MAAM,iBAAiB,SAAS,OAC9B,CAAC,OAAO,EAAE,SAAS,YAAY,EAAE,SAAS,gBAAgB,CAAC,EAAE,MAC/D;AAAA,EAEA,IAAI,eAAe,WAAW,GAAG;AAAA,IAC/B;AAAA,EACF;AAAA,EAEA,MAAM,QAAsB,CAAC;AAAA,EAC7B,WAAW,OAAO,gBAAgB;AAAA,IAChC,MAAM,KAAK,GAAG,cAAc,IAAI,OAAO,CAAC;AAAA,EAC1C;AAAA,EAEA,IAAI,MAAM,WAAW,GAAG;AAAA,IACtB;AAAA,EACF;AAAA,EAEA,OAAO;AAAA,IACL,MAAM;AAAA,IACN;AAAA,EACF;AAAA;AAmBK,SAAS,gBAAgB,CAAC,cAAgD;AAAA,EAC/E,MAAM,oBAAoB,yBAAyB,aAAa,QAAQ;AAAA,EAGxE,MAAM,gBAAgB,IAAI;AAAA,EAC1B,WAAW,WAAW,aAAa,UAAU;AAAA,IAC3C,IAAI,QAAQ,SAAS,cAAc,QAAQ,UAAU;AAAA,MACnD,cAAc,IAAI,QAAQ,SAAS,IAAI,QAAQ,SAAS,IAAI;AAAA,IAC9D;AAAA,EACF;AAAA,EAEA,MAAM,WAA4B,CAAC;AAAA,EAGnC,IAAI,cAAuC;AAAA,EAC3C,IAAI,eAA6B,CAAC;AAAA,EAElC,MAAM,eAAe,MAAM;AAAA,IACzB,IAAI,eAAe,aAAa,SAAS,GAAG;AAAA,MAC1C,SAAS,KAAK;AAAA,QACZ,MAAM;AAAA,QACN,OAAO;AAAA,MACT,CAAC;AAAA,MACD,eAAe,CAAC;AAAA,IAClB;AAAA,IACA,cAAc;AAAA;AAAA,EAGhB,WAAW,WAAW,aAAa,UAAU;AAAA,IAC3C,IAAI,QAAQ;AAAA,MAAQ;AAAA,IAGpB,IAAI,QAAQ,SAAS,YAAY,QAAQ,SAAS,aAAa;AAAA,MAC7D;AAAA,IACF;AAAA,IAGA,IAAI,QAAQ,SAAS,YAAY;AAAA,MAC/B;AAAA,IACF;AAAA,IAEA,IAAI;AAAA,IACJ,IAAI,QAAsB,CAAC;AAAA,IAE3B,IAAI,QAAQ,SAAS,QAAQ;AAAA,MAC3B,aAAa;AAAA,MACb,QAAQ,cAAc,QAAQ,OAAO;AAAA,IACvC,EAAO,SAAI,QAAQ,SAAS,aAAa;AAAA,MACvC,aAAa;AAAA,MACb,QAAQ,cAAc,QAAQ,OAAO;AAAA,IACvC,EAAO,SAAI,QAAQ,SAAS,cAAc,QAAQ,UAAU;AAAA,MAC1D,aAAa;AAAA,MACb,QAAQ,CAAC,mBAAmB,QAAQ,QAAQ,CAAC;AAAA,IAC/C,EAAO,SAAI,QAAQ,SAAS,iBAAiB,QAAQ,YAAY;AAAA,MAC/D,aAAa;AAAA,MACb,MAAM,eAAe,cAAc,IAAI,QAAQ,WAAW,MAAM,KAAK;AAAA,MACrE,QAAQ,CAAC,uBAAuB,QAAQ,YAAY,YAAY,CAAC;AAAA,IACnE,EAAO;AAAA,MACL;AAAA;AAAA,IAGF,IAAI,MAAM,WAAW,GAAG;AAAA,MACtB;AAAA,IACF;AAAA,IAGA,IAAI,gBAAgB,YAAY;AAAA,MAC9B,aAAa,KAAK,GAAG,KAAK;AAAA,IAC5B,EAAO;AAAA,MACL,aAAa;AAAA,MACb,cAAc;AAAA,MACd,eAAe;AAAA;AAAA,EAEnB;AAAA,EAEA,aAAa;AAAA,EAEb,MAAM,SAA6B,EAAE,SAAS;AAAA,EAC9C,IAAI,sBAAsB,WAAW;AAAA,IACnC,OAAO,oBAAoB;AAAA,EAC7B;AAAA,EACA,OAAO;AAAA;",
8
- "debugId": "0C64ADAD8EC3A21464756E2164756E21",
8
+ "mappings": ";AAEO,SAAS,kBAAkB,CAAC,cAAuC;AAAA,EACxE,MAAM,UAAqB,CAAC;AAAA,EAC5B,WAAW,MAAM,aAAa,KAAK;AAAA,IACjC,MAAM,UAAU,aAAa,SAAS;AAAA,IACtC,IAAI,SAAS;AAAA,MACX,QAAQ,KAAK,OAAO;AAAA,IACtB;AAAA,EACF;AAAA,EACA,OAAO;AAAA;;;ACoET,IAAM,yBAAyB;AAE/B,IAAM,yBAAiD;AAAA,EACrD,KAAK;AAAA,EACL,KAAK;AAAA,EACL,MAAM;AAAA,EACN,MAAM;AAAA,EACN,MAAM;AAAA,EACN,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,MAAM;AACR;AAEA,SAAS,aAAa,CAAC,KAAiC;AAAA,EACtD,MAAM,UAAU,IAAI,MAAM,GAAG,EAAE,IAAI,MAAM,GAAG,EAAE,MAAM;AAAA,EACpD,MAAM,WAAW,QAAQ,YAAY,GAAG;AAAA,EACxC,IAAI,aAAa,IAAI;AAAA,IACnB;AAAA,EACF;AAAA,EACA,MAAM,YAAY,QAAQ,MAAM,WAAW,CAAC,EAAE,YAAY;AAAA,EAC1D,OAAO,uBAAuB;AAAA;AAGhC,SAAS,eAAe,CAAC,KAAa,UAA2B;AAAA,EAC/D,OAAO,YAAY,cAAc,GAAG,KAAK;AAAA;AAG3C,SAAS,uBAAuB,CAAC,SAA2C;AAAA,EAC1E,IAAI,YAAY,QAAQ,OAAO,YAAY,UAAU;AAAA,IACnD,OAAO;AAAA,EACT;AAAA,EACA,OAAO,EAAE,QAAQ,QAAQ;AAAA;AAM3B,SAAS,aAAa,CAAC,SAAkE;AAAA,EACvF,IAAI,OAAO,YAAY,UAAU;AAAA,IAC/B,OAAO,UAAU,CAAC,EAAE,MAAM,QAAQ,CAAC,IAAI,CAAC;AAAA,EAC1C;AAAA,EAEA,MAAM,QAAsB,CAAC;AAAA,EAC7B,WAAW,QAAQ,SAAS;AAAA,IAC1B,IAAI,KAAK,SAAS,QAAQ;AAAA,MACxB,IAAI,KAAK,MAAM;AAAA,QACb,MAAM,KAAK,EAAE,MAAM,KAAK,KAAK,CAAC;AAAA,MAChC;AAAA,IACF,EAAO,SAAI,KAAK,SAAS,SAAS;AAAA,MAChC,MAAM,MAAM,KAAK,OAAO;AAAA,MACxB,IAAI,IAAI,WAAW,OAAO,GAAG;AAAA,QAE3B,MAAM,UAAU,IAAI,MAAM,4BAA4B;AAAA,QACtD,IAAI,SAAS;AAAA,UACX,MAAM,KAAK;AAAA,YACT,YAAY;AAAA,cACV,UAAU,QAAQ;AAAA,cAClB,MAAM,QAAQ;AAAA,YAChB;AAAA,UACF,CAAC;AAAA,QACH;AAAA,MACF,EAAO;AAAA,QAEL,MAAM,WAA2C;AAAA,UAC/C,SAAS;AAAA,UACT,UAAU,gBAAgB,KAAK,KAAK,QAAQ;AAAA,QAC9C;AAAA,QACA,MAAM,KAAK,EAAE,SAAS,CAAC;AAAA;AAAA,IAE3B;AAAA,EACF;AAAA,EAEA,OAAO;AAAA;AAMT,SAAS,kBAAkB,CAAC,UAA4C;AAAA,EACtE,IAAI;AAAA,EACJ,IAAI,OAAO,SAAS,cAAc,UAAU;AAAA,IAC1C,IAAI;AAAA,MACF,OAAO,KAAK,MAAM,SAAS,SAAS;AAAA,MACpC,MAAM;AAAA,MACN,OAAO,EAAE,MAAM,SAAS,UAAU;AAAA;AAAA,EAEtC,EAAO;AAAA,IACL,OAAO,SAAS;AAAA;AAAA,EAGlB,OAAO;AAAA,IACL,cAAc;AAAA,MACZ,MAAM,SAAS;AAAA,MACf;AAAA,IACF;AAAA,EACF;AAAA;AAOF,SAAS,sBAAsB,CAC7B,YACA,cAC4B;AAAA,EAC5B,OAAO;AAAA,IACL,kBAAkB;AAAA,MAChB,MAAM;AAAA,MACN,UAAU,wBAAwB,WAAW,OAAO;AAAA,IACtD;AAAA,EACF;AAAA;AAMF,SAAS,wBAAwB,CAC/B,UAC2B;AAAA,EAC3B,MAAM,iBAAiB,SAAS,OAC9B,CAAC,OAAO,EAAE,SAAS,YAAY,EAAE,SAAS,gBAAgB,CAAC,EAAE,MAC/D;AAAA,EAEA,IAAI,eAAe,WAAW,GAAG;AAAA,IAC/B;AAAA,EACF;AAAA,EAEA,MAAM,QAAsB,CAAC;AAAA,EAC7B,WAAW,OAAO,gBAAgB;AAAA,IAChC,MAAM,KAAK,GAAG,cAAc,IAAI,OAAO,CAAC;AAAA,EAC1C;AAAA,EAEA,IAAI,MAAM,WAAW,GAAG;AAAA,IACtB;AAAA,EACF;AAAA,EAEA,OAAO;AAAA,IACL,MAAM;AAAA,IACN;AAAA,EACF;AAAA;AAmBK,SAAS,gBAAgB,CAAC,cAAgD;AAAA,EAC/E,MAAM,UAAU,mBAAmB,YAAY;AAAA,EAC/C,MAAM,oBAAoB,yBAAyB,OAAO;AAAA,EAG1D,MAAM,gBAAgB,IAAI;AAAA,EAC1B,WAAW,WAAW,SAAS;AAAA,IAC7B,IAAI,QAAQ,SAAS,cAAc,QAAQ,UAAU;AAAA,MACnD,cAAc,IAAI,QAAQ,SAAS,IAAI,QAAQ,SAAS,IAAI;AAAA,IAC9D;AAAA,EACF;AAAA,EAEA,MAAM,WAA4B,CAAC;AAAA,EAGnC,IAAI,cAAuC;AAAA,EAC3C,IAAI,eAA6B,CAAC;AAAA,EAElC,MAAM,eAAe,MAAM;AAAA,IACzB,IAAI,eAAe,aAAa,SAAS,GAAG;AAAA,MAC1C,SAAS,KAAK;AAAA,QACZ,MAAM;AAAA,QACN,OAAO;AAAA,MACT,CAAC;AAAA,MACD,eAAe,CAAC;AAAA,IAClB;AAAA,IACA,cAAc;AAAA;AAAA,EAGhB,WAAW,WAAW,SAAS;AAAA,IAC7B,IAAI,QAAQ;AAAA,MAAQ;AAAA,IAGpB,IAAI,QAAQ,SAAS,YAAY,QAAQ,SAAS,aAAa;AAAA,MAC7D;AAAA,IACF;AAAA,IAGA,IAAI,QAAQ,SAAS,YAAY;AAAA,MAC/B;AAAA,IACF;AAAA,IAEA,IAAI;AAAA,IACJ,IAAI,QAAsB,CAAC;AAAA,IAE3B,IAAI,QAAQ,SAAS,QAAQ;AAAA,MAC3B,aAAa;AAAA,MACb,QAAQ,cAAc,QAAQ,OAAO;AAAA,IACvC,EAAO,SAAI,QAAQ,SAAS,aAAa;AAAA,MACvC,aAAa;AAAA,MACb,QAAQ,cAAc,QAAQ,OAAO;AAAA,IACvC,EAAO,SAAI,QAAQ,SAAS,cAAc,QAAQ,UAAU;AAAA,MAC1D,aAAa;AAAA,MACb,QAAQ,CAAC,mBAAmB,QAAQ,QAAQ,CAAC;AAAA,IAC/C,EAAO,SAAI,QAAQ,SAAS,iBAAiB,QAAQ,YAAY;AAAA,MAC/D,aAAa;AAAA,MACb,MAAM,eAAe,cAAc,IAAI,QAAQ,WAAW,MAAM,KAAK;AAAA,MACrE,QAAQ,CAAC,uBAAuB,QAAQ,YAAY,YAAY,CAAC;AAAA,IACnE,EAAO;AAAA,MACL;AAAA;AAAA,IAGF,IAAI,MAAM,WAAW,GAAG;AAAA,MACtB;AAAA,IACF;AAAA,IAGA,IAAI,gBAAgB,YAAY;AAAA,MAC9B,aAAa,KAAK,GAAG,KAAK;AAAA,IAC5B,EAAO;AAAA,MACL,aAAa;AAAA,MACb,cAAc;AAAA,MACd,eAAe;AAAA;AAAA,EAEnB;AAAA,EAEA,aAAa;AAAA,EAEb,MAAM,SAA6B,EAAE,SAAS;AAAA,EAC9C,IAAI,sBAAsB,WAAW;AAAA,IACnC,OAAO,oBAAoB;AAAA,EAC7B;AAAA,EACA,OAAO;AAAA;",
9
+ "debugId": "88465330F0A95D8664756E2164756E21",
9
10
  "names": []
10
11
  }
@@ -32,15 +32,42 @@ export interface OpenAIToolCall {
32
32
  };
33
33
  }
34
34
  /**
35
- * OpenAI message format for the Chat Completions API.
35
+ * OpenAI system message format for the Chat Completions API.
36
+ */
37
+ export interface OpenAISystemMessage {
38
+ role: 'system';
39
+ content: string | OpenAITextContentPart[];
40
+ name?: string;
41
+ }
42
+ /**
43
+ * OpenAI user message format for the Chat Completions API.
36
44
  */
37
- export interface OpenAIMessage {
38
- role: 'system' | 'user' | 'assistant' | 'tool';
39
- content: string | OpenAIContentPart[] | null;
45
+ export interface OpenAIUserMessage {
46
+ role: 'user';
47
+ content: string | OpenAIContentPart[];
48
+ name?: string;
49
+ }
50
+ /**
51
+ * OpenAI assistant message format for the Chat Completions API.
52
+ */
53
+ export interface OpenAIAssistantMessage {
54
+ role: 'assistant';
55
+ content: string | OpenAITextContentPart[] | null;
40
56
  name?: string;
41
57
  tool_calls?: OpenAIToolCall[];
42
- tool_call_id?: string;
43
58
  }
59
+ /**
60
+ * OpenAI tool message format for the Chat Completions API.
61
+ */
62
+ export interface OpenAIToolMessage {
63
+ role: 'tool';
64
+ content: string | OpenAITextContentPart[];
65
+ tool_call_id: string;
66
+ }
67
+ /**
68
+ * OpenAI message format for the Chat Completions API.
69
+ */
70
+ export type OpenAIMessage = OpenAISystemMessage | OpenAIUserMessage | OpenAIAssistantMessage | OpenAIToolMessage;
44
71
  /**
45
72
  * Converts a conversation to OpenAI Chat Completions API message format.
46
73
  * Handles role mapping, tool calls, and multi-modal content.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/adapters/openai/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAiC,MAAM,aAAa,CAAC;AAE/E;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,WAAW,CAAC;IAClB,SAAS,EAAE;QACT,GAAG,EAAE,MAAM,CAAC;QACZ,MAAM,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG,MAAM,CAAC;KAClC,CAAC;CACH;AAED;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAAG,qBAAqB,GAAG,sBAAsB,CAAC;AAE/E;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,UAAU,CAAC;IACjB,QAAQ,EAAE;QACR,IAAI,EAAE,MAAM,CAAC;QACb,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG,WAAW,GAAG,MAAM,CAAC;IAC/C,OAAO,EAAE,MAAM,GAAG,iBAAiB,EAAE,GAAG,IAAI,CAAC;IAC7C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,cAAc,EAAE,CAAC;IAC9B,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAiHD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,gBAAgB,CAAC,YAAY,EAAE,YAAY,GAAG,aAAa,EAAE,CAW5E;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,YAAY,EAAE,YAAY,GAAG,aAAa,EAAE,CAsCnF"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/adapters/openai/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAiC,MAAM,aAAa,CAAC;AAG/E;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,WAAW,CAAC;IAClB,SAAS,EAAE;QACT,GAAG,EAAE,MAAM,CAAC;QACZ,MAAM,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG,MAAM,CAAC;KAClC,CAAC;CACH;AAED;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAAG,qBAAqB,GAAG,sBAAsB,CAAC;AAE/E;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,UAAU,CAAC;IACjB,QAAQ,EAAE;QACR,IAAI,EAAE,MAAM,CAAC;QACb,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,QAAQ,CAAC;IACf,OAAO,EAAE,MAAM,GAAG,qBAAqB,EAAE,CAAC;IAC1C,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,GAAG,iBAAiB,EAAE,CAAC;IACtC,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,WAAW,CAAC;IAClB,OAAO,EAAE,MAAM,GAAG,qBAAqB,EAAE,GAAG,IAAI,CAAC;IACjD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,cAAc,EAAE,CAAC;CAC/B;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,GAAG,qBAAqB,EAAE,CAAC;IAC1C,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,MAAM,aAAa,GACrB,mBAAmB,GACnB,iBAAiB,GACjB,sBAAsB,GACtB,iBAAiB,CAAC;AA4ItB;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,gBAAgB,CAAC,YAAY,EAAE,YAAY,GAAG,aAAa,EAAE,CAW5E;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,YAAY,EAAE,YAAY,GAAG,aAAa,EAAE,CAsCnF"}
@@ -1,20 +1,42 @@
1
+ // src/utilities/message-store.ts
2
+ function getOrderedMessages(conversation) {
3
+ const ordered = [];
4
+ for (const id of conversation.ids) {
5
+ const message = conversation.messages[id];
6
+ if (message) {
7
+ ordered.push(message);
8
+ }
9
+ }
10
+ return ordered;
11
+ }
12
+
1
13
  // src/adapters/openai/index.ts
2
- function toOpenAIContent(content) {
14
+ function toOpenAIContent(content, options = {}) {
3
15
  if (typeof content === "string") {
4
16
  return content;
5
17
  }
18
+ const allowImages = options.allowImages ?? true;
6
19
  const parts = [];
7
20
  for (const part of content) {
8
21
  if (part.type === "text") {
9
22
  parts.push({ type: "text", text: part.text ?? "" });
10
- } else if (part.type === "image") {
23
+ } else if (part.type === "image" && allowImages) {
11
24
  parts.push({
12
25
  type: "image_url",
13
26
  image_url: { url: part.url ?? "" }
14
27
  });
15
28
  }
16
29
  }
17
- return parts.length === 1 && parts[0]?.type === "text" ? parts[0].text : parts;
30
+ if (parts.length === 0) {
31
+ return "";
32
+ }
33
+ if (parts.length === 1 && parts[0]?.type === "text") {
34
+ return parts[0].text;
35
+ }
36
+ return allowImages ? parts : parts;
37
+ }
38
+ function toOpenAITextContent(content) {
39
+ return toOpenAIContent(content, { allowImages: false });
18
40
  }
19
41
  function toOpenAIToolCall(toolCall) {
20
42
  return {
@@ -35,7 +57,7 @@ function convertMessage(message) {
35
57
  case "developer":
36
58
  return {
37
59
  role: "system",
38
- content: toOpenAIContent(message.content)
60
+ content: toOpenAITextContent(message.content)
39
61
  };
40
62
  case "user":
41
63
  return {
@@ -45,7 +67,7 @@ function convertMessage(message) {
45
67
  case "assistant":
46
68
  return {
47
69
  role: "assistant",
48
- content: toOpenAIContent(message.content)
70
+ content: toOpenAITextContent(message.content)
49
71
  };
50
72
  case "tool-use":
51
73
  if (!message.toolCall) {
@@ -79,7 +101,7 @@ function stringifyToolResult(result) {
79
101
  }
80
102
  function toOpenAIMessages(conversation) {
81
103
  const messages = [];
82
- for (const message of conversation.messages) {
104
+ for (const message of getOrderedMessages(conversation)) {
83
105
  const converted = convertMessage(message);
84
106
  if (converted) {
85
107
  messages.push(converted);
@@ -90,7 +112,7 @@ function toOpenAIMessages(conversation) {
90
112
  function toOpenAIMessagesGrouped(conversation) {
91
113
  const messages = [];
92
114
  let pendingToolCalls = [];
93
- for (const message of conversation.messages) {
115
+ for (const message of getOrderedMessages(conversation)) {
94
116
  if (message.hidden)
95
117
  continue;
96
118
  if (message.role === "tool-use" && message.toolCall) {
@@ -124,4 +146,4 @@ export {
124
146
  toOpenAIMessages
125
147
  };
126
148
 
127
- //# debugId=45A34764E7499FFC64756E2164756E21
149
+ //# debugId=76C027000C92020164756E2164756E21
@@ -1,10 +1,11 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../../../src/adapters/openai/index.ts"],
3
+ "sources": ["../../../src/utilities/message-store.ts", "../../../src/adapters/openai/index.ts"],
4
4
  "sourcesContent": [
5
- "import type { MultiModalContent } from '@lasercat/homogenaize';\n\nimport type { Conversation, Message, ToolCall, ToolResult } from '../../types';\n\n/**\n * OpenAI text content part.\n */\nexport interface OpenAITextContentPart {\n type: 'text';\n text: string;\n}\n\n/**\n * OpenAI image content part.\n */\nexport interface OpenAIImageContentPart {\n type: 'image_url';\n image_url: {\n url: string;\n detail?: 'auto' | 'low' | 'high';\n };\n}\n\n/**\n * OpenAI content part union type.\n */\nexport type OpenAIContentPart = OpenAITextContentPart | OpenAIImageContentPart;\n\n/**\n * OpenAI tool call format.\n */\nexport interface OpenAIToolCall {\n id: string;\n type: 'function';\n function: {\n name: string;\n arguments: string;\n };\n}\n\n/**\n * OpenAI message format for the Chat Completions API.\n */\nexport interface OpenAIMessage {\n role: 'system' | 'user' | 'assistant' | 'tool';\n content: string | OpenAIContentPart[] | null;\n name?: string;\n tool_calls?: OpenAIToolCall[];\n tool_call_id?: string;\n}\n\n/**\n * Converts internal multi-modal content to OpenAI content parts format.\n */\nfunction toOpenAIContent(\n content: string | ReadonlyArray<MultiModalContent>,\n): string | OpenAIContentPart[] {\n if (typeof content === 'string') {\n return content;\n }\n\n const parts: OpenAIContentPart[] = [];\n for (const part of content) {\n if (part.type === 'text') {\n parts.push({ type: 'text', text: part.text ?? '' });\n } else if (part.type === 'image') {\n parts.push({\n type: 'image_url',\n image_url: { url: part.url ?? '' },\n });\n }\n }\n\n return parts.length === 1 && parts[0]?.type === 'text' ? parts[0].text : parts;\n}\n\n/**\n * Converts an internal ToolCall to OpenAI format.\n */\nfunction toOpenAIToolCall(toolCall: ToolCall): OpenAIToolCall {\n return {\n id: toolCall.id,\n type: 'function',\n function: {\n name: toolCall.name,\n arguments:\n typeof toolCall.arguments === 'string'\n ? toolCall.arguments\n : JSON.stringify(toolCall.arguments),\n },\n };\n}\n\n/**\n * Converts a single message to OpenAI format.\n * Returns null for messages that should be skipped.\n */\nfunction convertMessage(message: Message): OpenAIMessage | null {\n // Skip hidden messages\n if (message.hidden) {\n return null;\n }\n\n switch (message.role) {\n case 'system':\n case 'developer':\n return {\n role: 'system',\n content: toOpenAIContent(message.content),\n };\n\n case 'user':\n return {\n role: 'user',\n content: toOpenAIContent(message.content),\n };\n\n case 'assistant':\n return {\n role: 'assistant',\n content: toOpenAIContent(message.content),\n };\n\n case 'tool-use':\n if (!message.toolCall) {\n return null;\n }\n return {\n role: 'assistant',\n content: null,\n tool_calls: [toOpenAIToolCall(message.toolCall)],\n };\n\n case 'tool-result':\n if (!message.toolResult) {\n return null;\n }\n return {\n role: 'tool',\n content: stringifyToolResult(message.toolResult),\n tool_call_id: message.toolResult.callId,\n };\n\n case 'snapshot':\n // Snapshots are internal state, not sent to API\n return null;\n\n default:\n return null;\n }\n}\n\n/**\n * Converts a tool result to a string for OpenAI.\n */\nfunction stringifyToolResult(result: ToolResult): string {\n if (typeof result.content === 'string') {\n return result.content;\n }\n return JSON.stringify(result.content);\n}\n\n/**\n * Converts a conversation to OpenAI Chat Completions API message format.\n * Handles role mapping, tool calls, and multi-modal content.\n *\n * @example\n * ```ts\n * import { toOpenAIMessages } from 'conversationalist/openai';\n *\n * const messages = toOpenAIMessages(conversation);\n * const response = await openai.chat.completions.create({\n * model: 'gpt-4',\n * messages,\n * });\n * ```\n */\nexport function toOpenAIMessages(conversation: Conversation): OpenAIMessage[] {\n const messages: OpenAIMessage[] = [];\n\n for (const message of conversation.messages) {\n const converted = convertMessage(message);\n if (converted) {\n messages.push(converted);\n }\n }\n\n return messages;\n}\n\n/**\n * Groups consecutive tool-use messages into a single assistant message with multiple tool_calls.\n * This is useful when the model made multiple tool calls in sequence.\n */\nexport function toOpenAIMessagesGrouped(conversation: Conversation): OpenAIMessage[] {\n const messages: OpenAIMessage[] = [];\n let pendingToolCalls: OpenAIToolCall[] = [];\n\n for (const message of conversation.messages) {\n if (message.hidden) continue;\n\n if (message.role === 'tool-use' && message.toolCall) {\n pendingToolCalls.push(toOpenAIToolCall(message.toolCall));\n continue;\n }\n\n // Flush pending tool calls before adding a new message\n if (pendingToolCalls.length > 0) {\n messages.push({\n role: 'assistant',\n content: null,\n tool_calls: pendingToolCalls,\n });\n pendingToolCalls = [];\n }\n\n const converted = convertMessage(message);\n if (converted && message.role !== 'tool-use') {\n messages.push(converted);\n }\n }\n\n // Flush any remaining tool calls\n if (pendingToolCalls.length > 0) {\n messages.push({\n role: 'assistant',\n content: null,\n tool_calls: pendingToolCalls,\n });\n }\n\n return messages;\n}\n"
5
+ "import type { Conversation, Message } from '../types';\n\nexport function getOrderedMessages(conversation: Conversation): Message[] {\n const ordered: Message[] = [];\n for (const id of conversation.ids) {\n const message = conversation.messages[id];\n if (message) {\n ordered.push(message);\n }\n }\n return ordered;\n}\n\nexport function toIdRecord<T extends { id: string }>(\n items: readonly T[],\n): Record<string, T> {\n const record: Record<string, T> = {};\n for (const item of items) {\n record[item.id] = item;\n }\n return record;\n}\n",
6
+ "import type { MultiModalContent } from '@lasercat/homogenaize';\n\nimport type { Conversation, Message, ToolCall, ToolResult } from '../../types';\nimport { getOrderedMessages } from '../../utilities/message-store';\n\n/**\n * OpenAI text content part.\n */\nexport interface OpenAITextContentPart {\n type: 'text';\n text: string;\n}\n\n/**\n * OpenAI image content part.\n */\nexport interface OpenAIImageContentPart {\n type: 'image_url';\n image_url: {\n url: string;\n detail?: 'auto' | 'low' | 'high';\n };\n}\n\n/**\n * OpenAI content part union type.\n */\nexport type OpenAIContentPart = OpenAITextContentPart | OpenAIImageContentPart;\n\n/**\n * OpenAI tool call format.\n */\nexport interface OpenAIToolCall {\n id: string;\n type: 'function';\n function: {\n name: string;\n arguments: string;\n };\n}\n\n/**\n * OpenAI system message format for the Chat Completions API.\n */\nexport interface OpenAISystemMessage {\n role: 'system';\n content: string | OpenAITextContentPart[];\n name?: string;\n}\n\n/**\n * OpenAI user message format for the Chat Completions API.\n */\nexport interface OpenAIUserMessage {\n role: 'user';\n content: string | OpenAIContentPart[];\n name?: string;\n}\n\n/**\n * OpenAI assistant message format for the Chat Completions API.\n */\nexport interface OpenAIAssistantMessage {\n role: 'assistant';\n content: string | OpenAITextContentPart[] | null;\n name?: string;\n tool_calls?: OpenAIToolCall[];\n}\n\n/**\n * OpenAI tool message format for the Chat Completions API.\n */\nexport interface OpenAIToolMessage {\n role: 'tool';\n content: string | OpenAITextContentPart[];\n tool_call_id: string;\n}\n\n/**\n * OpenAI message format for the Chat Completions API.\n */\nexport type OpenAIMessage =\n | OpenAISystemMessage\n | OpenAIUserMessage\n | OpenAIAssistantMessage\n | OpenAIToolMessage;\n\n/**\n * Converts internal multi-modal content to OpenAI content parts format.\n */\nfunction toOpenAIContent(\n content: string | ReadonlyArray<MultiModalContent>,\n options: { allowImages: false },\n): string | OpenAITextContentPart[];\nfunction toOpenAIContent(\n content: string | ReadonlyArray<MultiModalContent>,\n options?: { allowImages?: true },\n): string | OpenAIContentPart[];\nfunction toOpenAIContent(\n content: string | ReadonlyArray<MultiModalContent>,\n options: { allowImages?: boolean } = {},\n): string | OpenAIContentPart[] | OpenAITextContentPart[] {\n if (typeof content === 'string') {\n return content;\n }\n\n const allowImages = options.allowImages ?? true;\n const parts: OpenAIContentPart[] = [];\n for (const part of content) {\n if (part.type === 'text') {\n parts.push({ type: 'text', text: part.text ?? '' });\n } else if (part.type === 'image' && allowImages) {\n parts.push({\n type: 'image_url',\n image_url: { url: part.url ?? '' },\n });\n }\n }\n\n if (parts.length === 0) {\n return '';\n }\n\n if (parts.length === 1 && parts[0]?.type === 'text') {\n return parts[0].text;\n }\n\n return allowImages ? parts : (parts as OpenAITextContentPart[]);\n}\n\n/**\n * Converts internal multi-modal content to OpenAI text-only format.\n */\nfunction toOpenAITextContent(\n content: string | ReadonlyArray<MultiModalContent>,\n): string | OpenAITextContentPart[] {\n return toOpenAIContent(content, { allowImages: false });\n}\n\n/**\n * Converts an internal ToolCall to OpenAI format.\n */\nfunction toOpenAIToolCall(toolCall: ToolCall): OpenAIToolCall {\n return {\n id: toolCall.id,\n type: 'function',\n function: {\n name: toolCall.name,\n arguments:\n typeof toolCall.arguments === 'string'\n ? toolCall.arguments\n : JSON.stringify(toolCall.arguments),\n },\n };\n}\n\n/**\n * Converts a single message to OpenAI format.\n * Returns null for messages that should be skipped.\n */\nfunction convertMessage(message: Message): OpenAIMessage | null {\n // Skip hidden messages\n if (message.hidden) {\n return null;\n }\n\n switch (message.role) {\n case 'system':\n case 'developer':\n return {\n role: 'system',\n content: toOpenAITextContent(message.content),\n };\n\n case 'user':\n return {\n role: 'user',\n content: toOpenAIContent(message.content),\n };\n\n case 'assistant':\n return {\n role: 'assistant',\n content: toOpenAITextContent(message.content),\n };\n\n case 'tool-use':\n if (!message.toolCall) {\n return null;\n }\n return {\n role: 'assistant',\n content: null,\n tool_calls: [toOpenAIToolCall(message.toolCall)],\n };\n\n case 'tool-result':\n if (!message.toolResult) {\n return null;\n }\n return {\n role: 'tool',\n content: stringifyToolResult(message.toolResult),\n tool_call_id: message.toolResult.callId,\n };\n\n case 'snapshot':\n // Snapshots are internal state, not sent to API\n return null;\n\n default:\n return null;\n }\n}\n\n/**\n * Converts a tool result to a string for OpenAI.\n */\nfunction stringifyToolResult(result: ToolResult): string {\n if (typeof result.content === 'string') {\n return result.content;\n }\n return JSON.stringify(result.content);\n}\n\n/**\n * Converts a conversation to OpenAI Chat Completions API message format.\n * Handles role mapping, tool calls, and multi-modal content.\n *\n * @example\n * ```ts\n * import { toOpenAIMessages } from 'conversationalist/openai';\n *\n * const messages = toOpenAIMessages(conversation);\n * const response = await openai.chat.completions.create({\n * model: 'gpt-4',\n * messages,\n * });\n * ```\n */\nexport function toOpenAIMessages(conversation: Conversation): OpenAIMessage[] {\n const messages: OpenAIMessage[] = [];\n\n for (const message of getOrderedMessages(conversation)) {\n const converted = convertMessage(message);\n if (converted) {\n messages.push(converted);\n }\n }\n\n return messages;\n}\n\n/**\n * Groups consecutive tool-use messages into a single assistant message with multiple tool_calls.\n * This is useful when the model made multiple tool calls in sequence.\n */\nexport function toOpenAIMessagesGrouped(conversation: Conversation): OpenAIMessage[] {\n const messages: OpenAIMessage[] = [];\n let pendingToolCalls: OpenAIToolCall[] = [];\n\n for (const message of getOrderedMessages(conversation)) {\n if (message.hidden) continue;\n\n if (message.role === 'tool-use' && message.toolCall) {\n pendingToolCalls.push(toOpenAIToolCall(message.toolCall));\n continue;\n }\n\n // Flush pending tool calls before adding a new message\n if (pendingToolCalls.length > 0) {\n messages.push({\n role: 'assistant',\n content: null,\n tool_calls: pendingToolCalls,\n });\n pendingToolCalls = [];\n }\n\n const converted = convertMessage(message);\n if (converted && message.role !== 'tool-use') {\n messages.push(converted);\n }\n }\n\n // Flush any remaining tool calls\n if (pendingToolCalls.length > 0) {\n messages.push({\n role: 'assistant',\n content: null,\n tool_calls: pendingToolCalls,\n });\n }\n\n return messages;\n}\n"
6
7
  ],
7
- "mappings": "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",
8
- "debugId": "45A34764E7499FFC64756E2164756E21",
8
+ "mappings": "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",
9
+ "debugId": "76C027000C92020164756E2164756E21",
9
10
  "names": []
10
11
  }
@@ -1 +1 @@
1
- {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,uBAAuB,EAG5B,oBAAoB,EACrB,MAAM,eAAe,CAAC;AAEvB,OAAO,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAGrE,OAAO,EAAE,oBAAoB,EAAE,CAAC;AAEhC;;;GAGG;AACH,wBAAgB,0BAA0B,CACxC,YAAY,EAAE,YAAY,EAC1B,cAAc,CAAC,EAAE,cAAc,EAC/B,WAAW,CAAC,EAAE,OAAO,CAAC,uBAAuB,CAAC,GAC7C,MAAM,CAqBR;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,YAAY,EAAE,YAAY,EAC1B,SAAS,EAAE,MAAM,EACjB,kBAAkB,CAAC,EAAE,eAAe,GAAG,cAAc,EACrD,WAAW,CAAC,EAAE,OAAO,CAAC,uBAAuB,CAAC,GAC7C,YAAY,CAwId;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,YAAY,EAAE,YAAY,EAC1B,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE;IACR,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB,GACA,aAAa,CAAC,OAAO,CAAC,CAWxB;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,YAAY,EAAE,YAAY,EAC1B,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE;IACR,sBAAsB,CAAC,EAAE,OAAO,CAAC;CAClC,EACD,WAAW,CAAC,EAAE,OAAO,CAAC,uBAAuB,CAAC,GAC7C,YAAY,CAkCd"}
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,KAAK,uBAAuB,EAG5B,oBAAoB,EACrB,MAAM,eAAe,CAAC;AAEvB,OAAO,KAAK,EAAoB,YAAY,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAIvF,OAAO,EAAE,oBAAoB,EAAE,CAAC;AAgChC;;;GAGG;AACH,wBAAgB,0BAA0B,CACxC,YAAY,EAAE,YAAY,EAC1B,cAAc,CAAC,EAAE,cAAc,EAC/B,WAAW,CAAC,EAAE,OAAO,CAAC,uBAAuB,CAAC,GAC7C,MAAM,CAqBR;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,YAAY,EAAE,YAAY,EAC1B,SAAS,EAAE,MAAM,EACjB,kBAAkB,CAAC,EAAE,eAAe,GAAG,cAAc,EACrD,WAAW,CAAC,EAAE,OAAO,CAAC,uBAAuB,CAAC,GAC7C,YAAY,CAmHd;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,YAAY,EAAE,YAAY,EAC1B,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE;IACR,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB,GACA,aAAa,CAAC,OAAO,CAAC,CAWxB;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,YAAY,EAAE,YAAY,EAC1B,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE;IACR,sBAAsB,CAAC,EAAE,OAAO,CAAC;CAClC,EACD,WAAW,CAAC,EAAE,OAAO,CAAC,uBAAuB,CAAC,GAC7C,YAAY,CAwBd"}
@@ -1,5 +1,5 @@
1
1
  import { type ConversationEnvironment } from '../environment';
2
- import type { Conversation, MessageInput } from '../types';
2
+ import type { Conversation, JSONValue, MessageInput } from '../types';
3
3
  /**
4
4
  * Appends one or more messages to a conversation.
5
5
  * Validates that tool results reference existing function calls.
@@ -13,13 +13,13 @@ export declare function appendMessages(conversation: Conversation, ...inputsAndE
13
13
  /**
14
14
  * Appends a user message to the conversation.
15
15
  */
16
- export declare function appendUserMessage(conversation: Conversation, content: MessageInput['content'], metadata?: Record<string, unknown>, environment?: Partial<ConversationEnvironment>): Conversation;
16
+ export declare function appendUserMessage(conversation: Conversation, content: MessageInput['content'], metadata?: Record<string, JSONValue>, environment?: Partial<ConversationEnvironment>): Conversation;
17
17
  /**
18
18
  * Appends an assistant message to the conversation.
19
19
  */
20
- export declare function appendAssistantMessage(conversation: Conversation, content: MessageInput['content'], metadata?: Record<string, unknown>, environment?: Partial<ConversationEnvironment>): Conversation;
20
+ export declare function appendAssistantMessage(conversation: Conversation, content: MessageInput['content'], metadata?: Record<string, JSONValue>, environment?: Partial<ConversationEnvironment>): Conversation;
21
21
  /**
22
22
  * Appends a system message to the conversation.
23
23
  */
24
- export declare function appendSystemMessage(conversation: Conversation, content: string, metadata?: Record<string, unknown>, environment?: Partial<ConversationEnvironment>): Conversation;
24
+ export declare function appendSystemMessage(conversation: Conversation, content: string, metadata?: Record<string, JSONValue>, environment?: Partial<ConversationEnvironment>): Conversation;
25
25
  //# sourceMappingURL=append.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"append.d.ts","sourceRoot":"","sources":["../../src/conversation/append.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,KAAK,uBAAuB,EAG7B,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EAAE,YAAY,EAAW,YAAY,EAAE,MAAM,UAAU,CAAC;AAmCpE;;;;GAIG;AACH,wBAAgB,cAAc,CAC5B,YAAY,EAAE,YAAY,EAC1B,GAAG,MAAM,EAAE,YAAY,EAAE,GACxB,YAAY,CAAC;AAChB,wBAAgB,cAAc,CAC5B,YAAY,EAAE,YAAY,EAC1B,GAAG,oBAAoB,EAAE;IACvB,GAAG,YAAY,EAAE;IACjB,OAAO,CAAC,uBAAuB,CAAC,GAAG,SAAS;CAC7C,GACA,YAAY,CAAC;AA2DhB;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,YAAY,EAAE,YAAY,EAC1B,OAAO,EAAE,YAAY,CAAC,SAAS,CAAC,EAChC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAClC,WAAW,CAAC,EAAE,OAAO,CAAC,uBAAuB,CAAC,GAC7C,YAAY,CAEd;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,YAAY,EAAE,YAAY,EAC1B,OAAO,EAAE,YAAY,CAAC,SAAS,CAAC,EAChC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAClC,WAAW,CAAC,EAAE,OAAO,CAAC,uBAAuB,CAAC,GAC7C,YAAY,CAMd;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,YAAY,EAAE,YAAY,EAC1B,OAAO,EAAE,MAAM,EACf,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAClC,WAAW,CAAC,EAAE,OAAO,CAAC,uBAAuB,CAAC,GAC7C,YAAY,CAEd"}
1
+ {"version":3,"file":"append.d.ts","sourceRoot":"","sources":["../../src/conversation/append.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,KAAK,uBAAuB,EAG7B,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EAEV,YAAY,EACZ,SAAS,EAET,YAAY,EACb,MAAM,UAAU,CAAC;AAoClB;;;;GAIG;AACH,wBAAgB,cAAc,CAC5B,YAAY,EAAE,YAAY,EAC1B,GAAG,MAAM,EAAE,YAAY,EAAE,GACxB,YAAY,CAAC;AAChB,wBAAgB,cAAc,CAC5B,YAAY,EAAE,YAAY,EAC1B,GAAG,oBAAoB,EAAE;IACvB,GAAG,YAAY,EAAE;IACjB,OAAO,CAAC,uBAAuB,CAAC,GAAG,SAAS;CAC7C,GACA,YAAY,CAAC;AAwEhB;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,YAAY,EAAE,YAAY,EAC1B,OAAO,EAAE,YAAY,CAAC,SAAS,CAAC,EAChC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,EACpC,WAAW,CAAC,EAAE,OAAO,CAAC,uBAAuB,CAAC,GAC7C,YAAY,CAEd;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,YAAY,EAAE,YAAY,EAC1B,OAAO,EAAE,YAAY,CAAC,SAAS,CAAC,EAChC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,EACpC,WAAW,CAAC,EAAE,OAAO,CAAC,uBAAuB,CAAC,GAC7C,YAAY,CAMd;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,YAAY,EAAE,YAAY,EAC1B,OAAO,EAAE,MAAM,EACf,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,EACpC,WAAW,CAAC,EAAE,OAAO,CAAC,uBAAuB,CAAC,GAC7C,YAAY,CAEd"}
@@ -1,5 +1,5 @@
1
1
  import { type ConversationEnvironment } from '../environment';
2
- import type { Conversation, ConversationStatus } from '../types';
2
+ import type { Conversation, ConversationStatus, JSONValue } from '../types';
3
3
  /**
4
4
  * Creates a new empty conversation with the specified options.
5
5
  * Returns an immutable conversation object with timestamps set to the current time.
@@ -8,7 +8,6 @@ export declare function createConversation(options?: {
8
8
  id?: string;
9
9
  title?: string;
10
10
  status?: ConversationStatus;
11
- metadata?: Record<string, unknown>;
12
- tags?: string[];
11
+ metadata?: Record<string, JSONValue>;
13
12
  }, environment?: Partial<ConversationEnvironment>): Conversation;
14
13
  //# sourceMappingURL=create.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../src/conversation/create.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,uBAAuB,EAE7B,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAGjE;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,CAAC,EAAE;IACR,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,kBAAkB,CAAC;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;CACjB,EACD,WAAW,CAAC,EAAE,OAAO,CAAC,uBAAuB,CAAC,GAC7C,YAAY,CAcd"}
1
+ {"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../src/conversation/create.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,uBAAuB,EAE7B,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EAAE,YAAY,EAAE,kBAAkB,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAI5E;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,CAAC,EAAE;IACR,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,kBAAkB,CAAC;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;CACtC,EACD,WAAW,CAAC,EAAE,OAAO,CAAC,uBAAuB,CAAC,GAC7C,YAAY,CAed"}
@@ -1,9 +1,9 @@
1
1
  export type { ConversationEnvironment } from '../environment';
2
2
  export { createConversation } from './create';
3
3
  export { appendAssistantMessage, appendMessages, appendSystemMessage, appendUserMessage, } from './append';
4
- export { computeConversationStatistics, getConversationMessages, getMessageAtPosition, getMessageByIdentifier, searchConversationMessages, } from './query';
4
+ export { getMessageAtPosition, getMessageById, getMessageIds, getMessages, getStatistics, searchConversationMessages, } from './query';
5
5
  export { collapseSystemMessages, getFirstSystemMessage, getSystemMessages, hasSystemMessage, prependSystemMessage, replaceSystemMessage, } from './system-messages';
6
6
  export { redactMessageAtPosition } from './modify';
7
- export { deserializeConversation, migrateConversationJSON, serializeConversation, } from './serialization';
7
+ export { deserializeConversation, migrateConversation } from './serialization';
8
8
  export { toChatMessages } from './transform';
9
9
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/conversation/index.ts"],"names":[],"mappings":"AACA,YAAY,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAG9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAG9C,OAAO,EACL,sBAAsB,EACtB,cAAc,EACd,mBAAmB,EACnB,iBAAiB,GAClB,MAAM,UAAU,CAAC;AAGlB,OAAO,EACL,6BAA6B,EAC7B,uBAAuB,EACvB,oBAAoB,EACpB,sBAAsB,EACtB,0BAA0B,GAC3B,MAAM,SAAS,CAAC;AAGjB,OAAO,EACL,sBAAsB,EACtB,qBAAqB,EACrB,iBAAiB,EACjB,gBAAgB,EAChB,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EAAE,uBAAuB,EAAE,MAAM,UAAU,CAAC;AAGnD,OAAO,EACL,uBAAuB,EACvB,uBAAuB,EACvB,qBAAqB,GACtB,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/conversation/index.ts"],"names":[],"mappings":"AACA,YAAY,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAG9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAG9C,OAAO,EACL,sBAAsB,EACtB,cAAc,EACd,mBAAmB,EACnB,iBAAiB,GAClB,MAAM,UAAU,CAAC;AAGlB,OAAO,EACL,oBAAoB,EACpB,cAAc,EACd,aAAa,EACb,WAAW,EACX,aAAa,EACb,0BAA0B,GAC3B,MAAM,SAAS,CAAC;AAGjB,OAAO,EACL,sBAAsB,EACtB,qBAAqB,EACrB,iBAAiB,EACjB,gBAAgB,EAChB,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EAAE,uBAAuB,EAAE,MAAM,UAAU,CAAC;AAGnD,OAAO,EAAE,uBAAuB,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAG/E,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"modify.d.ts","sourceRoot":"","sources":["../../src/conversation/modify.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,uBAAuB,EAE7B,MAAM,gBAAgB,CAAC;AAExB,OAAO,KAAK,EAAE,YAAY,EAAW,MAAM,UAAU,CAAC;AAGtD;;;;GAIG;AACH,wBAAgB,uBAAuB,CACrC,YAAY,EAAE,YAAY,EAC1B,QAAQ,EAAE,MAAM,EAChB,WAAW,GAAE,MAAqB,EAClC,WAAW,CAAC,EAAE,OAAO,CAAC,uBAAuB,CAAC,GAC7C,YAAY,CA2Bd"}
1
+ {"version":3,"file":"modify.d.ts","sourceRoot":"","sources":["../../src/conversation/modify.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,uBAAuB,EAE7B,MAAM,gBAAgB,CAAC;AAExB,OAAO,KAAK,EAAE,YAAY,EAAW,MAAM,UAAU,CAAC;AAGtD;;;;GAIG;AACH,wBAAgB,uBAAuB,CACrC,YAAY,EAAE,YAAY,EAC1B,QAAQ,EAAE,MAAM,EAChB,WAAW,GAAE,MAAqB,EAClC,WAAW,CAAC,EAAE,OAAO,CAAC,uBAAuB,CAAC,GAC7C,YAAY,CAgCd"}
@@ -1,21 +1,25 @@
1
1
  import type { Conversation, Message } from '../types';
2
2
  /**
3
- * Returns all messages from a conversation.
3
+ * Returns all messages from a conversation in order.
4
4
  * By default excludes hidden messages unless includeHidden is true.
5
5
  */
6
- export declare function getConversationMessages(conversation: Conversation, options?: {
6
+ export declare function getMessages(conversation: Conversation, options?: {
7
7
  includeHidden?: boolean;
8
- }): ReadonlyArray<Message>;
8
+ }): Message[];
9
9
  /**
10
10
  * Returns the message at the specified position index.
11
11
  * Returns undefined if no message exists at that position.
12
12
  */
13
13
  export declare function getMessageAtPosition(conversation: Conversation, position: number): Message | undefined;
14
+ /**
15
+ * Returns all message IDs for the conversation in order.
16
+ */
17
+ export declare function getMessageIds(conversation: Conversation): string[];
14
18
  /**
15
19
  * Finds a message by its unique identifier.
16
20
  * Returns undefined if no message with that ID exists.
17
21
  */
18
- export declare function getMessageByIdentifier(conversation: Conversation, id: string): Message | undefined;
22
+ export declare function getMessageById(conversation: Conversation, id: string): Message | undefined;
19
23
  /**
20
24
  * Filters messages using a custom predicate function.
21
25
  * Returns all messages for which the predicate returns true.
@@ -25,7 +29,7 @@ export declare function searchConversationMessages(conversation: Conversation, p
25
29
  * Computes statistics about a conversation's messages.
26
30
  * Returns totals, counts by role, hidden message count, and image count.
27
31
  */
28
- export declare function computeConversationStatistics(conversation: Conversation): {
32
+ export declare function getStatistics(conversation: Conversation): {
29
33
  total: number;
30
34
  byRole: Record<string, number>;
31
35
  hidden: number;
@@ -1 +1 @@
1
- {"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../../src/conversation/query.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAGtD;;;GAGG;AACH,wBAAgB,uBAAuB,CACrC,YAAY,EAAE,YAAY,EAC1B,OAAO,CAAC,EAAE;IAAE,aAAa,CAAC,EAAE,OAAO,CAAA;CAAE,GACpC,aAAa,CAAC,OAAO,CAAC,CAKxB;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,YAAY,EAAE,YAAY,EAC1B,QAAQ,EAAE,MAAM,GACf,OAAO,GAAG,SAAS,CAErB;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CACpC,YAAY,EAAE,YAAY,EAC1B,EAAE,EAAE,MAAM,GACT,OAAO,GAAG,SAAS,CAErB;AAED;;;GAGG;AACH,wBAAgB,0BAA0B,CACxC,YAAY,EAAE,YAAY,EAC1B,SAAS,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,OAAO,GACjC,OAAO,EAAE,CAEX;AAED;;;GAGG;AACH,wBAAgB,6BAA6B,CAAC,YAAY,EAAE,YAAY,GAAG;IACzE,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;CACpB,CAiBA"}
1
+ {"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../../src/conversation/query.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAItD;;;GAGG;AACH,wBAAgB,WAAW,CACzB,YAAY,EAAE,YAAY,EAC1B,OAAO,CAAC,EAAE;IAAE,aAAa,CAAC,EAAE,OAAO,CAAA;CAAE,GACpC,OAAO,EAAE,CAIX;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,YAAY,EAAE,YAAY,EAC1B,QAAQ,EAAE,MAAM,GACf,OAAO,GAAG,SAAS,CAGrB;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,YAAY,EAAE,YAAY,GAAG,MAAM,EAAE,CAElE;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAC5B,YAAY,EAAE,YAAY,EAC1B,EAAE,EAAE,MAAM,GACT,OAAO,GAAG,SAAS,CAErB;AAED;;;GAGG;AACH,wBAAgB,0BAA0B,CACxC,YAAY,EAAE,YAAY,EAC1B,SAAS,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,OAAO,GACjC,OAAO,EAAE,CAEX;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,YAAY,EAAE,YAAY,GAAG;IACzD,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;CACpB,CAkBA"}
@@ -1,42 +1,20 @@
1
- import type { Conversation, ConversationJSON, SerializeOptions } from '../types';
1
+ import type { Conversation } from '../types';
2
2
  /**
3
- * Migrates a conversation JSON object to the current schema version.
3
+ * Migrates a serialized conversation object to the current schema version.
4
4
  * Handles data from older versions that may not have a schemaVersion field.
5
5
  *
6
- * @param json - The conversation JSON to migrate (may be from an older version)
7
- * @returns A ConversationJSON with the current schema version
6
+ * @param json - The conversation data to migrate (may be from an older version)
7
+ * @returns A Conversation with the current schema version
8
8
  *
9
9
  * @example
10
10
  * ```ts
11
11
  * // Old data without schemaVersion
12
12
  * const old = { id: 'conv-1', status: 'active', ... };
13
- * const migrated = migrateConversationJSON(old);
13
+ * const migrated = migrateConversation(old);
14
14
  * // migrated.schemaVersion === CURRENT_SCHEMA_VERSION
15
15
  * ```
16
16
  */
17
- export declare function migrateConversationJSON(json: unknown): ConversationJSON;
18
- /**
19
- * Converts a conversation to a plain JSON-serializable object.
20
- * Creates deep copies of all nested objects to ensure immutability.
21
- *
22
- * @param conversation - The conversation to serialize
23
- * @param options - Serialization options
24
- * @returns A JSON-serializable conversation object
25
- *
26
- * @example
27
- * ```ts
28
- * // Basic serialization
29
- * const json = serializeConversation(conversation);
30
- *
31
- * // With options
32
- * const json = serializeConversation(conversation, {
33
- * deterministic: true,
34
- * stripTransient: true,
35
- * redactToolArguments: true,
36
- * });
37
- * ```
38
- */
39
- export declare function serializeConversation(conversation: Conversation, options?: SerializeOptions): ConversationJSON;
17
+ export declare function migrateConversation(json: unknown): Conversation;
40
18
  /**
41
19
  * Reconstructs a conversation from a JSON object.
42
20
  * Automatically migrates data from older schema versions.
@@ -1 +1 @@
1
- {"version":3,"file":"serialization.d.ts","sourceRoot":"","sources":["../../src/conversation/serialization.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,YAAY,EACZ,gBAAgB,EAGhB,gBAAgB,EACjB,MAAM,UAAU,CAAC;AAUlB;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,OAAO,GAAG,gBAAgB,CA2BvE;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,qBAAqB,CACnC,YAAY,EAAE,YAAY,EAC1B,OAAO,GAAE,gBAAqB,GAC7B,gBAAgB,CAqElB;AAED;;;;;;;;;GASG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,OAAO,GAAG,YAAY,CA8CnE"}
1
+ {"version":3,"file":"serialization.d.ts","sourceRoot":"","sources":["../../src/conversation/serialization.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAW,MAAM,UAAU,CAAC;AAMtD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,OAAO,GAAG,YAAY,CAgE/D;AAED;;;;;;;;;GASG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,OAAO,GAAG,YAAY,CAsDnE"}
@@ -1,5 +1,5 @@
1
1
  import { type ConversationEnvironment } from '../environment';
2
- import type { Conversation, Message } from '../types';
2
+ import type { Conversation, JSONValue, Message } from '../types';
3
3
  /**
4
4
  * Checks if a conversation contains any system messages.
5
5
  */
@@ -17,12 +17,12 @@ export declare function getSystemMessages(conversation: Conversation): ReadonlyA
17
17
  * Inserts a system message at the beginning of the conversation.
18
18
  * Renumbers all existing message positions.
19
19
  */
20
- export declare function prependSystemMessage(conversation: Conversation, content: string, metadata?: Record<string, unknown>, environment?: Partial<ConversationEnvironment>): Conversation;
20
+ export declare function prependSystemMessage(conversation: Conversation, content: string, metadata?: Record<string, JSONValue>, environment?: Partial<ConversationEnvironment>): Conversation;
21
21
  /**
22
22
  * Replaces the first system message with new content.
23
23
  * If no system message exists, prepends a new one.
24
24
  */
25
- export declare function replaceSystemMessage(conversation: Conversation, content: string, metadata?: Record<string, unknown>, environment?: Partial<ConversationEnvironment>): Conversation;
25
+ export declare function replaceSystemMessage(conversation: Conversation, content: string, metadata?: Record<string, JSONValue>, environment?: Partial<ConversationEnvironment>): Conversation;
26
26
  /**
27
27
  * Merges all system messages into a single message at the first position.
28
28
  * Duplicate content is removed. Returns unchanged if 0 or 1 system messages.
@@ -1 +1 @@
1
- {"version":3,"file":"system-messages.d.ts","sourceRoot":"","sources":["../../src/conversation/system-messages.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,uBAAuB,EAE7B,MAAM,gBAAgB,CAAC;AAExB,OAAO,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAGtD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,YAAY,EAAE,YAAY,GAAG,OAAO,CAEpE;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,YAAY,EAAE,YAAY,GAAG,OAAO,GAAG,SAAS,CAErF;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,YAAY,EAAE,YAAY,GAAG,aAAa,CAAC,OAAO,CAAC,CAEpF;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,YAAY,EAAE,YAAY,EAC1B,OAAO,EAAE,MAAM,EACf,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAClC,WAAW,CAAC,EAAE,OAAO,CAAC,uBAAuB,CAAC,GAC7C,YAAY,CAqCd;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,YAAY,EAAE,YAAY,EAC1B,OAAO,EAAE,MAAM,EACf,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAClC,WAAW,CAAC,EAAE,OAAO,CAAC,uBAAuB,CAAC,GAC7C,YAAY,CA6Bd;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CACpC,YAAY,EAAE,YAAY,EAC1B,WAAW,CAAC,EAAE,OAAO,CAAC,uBAAuB,CAAC,GAC7C,YAAY,CA+Ed"}
1
+ {"version":3,"file":"system-messages.d.ts","sourceRoot":"","sources":["../../src/conversation/system-messages.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,uBAAuB,EAE7B,MAAM,gBAAgB,CAAC;AAExB,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAIjE;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,YAAY,EAAE,YAAY,GAAG,OAAO,CAEpE;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,YAAY,EAAE,YAAY,GAAG,OAAO,GAAG,SAAS,CAErF;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,YAAY,EAAE,YAAY,GAAG,aAAa,CAAC,OAAO,CAAC,CAEpF;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,YAAY,EAAE,YAAY,EAC1B,OAAO,EAAE,MAAM,EACf,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,EACpC,WAAW,CAAC,EAAE,OAAO,CAAC,uBAAuB,CAAC,GAC7C,YAAY,CAuCd;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,YAAY,EAAE,YAAY,EAC1B,OAAO,EAAE,MAAM,EACf,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,EACpC,WAAW,CAAC,EAAE,OAAO,CAAC,uBAAuB,CAAC,GAC7C,YAAY,CA+Bd;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CACpC,YAAY,EAAE,YAAY,EAC1B,WAAW,CAAC,EAAE,OAAO,CAAC,uBAAuB,CAAC,GAC7C,YAAY,CAiFd"}
@@ -1 +1 @@
1
- {"version":3,"file":"transform.d.ts","sourceRoot":"","sources":["../../src/conversation/transform.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,OAAO,IAAI,eAAe,EAE3B,MAAM,uBAAuB,CAAC;AAE/B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAE7C;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,YAAY,EAAE,YAAY,GAAG,eAAe,EAAE,CAqB5E"}
1
+ {"version":3,"file":"transform.d.ts","sourceRoot":"","sources":["../../src/conversation/transform.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,OAAO,IAAI,eAAe,EAE3B,MAAM,uBAAuB,CAAC;AAE/B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAG7C;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,YAAY,EAAE,YAAY,GAAG,eAAe,EAAE,CAqB5E"}