@agentscope-ai/agentscope 0.0.2 → 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +202 -0
- package/dist/agent/index.d.mts +10 -10
- package/dist/agent/index.d.ts +10 -10
- package/dist/agent/index.js +104 -93
- package/dist/agent/index.js.map +1 -1
- package/dist/agent/index.mjs +104 -93
- package/dist/agent/index.mjs.map +1 -1
- package/dist/{base-BOx3UzOl.d.mts → base-1YVBgB4n.d.mts} +2 -2
- package/dist/{base-DYlBMCy_.d.mts → base-B_MQMHWr.d.mts} +3 -3
- package/dist/{base-Cwi4bjze.d.ts → base-BherSLRs.d.ts} +3 -3
- package/dist/{base-NX-knWOv.d.ts → base-CY4DMBH1.d.ts} +1 -1
- package/dist/{base-BoIps2RL.d.ts → base-ChWjyzPL.d.ts} +2 -2
- package/dist/{base-C7jwyH4Z.d.mts → base-ClilytRZ.d.mts} +1 -1
- package/dist/{block-VsnHrllL.d.mts → block-B72uPF1H.d.mts} +7 -5
- package/dist/{block-VsnHrllL.d.ts → block-B72uPF1H.d.ts} +7 -5
- package/dist/event/index.d.mts +105 -89
- package/dist/event/index.d.ts +105 -89
- package/dist/event/index.js +8 -8
- package/dist/event/index.js.map +1 -1
- package/dist/event/index.mjs +8 -8
- package/dist/event/index.mjs.map +1 -1
- package/dist/formatter/index.d.mts +4 -3
- package/dist/formatter/index.d.ts +4 -3
- package/dist/formatter/index.js +17 -17
- package/dist/formatter/index.js.map +1 -1
- package/dist/formatter/index.mjs +17 -17
- package/dist/formatter/index.mjs.map +1 -1
- package/dist/{index-BcatlwXQ.d.ts → index-BNfyKbQN.d.ts} +1 -1
- package/dist/{index-BTJDlKvQ.d.mts → index-UQCwdfet.d.mts} +1 -1
- package/dist/mcp/index.d.mts +2 -2
- package/dist/mcp/index.d.ts +2 -2
- package/dist/mcp/index.js +1 -1
- package/dist/mcp/index.js.map +1 -1
- package/dist/mcp/index.mjs +1 -1
- package/dist/mcp/index.mjs.map +1 -1
- package/dist/message/index.d.mts +3 -2
- package/dist/message/index.d.ts +3 -2
- package/dist/message/index.js +204 -5
- package/dist/message/index.js.map +1 -1
- package/dist/message/index.mjs +200 -5
- package/dist/message/index.mjs.map +1 -1
- package/dist/message-CPZd0NIc.d.ts +133 -0
- package/dist/message-DgpfAaHK.d.mts +133 -0
- package/dist/model/index.d.mts +6 -5
- package/dist/model/index.d.ts +6 -5
- package/dist/model/index.js +39 -28
- package/dist/model/index.js.map +1 -1
- package/dist/model/index.mjs +39 -28
- package/dist/model/index.mjs.map +1 -1
- package/dist/storage/index.d.mts +4 -3
- package/dist/storage/index.d.ts +4 -3
- package/dist/storage/index.js +4 -4
- package/dist/storage/index.js.map +1 -1
- package/dist/storage/index.mjs +4 -4
- package/dist/storage/index.mjs.map +1 -1
- package/dist/tool/index.d.mts +4 -4
- package/dist/tool/index.d.ts +4 -4
- package/dist/{toolkit-CEpulFi0.d.ts → toolkit-DeOlul5Y.d.ts} +2 -2
- package/dist/{toolkit-CGEZSZPa.d.mts → toolkit-jwe7NmVJ.d.mts} +2 -2
- package/package.json +87 -87
- package/src/agent/agent.test.ts +104 -71
- package/src/agent/agent.ts +112 -104
- package/src/agent/test-compression.ts +1 -1
- package/src/event/index.ts +96 -98
- package/src/formatter/base.ts +3 -3
- package/src/formatter/dashscope-chat-formatter.test.ts +11 -8
- package/src/formatter/dashscope-chat-formatter.ts +3 -3
- package/src/formatter/openai-chat-formatter.test.ts +13 -5
- package/src/formatter/openai-chat-formatter.ts +6 -6
- package/src/mcp/base.ts +1 -1
- package/src/mcp/http.test.ts +2 -0
- package/src/mcp/stdio.test.ts +1 -0
- package/src/message/append-event.test.ts +783 -0
- package/src/message/block.ts +8 -4
- package/src/message/index.ts +12 -1
- package/src/message/message.test.ts +3 -1
- package/src/message/message.ts +310 -47
- package/src/model/dashscope-model.test.ts +4 -0
- package/src/model/dashscope-model.ts +3 -0
- package/src/model/deepseek-model.test.ts +2 -0
- package/src/model/deepseek-model.ts +3 -0
- package/src/model/ollama-model.test.ts +1 -0
- package/src/model/ollama-model.ts +2 -0
- package/src/model/openai-model.ts +3 -0
- package/src/permission/index.ts +13 -0
- package/src/storage/file-system.test.ts +4 -3
- package/src/storage/file-system.ts +4 -4
- package/src/tool/toolkit.test.ts +12 -0
- package/dist/message-CkN21KaY.d.mts +0 -99
- package/dist/message-CzLeTlua.d.ts +0 -99
package/dist/message/index.js
CHANGED
|
@@ -20,7 +20,11 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/message/index.ts
|
|
21
21
|
var message_exports = {};
|
|
22
22
|
__export(message_exports, {
|
|
23
|
+
AssistantMsg: () => AssistantMsg,
|
|
23
24
|
GenerateReason: () => GenerateReason,
|
|
25
|
+
SystemMsg: () => SystemMsg,
|
|
26
|
+
UserMsg: () => UserMsg,
|
|
27
|
+
appendEvent: () => appendEvent,
|
|
24
28
|
createMsg: () => createMsg,
|
|
25
29
|
getContentBlocks: () => getContentBlocks,
|
|
26
30
|
getTextContent: () => getTextContent
|
|
@@ -34,22 +38,213 @@ function createMsg({
|
|
|
34
38
|
role,
|
|
35
39
|
metadata = {},
|
|
36
40
|
id = crypto.randomUUID(),
|
|
37
|
-
|
|
41
|
+
created_at = (/* @__PURE__ */ new Date()).toISOString(),
|
|
42
|
+
finished_at,
|
|
38
43
|
usage
|
|
39
44
|
}) {
|
|
40
|
-
|
|
45
|
+
const contentBlocks = typeof content === "string" ? [{ id: crypto.randomUUID(), type: "text", text: content }] : content;
|
|
46
|
+
return { id, name, role, content: contentBlocks, metadata, created_at, finished_at, usage };
|
|
47
|
+
}
|
|
48
|
+
function UserMsg({
|
|
49
|
+
name,
|
|
50
|
+
content,
|
|
51
|
+
metadata = {},
|
|
52
|
+
id = crypto.randomUUID(),
|
|
53
|
+
created_at = (/* @__PURE__ */ new Date()).toISOString()
|
|
54
|
+
}) {
|
|
55
|
+
return createMsg({ name, content, role: "user", metadata, id, created_at });
|
|
56
|
+
}
|
|
57
|
+
function AssistantMsg({
|
|
58
|
+
name,
|
|
59
|
+
content,
|
|
60
|
+
metadata = {},
|
|
61
|
+
id = crypto.randomUUID(),
|
|
62
|
+
created_at = (/* @__PURE__ */ new Date()).toISOString(),
|
|
63
|
+
usage
|
|
64
|
+
}) {
|
|
65
|
+
return createMsg({ name, content, role: "assistant", metadata, id, created_at, usage });
|
|
66
|
+
}
|
|
67
|
+
function SystemMsg({
|
|
68
|
+
name,
|
|
69
|
+
content,
|
|
70
|
+
metadata = {},
|
|
71
|
+
id = crypto.randomUUID(),
|
|
72
|
+
created_at = (/* @__PURE__ */ new Date()).toISOString()
|
|
73
|
+
}) {
|
|
74
|
+
return createMsg({ name, content, role: "system", metadata, id, created_at });
|
|
41
75
|
}
|
|
42
76
|
function getTextContent(msg, separator = "\n") {
|
|
43
77
|
const textBlocks = msg.content.filter((block) => block.type === "text");
|
|
44
|
-
if (textBlocks.length === 0)
|
|
45
|
-
return null;
|
|
46
|
-
}
|
|
78
|
+
if (textBlocks.length === 0) return null;
|
|
47
79
|
return textBlocks.map((block) => block.text).join(separator);
|
|
48
80
|
}
|
|
49
81
|
function getContentBlocks(msg, blockType) {
|
|
50
82
|
if (!blockType) return msg.content;
|
|
51
83
|
return msg.content.filter((block) => block.type === blockType);
|
|
52
84
|
}
|
|
85
|
+
function findBlock(msg, blockType, blockId) {
|
|
86
|
+
return msg.content.find((block) => block.type === blockType && block.id === blockId);
|
|
87
|
+
}
|
|
88
|
+
function appendEvent(msg, event) {
|
|
89
|
+
if (!("reply_id" in event)) return msg;
|
|
90
|
+
if (event.reply_id !== msg.id) {
|
|
91
|
+
console.warn(
|
|
92
|
+
`Event reply_id "${event.reply_id}" does not match message id "${msg.id}", skipping.`
|
|
93
|
+
);
|
|
94
|
+
return msg;
|
|
95
|
+
}
|
|
96
|
+
switch (event.type) {
|
|
97
|
+
case "REPLY_END" /* REPLY_END */:
|
|
98
|
+
msg.finished_at = event.created_at;
|
|
99
|
+
break;
|
|
100
|
+
case "TEXT_BLOCK_START" /* TEXT_BLOCK_START */:
|
|
101
|
+
msg.content.push({ type: "text", id: event.block_id, text: "" });
|
|
102
|
+
break;
|
|
103
|
+
case "TEXT_BLOCK_DELTA" /* TEXT_BLOCK_DELTA */: {
|
|
104
|
+
const block = findBlock(msg, "text", event.block_id);
|
|
105
|
+
if (!block) {
|
|
106
|
+
console.warn(`TextBlock "${event.block_id}" not found, skipping.`);
|
|
107
|
+
} else {
|
|
108
|
+
block.text += event.delta;
|
|
109
|
+
}
|
|
110
|
+
break;
|
|
111
|
+
}
|
|
112
|
+
case "TEXT_BLOCK_END" /* TEXT_BLOCK_END */:
|
|
113
|
+
break;
|
|
114
|
+
case "THINKING_BLOCK_START" /* THINKING_BLOCK_START */:
|
|
115
|
+
msg.content.push({ type: "thinking", id: event.block_id, thinking: "" });
|
|
116
|
+
break;
|
|
117
|
+
case "THINKING_BLOCK_DELTA" /* THINKING_BLOCK_DELTA */: {
|
|
118
|
+
const block = findBlock(msg, "thinking", event.block_id);
|
|
119
|
+
if (!block) {
|
|
120
|
+
console.warn(`ThinkingBlock "${event.block_id}" not found, skipping.`);
|
|
121
|
+
} else {
|
|
122
|
+
block.thinking += event.delta;
|
|
123
|
+
}
|
|
124
|
+
break;
|
|
125
|
+
}
|
|
126
|
+
case "THINKING_BLOCK_END" /* THINKING_BLOCK_END */:
|
|
127
|
+
break;
|
|
128
|
+
case "DATA_BLOCK_START" /* DATA_BLOCK_START */:
|
|
129
|
+
msg.content.push({
|
|
130
|
+
type: "data",
|
|
131
|
+
id: event.block_id,
|
|
132
|
+
source: { type: "base64", data: "", media_type: event.media_type }
|
|
133
|
+
});
|
|
134
|
+
break;
|
|
135
|
+
case "DATA_BLOCK_DELTA" /* DATA_BLOCK_DELTA */: {
|
|
136
|
+
const block = findBlock(msg, "data", event.block_id);
|
|
137
|
+
if (!block) {
|
|
138
|
+
console.warn(`DataBlock "${event.block_id}" not found, skipping.`);
|
|
139
|
+
} else {
|
|
140
|
+
block.source.data += event.data;
|
|
141
|
+
}
|
|
142
|
+
break;
|
|
143
|
+
}
|
|
144
|
+
case "DATA_BLOCK_END" /* DATA_BLOCK_END */:
|
|
145
|
+
break;
|
|
146
|
+
case "TOOL_CALL_START" /* TOOL_CALL_START */:
|
|
147
|
+
msg.content.push({
|
|
148
|
+
type: "tool_call",
|
|
149
|
+
id: event.tool_call_id,
|
|
150
|
+
name: event.tool_call_name,
|
|
151
|
+
input: "",
|
|
152
|
+
state: "pending"
|
|
153
|
+
});
|
|
154
|
+
break;
|
|
155
|
+
case "TOOL_CALL_DELTA" /* TOOL_CALL_DELTA */: {
|
|
156
|
+
const block = findBlock(msg, "tool_call", event.tool_call_id);
|
|
157
|
+
if (!block) {
|
|
158
|
+
console.warn(`ToolCallBlock "${event.tool_call_id}" not found, skipping.`);
|
|
159
|
+
} else {
|
|
160
|
+
block.input += event.delta;
|
|
161
|
+
}
|
|
162
|
+
break;
|
|
163
|
+
}
|
|
164
|
+
case "TOOL_CALL_END" /* TOOL_CALL_END */:
|
|
165
|
+
break;
|
|
166
|
+
case "TOOL_RESULT_START" /* TOOL_RESULT_START */:
|
|
167
|
+
msg.content.push({
|
|
168
|
+
type: "tool_result",
|
|
169
|
+
id: event.tool_call_id,
|
|
170
|
+
name: event.tool_call_name,
|
|
171
|
+
output: [],
|
|
172
|
+
state: "running"
|
|
173
|
+
});
|
|
174
|
+
break;
|
|
175
|
+
case "TOOL_RESULT_TEXT_DELTA" /* TOOL_RESULT_TEXT_DELTA */: {
|
|
176
|
+
const block = findBlock(msg, "tool_result", event.tool_call_id);
|
|
177
|
+
if (!block) {
|
|
178
|
+
console.warn(`ToolResultBlock "${event.tool_call_id}" not found, skipping.`);
|
|
179
|
+
} else {
|
|
180
|
+
const trb = block;
|
|
181
|
+
if (typeof trb.output === "string") {
|
|
182
|
+
trb.output = [{ type: "text", id: crypto.randomUUID(), text: trb.output }];
|
|
183
|
+
}
|
|
184
|
+
const last = trb.output[trb.output.length - 1];
|
|
185
|
+
if (!last || last.type !== "text") {
|
|
186
|
+
trb.output.push({
|
|
187
|
+
type: "text",
|
|
188
|
+
id: event.block_id ?? crypto.randomUUID(),
|
|
189
|
+
text: event.delta
|
|
190
|
+
});
|
|
191
|
+
} else {
|
|
192
|
+
last.text += event.delta;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
break;
|
|
196
|
+
}
|
|
197
|
+
case "TOOL_RESULT_DATA_DELTA" /* TOOL_RESULT_DATA_DELTA */: {
|
|
198
|
+
const block = findBlock(msg, "tool_result", event.tool_call_id);
|
|
199
|
+
if (!block) {
|
|
200
|
+
console.warn(`ToolResultBlock "${event.tool_call_id}" not found, skipping.`);
|
|
201
|
+
} else {
|
|
202
|
+
const trb = block;
|
|
203
|
+
if (typeof trb.output === "string") {
|
|
204
|
+
trb.output = [{ type: "text", id: crypto.randomUUID(), text: trb.output }];
|
|
205
|
+
}
|
|
206
|
+
const source = event.data != null ? { type: "base64", data: event.data, media_type: event.media_type } : { type: "url", url: event.url, media_type: event.media_type };
|
|
207
|
+
trb.output.push({ type: "data", id: event.block_id, source });
|
|
208
|
+
}
|
|
209
|
+
break;
|
|
210
|
+
}
|
|
211
|
+
case "TOOL_RESULT_END" /* TOOL_RESULT_END */: {
|
|
212
|
+
const block = findBlock(msg, "tool_result", event.tool_call_id);
|
|
213
|
+
if (!block) {
|
|
214
|
+
console.warn(`ToolResultBlock "${event.tool_call_id}" not found, skipping.`);
|
|
215
|
+
} else {
|
|
216
|
+
block.state = event.state;
|
|
217
|
+
}
|
|
218
|
+
break;
|
|
219
|
+
}
|
|
220
|
+
case "REQUIRE_USER_CONFIRM" /* REQUIRE_USER_CONFIRM */:
|
|
221
|
+
for (const tc of event.tool_calls) {
|
|
222
|
+
const b = findBlock(msg, "tool_call", tc.id);
|
|
223
|
+
if (b) b.state = "asking";
|
|
224
|
+
}
|
|
225
|
+
break;
|
|
226
|
+
case "USER_CONFIRM_RESULT" /* USER_CONFIRM_RESULT */:
|
|
227
|
+
for (const result of event.confirm_results) {
|
|
228
|
+
const b = findBlock(msg, "tool_call", result.tool_call.id);
|
|
229
|
+
if (b) {
|
|
230
|
+
b.state = result.confirmed ? "allowed" : "finished";
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
break;
|
|
234
|
+
case "REQUIRE_EXTERNAL_EXECUTION" /* REQUIRE_EXTERNAL_EXECUTION */:
|
|
235
|
+
for (const tc of event.tool_calls) {
|
|
236
|
+
const b = findBlock(msg, "tool_call", tc.id);
|
|
237
|
+
if (b) b.state = "submitted";
|
|
238
|
+
}
|
|
239
|
+
break;
|
|
240
|
+
case "EXTERNAL_EXECUTION_RESULT" /* EXTERNAL_EXECUTION_RESULT */:
|
|
241
|
+
for (const result of event.execution_results) {
|
|
242
|
+
msg.content.push(result);
|
|
243
|
+
}
|
|
244
|
+
break;
|
|
245
|
+
}
|
|
246
|
+
return msg;
|
|
247
|
+
}
|
|
53
248
|
|
|
54
249
|
// src/message/enums.ts
|
|
55
250
|
var GenerateReason = /* @__PURE__ */ ((GenerateReason2) => {
|
|
@@ -59,7 +254,11 @@ var GenerateReason = /* @__PURE__ */ ((GenerateReason2) => {
|
|
|
59
254
|
})(GenerateReason || {});
|
|
60
255
|
// Annotate the CommonJS export names for ESM import in node:
|
|
61
256
|
0 && (module.exports = {
|
|
257
|
+
AssistantMsg,
|
|
62
258
|
GenerateReason,
|
|
259
|
+
SystemMsg,
|
|
260
|
+
UserMsg,
|
|
261
|
+
appendEvent,
|
|
63
262
|
createMsg,
|
|
64
263
|
getContentBlocks,
|
|
65
264
|
getTextContent
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/message/index.ts","../../src/message/message.ts","../../src/message/enums.ts"],"sourcesContent":["export { Msg, createMsg, getTextContent, getContentBlocks } from './message';\nexport {\n TextBlock,\n ThinkingBlock,\n ToolCallBlock,\n ToolResultBlock,\n ContentBlock,\n Base64Source,\n URLSource,\n DataBlock,\n} from './block';\nexport { GenerateReason } from './enums';\n","import { JSONSerializableObject } from '../type';\nimport {\n ContentBlock,\n TextBlock,\n ThinkingBlock,\n ToolResultBlock,\n ToolCallBlock,\n DataBlock,\n} from './block';\n\n/** A chat message exchanged between agents or between an agent and a model. */\nexport interface Msg {\n /** Unique identifier for the message. */\n id: string;\n /** Display name of the message sender. */\n name: string;\n /** Conversation role of the sender. */\n role: 'user' | 'assistant' | 'system';\n /** Message body. */\n content: ContentBlock[];\n /** Arbitrary key-value metadata attached to the message. */\n metadata: Record<string, JSONSerializableObject>;\n /** ISO-8601 creation timestamp. */\n timestamp: string;\n /** Usage information for the message, such as token counts. */\n usage?: {\n inputTokens: number;\n outputTokens: number;\n };\n}\n\n/**\n * Create a new {@link Msg} object, filling in `id` and `timestamp` when omitted.\n *\n * @param root0\n * @param root0.name\n * @param root0.content\n * @param root0.role\n * @param root0.metadata\n * @param root0.id\n * @param root0.timestamp\n * @param root0.usage\n * @returns A fully-populated {@link Msg} object.\n */\nexport function createMsg({\n name,\n content,\n role,\n metadata = {},\n id = crypto.randomUUID(),\n timestamp = new Date().toISOString(),\n usage,\n}: Omit<Msg, 'id' | 'timestamp' | 'metadata'> &\n Partial<Pick<Msg, 'id' | 'timestamp' | 'metadata'>>): Msg {\n return { id, name, role, content, metadata, timestamp, usage } as Msg;\n}\n\n/**\n * Extract the plain-text content from a message.\n *\n * When `content` is a string it is returned as-is. When it is an array of\n * content blocks, all {@link TextBlock} texts are joined with `separator`.\n *\n * @param msg - The message to read.\n * @param separator - String inserted between consecutive text blocks. Defaults to `'\\n'`.\n * @returns The concatenated text, or `null` when no text blocks are present.\n */\nexport function getTextContent(msg: Msg, separator: string = '\\n'): string | null {\n const textBlocks = msg.content.filter(block => block.type === 'text');\n if (textBlocks.length === 0) {\n return null;\n }\n return textBlocks.map(block => (block as TextBlock).text).join(separator);\n}\n\n/**\n * Return all content blocks from a message, regardless of type.\n *\n * When `content` is a plain string it is wrapped in a single {@link TextBlock}.\n *\n * @param msg - The message to read.\n * @returns An array of all {@link ContentBlock} objects.\n */\nexport function getContentBlocks(msg: Msg): ContentBlock[];\n/**\n * Return all {@link TextBlock} objects from a message.\n *\n * @param msg - The message to read.\n * @param blockType - `'text'`\n * @returns An array of {@link TextBlock} objects.\n */\nexport function getContentBlocks(msg: Msg, blockType: 'text'): TextBlock[];\n/**\n * Return all {@link ThinkingBlock} objects from a message.\n *\n * @param msg - The message to read.\n * @param blockType - `'thinking'`\n * @returns An array of {@link ThinkingBlock} objects.\n */\nexport function getContentBlocks(msg: Msg, blockType: 'thinking'): ThinkingBlock[];\n/**\n * Return all {@link DataBlock} objects from a message.\n *\n * @param msg - The message to read.\n * @param blockType - `'video'`\n * @returns An array of {@link DataBlock} objects.\n */\nexport function getContentBlocks(msg: Msg, blockType: 'data'): DataBlock[];\n/**\n * Return all {@link ToolCallBlock} objects from a message.\n *\n * @param msg - The message to read.\n * @param blockType - `'tool_call'`\n * @returns An array of {@link ToolCallBlock} objects.\n */\nexport function getContentBlocks(msg: Msg, blockType: 'tool_call'): ToolCallBlock[];\n/**\n * Return all {@link ToolResultBlock} objects from a message.\n *\n * @param msg - The message to read.\n * @param blockType - `'tool_result'`\n * @returns An array of {@link ToolResultBlock} objects.\n */\nexport function getContentBlocks(msg: Msg, blockType: 'tool_result'): ToolResultBlock[];\nexport function getContentBlocks(\n msg: Msg,\n blockType?: 'text' | 'thinking' | 'data' | 'tool_call' | 'tool_result'\n): ContentBlock[] {\n if (!blockType) return msg.content;\n return msg.content.filter(block => block.type === blockType);\n}\n","export enum GenerateReason {\n AWAITING_TOOL_RESULT = 'AWAITING_TOOL_RESULT',\n AWAITING_USER_CONFIRMATION = 'AWAITING_USER_CONFIRMATION',\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;AC4CO,SAAS,UAAU;AAAA,EACtB;AAAA,EACA;AAAA,EACA;AAAA,EACA,WAAW,CAAC;AAAA,EACZ,KAAK,OAAO,WAAW;AAAA,EACvB,aAAY,oBAAI,KAAK,GAAE,YAAY;AAAA,EACnC;AACJ,GAC8D;AAC1D,SAAO,EAAE,IAAI,MAAM,MAAM,SAAS,UAAU,WAAW,MAAM;AACjE;AAYO,SAAS,eAAe,KAAU,YAAoB,MAAqB;AAC9E,QAAM,aAAa,IAAI,QAAQ,OAAO,WAAS,MAAM,SAAS,MAAM;AACpE,MAAI,WAAW,WAAW,GAAG;AACzB,WAAO;AAAA,EACX;AACA,SAAO,WAAW,IAAI,WAAU,MAAoB,IAAI,EAAE,KAAK,SAAS;AAC5E;AAmDO,SAAS,iBACZ,KACA,WACc;AACd,MAAI,CAAC,UAAW,QAAO,IAAI;AAC3B,SAAO,IAAI,QAAQ,OAAO,WAAS,MAAM,SAAS,SAAS;AAC/D;;;AClIO,IAAK,iBAAL,kBAAKA,oBAAL;AACH,EAAAA,gBAAA,0BAAuB;AACvB,EAAAA,gBAAA,gCAA6B;AAFrB,SAAAA;AAAA,GAAA;","names":["GenerateReason"]}
|
|
1
|
+
{"version":3,"sources":["../../src/message/index.ts","../../src/message/message.ts","../../src/message/enums.ts"],"sourcesContent":["export {\n Msg,\n createMsg,\n UserMsg,\n AssistantMsg,\n SystemMsg,\n getTextContent,\n getContentBlocks,\n appendEvent,\n} from './message';\nexport {\n TextBlock,\n ThinkingBlock,\n ToolCallBlock,\n ToolCallState,\n ToolResultBlock,\n ToolResultState,\n ContentBlock,\n Base64Source,\n URLSource,\n DataBlock,\n} from './block';\nexport { GenerateReason } from './enums';\n","import { JSONSerializableObject } from '../type';\nimport {\n ContentBlock,\n TextBlock,\n ThinkingBlock,\n ToolResultBlock,\n ToolCallBlock,\n DataBlock,\n Base64Source,\n URLSource,\n} from './block';\nimport { AgentEvent, EventType } from '../event';\n\n/** A chat message exchanged between agents or between an agent and a model. */\nexport interface Msg {\n /** Unique identifier for the message. */\n id: string;\n /** Display name of the message sender. */\n name: string;\n /** Conversation role of the sender. */\n role: 'user' | 'assistant' | 'system';\n /** Message body. */\n content: ContentBlock[];\n /** Arbitrary key-value metadata attached to the message. */\n metadata: Record<string, JSONSerializableObject>;\n /** ISO-8601 creation timestamp. */\n created_at: string;\n /** ISO-8601 finished timestamp. */\n finished_at?: string | null;\n /** Usage information for the message, such as token counts. */\n usage?: {\n inputTokens: number;\n outputTokens: number;\n };\n}\n\n/**\n * Create a new {@link Msg} object, filling in `id` and `created_at` when omitted.\n * A plain string `content` is automatically wrapped in a single {@link TextBlock}.\n * @param root0\n * @param root0.name\n * @param root0.content\n * @param root0.role\n * @param root0.metadata\n * @param root0.id\n * @param root0.created_at\n * @param root0.finished_at\n * @param root0.usage\n * @returns A Msg object.\n */\nexport function createMsg({\n name,\n content,\n role,\n metadata = {},\n id = crypto.randomUUID(),\n created_at = new Date().toISOString(),\n finished_at,\n usage,\n}: Omit<Msg, 'id' | 'created_at' | 'metadata' | 'content'> &\n Partial<Pick<Msg, 'id' | 'created_at' | 'metadata'>> & {\n content: string | ContentBlock[];\n }): Msg {\n const contentBlocks: ContentBlock[] =\n typeof content === 'string'\n ? [{ id: crypto.randomUUID(), type: 'text', text: content } as TextBlock]\n : content;\n return { id, name, role, content: contentBlocks, metadata, created_at, finished_at, usage };\n}\n\n/**\n * Create a user {@link Msg}.\n * @param root0\n * @param root0.name\n * @param root0.content\n * @param root0.metadata\n * @param root0.id\n * @param root0.created_at\n * @returns A Msg object with role 'user'.\n */\nexport function UserMsg({\n name,\n content,\n metadata = {},\n id = crypto.randomUUID(),\n created_at = new Date().toISOString(),\n}: {\n name: string;\n content: string | ContentBlock[];\n metadata?: Record<string, JSONSerializableObject>;\n id?: string;\n created_at?: string;\n}): Msg {\n return createMsg({ name, content, role: 'user', metadata, id, created_at });\n}\n\n/**\n * Create an assistant {@link Msg}.\n * @param root0\n * @param root0.name\n * @param root0.content\n * @param root0.metadata\n * @param root0.id\n * @param root0.created_at\n * @param root0.usage\n * @returns A Msg object with role 'assistant'.\n */\nexport function AssistantMsg({\n name,\n content,\n metadata = {},\n id = crypto.randomUUID(),\n created_at = new Date().toISOString(),\n usage,\n}: {\n name: string;\n content: string | ContentBlock[];\n metadata?: Record<string, JSONSerializableObject>;\n id?: string;\n created_at?: string;\n usage?: Msg['usage'];\n}): Msg {\n return createMsg({ name, content, role: 'assistant', metadata, id, created_at, usage });\n}\n\n/**\n * Create a system {@link Msg}.\n * @param root0\n * @param root0.name\n * @param root0.content\n * @param root0.metadata\n * @param root0.id\n * @param root0.created_at\n * @returns A Msg object with role 'system'.\n */\nexport function SystemMsg({\n name,\n content,\n metadata = {},\n id = crypto.randomUUID(),\n created_at = new Date().toISOString(),\n}: {\n name: string;\n content: string | ContentBlock[];\n metadata?: Record<string, JSONSerializableObject>;\n id?: string;\n created_at?: string;\n}): Msg {\n return createMsg({ name, content, role: 'system', metadata, id, created_at });\n}\n\n/**\n * Extract the plain-text content from a message.\n *\n * When `content` is a string it is returned as-is. When it is an array of\n * content blocks, all {@link TextBlock} texts are joined with `separator`.\n *\n * @param msg - The message to read.\n * @param separator - String inserted between consecutive text blocks. Defaults to `'\\n'`.\n * @returns The concatenated text, or `null` when no text blocks are present.\n */\nexport function getTextContent(msg: Msg, separator: string = '\\n'): string | null {\n const textBlocks = msg.content.filter(block => block.type === 'text');\n if (textBlocks.length === 0) return null;\n return textBlocks.map(block => (block as TextBlock).text).join(separator);\n}\n\n/**\n * Return all content blocks from a message, regardless of type.\n *\n * When `content` is a plain string it is wrapped in a single {@link TextBlock}.\n *\n * @param msg - The message to read.\n * @returns An array of all {@link ContentBlock} objects.\n */\nexport function getContentBlocks(msg: Msg): ContentBlock[];\nexport function getContentBlocks(msg: Msg, blockType: 'text'): TextBlock[];\nexport function getContentBlocks(msg: Msg, blockType: 'thinking'): ThinkingBlock[];\nexport function getContentBlocks(msg: Msg, blockType: 'data'): DataBlock[];\nexport function getContentBlocks(msg: Msg, blockType: 'tool_call'): ToolCallBlock[];\nexport function getContentBlocks(msg: Msg, blockType: 'tool_result'): ToolResultBlock[];\nexport function getContentBlocks(\n msg: Msg,\n blockType?: 'text' | 'thinking' | 'data' | 'tool_call' | 'tool_result'\n): ContentBlock[] {\n if (!blockType) return msg.content;\n return msg.content.filter(block => block.type === blockType);\n}\n\n/**\n * Find a content block by type and id within a message.\n * @param msg\n * @param blockType\n * @param blockId\n * @returns The matching {@link ContentBlock}, or `undefined` if not found.\n */\nfunction findBlock(msg: Msg, blockType: string, blockId: string): ContentBlock | undefined {\n return msg.content.find(block => block.type === blockType && block.id === blockId);\n}\n\n/**\n * Apply a streaming {@link AgentEvent} to a {@link Msg}, mutating it in place.\n *\n * Only `content` and `finished_at` are ever modified. Events whose\n * `reply_id` does not match `msg.id` are skipped with a warning.\n * @param msg\n * @param event\n * @returns The mutated {@link Msg} object.\n */\nexport function appendEvent(msg: Msg, event: AgentEvent): Msg {\n if (!('reply_id' in event)) return msg;\n if (event.reply_id !== msg.id) {\n console.warn(\n `Event reply_id \"${event.reply_id}\" does not match message id \"${msg.id}\", skipping.`\n );\n return msg;\n }\n\n switch (event.type) {\n case EventType.REPLY_END:\n msg.finished_at = event.created_at;\n break;\n\n case EventType.TEXT_BLOCK_START:\n msg.content.push({ type: 'text', id: event.block_id, text: '' });\n break;\n\n case EventType.TEXT_BLOCK_DELTA: {\n const block = findBlock(msg, 'text', event.block_id);\n if (!block) {\n console.warn(`TextBlock \"${event.block_id}\" not found, skipping.`);\n } else {\n (block as TextBlock).text += event.delta;\n }\n break;\n }\n\n case EventType.TEXT_BLOCK_END:\n break;\n\n case EventType.THINKING_BLOCK_START:\n msg.content.push({ type: 'thinking', id: event.block_id, thinking: '' });\n break;\n\n case EventType.THINKING_BLOCK_DELTA: {\n const block = findBlock(msg, 'thinking', event.block_id);\n if (!block) {\n console.warn(`ThinkingBlock \"${event.block_id}\" not found, skipping.`);\n } else {\n (block as ThinkingBlock).thinking += event.delta;\n }\n break;\n }\n\n case EventType.THINKING_BLOCK_END:\n break;\n\n case EventType.DATA_BLOCK_START:\n msg.content.push({\n type: 'data',\n id: event.block_id,\n source: { type: 'base64', data: '', media_type: event.media_type },\n });\n break;\n\n case EventType.DATA_BLOCK_DELTA: {\n const block = findBlock(msg, 'data', event.block_id);\n if (!block) {\n console.warn(`DataBlock \"${event.block_id}\" not found, skipping.`);\n } else {\n ((block as DataBlock).source as Base64Source).data += event.data;\n }\n break;\n }\n\n case EventType.DATA_BLOCK_END:\n break;\n\n case EventType.TOOL_CALL_START:\n msg.content.push({\n type: 'tool_call',\n id: event.tool_call_id,\n name: event.tool_call_name,\n input: '',\n state: 'pending',\n });\n break;\n\n case EventType.TOOL_CALL_DELTA: {\n const block = findBlock(msg, 'tool_call', event.tool_call_id);\n if (!block) {\n console.warn(`ToolCallBlock \"${event.tool_call_id}\" not found, skipping.`);\n } else {\n (block as ToolCallBlock).input += event.delta;\n }\n break;\n }\n\n case EventType.TOOL_CALL_END:\n break;\n\n case EventType.TOOL_RESULT_START:\n msg.content.push({\n type: 'tool_result',\n id: event.tool_call_id,\n name: event.tool_call_name,\n output: [],\n state: 'running',\n });\n break;\n\n case EventType.TOOL_RESULT_TEXT_DELTA: {\n const block = findBlock(msg, 'tool_result', event.tool_call_id);\n if (!block) {\n console.warn(`ToolResultBlock \"${event.tool_call_id}\" not found, skipping.`);\n } else {\n const trb = block as ToolResultBlock;\n if (typeof trb.output === 'string') {\n trb.output = [{ type: 'text', id: crypto.randomUUID(), text: trb.output }];\n }\n const last = trb.output[trb.output.length - 1];\n if (!last || last.type !== 'text') {\n trb.output.push({\n type: 'text',\n id: event.block_id ?? crypto.randomUUID(),\n text: event.delta,\n });\n } else {\n (last as TextBlock).text += event.delta;\n }\n }\n break;\n }\n\n case EventType.TOOL_RESULT_DATA_DELTA: {\n const block = findBlock(msg, 'tool_result', event.tool_call_id);\n if (!block) {\n console.warn(`ToolResultBlock \"${event.tool_call_id}\" not found, skipping.`);\n } else {\n const trb = block as ToolResultBlock;\n if (typeof trb.output === 'string') {\n trb.output = [{ type: 'text', id: crypto.randomUUID(), text: trb.output }];\n }\n const source: Base64Source | URLSource =\n event.data != null\n ? { type: 'base64', data: event.data, media_type: event.media_type }\n : { type: 'url', url: event.url!, media_type: event.media_type };\n trb.output.push({ type: 'data', id: event.block_id, source });\n }\n break;\n }\n\n case EventType.TOOL_RESULT_END: {\n const block = findBlock(msg, 'tool_result', event.tool_call_id);\n if (!block) {\n console.warn(`ToolResultBlock \"${event.tool_call_id}\" not found, skipping.`);\n } else {\n (block as ToolResultBlock).state = event.state;\n }\n break;\n }\n\n case EventType.REQUIRE_USER_CONFIRM:\n for (const tc of event.tool_calls) {\n const b = findBlock(msg, 'tool_call', tc.id);\n if (b) (b as ToolCallBlock).state = 'asking';\n }\n break;\n\n case EventType.USER_CONFIRM_RESULT:\n for (const result of event.confirm_results) {\n const b = findBlock(msg, 'tool_call', result.tool_call.id);\n if (b) {\n (b as ToolCallBlock).state = result.confirmed ? 'allowed' : 'finished';\n }\n }\n break;\n\n case EventType.REQUIRE_EXTERNAL_EXECUTION:\n for (const tc of event.tool_calls) {\n const b = findBlock(msg, 'tool_call', tc.id);\n if (b) (b as ToolCallBlock).state = 'submitted';\n }\n break;\n\n case EventType.EXTERNAL_EXECUTION_RESULT:\n for (const result of event.execution_results) {\n msg.content.push(result);\n }\n break;\n }\n\n return msg;\n}\n","export enum GenerateReason {\n AWAITING_TOOL_RESULT = 'AWAITING_TOOL_RESULT',\n AWAITING_USER_CONFIRMATION = 'AWAITING_USER_CONFIRMATION',\n}\n"],"mappings":"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","names":["GenerateReason"]}
|
package/dist/message/index.mjs
CHANGED
|
@@ -5,22 +5,213 @@ function createMsg({
|
|
|
5
5
|
role,
|
|
6
6
|
metadata = {},
|
|
7
7
|
id = crypto.randomUUID(),
|
|
8
|
-
|
|
8
|
+
created_at = (/* @__PURE__ */ new Date()).toISOString(),
|
|
9
|
+
finished_at,
|
|
9
10
|
usage
|
|
10
11
|
}) {
|
|
11
|
-
|
|
12
|
+
const contentBlocks = typeof content === "string" ? [{ id: crypto.randomUUID(), type: "text", text: content }] : content;
|
|
13
|
+
return { id, name, role, content: contentBlocks, metadata, created_at, finished_at, usage };
|
|
14
|
+
}
|
|
15
|
+
function UserMsg({
|
|
16
|
+
name,
|
|
17
|
+
content,
|
|
18
|
+
metadata = {},
|
|
19
|
+
id = crypto.randomUUID(),
|
|
20
|
+
created_at = (/* @__PURE__ */ new Date()).toISOString()
|
|
21
|
+
}) {
|
|
22
|
+
return createMsg({ name, content, role: "user", metadata, id, created_at });
|
|
23
|
+
}
|
|
24
|
+
function AssistantMsg({
|
|
25
|
+
name,
|
|
26
|
+
content,
|
|
27
|
+
metadata = {},
|
|
28
|
+
id = crypto.randomUUID(),
|
|
29
|
+
created_at = (/* @__PURE__ */ new Date()).toISOString(),
|
|
30
|
+
usage
|
|
31
|
+
}) {
|
|
32
|
+
return createMsg({ name, content, role: "assistant", metadata, id, created_at, usage });
|
|
33
|
+
}
|
|
34
|
+
function SystemMsg({
|
|
35
|
+
name,
|
|
36
|
+
content,
|
|
37
|
+
metadata = {},
|
|
38
|
+
id = crypto.randomUUID(),
|
|
39
|
+
created_at = (/* @__PURE__ */ new Date()).toISOString()
|
|
40
|
+
}) {
|
|
41
|
+
return createMsg({ name, content, role: "system", metadata, id, created_at });
|
|
12
42
|
}
|
|
13
43
|
function getTextContent(msg, separator = "\n") {
|
|
14
44
|
const textBlocks = msg.content.filter((block) => block.type === "text");
|
|
15
|
-
if (textBlocks.length === 0)
|
|
16
|
-
return null;
|
|
17
|
-
}
|
|
45
|
+
if (textBlocks.length === 0) return null;
|
|
18
46
|
return textBlocks.map((block) => block.text).join(separator);
|
|
19
47
|
}
|
|
20
48
|
function getContentBlocks(msg, blockType) {
|
|
21
49
|
if (!blockType) return msg.content;
|
|
22
50
|
return msg.content.filter((block) => block.type === blockType);
|
|
23
51
|
}
|
|
52
|
+
function findBlock(msg, blockType, blockId) {
|
|
53
|
+
return msg.content.find((block) => block.type === blockType && block.id === blockId);
|
|
54
|
+
}
|
|
55
|
+
function appendEvent(msg, event) {
|
|
56
|
+
if (!("reply_id" in event)) return msg;
|
|
57
|
+
if (event.reply_id !== msg.id) {
|
|
58
|
+
console.warn(
|
|
59
|
+
`Event reply_id "${event.reply_id}" does not match message id "${msg.id}", skipping.`
|
|
60
|
+
);
|
|
61
|
+
return msg;
|
|
62
|
+
}
|
|
63
|
+
switch (event.type) {
|
|
64
|
+
case "REPLY_END" /* REPLY_END */:
|
|
65
|
+
msg.finished_at = event.created_at;
|
|
66
|
+
break;
|
|
67
|
+
case "TEXT_BLOCK_START" /* TEXT_BLOCK_START */:
|
|
68
|
+
msg.content.push({ type: "text", id: event.block_id, text: "" });
|
|
69
|
+
break;
|
|
70
|
+
case "TEXT_BLOCK_DELTA" /* TEXT_BLOCK_DELTA */: {
|
|
71
|
+
const block = findBlock(msg, "text", event.block_id);
|
|
72
|
+
if (!block) {
|
|
73
|
+
console.warn(`TextBlock "${event.block_id}" not found, skipping.`);
|
|
74
|
+
} else {
|
|
75
|
+
block.text += event.delta;
|
|
76
|
+
}
|
|
77
|
+
break;
|
|
78
|
+
}
|
|
79
|
+
case "TEXT_BLOCK_END" /* TEXT_BLOCK_END */:
|
|
80
|
+
break;
|
|
81
|
+
case "THINKING_BLOCK_START" /* THINKING_BLOCK_START */:
|
|
82
|
+
msg.content.push({ type: "thinking", id: event.block_id, thinking: "" });
|
|
83
|
+
break;
|
|
84
|
+
case "THINKING_BLOCK_DELTA" /* THINKING_BLOCK_DELTA */: {
|
|
85
|
+
const block = findBlock(msg, "thinking", event.block_id);
|
|
86
|
+
if (!block) {
|
|
87
|
+
console.warn(`ThinkingBlock "${event.block_id}" not found, skipping.`);
|
|
88
|
+
} else {
|
|
89
|
+
block.thinking += event.delta;
|
|
90
|
+
}
|
|
91
|
+
break;
|
|
92
|
+
}
|
|
93
|
+
case "THINKING_BLOCK_END" /* THINKING_BLOCK_END */:
|
|
94
|
+
break;
|
|
95
|
+
case "DATA_BLOCK_START" /* DATA_BLOCK_START */:
|
|
96
|
+
msg.content.push({
|
|
97
|
+
type: "data",
|
|
98
|
+
id: event.block_id,
|
|
99
|
+
source: { type: "base64", data: "", media_type: event.media_type }
|
|
100
|
+
});
|
|
101
|
+
break;
|
|
102
|
+
case "DATA_BLOCK_DELTA" /* DATA_BLOCK_DELTA */: {
|
|
103
|
+
const block = findBlock(msg, "data", event.block_id);
|
|
104
|
+
if (!block) {
|
|
105
|
+
console.warn(`DataBlock "${event.block_id}" not found, skipping.`);
|
|
106
|
+
} else {
|
|
107
|
+
block.source.data += event.data;
|
|
108
|
+
}
|
|
109
|
+
break;
|
|
110
|
+
}
|
|
111
|
+
case "DATA_BLOCK_END" /* DATA_BLOCK_END */:
|
|
112
|
+
break;
|
|
113
|
+
case "TOOL_CALL_START" /* TOOL_CALL_START */:
|
|
114
|
+
msg.content.push({
|
|
115
|
+
type: "tool_call",
|
|
116
|
+
id: event.tool_call_id,
|
|
117
|
+
name: event.tool_call_name,
|
|
118
|
+
input: "",
|
|
119
|
+
state: "pending"
|
|
120
|
+
});
|
|
121
|
+
break;
|
|
122
|
+
case "TOOL_CALL_DELTA" /* TOOL_CALL_DELTA */: {
|
|
123
|
+
const block = findBlock(msg, "tool_call", event.tool_call_id);
|
|
124
|
+
if (!block) {
|
|
125
|
+
console.warn(`ToolCallBlock "${event.tool_call_id}" not found, skipping.`);
|
|
126
|
+
} else {
|
|
127
|
+
block.input += event.delta;
|
|
128
|
+
}
|
|
129
|
+
break;
|
|
130
|
+
}
|
|
131
|
+
case "TOOL_CALL_END" /* TOOL_CALL_END */:
|
|
132
|
+
break;
|
|
133
|
+
case "TOOL_RESULT_START" /* TOOL_RESULT_START */:
|
|
134
|
+
msg.content.push({
|
|
135
|
+
type: "tool_result",
|
|
136
|
+
id: event.tool_call_id,
|
|
137
|
+
name: event.tool_call_name,
|
|
138
|
+
output: [],
|
|
139
|
+
state: "running"
|
|
140
|
+
});
|
|
141
|
+
break;
|
|
142
|
+
case "TOOL_RESULT_TEXT_DELTA" /* TOOL_RESULT_TEXT_DELTA */: {
|
|
143
|
+
const block = findBlock(msg, "tool_result", event.tool_call_id);
|
|
144
|
+
if (!block) {
|
|
145
|
+
console.warn(`ToolResultBlock "${event.tool_call_id}" not found, skipping.`);
|
|
146
|
+
} else {
|
|
147
|
+
const trb = block;
|
|
148
|
+
if (typeof trb.output === "string") {
|
|
149
|
+
trb.output = [{ type: "text", id: crypto.randomUUID(), text: trb.output }];
|
|
150
|
+
}
|
|
151
|
+
const last = trb.output[trb.output.length - 1];
|
|
152
|
+
if (!last || last.type !== "text") {
|
|
153
|
+
trb.output.push({
|
|
154
|
+
type: "text",
|
|
155
|
+
id: event.block_id ?? crypto.randomUUID(),
|
|
156
|
+
text: event.delta
|
|
157
|
+
});
|
|
158
|
+
} else {
|
|
159
|
+
last.text += event.delta;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
break;
|
|
163
|
+
}
|
|
164
|
+
case "TOOL_RESULT_DATA_DELTA" /* TOOL_RESULT_DATA_DELTA */: {
|
|
165
|
+
const block = findBlock(msg, "tool_result", event.tool_call_id);
|
|
166
|
+
if (!block) {
|
|
167
|
+
console.warn(`ToolResultBlock "${event.tool_call_id}" not found, skipping.`);
|
|
168
|
+
} else {
|
|
169
|
+
const trb = block;
|
|
170
|
+
if (typeof trb.output === "string") {
|
|
171
|
+
trb.output = [{ type: "text", id: crypto.randomUUID(), text: trb.output }];
|
|
172
|
+
}
|
|
173
|
+
const source = event.data != null ? { type: "base64", data: event.data, media_type: event.media_type } : { type: "url", url: event.url, media_type: event.media_type };
|
|
174
|
+
trb.output.push({ type: "data", id: event.block_id, source });
|
|
175
|
+
}
|
|
176
|
+
break;
|
|
177
|
+
}
|
|
178
|
+
case "TOOL_RESULT_END" /* TOOL_RESULT_END */: {
|
|
179
|
+
const block = findBlock(msg, "tool_result", event.tool_call_id);
|
|
180
|
+
if (!block) {
|
|
181
|
+
console.warn(`ToolResultBlock "${event.tool_call_id}" not found, skipping.`);
|
|
182
|
+
} else {
|
|
183
|
+
block.state = event.state;
|
|
184
|
+
}
|
|
185
|
+
break;
|
|
186
|
+
}
|
|
187
|
+
case "REQUIRE_USER_CONFIRM" /* REQUIRE_USER_CONFIRM */:
|
|
188
|
+
for (const tc of event.tool_calls) {
|
|
189
|
+
const b = findBlock(msg, "tool_call", tc.id);
|
|
190
|
+
if (b) b.state = "asking";
|
|
191
|
+
}
|
|
192
|
+
break;
|
|
193
|
+
case "USER_CONFIRM_RESULT" /* USER_CONFIRM_RESULT */:
|
|
194
|
+
for (const result of event.confirm_results) {
|
|
195
|
+
const b = findBlock(msg, "tool_call", result.tool_call.id);
|
|
196
|
+
if (b) {
|
|
197
|
+
b.state = result.confirmed ? "allowed" : "finished";
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
break;
|
|
201
|
+
case "REQUIRE_EXTERNAL_EXECUTION" /* REQUIRE_EXTERNAL_EXECUTION */:
|
|
202
|
+
for (const tc of event.tool_calls) {
|
|
203
|
+
const b = findBlock(msg, "tool_call", tc.id);
|
|
204
|
+
if (b) b.state = "submitted";
|
|
205
|
+
}
|
|
206
|
+
break;
|
|
207
|
+
case "EXTERNAL_EXECUTION_RESULT" /* EXTERNAL_EXECUTION_RESULT */:
|
|
208
|
+
for (const result of event.execution_results) {
|
|
209
|
+
msg.content.push(result);
|
|
210
|
+
}
|
|
211
|
+
break;
|
|
212
|
+
}
|
|
213
|
+
return msg;
|
|
214
|
+
}
|
|
24
215
|
|
|
25
216
|
// src/message/enums.ts
|
|
26
217
|
var GenerateReason = /* @__PURE__ */ ((GenerateReason2) => {
|
|
@@ -29,7 +220,11 @@ var GenerateReason = /* @__PURE__ */ ((GenerateReason2) => {
|
|
|
29
220
|
return GenerateReason2;
|
|
30
221
|
})(GenerateReason || {});
|
|
31
222
|
export {
|
|
223
|
+
AssistantMsg,
|
|
32
224
|
GenerateReason,
|
|
225
|
+
SystemMsg,
|
|
226
|
+
UserMsg,
|
|
227
|
+
appendEvent,
|
|
33
228
|
createMsg,
|
|
34
229
|
getContentBlocks,
|
|
35
230
|
getTextContent
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/message/message.ts","../../src/message/enums.ts"],"sourcesContent":["import { JSONSerializableObject } from '../type';\nimport {\n ContentBlock,\n TextBlock,\n ThinkingBlock,\n ToolResultBlock,\n ToolCallBlock,\n DataBlock,\n} from './block';\n\n/** A chat message exchanged between agents or between an agent and a model. */\nexport interface Msg {\n /** Unique identifier for the message. */\n id: string;\n /** Display name of the message sender. */\n name: string;\n /** Conversation role of the sender. */\n role: 'user' | 'assistant' | 'system';\n /** Message body. */\n content: ContentBlock[];\n /** Arbitrary key-value metadata attached to the message. */\n metadata: Record<string, JSONSerializableObject>;\n /** ISO-8601 creation timestamp. */\n timestamp: string;\n /** Usage information for the message, such as token counts. */\n usage?: {\n inputTokens: number;\n outputTokens: number;\n };\n}\n\n/**\n * Create a new {@link Msg} object, filling in `id` and `timestamp` when omitted.\n *\n * @param root0\n * @param root0.name\n * @param root0.content\n * @param root0.role\n * @param root0.metadata\n * @param root0.id\n * @param root0.timestamp\n * @param root0.usage\n * @returns A fully-populated {@link Msg} object.\n */\nexport function createMsg({\n name,\n content,\n role,\n metadata = {},\n id = crypto.randomUUID(),\n timestamp = new Date().toISOString(),\n usage,\n}: Omit<Msg, 'id' | 'timestamp' | 'metadata'> &\n Partial<Pick<Msg, 'id' | 'timestamp' | 'metadata'>>): Msg {\n return { id, name, role, content, metadata, timestamp, usage } as Msg;\n}\n\n/**\n * Extract the plain-text content from a message.\n *\n * When `content` is a string it is returned as-is. When it is an array of\n * content blocks, all {@link TextBlock} texts are joined with `separator`.\n *\n * @param msg - The message to read.\n * @param separator - String inserted between consecutive text blocks. Defaults to `'\\n'`.\n * @returns The concatenated text, or `null` when no text blocks are present.\n */\nexport function getTextContent(msg: Msg, separator: string = '\\n'): string | null {\n const textBlocks = msg.content.filter(block => block.type === 'text');\n if (textBlocks.length === 0) {\n return null;\n }\n return textBlocks.map(block => (block as TextBlock).text).join(separator);\n}\n\n/**\n * Return all content blocks from a message, regardless of type.\n *\n * When `content` is a plain string it is wrapped in a single {@link TextBlock}.\n *\n * @param msg - The message to read.\n * @returns An array of all {@link ContentBlock} objects.\n */\nexport function getContentBlocks(msg: Msg): ContentBlock[];\n/**\n * Return all {@link TextBlock} objects from a message.\n *\n * @param msg - The message to read.\n * @param blockType - `'text'`\n * @returns An array of {@link TextBlock} objects.\n */\nexport function getContentBlocks(msg: Msg, blockType: 'text'): TextBlock[];\n/**\n * Return all {@link ThinkingBlock} objects from a message.\n *\n * @param msg - The message to read.\n * @param blockType - `'thinking'`\n * @returns An array of {@link ThinkingBlock} objects.\n */\nexport function getContentBlocks(msg: Msg, blockType: 'thinking'): ThinkingBlock[];\n/**\n * Return all {@link DataBlock} objects from a message.\n *\n * @param msg - The message to read.\n * @param blockType - `'video'`\n * @returns An array of {@link DataBlock} objects.\n */\nexport function getContentBlocks(msg: Msg, blockType: 'data'): DataBlock[];\n/**\n * Return all {@link ToolCallBlock} objects from a message.\n *\n * @param msg - The message to read.\n * @param blockType - `'tool_call'`\n * @returns An array of {@link ToolCallBlock} objects.\n */\nexport function getContentBlocks(msg: Msg, blockType: 'tool_call'): ToolCallBlock[];\n/**\n * Return all {@link ToolResultBlock} objects from a message.\n *\n * @param msg - The message to read.\n * @param blockType - `'tool_result'`\n * @returns An array of {@link ToolResultBlock} objects.\n */\nexport function getContentBlocks(msg: Msg, blockType: 'tool_result'): ToolResultBlock[];\nexport function getContentBlocks(\n msg: Msg,\n blockType?: 'text' | 'thinking' | 'data' | 'tool_call' | 'tool_result'\n): ContentBlock[] {\n if (!blockType) return msg.content;\n return msg.content.filter(block => block.type === blockType);\n}\n","export enum GenerateReason {\n AWAITING_TOOL_RESULT = 'AWAITING_TOOL_RESULT',\n AWAITING_USER_CONFIRMATION = 'AWAITING_USER_CONFIRMATION',\n}\n"],"mappings":";AA4CO,SAAS,UAAU;AAAA,EACtB;AAAA,EACA;AAAA,EACA;AAAA,EACA,WAAW,CAAC;AAAA,EACZ,KAAK,OAAO,WAAW;AAAA,EACvB,aAAY,oBAAI,KAAK,GAAE,YAAY;AAAA,EACnC;AACJ,GAC8D;AAC1D,SAAO,EAAE,IAAI,MAAM,MAAM,SAAS,UAAU,WAAW,MAAM;AACjE;AAYO,SAAS,eAAe,KAAU,YAAoB,MAAqB;AAC9E,QAAM,aAAa,IAAI,QAAQ,OAAO,WAAS,MAAM,SAAS,MAAM;AACpE,MAAI,WAAW,WAAW,GAAG;AACzB,WAAO;AAAA,EACX;AACA,SAAO,WAAW,IAAI,WAAU,MAAoB,IAAI,EAAE,KAAK,SAAS;AAC5E;AAmDO,SAAS,iBACZ,KACA,WACc;AACd,MAAI,CAAC,UAAW,QAAO,IAAI;AAC3B,SAAO,IAAI,QAAQ,OAAO,WAAS,MAAM,SAAS,SAAS;AAC/D;;;AClIO,IAAK,iBAAL,kBAAKA,oBAAL;AACH,EAAAA,gBAAA,0BAAuB;AACvB,EAAAA,gBAAA,gCAA6B;AAFrB,SAAAA;AAAA,GAAA;","names":["GenerateReason"]}
|
|
1
|
+
{"version":3,"sources":["../../src/message/message.ts","../../src/message/enums.ts"],"sourcesContent":["import { JSONSerializableObject } from '../type';\nimport {\n ContentBlock,\n TextBlock,\n ThinkingBlock,\n ToolResultBlock,\n ToolCallBlock,\n DataBlock,\n Base64Source,\n URLSource,\n} from './block';\nimport { AgentEvent, EventType } from '../event';\n\n/** A chat message exchanged between agents or between an agent and a model. */\nexport interface Msg {\n /** Unique identifier for the message. */\n id: string;\n /** Display name of the message sender. */\n name: string;\n /** Conversation role of the sender. */\n role: 'user' | 'assistant' | 'system';\n /** Message body. */\n content: ContentBlock[];\n /** Arbitrary key-value metadata attached to the message. */\n metadata: Record<string, JSONSerializableObject>;\n /** ISO-8601 creation timestamp. */\n created_at: string;\n /** ISO-8601 finished timestamp. */\n finished_at?: string | null;\n /** Usage information for the message, such as token counts. */\n usage?: {\n inputTokens: number;\n outputTokens: number;\n };\n}\n\n/**\n * Create a new {@link Msg} object, filling in `id` and `created_at` when omitted.\n * A plain string `content` is automatically wrapped in a single {@link TextBlock}.\n * @param root0\n * @param root0.name\n * @param root0.content\n * @param root0.role\n * @param root0.metadata\n * @param root0.id\n * @param root0.created_at\n * @param root0.finished_at\n * @param root0.usage\n * @returns A Msg object.\n */\nexport function createMsg({\n name,\n content,\n role,\n metadata = {},\n id = crypto.randomUUID(),\n created_at = new Date().toISOString(),\n finished_at,\n usage,\n}: Omit<Msg, 'id' | 'created_at' | 'metadata' | 'content'> &\n Partial<Pick<Msg, 'id' | 'created_at' | 'metadata'>> & {\n content: string | ContentBlock[];\n }): Msg {\n const contentBlocks: ContentBlock[] =\n typeof content === 'string'\n ? [{ id: crypto.randomUUID(), type: 'text', text: content } as TextBlock]\n : content;\n return { id, name, role, content: contentBlocks, metadata, created_at, finished_at, usage };\n}\n\n/**\n * Create a user {@link Msg}.\n * @param root0\n * @param root0.name\n * @param root0.content\n * @param root0.metadata\n * @param root0.id\n * @param root0.created_at\n * @returns A Msg object with role 'user'.\n */\nexport function UserMsg({\n name,\n content,\n metadata = {},\n id = crypto.randomUUID(),\n created_at = new Date().toISOString(),\n}: {\n name: string;\n content: string | ContentBlock[];\n metadata?: Record<string, JSONSerializableObject>;\n id?: string;\n created_at?: string;\n}): Msg {\n return createMsg({ name, content, role: 'user', metadata, id, created_at });\n}\n\n/**\n * Create an assistant {@link Msg}.\n * @param root0\n * @param root0.name\n * @param root0.content\n * @param root0.metadata\n * @param root0.id\n * @param root0.created_at\n * @param root0.usage\n * @returns A Msg object with role 'assistant'.\n */\nexport function AssistantMsg({\n name,\n content,\n metadata = {},\n id = crypto.randomUUID(),\n created_at = new Date().toISOString(),\n usage,\n}: {\n name: string;\n content: string | ContentBlock[];\n metadata?: Record<string, JSONSerializableObject>;\n id?: string;\n created_at?: string;\n usage?: Msg['usage'];\n}): Msg {\n return createMsg({ name, content, role: 'assistant', metadata, id, created_at, usage });\n}\n\n/**\n * Create a system {@link Msg}.\n * @param root0\n * @param root0.name\n * @param root0.content\n * @param root0.metadata\n * @param root0.id\n * @param root0.created_at\n * @returns A Msg object with role 'system'.\n */\nexport function SystemMsg({\n name,\n content,\n metadata = {},\n id = crypto.randomUUID(),\n created_at = new Date().toISOString(),\n}: {\n name: string;\n content: string | ContentBlock[];\n metadata?: Record<string, JSONSerializableObject>;\n id?: string;\n created_at?: string;\n}): Msg {\n return createMsg({ name, content, role: 'system', metadata, id, created_at });\n}\n\n/**\n * Extract the plain-text content from a message.\n *\n * When `content` is a string it is returned as-is. When it is an array of\n * content blocks, all {@link TextBlock} texts are joined with `separator`.\n *\n * @param msg - The message to read.\n * @param separator - String inserted between consecutive text blocks. Defaults to `'\\n'`.\n * @returns The concatenated text, or `null` when no text blocks are present.\n */\nexport function getTextContent(msg: Msg, separator: string = '\\n'): string | null {\n const textBlocks = msg.content.filter(block => block.type === 'text');\n if (textBlocks.length === 0) return null;\n return textBlocks.map(block => (block as TextBlock).text).join(separator);\n}\n\n/**\n * Return all content blocks from a message, regardless of type.\n *\n * When `content` is a plain string it is wrapped in a single {@link TextBlock}.\n *\n * @param msg - The message to read.\n * @returns An array of all {@link ContentBlock} objects.\n */\nexport function getContentBlocks(msg: Msg): ContentBlock[];\nexport function getContentBlocks(msg: Msg, blockType: 'text'): TextBlock[];\nexport function getContentBlocks(msg: Msg, blockType: 'thinking'): ThinkingBlock[];\nexport function getContentBlocks(msg: Msg, blockType: 'data'): DataBlock[];\nexport function getContentBlocks(msg: Msg, blockType: 'tool_call'): ToolCallBlock[];\nexport function getContentBlocks(msg: Msg, blockType: 'tool_result'): ToolResultBlock[];\nexport function getContentBlocks(\n msg: Msg,\n blockType?: 'text' | 'thinking' | 'data' | 'tool_call' | 'tool_result'\n): ContentBlock[] {\n if (!blockType) return msg.content;\n return msg.content.filter(block => block.type === blockType);\n}\n\n/**\n * Find a content block by type and id within a message.\n * @param msg\n * @param blockType\n * @param blockId\n * @returns The matching {@link ContentBlock}, or `undefined` if not found.\n */\nfunction findBlock(msg: Msg, blockType: string, blockId: string): ContentBlock | undefined {\n return msg.content.find(block => block.type === blockType && block.id === blockId);\n}\n\n/**\n * Apply a streaming {@link AgentEvent} to a {@link Msg}, mutating it in place.\n *\n * Only `content` and `finished_at` are ever modified. Events whose\n * `reply_id` does not match `msg.id` are skipped with a warning.\n * @param msg\n * @param event\n * @returns The mutated {@link Msg} object.\n */\nexport function appendEvent(msg: Msg, event: AgentEvent): Msg {\n if (!('reply_id' in event)) return msg;\n if (event.reply_id !== msg.id) {\n console.warn(\n `Event reply_id \"${event.reply_id}\" does not match message id \"${msg.id}\", skipping.`\n );\n return msg;\n }\n\n switch (event.type) {\n case EventType.REPLY_END:\n msg.finished_at = event.created_at;\n break;\n\n case EventType.TEXT_BLOCK_START:\n msg.content.push({ type: 'text', id: event.block_id, text: '' });\n break;\n\n case EventType.TEXT_BLOCK_DELTA: {\n const block = findBlock(msg, 'text', event.block_id);\n if (!block) {\n console.warn(`TextBlock \"${event.block_id}\" not found, skipping.`);\n } else {\n (block as TextBlock).text += event.delta;\n }\n break;\n }\n\n case EventType.TEXT_BLOCK_END:\n break;\n\n case EventType.THINKING_BLOCK_START:\n msg.content.push({ type: 'thinking', id: event.block_id, thinking: '' });\n break;\n\n case EventType.THINKING_BLOCK_DELTA: {\n const block = findBlock(msg, 'thinking', event.block_id);\n if (!block) {\n console.warn(`ThinkingBlock \"${event.block_id}\" not found, skipping.`);\n } else {\n (block as ThinkingBlock).thinking += event.delta;\n }\n break;\n }\n\n case EventType.THINKING_BLOCK_END:\n break;\n\n case EventType.DATA_BLOCK_START:\n msg.content.push({\n type: 'data',\n id: event.block_id,\n source: { type: 'base64', data: '', media_type: event.media_type },\n });\n break;\n\n case EventType.DATA_BLOCK_DELTA: {\n const block = findBlock(msg, 'data', event.block_id);\n if (!block) {\n console.warn(`DataBlock \"${event.block_id}\" not found, skipping.`);\n } else {\n ((block as DataBlock).source as Base64Source).data += event.data;\n }\n break;\n }\n\n case EventType.DATA_BLOCK_END:\n break;\n\n case EventType.TOOL_CALL_START:\n msg.content.push({\n type: 'tool_call',\n id: event.tool_call_id,\n name: event.tool_call_name,\n input: '',\n state: 'pending',\n });\n break;\n\n case EventType.TOOL_CALL_DELTA: {\n const block = findBlock(msg, 'tool_call', event.tool_call_id);\n if (!block) {\n console.warn(`ToolCallBlock \"${event.tool_call_id}\" not found, skipping.`);\n } else {\n (block as ToolCallBlock).input += event.delta;\n }\n break;\n }\n\n case EventType.TOOL_CALL_END:\n break;\n\n case EventType.TOOL_RESULT_START:\n msg.content.push({\n type: 'tool_result',\n id: event.tool_call_id,\n name: event.tool_call_name,\n output: [],\n state: 'running',\n });\n break;\n\n case EventType.TOOL_RESULT_TEXT_DELTA: {\n const block = findBlock(msg, 'tool_result', event.tool_call_id);\n if (!block) {\n console.warn(`ToolResultBlock \"${event.tool_call_id}\" not found, skipping.`);\n } else {\n const trb = block as ToolResultBlock;\n if (typeof trb.output === 'string') {\n trb.output = [{ type: 'text', id: crypto.randomUUID(), text: trb.output }];\n }\n const last = trb.output[trb.output.length - 1];\n if (!last || last.type !== 'text') {\n trb.output.push({\n type: 'text',\n id: event.block_id ?? crypto.randomUUID(),\n text: event.delta,\n });\n } else {\n (last as TextBlock).text += event.delta;\n }\n }\n break;\n }\n\n case EventType.TOOL_RESULT_DATA_DELTA: {\n const block = findBlock(msg, 'tool_result', event.tool_call_id);\n if (!block) {\n console.warn(`ToolResultBlock \"${event.tool_call_id}\" not found, skipping.`);\n } else {\n const trb = block as ToolResultBlock;\n if (typeof trb.output === 'string') {\n trb.output = [{ type: 'text', id: crypto.randomUUID(), text: trb.output }];\n }\n const source: Base64Source | URLSource =\n event.data != null\n ? { type: 'base64', data: event.data, media_type: event.media_type }\n : { type: 'url', url: event.url!, media_type: event.media_type };\n trb.output.push({ type: 'data', id: event.block_id, source });\n }\n break;\n }\n\n case EventType.TOOL_RESULT_END: {\n const block = findBlock(msg, 'tool_result', event.tool_call_id);\n if (!block) {\n console.warn(`ToolResultBlock \"${event.tool_call_id}\" not found, skipping.`);\n } else {\n (block as ToolResultBlock).state = event.state;\n }\n break;\n }\n\n case EventType.REQUIRE_USER_CONFIRM:\n for (const tc of event.tool_calls) {\n const b = findBlock(msg, 'tool_call', tc.id);\n if (b) (b as ToolCallBlock).state = 'asking';\n }\n break;\n\n case EventType.USER_CONFIRM_RESULT:\n for (const result of event.confirm_results) {\n const b = findBlock(msg, 'tool_call', result.tool_call.id);\n if (b) {\n (b as ToolCallBlock).state = result.confirmed ? 'allowed' : 'finished';\n }\n }\n break;\n\n case EventType.REQUIRE_EXTERNAL_EXECUTION:\n for (const tc of event.tool_calls) {\n const b = findBlock(msg, 'tool_call', tc.id);\n if (b) (b as ToolCallBlock).state = 'submitted';\n }\n break;\n\n case EventType.EXTERNAL_EXECUTION_RESULT:\n for (const result of event.execution_results) {\n msg.content.push(result);\n }\n break;\n }\n\n return msg;\n}\n","export enum GenerateReason {\n AWAITING_TOOL_RESULT = 'AWAITING_TOOL_RESULT',\n AWAITING_USER_CONFIRMATION = 'AWAITING_USER_CONFIRMATION',\n}\n"],"mappings":";AAkDO,SAAS,UAAU;AAAA,EACtB;AAAA,EACA;AAAA,EACA;AAAA,EACA,WAAW,CAAC;AAAA,EACZ,KAAK,OAAO,WAAW;AAAA,EACvB,cAAa,oBAAI,KAAK,GAAE,YAAY;AAAA,EACpC;AAAA,EACA;AACJ,GAGY;AACR,QAAM,gBACF,OAAO,YAAY,WACb,CAAC,EAAE,IAAI,OAAO,WAAW,GAAG,MAAM,QAAQ,MAAM,QAAQ,CAAc,IACtE;AACV,SAAO,EAAE,IAAI,MAAM,MAAM,SAAS,eAAe,UAAU,YAAY,aAAa,MAAM;AAC9F;AAYO,SAAS,QAAQ;AAAA,EACpB;AAAA,EACA;AAAA,EACA,WAAW,CAAC;AAAA,EACZ,KAAK,OAAO,WAAW;AAAA,EACvB,cAAa,oBAAI,KAAK,GAAE,YAAY;AACxC,GAMQ;AACJ,SAAO,UAAU,EAAE,MAAM,SAAS,MAAM,QAAQ,UAAU,IAAI,WAAW,CAAC;AAC9E;AAaO,SAAS,aAAa;AAAA,EACzB;AAAA,EACA;AAAA,EACA,WAAW,CAAC;AAAA,EACZ,KAAK,OAAO,WAAW;AAAA,EACvB,cAAa,oBAAI,KAAK,GAAE,YAAY;AAAA,EACpC;AACJ,GAOQ;AACJ,SAAO,UAAU,EAAE,MAAM,SAAS,MAAM,aAAa,UAAU,IAAI,YAAY,MAAM,CAAC;AAC1F;AAYO,SAAS,UAAU;AAAA,EACtB;AAAA,EACA;AAAA,EACA,WAAW,CAAC;AAAA,EACZ,KAAK,OAAO,WAAW;AAAA,EACvB,cAAa,oBAAI,KAAK,GAAE,YAAY;AACxC,GAMQ;AACJ,SAAO,UAAU,EAAE,MAAM,SAAS,MAAM,UAAU,UAAU,IAAI,WAAW,CAAC;AAChF;AAYO,SAAS,eAAe,KAAU,YAAoB,MAAqB;AAC9E,QAAM,aAAa,IAAI,QAAQ,OAAO,WAAS,MAAM,SAAS,MAAM;AACpE,MAAI,WAAW,WAAW,EAAG,QAAO;AACpC,SAAO,WAAW,IAAI,WAAU,MAAoB,IAAI,EAAE,KAAK,SAAS;AAC5E;AAgBO,SAAS,iBACZ,KACA,WACc;AACd,MAAI,CAAC,UAAW,QAAO,IAAI;AAC3B,SAAO,IAAI,QAAQ,OAAO,WAAS,MAAM,SAAS,SAAS;AAC/D;AASA,SAAS,UAAU,KAAU,WAAmB,SAA2C;AACvF,SAAO,IAAI,QAAQ,KAAK,WAAS,MAAM,SAAS,aAAa,MAAM,OAAO,OAAO;AACrF;AAWO,SAAS,YAAY,KAAU,OAAwB;AAC1D,MAAI,EAAE,cAAc,OAAQ,QAAO;AACnC,MAAI,MAAM,aAAa,IAAI,IAAI;AAC3B,YAAQ;AAAA,MACJ,mBAAmB,MAAM,QAAQ,gCAAgC,IAAI,EAAE;AAAA,IAC3E;AACA,WAAO;AAAA,EACX;AAEA,UAAQ,MAAM,MAAM;AAAA,IAChB;AACI,UAAI,cAAc,MAAM;AACxB;AAAA,IAEJ;AACI,UAAI,QAAQ,KAAK,EAAE,MAAM,QAAQ,IAAI,MAAM,UAAU,MAAM,GAAG,CAAC;AAC/D;AAAA,IAEJ,gDAAiC;AAC7B,YAAM,QAAQ,UAAU,KAAK,QAAQ,MAAM,QAAQ;AACnD,UAAI,CAAC,OAAO;AACR,gBAAQ,KAAK,cAAc,MAAM,QAAQ,wBAAwB;AAAA,MACrE,OAAO;AACH,QAAC,MAAoB,QAAQ,MAAM;AAAA,MACvC;AACA;AAAA,IACJ;AAAA,IAEA;AACI;AAAA,IAEJ;AACI,UAAI,QAAQ,KAAK,EAAE,MAAM,YAAY,IAAI,MAAM,UAAU,UAAU,GAAG,CAAC;AACvE;AAAA,IAEJ,wDAAqC;AACjC,YAAM,QAAQ,UAAU,KAAK,YAAY,MAAM,QAAQ;AACvD,UAAI,CAAC,OAAO;AACR,gBAAQ,KAAK,kBAAkB,MAAM,QAAQ,wBAAwB;AAAA,MACzE,OAAO;AACH,QAAC,MAAwB,YAAY,MAAM;AAAA,MAC/C;AACA;AAAA,IACJ;AAAA,IAEA;AACI;AAAA,IAEJ;AACI,UAAI,QAAQ,KAAK;AAAA,QACb,MAAM;AAAA,QACN,IAAI,MAAM;AAAA,QACV,QAAQ,EAAE,MAAM,UAAU,MAAM,IAAI,YAAY,MAAM,WAAW;AAAA,MACrE,CAAC;AACD;AAAA,IAEJ,gDAAiC;AAC7B,YAAM,QAAQ,UAAU,KAAK,QAAQ,MAAM,QAAQ;AACnD,UAAI,CAAC,OAAO;AACR,gBAAQ,KAAK,cAAc,MAAM,QAAQ,wBAAwB;AAAA,MACrE,OAAO;AACH,QAAE,MAAoB,OAAwB,QAAQ,MAAM;AAAA,MAChE;AACA;AAAA,IACJ;AAAA,IAEA;AACI;AAAA,IAEJ;AACI,UAAI,QAAQ,KAAK;AAAA,QACb,MAAM;AAAA,QACN,IAAI,MAAM;AAAA,QACV,MAAM,MAAM;AAAA,QACZ,OAAO;AAAA,QACP,OAAO;AAAA,MACX,CAAC;AACD;AAAA,IAEJ,8CAAgC;AAC5B,YAAM,QAAQ,UAAU,KAAK,aAAa,MAAM,YAAY;AAC5D,UAAI,CAAC,OAAO;AACR,gBAAQ,KAAK,kBAAkB,MAAM,YAAY,wBAAwB;AAAA,MAC7E,OAAO;AACH,QAAC,MAAwB,SAAS,MAAM;AAAA,MAC5C;AACA;AAAA,IACJ;AAAA,IAEA;AACI;AAAA,IAEJ;AACI,UAAI,QAAQ,KAAK;AAAA,QACb,MAAM;AAAA,QACN,IAAI,MAAM;AAAA,QACV,MAAM,MAAM;AAAA,QACZ,QAAQ,CAAC;AAAA,QACT,OAAO;AAAA,MACX,CAAC;AACD;AAAA,IAEJ,4DAAuC;AACnC,YAAM,QAAQ,UAAU,KAAK,eAAe,MAAM,YAAY;AAC9D,UAAI,CAAC,OAAO;AACR,gBAAQ,KAAK,oBAAoB,MAAM,YAAY,wBAAwB;AAAA,MAC/E,OAAO;AACH,cAAM,MAAM;AACZ,YAAI,OAAO,IAAI,WAAW,UAAU;AAChC,cAAI,SAAS,CAAC,EAAE,MAAM,QAAQ,IAAI,OAAO,WAAW,GAAG,MAAM,IAAI,OAAO,CAAC;AAAA,QAC7E;AACA,cAAM,OAAO,IAAI,OAAO,IAAI,OAAO,SAAS,CAAC;AAC7C,YAAI,CAAC,QAAQ,KAAK,SAAS,QAAQ;AAC/B,cAAI,OAAO,KAAK;AAAA,YACZ,MAAM;AAAA,YACN,IAAI,MAAM,YAAY,OAAO,WAAW;AAAA,YACxC,MAAM,MAAM;AAAA,UAChB,CAAC;AAAA,QACL,OAAO;AACH,UAAC,KAAmB,QAAQ,MAAM;AAAA,QACtC;AAAA,MACJ;AACA;AAAA,IACJ;AAAA,IAEA,4DAAuC;AACnC,YAAM,QAAQ,UAAU,KAAK,eAAe,MAAM,YAAY;AAC9D,UAAI,CAAC,OAAO;AACR,gBAAQ,KAAK,oBAAoB,MAAM,YAAY,wBAAwB;AAAA,MAC/E,OAAO;AACH,cAAM,MAAM;AACZ,YAAI,OAAO,IAAI,WAAW,UAAU;AAChC,cAAI,SAAS,CAAC,EAAE,MAAM,QAAQ,IAAI,OAAO,WAAW,GAAG,MAAM,IAAI,OAAO,CAAC;AAAA,QAC7E;AACA,cAAM,SACF,MAAM,QAAQ,OACR,EAAE,MAAM,UAAU,MAAM,MAAM,MAAM,YAAY,MAAM,WAAW,IACjE,EAAE,MAAM,OAAO,KAAK,MAAM,KAAM,YAAY,MAAM,WAAW;AACvE,YAAI,OAAO,KAAK,EAAE,MAAM,QAAQ,IAAI,MAAM,UAAU,OAAO,CAAC;AAAA,MAChE;AACA;AAAA,IACJ;AAAA,IAEA,8CAAgC;AAC5B,YAAM,QAAQ,UAAU,KAAK,eAAe,MAAM,YAAY;AAC9D,UAAI,CAAC,OAAO;AACR,gBAAQ,KAAK,oBAAoB,MAAM,YAAY,wBAAwB;AAAA,MAC/E,OAAO;AACH,QAAC,MAA0B,QAAQ,MAAM;AAAA,MAC7C;AACA;AAAA,IACJ;AAAA,IAEA;AACI,iBAAW,MAAM,MAAM,YAAY;AAC/B,cAAM,IAAI,UAAU,KAAK,aAAa,GAAG,EAAE;AAC3C,YAAI,EAAG,CAAC,EAAoB,QAAQ;AAAA,MACxC;AACA;AAAA,IAEJ;AACI,iBAAW,UAAU,MAAM,iBAAiB;AACxC,cAAM,IAAI,UAAU,KAAK,aAAa,OAAO,UAAU,EAAE;AACzD,YAAI,GAAG;AACH,UAAC,EAAoB,QAAQ,OAAO,YAAY,YAAY;AAAA,QAChE;AAAA,MACJ;AACA;AAAA,IAEJ;AACI,iBAAW,MAAM,MAAM,YAAY;AAC/B,cAAM,IAAI,UAAU,KAAK,aAAa,GAAG,EAAE;AAC3C,YAAI,EAAG,CAAC,EAAoB,QAAQ;AAAA,MACxC;AACA;AAAA,IAEJ;AACI,iBAAW,UAAU,MAAM,mBAAmB;AAC1C,YAAI,QAAQ,KAAK,MAAM;AAAA,MAC3B;AACA;AAAA,EACR;AAEA,SAAO;AACX;;;ACzYO,IAAK,iBAAL,kBAAKA,oBAAL;AACH,EAAAA,gBAAA,0BAAuB;AACvB,EAAAA,gBAAA,gCAA6B;AAFrB,SAAAA;AAAA,GAAA;","names":["GenerateReason"]}
|