@openharness/core 0.3.2 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=messages.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"messages.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/messages.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,66 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { extractUserInput } from "../messages.js";
3
+ function makeTextMessage(text, role = "user") {
4
+ return {
5
+ id: "msg-1",
6
+ role,
7
+ parts: [{ type: "text", text }],
8
+ };
9
+ }
10
+ function makeFileMessage(mediaType, url, filename, text) {
11
+ const parts = [];
12
+ if (text) {
13
+ parts.push({ type: "text", text });
14
+ }
15
+ parts.push({ type: "file", mediaType, url, filename });
16
+ return {
17
+ id: "msg-2",
18
+ role: "user",
19
+ parts,
20
+ };
21
+ }
22
+ describe("extractUserInput", () => {
23
+ it("returns string for text-only message", async () => {
24
+ const result = await extractUserInput([makeTextMessage("hello world")]);
25
+ expect(result).toBe("hello world");
26
+ });
27
+ it("concatenates multiple text parts", async () => {
28
+ const msg = {
29
+ id: "msg-1",
30
+ role: "user",
31
+ parts: [
32
+ { type: "text", text: "hello " },
33
+ { type: "text", text: "world" },
34
+ ],
35
+ };
36
+ const result = await extractUserInput([msg]);
37
+ expect(result).toBe("hello world");
38
+ });
39
+ it("returns ModelMessage[] for message with file", async () => {
40
+ const msg = makeFileMessage("image/png", "data:image/png;base64,iVBOR", "test.png", "describe this image");
41
+ const result = await extractUserInput([msg]);
42
+ expect(Array.isArray(result)).toBe(true);
43
+ const messages = result;
44
+ expect(messages.length).toBeGreaterThan(0);
45
+ expect(messages[0].role).toBe("user");
46
+ });
47
+ it("returns ModelMessage[] for file-only (no text)", async () => {
48
+ const msg = makeFileMessage("image/jpeg", "data:image/jpeg;base64,/9j/4A");
49
+ const result = await extractUserInput([msg]);
50
+ expect(Array.isArray(result)).toBe(true);
51
+ });
52
+ it("uses only the last message", async () => {
53
+ const result = await extractUserInput([
54
+ makeTextMessage("first message"),
55
+ makeTextMessage("second message"),
56
+ ]);
57
+ expect(result).toBe("second message");
58
+ });
59
+ it("throws on empty array", async () => {
60
+ await expect(extractUserInput([])).rejects.toThrow("messages array is empty");
61
+ });
62
+ it("throws when last message is not from user", async () => {
63
+ await expect(extractUserInput([makeTextMessage("hi", "assistant")])).rejects.toThrow('expected "user"');
64
+ });
65
+ });
66
+ //# sourceMappingURL=messages.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"messages.test.js","sourceRoot":"","sources":["../../src/__tests__/messages.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=skills.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skills.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/skills.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,293 @@
1
+ import { describe, it, expect, beforeEach, afterEach } from "vitest";
2
+ import fs from "node:fs/promises";
3
+ import path from "node:path";
4
+ import os from "node:os";
5
+ import { discoverSkills, scanSkillFiles } from "../skills.js";
6
+ import { createSkillTool } from "../tools/skill.js";
7
+ // ── Helpers ─────────────────────────────────────────────────────────
8
+ let tmpDir;
9
+ beforeEach(async () => {
10
+ tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), "oh-skills-test-"));
11
+ });
12
+ afterEach(async () => {
13
+ await fs.rm(tmpDir, { recursive: true, force: true });
14
+ });
15
+ /** Write a SKILL.md file under `tmpDir/<name>/SKILL.md`. */
16
+ async function writeSkill(name, content, extraFiles) {
17
+ const dir = path.join(tmpDir, name);
18
+ await fs.mkdir(dir, { recursive: true });
19
+ await fs.writeFile(path.join(dir, "SKILL.md"), content, "utf-8");
20
+ for (const [filePath, fileContent] of Object.entries(extraFiles ?? {})) {
21
+ const full = path.join(dir, filePath);
22
+ await fs.mkdir(path.dirname(full), { recursive: true });
23
+ await fs.writeFile(full, fileContent, "utf-8");
24
+ }
25
+ return dir;
26
+ }
27
+ // ── discoverSkills ──────────────────────────────────────────────────
28
+ describe("discoverSkills", () => {
29
+ it("discovers a single skill", async () => {
30
+ await writeSkill("my-skill", `---
31
+ name: my-skill
32
+ description: A test skill
33
+ ---
34
+
35
+ # Instructions
36
+
37
+ Do the thing.`);
38
+ const skills = await discoverSkills({ paths: [tmpDir] });
39
+ expect(skills).toHaveLength(1);
40
+ expect(skills[0].name).toBe("my-skill");
41
+ expect(skills[0].description).toBe("A test skill");
42
+ expect(skills[0].content).toBe("# Instructions\n\nDo the thing.");
43
+ expect(skills[0].location).toBe(path.join(tmpDir, "my-skill", "SKILL.md"));
44
+ });
45
+ it("discovers multiple skills", async () => {
46
+ await writeSkill("skill-a", `---
47
+ name: skill-a
48
+ description: First skill
49
+ ---
50
+
51
+ Content A`);
52
+ await writeSkill("skill-b", `---
53
+ name: skill-b
54
+ description: Second skill
55
+ ---
56
+
57
+ Content B`);
58
+ const skills = await discoverSkills({ paths: [tmpDir] });
59
+ expect(skills).toHaveLength(2);
60
+ const names = skills.map((s) => s.name).sort();
61
+ expect(names).toEqual(["skill-a", "skill-b"]);
62
+ });
63
+ it("discovers nested skills", async () => {
64
+ const nestedDir = path.join(tmpDir, "deep", "nested", "my-skill");
65
+ await fs.mkdir(nestedDir, { recursive: true });
66
+ await fs.writeFile(path.join(nestedDir, "SKILL.md"), `---
67
+ name: nested-skill
68
+ description: Found deep
69
+ ---
70
+
71
+ Nested content`, "utf-8");
72
+ const skills = await discoverSkills({ paths: [tmpDir] });
73
+ expect(skills).toHaveLength(1);
74
+ expect(skills[0].name).toBe("nested-skill");
75
+ });
76
+ it("later paths overwrite earlier ones on name collision", async () => {
77
+ const dir1 = path.join(tmpDir, "first");
78
+ const dir2 = path.join(tmpDir, "second");
79
+ await fs.mkdir(path.join(dir1, "my-skill"), { recursive: true });
80
+ await fs.writeFile(path.join(dir1, "my-skill", "SKILL.md"), `---
81
+ name: my-skill
82
+ description: From first
83
+ ---
84
+
85
+ First version`, "utf-8");
86
+ await fs.mkdir(path.join(dir2, "my-skill"), { recursive: true });
87
+ await fs.writeFile(path.join(dir2, "my-skill", "SKILL.md"), `---
88
+ name: my-skill
89
+ description: From second
90
+ ---
91
+
92
+ Second version`, "utf-8");
93
+ const skills = await discoverSkills({ paths: [dir1, dir2] });
94
+ expect(skills).toHaveLength(1);
95
+ expect(skills[0].description).toBe("From second");
96
+ expect(skills[0].content).toBe("Second version");
97
+ });
98
+ it("returns empty array for empty paths", async () => {
99
+ const skills = await discoverSkills({ paths: [] });
100
+ expect(skills).toEqual([]);
101
+ });
102
+ it("returns empty array when paths is undefined", async () => {
103
+ const skills = await discoverSkills({});
104
+ expect(skills).toEqual([]);
105
+ });
106
+ it("silently skips non-existent directories", async () => {
107
+ const skills = await discoverSkills({
108
+ paths: [path.join(tmpDir, "does-not-exist")],
109
+ });
110
+ expect(skills).toEqual([]);
111
+ });
112
+ it("skips SKILL.md with missing frontmatter", async () => {
113
+ await writeSkill("bad", "# No frontmatter here\n\nJust content.");
114
+ const skills = await discoverSkills({ paths: [tmpDir] });
115
+ expect(skills).toEqual([]);
116
+ });
117
+ it("skips SKILL.md with missing name", async () => {
118
+ await writeSkill("no-name", `---
119
+ description: Has description but no name
120
+ ---
121
+
122
+ Content`);
123
+ const skills = await discoverSkills({ paths: [tmpDir] });
124
+ expect(skills).toEqual([]);
125
+ });
126
+ it("skips SKILL.md with missing description", async () => {
127
+ await writeSkill("no-desc", `---
128
+ name: no-desc
129
+ ---
130
+
131
+ Content`);
132
+ const skills = await discoverSkills({ paths: [tmpDir] });
133
+ expect(skills).toEqual([]);
134
+ });
135
+ it("skips SKILL.md with invalid name format", async () => {
136
+ await writeSkill("bad-name", `---
137
+ name: UPPER_CASE
138
+ description: Invalid name
139
+ ---
140
+
141
+ Content`);
142
+ const skills = await discoverSkills({ paths: [tmpDir] });
143
+ expect(skills).toEqual([]);
144
+ });
145
+ it("rejects names starting with a hyphen", async () => {
146
+ await writeSkill("hyphen", `---
147
+ name: -leading
148
+ description: Bad
149
+ ---
150
+
151
+ Content`);
152
+ const skills = await discoverSkills({ paths: [tmpDir] });
153
+ expect(skills).toEqual([]);
154
+ });
155
+ it("rejects names with consecutive hyphens", async () => {
156
+ await writeSkill("double", `---
157
+ name: foo--bar
158
+ description: Bad
159
+ ---
160
+
161
+ Content`);
162
+ const skills = await discoverSkills({ paths: [tmpDir] });
163
+ expect(skills).toEqual([]);
164
+ });
165
+ it("preserves colons in description values", async () => {
166
+ await writeSkill("colon", `---
167
+ name: colon-test
168
+ description: Build AI agents: stateful workflows
169
+ ---
170
+
171
+ Content`);
172
+ const skills = await discoverSkills({ paths: [tmpDir] });
173
+ expect(skills).toHaveLength(1);
174
+ expect(skills[0].description).toBe("Build AI agents: stateful workflows");
175
+ });
176
+ });
177
+ // ── scanSkillFiles ──────────────────────────────────────────────────
178
+ describe("scanSkillFiles", () => {
179
+ it("returns auxiliary files excluding SKILL.md", async () => {
180
+ const dir = await writeSkill("with-files", `---
181
+ name: with-files
182
+ description: Has extra files
183
+ ---
184
+
185
+ Content`, {
186
+ "references/api.md": "# API docs",
187
+ "scripts/setup.sh": "#!/bin/bash\necho hi",
188
+ });
189
+ const files = await scanSkillFiles(dir);
190
+ expect(files).toHaveLength(2);
191
+ const basenames = files.map((f) => path.relative(dir, f)).sort();
192
+ expect(basenames).toEqual(["references/api.md", "scripts/setup.sh"]);
193
+ });
194
+ it("excludes SKILL.md from results", async () => {
195
+ const dir = await writeSkill("only-skill", `---
196
+ name: only-skill
197
+ description: Just the skill file
198
+ ---
199
+
200
+ Content`);
201
+ const files = await scanSkillFiles(dir);
202
+ expect(files).toEqual([]);
203
+ });
204
+ it("respects the limit parameter", async () => {
205
+ const extras = {};
206
+ for (let i = 0; i < 15; i++) {
207
+ extras[`file-${String(i).padStart(2, "0")}.txt`] = `content ${i}`;
208
+ }
209
+ const dir = await writeSkill("many-files", `---
210
+ name: many-files
211
+ description: Lots of files
212
+ ---
213
+
214
+ Content`, extras);
215
+ const files = await scanSkillFiles(dir, 5);
216
+ expect(files).toHaveLength(5);
217
+ });
218
+ it("returns empty array for non-existent directory", async () => {
219
+ const files = await scanSkillFiles(path.join(tmpDir, "nope"));
220
+ expect(files).toEqual([]);
221
+ });
222
+ });
223
+ // ── createSkillTool ─────────────────────────────────────────────────
224
+ describe("createSkillTool", () => {
225
+ const baseSkill = {
226
+ name: "test-skill",
227
+ description: "A test skill",
228
+ location: "/fake/test-skill/SKILL.md",
229
+ content: "# Test\n\nDo the thing.",
230
+ };
231
+ it("creates a tool with available skills in description", () => {
232
+ const skillTool = createSkillTool([baseSkill]);
233
+ expect(skillTool.description).toContain("test-skill");
234
+ expect(skillTool.description).toContain("A test skill");
235
+ expect(skillTool.description).toContain("<available_skills>");
236
+ });
237
+ it("lists multiple skills in description", () => {
238
+ const skills = [
239
+ baseSkill,
240
+ { name: "other-skill", description: "Another one", location: "/fake/other/SKILL.md", content: "Other" },
241
+ ];
242
+ const skillTool = createSkillTool(skills);
243
+ expect(skillTool.description).toContain("test-skill");
244
+ expect(skillTool.description).toContain("other-skill");
245
+ });
246
+ it("executes and returns skill content", async () => {
247
+ const dir = await writeSkill("real-skill", `---
248
+ name: real-skill
249
+ description: Real
250
+ ---
251
+
252
+ # Instructions
253
+
254
+ Follow these steps.`, { "ref.md": "# Reference" });
255
+ const skill = {
256
+ name: "real-skill",
257
+ description: "Real",
258
+ location: path.join(dir, "SKILL.md"),
259
+ content: "# Instructions\n\nFollow these steps.",
260
+ };
261
+ const skillTool = createSkillTool([skill]);
262
+ const result = await skillTool.execute({ name: "real-skill" }, { toolCallId: "test", messages: [], abortSignal: undefined });
263
+ expect(result).toContain("<skill_content name=\"real-skill\">");
264
+ expect(result).toContain("# Skill: real-skill");
265
+ expect(result).toContain("Follow these steps.");
266
+ expect(result).toContain(`Base directory for this skill: ${dir}`);
267
+ expect(result).toContain("<skill_files>");
268
+ expect(result).toContain("ref.md</file>");
269
+ expect(result).toContain("</skill_content>");
270
+ });
271
+ it("omits skill_files section when no auxiliary files exist", async () => {
272
+ const dir = await writeSkill("bare-skill", `---
273
+ name: bare-skill
274
+ description: Bare
275
+ ---
276
+
277
+ Content only`);
278
+ const skill = {
279
+ name: "bare-skill",
280
+ description: "Bare",
281
+ location: path.join(dir, "SKILL.md"),
282
+ content: "Content only",
283
+ };
284
+ const skillTool = createSkillTool([skill]);
285
+ const result = await skillTool.execute({ name: "bare-skill" }, { toolCallId: "test", messages: [], abortSignal: undefined });
286
+ expect(result).not.toContain("<skill_files>");
287
+ });
288
+ it("throws for unknown skill name", async () => {
289
+ const skillTool = createSkillTool([baseSkill]);
290
+ await expect(skillTool.execute({ name: "nope" }, { toolCallId: "test", messages: [], abortSignal: undefined })).rejects.toThrow('Skill "nope" not found');
291
+ });
292
+ });
293
+ //# sourceMappingURL=skills.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skills.test.js","sourceRoot":"","sources":["../../src/__tests__/skills.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACrE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9D,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAGpD,uEAAuE;AAEvE,IAAI,MAAc,CAAC;AAEnB,UAAU,CAAC,KAAK,IAAI,EAAE;IACpB,MAAM,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,iBAAiB,CAAC,CAAC,CAAC;AACvE,CAAC,CAAC,CAAC;AAEH,SAAS,CAAC,KAAK,IAAI,EAAE;IACnB,MAAM,EAAE,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;AACxD,CAAC,CAAC,CAAC;AAEH,4DAA4D;AAC5D,KAAK,UAAU,UAAU,CACvB,IAAY,EACZ,OAAe,EACf,UAAmC;IAEnC,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IACpC,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACzC,MAAM,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,UAAU,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IACjE,KAAK,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,UAAU,IAAI,EAAE,CAAC,EAAE,CAAC;QACvE,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;QACtC,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACxD,MAAM,EAAE,CAAC,SAAS,CAAC,IAAI,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC;IACjD,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,uEAAuE;AAEvE,QAAQ,CAAC,gBAAgB,EAAE,GAAG,EAAE;IAC9B,EAAE,CAAC,0BAA0B,EAAE,KAAK,IAAI,EAAE;QACxC,MAAM,UAAU,CACd,UAAU,EACV;;;;;;;cAOQ,CACT,CAAC;QAEF,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,EAAE,KAAK,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACzD,MAAM,CAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAC/B,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACxC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QACnD,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,iCAAiC,CAAC,CAAC;QAClE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC;IAC7E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2BAA2B,EAAE,KAAK,IAAI,EAAE;QACzC,MAAM,UAAU,CACd,SAAS,EACT;;;;;UAKI,CACL,CAAC;QACF,MAAM,UAAU,CACd,SAAS,EACT;;;;;UAKI,CACL,CAAC;QAEF,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,EAAE,KAAK,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACzD,MAAM,CAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAE/B,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;QAC/C,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC;IAChD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yBAAyB,EAAE,KAAK,IAAI,EAAE;QACvC,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC;QAClE,MAAM,EAAE,CAAC,KAAK,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC/C,MAAM,EAAE,CAAC,SAAS,CAChB,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,UAAU,CAAC,EAChC;;;;;eAKS,EACT,OAAO,CACR,CAAC;QAEF,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,EAAE,KAAK,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACzD,MAAM,CAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAC/B,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sDAAsD,EAAE,KAAK,IAAI,EAAE;QACpE,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACxC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;QAEzC,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACjE,MAAM,EAAE,CAAC,SAAS,CAChB,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,EAAE,UAAU,CAAC,EACvC;;;;;cAKQ,EACR,OAAO,CACR,CAAC;QAEF,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACjE,MAAM,EAAE,CAAC,SAAS,CAChB,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,EAAE,UAAU,CAAC,EACvC;;;;;eAKS,EACT,OAAO,CACR,CAAC;QAEF,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,EAAE,KAAK,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;QAC7D,MAAM,CAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAC/B,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAClD,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;IACnD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qCAAqC,EAAE,KAAK,IAAI,EAAE;QACnD,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC;QACnD,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAC7B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6CAA6C,EAAE,KAAK,IAAI,EAAE;QAC3D,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,EAAE,CAAC,CAAC;QACxC,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAC7B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yCAAyC,EAAE,KAAK,IAAI,EAAE;QACvD,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC;YAClC,KAAK,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;SAC7C,CAAC,CAAC;QACH,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAC7B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yCAAyC,EAAE,KAAK,IAAI,EAAE;QACvD,MAAM,UAAU,CAAC,KAAK,EAAE,wCAAwC,CAAC,CAAC;QAElE,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,EAAE,KAAK,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACzD,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAC7B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kCAAkC,EAAE,KAAK,IAAI,EAAE;QAChD,MAAM,UAAU,CACd,SAAS,EACT;;;;QAIE,CACH,CAAC;QAEF,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,EAAE,KAAK,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACzD,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAC7B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yCAAyC,EAAE,KAAK,IAAI,EAAE;QACvD,MAAM,UAAU,CACd,SAAS,EACT;;;;QAIE,CACH,CAAC;QAEF,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,EAAE,KAAK,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACzD,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAC7B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yCAAyC,EAAE,KAAK,IAAI,EAAE;QACvD,MAAM,UAAU,CACd,UAAU,EACV;;;;;QAKE,CACH,CAAC;QAEF,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,EAAE,KAAK,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACzD,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAC7B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sCAAsC,EAAE,KAAK,IAAI,EAAE;QACpD,MAAM,UAAU,CACd,QAAQ,EACR;;;;;QAKE,CACH,CAAC;QAEF,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,EAAE,KAAK,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACzD,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAC7B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wCAAwC,EAAE,KAAK,IAAI,EAAE;QACtD,MAAM,UAAU,CACd,QAAQ,EACR;;;;;QAKE,CACH,CAAC;QAEF,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,EAAE,KAAK,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACzD,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAC7B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wCAAwC,EAAE,KAAK,IAAI,EAAE;QACtD,MAAM,UAAU,CACd,OAAO,EACP;;;;;QAKE,CACH,CAAC;QAEF,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,EAAE,KAAK,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACzD,MAAM,CAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAC/B,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,qCAAqC,CAAC,CAAC;IAC5E,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,uEAAuE;AAEvE,QAAQ,CAAC,gBAAgB,EAAE,GAAG,EAAE;IAC9B,EAAE,CAAC,4CAA4C,EAAE,KAAK,IAAI,EAAE;QAC1D,MAAM,GAAG,GAAG,MAAM,UAAU,CAC1B,YAAY,EACZ;;;;;QAKE,EACF;YACE,mBAAmB,EAAE,YAAY;YACjC,kBAAkB,EAAE,sBAAsB;SAC3C,CACF,CAAC;QAEF,MAAM,KAAK,GAAG,MAAM,cAAc,CAAC,GAAG,CAAC,CAAC;QACxC,MAAM,CAAC,KAAK,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAE9B,MAAM,SAAS,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACjE,MAAM,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,CAAC,mBAAmB,EAAE,kBAAkB,CAAC,CAAC,CAAC;IACvE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gCAAgC,EAAE,KAAK,IAAI,EAAE;QAC9C,MAAM,GAAG,GAAG,MAAM,UAAU,CAC1B,YAAY,EACZ;;;;;QAKE,CACH,CAAC;QAEF,MAAM,KAAK,GAAG,MAAM,cAAc,CAAC,GAAG,CAAC,CAAC;QACxC,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAC5B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8BAA8B,EAAE,KAAK,IAAI,EAAE;QAC5C,MAAM,MAAM,GAA2B,EAAE,CAAC;QAC1C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;YAC5B,MAAM,CAAC,QAAQ,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,WAAW,CAAC,EAAE,CAAC;QACpE,CAAC;QAED,MAAM,GAAG,GAAG,MAAM,UAAU,CAC1B,YAAY,EACZ;;;;;QAKE,EACF,MAAM,CACP,CAAC;QAEF,MAAM,KAAK,GAAG,MAAM,cAAc,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QAC3C,MAAM,CAAC,KAAK,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IAChC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gDAAgD,EAAE,KAAK,IAAI,EAAE;QAC9D,MAAM,KAAK,GAAG,MAAM,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;QAC9D,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAC5B,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,uEAAuE;AAEvE,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;IAC/B,MAAM,SAAS,GAAc;QAC3B,IAAI,EAAE,YAAY;QAClB,WAAW,EAAE,cAAc;QAC3B,QAAQ,EAAE,2BAA2B;QACrC,OAAO,EAAE,yBAAyB;KACnC,CAAC;IAEF,EAAE,CAAC,qDAAqD,EAAE,GAAG,EAAE;QAC7D,MAAM,SAAS,GAAG,eAAe,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;QAC/C,MAAM,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;QACtD,MAAM,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;QACxD,MAAM,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,SAAS,CAAC,oBAAoB,CAAC,CAAC;IAChE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sCAAsC,EAAE,GAAG,EAAE;QAC9C,MAAM,MAAM,GAAgB;YAC1B,SAAS;YACT,EAAE,IAAI,EAAE,aAAa,EAAE,WAAW,EAAE,aAAa,EAAE,QAAQ,EAAE,sBAAsB,EAAE,OAAO,EAAE,OAAO,EAAE;SACxG,CAAC;QACF,MAAM,SAAS,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC;QAC1C,MAAM,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;QACtD,MAAM,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;IACzD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oCAAoC,EAAE,KAAK,IAAI,EAAE;QAClD,MAAM,GAAG,GAAG,MAAM,UAAU,CAC1B,YAAY,EACZ;;;;;;;oBAOc,EACd,EAAE,QAAQ,EAAE,aAAa,EAAE,CAC5B,CAAC;QAEF,MAAM,KAAK,GAAc;YACvB,IAAI,EAAE,YAAY;YAClB,WAAW,EAAE,MAAM;YACnB,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,UAAU,CAAC;YACpC,OAAO,EAAE,uCAAuC;SACjD,CAAC;QAEF,MAAM,SAAS,GAAG,eAAe,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;QAC3C,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,OAAQ,CACrC,EAAE,IAAI,EAAE,YAAY,EAAE,EACtB,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,EAAE,WAAW,EAAE,SAAgB,EAAE,CACpE,CAAC;QAEF,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,qCAAqC,CAAC,CAAC;QAChE,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,qBAAqB,CAAC,CAAC;QAChD,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,qBAAqB,CAAC,CAAC;QAChD,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,kCAAkC,GAAG,EAAE,CAAC,CAAC;QAClE,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC;QAC1C,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC;QAC1C,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yDAAyD,EAAE,KAAK,IAAI,EAAE;QACvE,MAAM,GAAG,GAAG,MAAM,UAAU,CAC1B,YAAY,EACZ;;;;;aAKO,CACR,CAAC;QAEF,MAAM,KAAK,GAAc;YACvB,IAAI,EAAE,YAAY;YAClB,WAAW,EAAE,MAAM;YACnB,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,UAAU,CAAC;YACpC,OAAO,EAAE,cAAc;SACxB,CAAC;QAEF,MAAM,SAAS,GAAG,eAAe,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;QAC3C,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,OAAQ,CACrC,EAAE,IAAI,EAAE,YAAY,EAAE,EACtB,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,EAAE,WAAW,EAAE,SAAgB,EAAE,CACpE,CAAC;QAEF,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC;IAChD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+BAA+B,EAAE,KAAK,IAAI,EAAE;QAC7C,MAAM,SAAS,GAAG,eAAe,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;QAE/C,MAAM,MAAM,CACV,SAAS,CAAC,OAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,EAAE,WAAW,EAAE,SAAgB,EAAE,CAAC,CAC1G,CAAC,OAAO,CAAC,OAAO,CAAC,wBAAwB,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
package/dist/index.d.ts CHANGED
@@ -6,5 +6,6 @@ export { createSkillTool } from "./tools/skill.js";
6
6
  export { findInstructions, loadInstructions } from "./instructions.js";
7
7
  export { type OHDataTypes, type OHMetadata, type OHUIMessage, } from "./types/ui-message.js";
8
8
  export { type OHDataPart, type OHSubagentPart, type OHCompactionPart, type OHRetryPart, type OHSessionLifecyclePart, isOHDataPart, isSubagentEvent, isCompactionEvent, isRetryEvent, isSessionLifecycleEvent, formatSSE, formatTextDelta, formatReasoningDelta, formatDataPart, formatToolStart, formatToolResult, formatToolError, formatStepStart, formatStepFinish, formatFinishMessage, formatDone, } from "./types/stream-parts.js";
9
+ export { extractUserInput } from "./messages.js";
9
10
  export { sessionEventsToUIStream } from "./ui-stream.js";
10
11
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,KAAK,EACL,eAAe,EACf,KAAK,UAAU,EACf,KAAK,UAAU,EACf,KAAK,YAAY,EACjB,KAAK,SAAS,EACd,KAAK,eAAe,GACrB,MAAM,YAAY,CAAC;AAIpB,OAAO,EACL,iBAAiB,EACjB,eAAe,EACf,KAAK,eAAe,EACpB,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,KAAK,YAAY,GAClB,MAAM,UAAU,CAAC;AAIlB,OAAO,EACL,OAAO,EACP,yBAAyB,EACzB,KAAK,YAAY,EACjB,KAAK,qBAAqB,EAC1B,KAAK,cAAc,EACnB,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,KAAK,QAAQ,EACb,KAAK,YAAY,EACjB,KAAK,mBAAmB,GACzB,MAAM,cAAc,CAAC;AAItB,OAAO,EACL,cAAc,EACd,cAAc,EACd,KAAK,SAAS,EACd,KAAK,YAAY,GAClB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAInD,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAIvE,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,KAAK,WAAW,GACjB,MAAM,uBAAuB,CAAC;AAI/B,OAAO,EAEL,KAAK,UAAU,EACf,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,KAAK,WAAW,EAChB,KAAK,sBAAsB,EAG3B,YAAY,EACZ,eAAe,EACf,iBAAiB,EACjB,YAAY,EACZ,uBAAuB,EAGvB,SAAS,EACT,eAAe,EACf,oBAAoB,EACpB,cAAc,EACd,eAAe,EACf,gBAAgB,EAChB,eAAe,EACf,eAAe,EACf,gBAAgB,EAChB,mBAAmB,EACnB,UAAU,GACX,MAAM,yBAAyB,CAAC;AAIjC,OAAO,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,KAAK,EACL,eAAe,EACf,KAAK,UAAU,EACf,KAAK,UAAU,EACf,KAAK,YAAY,EACjB,KAAK,SAAS,EACd,KAAK,eAAe,GACrB,MAAM,YAAY,CAAC;AAIpB,OAAO,EACL,iBAAiB,EACjB,eAAe,EACf,KAAK,eAAe,EACpB,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,KAAK,YAAY,GAClB,MAAM,UAAU,CAAC;AAIlB,OAAO,EACL,OAAO,EACP,yBAAyB,EACzB,KAAK,YAAY,EACjB,KAAK,qBAAqB,EAC1B,KAAK,cAAc,EACnB,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,KAAK,QAAQ,EACb,KAAK,YAAY,EACjB,KAAK,mBAAmB,GACzB,MAAM,cAAc,CAAC;AAItB,OAAO,EACL,cAAc,EACd,cAAc,EACd,KAAK,SAAS,EACd,KAAK,YAAY,GAClB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAInD,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAIvE,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,KAAK,WAAW,GACjB,MAAM,uBAAuB,CAAC;AAI/B,OAAO,EAEL,KAAK,UAAU,EACf,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,KAAK,WAAW,EAChB,KAAK,sBAAsB,EAG3B,YAAY,EACZ,eAAe,EACf,iBAAiB,EACjB,YAAY,EACZ,uBAAuB,EAGvB,SAAS,EACT,eAAe,EACf,oBAAoB,EACpB,cAAc,EACd,eAAe,EACf,gBAAgB,EAChB,eAAe,EACf,eAAe,EACf,gBAAgB,EAChB,mBAAmB,EACnB,UAAU,GACX,MAAM,yBAAyB,CAAC;AAIjC,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAIjD,OAAO,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC"}
package/dist/index.js CHANGED
@@ -15,6 +15,8 @@ export {
15
15
  isOHDataPart, isSubagentEvent, isCompactionEvent, isRetryEvent, isSessionLifecycleEvent,
16
16
  // SSE formatters
17
17
  formatSSE, formatTextDelta, formatReasoningDelta, formatDataPart, formatToolStart, formatToolResult, formatToolError, formatStepStart, formatStepFinish, formatFinishMessage, formatDone, } from "./types/stream-parts.js";
18
+ // ── Message utilities ────────────────────────────────────────────────
19
+ export { extractUserInput } from "./messages.js";
18
20
  // ── UI Stream ───────────────────────────────────────────────────────
19
21
  export { sessionEventsToUIStream } from "./ui-stream.js";
20
22
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,wEAAwE;AAExE,OAAO,EACL,KAAK,EACL,eAAe,GAMhB,MAAM,YAAY,CAAC;AAEpB,uEAAuE;AAEvE,OAAO,EACL,iBAAiB,EACjB,eAAe,GAMhB,MAAM,UAAU,CAAC;AAElB,uEAAuE;AAEvE,OAAO,EACL,OAAO,EACP,yBAAyB,GAY1B,MAAM,cAAc,CAAC;AAEtB,uEAAuE;AAEvE,OAAO,EACL,cAAc,EACd,cAAc,GAGf,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAEnD,uEAAuE;AAEvE,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAUvE,uEAAuE;AAEvE,OAAO;AAQL,cAAc;AACd,YAAY,EACZ,eAAe,EACf,iBAAiB,EACjB,YAAY,EACZ,uBAAuB;AAEvB,iBAAiB;AACjB,SAAS,EACT,eAAe,EACf,oBAAoB,EACpB,cAAc,EACd,eAAe,EACf,gBAAgB,EAChB,eAAe,EACf,eAAe,EACf,gBAAgB,EAChB,mBAAmB,EACnB,UAAU,GACX,MAAM,yBAAyB,CAAC;AAEjC,uEAAuE;AAEvE,OAAO,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,wEAAwE;AAExE,OAAO,EACL,KAAK,EACL,eAAe,GAMhB,MAAM,YAAY,CAAC;AAEpB,uEAAuE;AAEvE,OAAO,EACL,iBAAiB,EACjB,eAAe,GAMhB,MAAM,UAAU,CAAC;AAElB,uEAAuE;AAEvE,OAAO,EACL,OAAO,EACP,yBAAyB,GAY1B,MAAM,cAAc,CAAC;AAEtB,uEAAuE;AAEvE,OAAO,EACL,cAAc,EACd,cAAc,GAGf,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAEnD,uEAAuE;AAEvE,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAUvE,uEAAuE;AAEvE,OAAO;AAQL,cAAc;AACd,YAAY,EACZ,eAAe,EACf,iBAAiB,EACjB,YAAY,EACZ,uBAAuB;AAEvB,iBAAiB;AACjB,SAAS,EACT,eAAe,EACf,oBAAoB,EACpB,cAAc,EACd,eAAe,EACf,gBAAgB,EAChB,eAAe,EACf,eAAe,EACf,gBAAgB,EAChB,mBAAmB,EACnB,UAAU,GACX,MAAM,yBAAyB,CAAC;AAEjC,wEAAwE;AAExE,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEjD,uEAAuE;AAEvE,OAAO,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,10 @@
1
+ import type { UIMessage, ModelMessage } from "ai";
2
+ /**
3
+ * Extract user input from an AI SDK 5 UIMessage array, ready to pass
4
+ * to `session.send()` or `session.toResponse()`.
5
+ *
6
+ * - Text-only → returns `string` (fast path, preserves existing behavior)
7
+ * - Has files → returns `ModelMessage[]` with properly decoded file data
8
+ */
9
+ export declare function extractUserInput(messages: UIMessage[]): Promise<string | ModelMessage[]>;
10
+ //# sourceMappingURL=messages.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../src/messages.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAElD;;;;;;GAMG;AACH,wBAAsB,gBAAgB,CACpC,QAAQ,EAAE,SAAS,EAAE,GACpB,OAAO,CAAC,MAAM,GAAG,YAAY,EAAE,CAAC,CA2ClC"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Extract user input from an AI SDK 5 UIMessage array, ready to pass
3
+ * to `session.send()` or `session.toResponse()`.
4
+ *
5
+ * - Text-only → returns `string` (fast path, preserves existing behavior)
6
+ * - Has files → returns `ModelMessage[]` with properly decoded file data
7
+ */
8
+ export async function extractUserInput(messages) {
9
+ if (messages.length === 0) {
10
+ throw new Error("extractUserInput: messages array is empty");
11
+ }
12
+ const lastMessage = messages[messages.length - 1];
13
+ if (lastMessage.role !== "user") {
14
+ throw new Error(`extractUserInput: last message has role "${lastMessage.role}", expected "user"`);
15
+ }
16
+ const hasFiles = lastMessage.parts.some((p) => p.type === "file");
17
+ if (!hasFiles) {
18
+ // Text-only fast path
19
+ return lastMessage.parts
20
+ .filter((p) => p.type === "text")
21
+ .map((p) => p.text)
22
+ .join("");
23
+ }
24
+ // Has files — build ModelMessage manually so data URLs are decoded to
25
+ // raw base64, which is what FilePart.data expects. convertToModelMessages
26
+ // passes data URLs through as-is, causing providers to attempt an HTTP
27
+ // download of the data: scheme which fails.
28
+ const content = [];
29
+ for (const part of lastMessage.parts) {
30
+ if (part.type === "text") {
31
+ content.push({ type: "text", text: part.text });
32
+ }
33
+ else if (part.type === "file") {
34
+ const filePart = part;
35
+ content.push({
36
+ type: "file",
37
+ data: stripDataUrlPrefix(filePart.url),
38
+ mediaType: filePart.mediaType,
39
+ ...(filePart.filename ? { filename: filePart.filename } : {}),
40
+ });
41
+ }
42
+ }
43
+ return [{ role: "user", content }];
44
+ }
45
+ /**
46
+ * Strip the `data:<mediaType>;base64,` prefix from a data URL,
47
+ * returning raw base64. Non-data URLs are returned as-is.
48
+ */
49
+ function stripDataUrlPrefix(url) {
50
+ const match = url.match(/^data:[^;]+;base64,(.*)$/);
51
+ return match ? match[1] : url;
52
+ }
53
+ //# sourceMappingURL=messages.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"messages.js","sourceRoot":"","sources":["../src/messages.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,QAAqB;IAErB,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;IAC/D,CAAC;IAED,MAAM,WAAW,GAAG,QAAQ,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAClD,IAAI,WAAW,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QAChC,MAAM,IAAI,KAAK,CACb,4CAA4C,WAAW,CAAC,IAAI,oBAAoB,CACjF,CAAC;IACJ,CAAC;IAED,MAAM,QAAQ,GAAG,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC;IAElE,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,sBAAsB;QACtB,OAAO,WAAW,CAAC,KAAK;aACrB,MAAM,CAAC,CAAC,CAAC,EAA4C,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC;aAC1E,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;aAClB,IAAI,CAAC,EAAE,CAAC,CAAC;IACd,CAAC;IAED,sEAAsE;IACtE,0EAA0E;IAC1E,uEAAuE;IACvE,4CAA4C;IAC5C,MAAM,OAAO,GAAiH,EAAE,CAAC;IAEjI,KAAK,MAAM,IAAI,IAAI,WAAW,CAAC,KAAK,EAAE,CAAC;QACrC,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YACzB,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QAClD,CAAC;aAAM,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YAChC,MAAM,QAAQ,GAAG,IAA2E,CAAC;YAC7F,OAAO,CAAC,IAAI,CAAC;gBACX,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE,kBAAkB,CAAC,QAAQ,CAAC,GAAG,CAAC;gBACtC,SAAS,EAAE,QAAQ,CAAC,SAAS;gBAC7B,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aAC9D,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAmB,CAAC;AACvD,CAAC;AAED;;;GAGG;AACH,SAAS,kBAAkB,CAAC,GAAW;IACrC,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAC;IACpD,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;AAChC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openharness/core",
3
- "version": "0.3.2",
3
+ "version": "0.4.0",
4
4
  "type": "module",
5
5
  "description": "Building blocks for capable, general-purpose agents",
6
6
  "exports": {