@roackb2/heddle 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.
Files changed (65) hide show
  1. package/README.md +61 -54
  2. package/dist/src/__tests__/file-mentions.test.d.ts +2 -0
  3. package/dist/src/__tests__/file-mentions.test.d.ts.map +1 -0
  4. package/dist/src/__tests__/file-mentions.test.js +29 -0
  5. package/dist/src/__tests__/file-mentions.test.js.map +1 -0
  6. package/dist/src/__tests__/local-commands.test.js +27 -1
  7. package/dist/src/__tests__/local-commands.test.js.map +1 -1
  8. package/dist/src/__tests__/prompt-input.test.d.ts +2 -0
  9. package/dist/src/__tests__/prompt-input.test.d.ts.map +1 -0
  10. package/dist/src/__tests__/prompt-input.test.js +10 -0
  11. package/dist/src/__tests__/prompt-input.test.js.map +1 -0
  12. package/dist/src/__tests__/tools.test.js +64 -1
  13. package/dist/src/__tests__/tools.test.js.map +1 -1
  14. package/dist/src/cli/ask.d.ts.map +1 -1
  15. package/dist/src/cli/ask.js +13 -1
  16. package/dist/src/cli/ask.js.map +1 -1
  17. package/dist/src/cli/chat/App.d.ts.map +1 -1
  18. package/dist/src/cli/chat/App.js +62 -4
  19. package/dist/src/cli/chat/App.js.map +1 -1
  20. package/dist/src/cli/chat/components/FileMentionPickerPanel.d.ts +6 -0
  21. package/dist/src/cli/chat/components/FileMentionPickerPanel.d.ts.map +1 -0
  22. package/dist/src/cli/chat/components/FileMentionPickerPanel.js +30 -0
  23. package/dist/src/cli/chat/components/FileMentionPickerPanel.js.map +1 -0
  24. package/dist/src/cli/chat/components/PromptInput.d.ts +3 -1
  25. package/dist/src/cli/chat/components/PromptInput.d.ts.map +1 -1
  26. package/dist/src/cli/chat/components/PromptInput.js +41 -17
  27. package/dist/src/cli/chat/components/PromptInput.js.map +1 -1
  28. package/dist/src/cli/chat/components/SlashHintPanel.d.ts.map +1 -1
  29. package/dist/src/cli/chat/components/SlashHintPanel.js +2 -1
  30. package/dist/src/cli/chat/components/SlashHintPanel.js.map +1 -1
  31. package/dist/src/cli/chat/components/index.d.ts +1 -0
  32. package/dist/src/cli/chat/components/index.d.ts.map +1 -1
  33. package/dist/src/cli/chat/components/index.js +1 -0
  34. package/dist/src/cli/chat/components/index.js.map +1 -1
  35. package/dist/src/cli/chat/hooks/useAgentRun.d.ts.map +1 -1
  36. package/dist/src/cli/chat/hooks/useAgentRun.js +23 -11
  37. package/dist/src/cli/chat/hooks/useAgentRun.js.map +1 -1
  38. package/dist/src/cli/chat/state/local-commands.d.ts +1 -0
  39. package/dist/src/cli/chat/state/local-commands.d.ts.map +1 -1
  40. package/dist/src/cli/chat/state/local-commands.js +22 -1
  41. package/dist/src/cli/chat/state/local-commands.js.map +1 -1
  42. package/dist/src/cli/chat/submit.d.ts +4 -0
  43. package/dist/src/cli/chat/submit.d.ts.map +1 -1
  44. package/dist/src/cli/chat/submit.js +2 -1
  45. package/dist/src/cli/chat/submit.js.map +1 -1
  46. package/dist/src/cli/chat/utils/file-mentions.d.ts +14 -0
  47. package/dist/src/cli/chat/utils/file-mentions.d.ts.map +1 -0
  48. package/dist/src/cli/chat/utils/file-mentions.js +136 -0
  49. package/dist/src/cli/chat/utils/file-mentions.js.map +1 -0
  50. package/dist/src/index.d.ts +4 -0
  51. package/dist/src/index.d.ts.map +1 -1
  52. package/dist/src/index.js +2 -0
  53. package/dist/src/index.js.map +1 -1
  54. package/dist/src/prompts/system-prompt.d.ts.map +1 -1
  55. package/dist/src/prompts/system-prompt.js +2 -0
  56. package/dist/src/prompts/system-prompt.js.map +1 -1
  57. package/dist/src/tools/view-image.d.ts +10 -0
  58. package/dist/src/tools/view-image.d.ts.map +1 -0
  59. package/dist/src/tools/view-image.js +200 -0
  60. package/dist/src/tools/view-image.js.map +1 -0
  61. package/dist/src/tools/web-search.d.ts +10 -0
  62. package/dist/src/tools/web-search.d.ts.map +1 -0
  63. package/dist/src/tools/web-search.js +205 -0
  64. package/dist/src/tools/web-search.js.map +1 -0
  65. package/package.json +28 -6
@@ -0,0 +1,200 @@
1
+ // ---------------------------------------------------------------------------
2
+ // Tool: view_image
3
+ // Host-side image viewing MVP backed by the active model provider.
4
+ // ---------------------------------------------------------------------------
5
+ import { readFile } from 'node:fs/promises';
6
+ import { extname, resolve } from 'node:path';
7
+ import Anthropic from '@anthropic-ai/sdk';
8
+ import OpenAI from 'openai';
9
+ import { inferProviderFromModel } from '../llm/factory.js';
10
+ import { DEFAULT_ANTHROPIC_MODEL, DEFAULT_OPENAI_MODEL } from '../config.js';
11
+ const DEFAULT_IMAGE_PROMPT = 'Describe the image for a coding assistant. Focus on UI text, error messages, filenames, commands, code, diagrams, and any details relevant to software work.';
12
+ export const viewImageTool = createViewImageTool();
13
+ export function createViewImageTool(options = {}) {
14
+ return {
15
+ name: 'view_image',
16
+ description: 'Inspect a local image file when the user references a screenshot, diagram, or other visual file path and the image contents are actually needed. Use this only after the user has provided or implied a concrete image path. Input example: { "path": "/absolute/path/to/screenshot.png" }. Optional field: prompt for a more specific visual question. Returns a concise text description of the image contents.',
17
+ parameters: {
18
+ type: 'object',
19
+ additionalProperties: false,
20
+ properties: {
21
+ path: {
22
+ type: 'string',
23
+ description: 'Path to the local image file.',
24
+ },
25
+ prompt: {
26
+ type: 'string',
27
+ description: 'Optional focused instruction for what to extract from the image.',
28
+ },
29
+ },
30
+ required: ['path'],
31
+ },
32
+ async execute(raw) {
33
+ if (!isViewImageInput(raw)) {
34
+ return {
35
+ ok: false,
36
+ error: 'Invalid input for view_image. Required field: path. Optional field: prompt.',
37
+ };
38
+ }
39
+ const input = raw;
40
+ const filePath = resolve(input.path);
41
+ const mediaType = detectMediaType(filePath);
42
+ if (!mediaType) {
43
+ return {
44
+ ok: false,
45
+ error: 'view_image supports .png, .jpg, .jpeg, .gif, and .webp files.',
46
+ };
47
+ }
48
+ const provider = options.provider ?? inferProviderFromModel(options.model ?? DEFAULT_OPENAI_MODEL);
49
+ const prompt = input.prompt?.trim() || DEFAULT_IMAGE_PROMPT;
50
+ try {
51
+ const data = await readFile(filePath);
52
+ switch (provider) {
53
+ case 'openai':
54
+ return await executeOpenAiImageView({ filePath, mediaType, data, prompt, options });
55
+ case 'anthropic':
56
+ return await executeAnthropicImageView({ filePath, mediaType, data, prompt, options });
57
+ case 'google':
58
+ return {
59
+ ok: false,
60
+ error: 'view_image is not wired for Google models yet.',
61
+ };
62
+ }
63
+ }
64
+ catch (error) {
65
+ return {
66
+ ok: false,
67
+ error: `Image view failed: ${error instanceof Error ? error.message : String(error)}`,
68
+ };
69
+ }
70
+ },
71
+ };
72
+ }
73
+ async function executeOpenAiImageView(args) {
74
+ const apiKey = firstDefinedNonEmpty(args.options.apiKey, process.env.OPENAI_API_KEY, process.env.PERSONAL_OPENAI_API_KEY);
75
+ if (!apiKey) {
76
+ return {
77
+ ok: false,
78
+ error: 'view_image requires OPENAI_API_KEY (or PERSONAL_OPENAI_API_KEY) when the active model provider is OpenAI.',
79
+ };
80
+ }
81
+ const client = new OpenAI({ apiKey });
82
+ const model = args.options.model ?? DEFAULT_OPENAI_MODEL;
83
+ const imageBase64 = args.data.toString('base64');
84
+ const response = await client.responses.create({
85
+ model,
86
+ input: [{
87
+ role: 'user',
88
+ content: [
89
+ { type: 'input_text', text: args.prompt },
90
+ {
91
+ type: 'input_image',
92
+ detail: 'auto',
93
+ image_url: `data:${args.mediaType};base64,${imageBase64}`,
94
+ },
95
+ ],
96
+ }],
97
+ });
98
+ return {
99
+ ok: true,
100
+ output: {
101
+ provider: 'openai',
102
+ model: response.model,
103
+ path: args.filePath,
104
+ summary: response.output_text?.trim() || 'No image description returned.',
105
+ },
106
+ };
107
+ }
108
+ async function executeAnthropicImageView(args) {
109
+ const apiKey = firstDefinedNonEmpty(args.options.apiKey, process.env.ANTHROPIC_API_KEY, process.env.PERSONAL_ANTHROPIC_API_KEY);
110
+ if (!apiKey) {
111
+ return {
112
+ ok: false,
113
+ error: 'view_image requires ANTHROPIC_API_KEY (or PERSONAL_ANTHROPIC_API_KEY) when the active model provider is Anthropic.',
114
+ };
115
+ }
116
+ const anthropicMediaType = toAnthropicMediaType(args.mediaType);
117
+ if (!anthropicMediaType) {
118
+ return {
119
+ ok: false,
120
+ error: 'Anthropic image viewing supports jpeg, png, gif, and webp.',
121
+ };
122
+ }
123
+ const client = new Anthropic({ apiKey });
124
+ const model = args.options.model ?? DEFAULT_ANTHROPIC_MODEL;
125
+ const response = await client.messages.create({
126
+ model,
127
+ max_tokens: 1024,
128
+ messages: [{
129
+ role: 'user',
130
+ content: [
131
+ {
132
+ type: 'image',
133
+ source: {
134
+ type: 'base64',
135
+ media_type: anthropicMediaType,
136
+ data: args.data.toString('base64'),
137
+ },
138
+ },
139
+ {
140
+ type: 'text',
141
+ text: args.prompt,
142
+ },
143
+ ],
144
+ }],
145
+ });
146
+ return {
147
+ ok: true,
148
+ output: {
149
+ provider: 'anthropic',
150
+ model: response.model,
151
+ path: args.filePath,
152
+ summary: response.content
153
+ .flatMap((block) => (block.type === 'text' ? [block.text] : []))
154
+ .join('\n')
155
+ .trim() || 'No image description returned.',
156
+ },
157
+ };
158
+ }
159
+ function isViewImageInput(raw) {
160
+ if (!raw || typeof raw !== 'object' || Array.isArray(raw)) {
161
+ return false;
162
+ }
163
+ const input = raw;
164
+ const keys = Object.keys(input);
165
+ if (keys.some((key) => key !== 'path' && key !== 'prompt')) {
166
+ return false;
167
+ }
168
+ if (typeof input.path !== 'string' || input.path.trim().length === 0) {
169
+ return false;
170
+ }
171
+ return input.prompt === undefined || typeof input.prompt === 'string';
172
+ }
173
+ function detectMediaType(filePath) {
174
+ switch (extname(filePath).toLowerCase()) {
175
+ case '.png':
176
+ return 'image/png';
177
+ case '.jpg':
178
+ case '.jpeg':
179
+ return 'image/jpeg';
180
+ case '.gif':
181
+ return 'image/gif';
182
+ case '.webp':
183
+ return 'image/webp';
184
+ default:
185
+ return undefined;
186
+ }
187
+ }
188
+ function toAnthropicMediaType(mediaType) {
189
+ if (mediaType === 'image/jpeg'
190
+ || mediaType === 'image/png'
191
+ || mediaType === 'image/gif'
192
+ || mediaType === 'image/webp') {
193
+ return mediaType;
194
+ }
195
+ return undefined;
196
+ }
197
+ function firstDefinedNonEmpty(...values) {
198
+ return values.find((value) => typeof value === 'string' && value.trim().length > 0);
199
+ }
200
+ //# sourceMappingURL=view-image.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"view-image.js","sourceRoot":"","sources":["../../../src/tools/view-image.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import type { ToolDefinition } from '../types.js';
2
+ import type { LlmProvider } from '../llm/types.js';
3
+ export type WebSearchToolOptions = {
4
+ model?: string;
5
+ provider?: LlmProvider;
6
+ apiKey?: string;
7
+ };
8
+ export declare const webSearchTool: ToolDefinition;
9
+ export declare function createWebSearchTool(options?: WebSearchToolOptions): ToolDefinition;
10
+ //# sourceMappingURL=web-search.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"web-search.d.ts","sourceRoot":"","sources":["../../../src/tools/web-search.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,cAAc,EAAc,MAAM,aAAa,CAAC;AAE9D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAQnD,MAAM,MAAM,oBAAoB,GAAG;IACjC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,WAAW,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,cAAsC,CAAC;AAEnE,wBAAgB,mBAAmB,CAAC,OAAO,GAAE,oBAAyB,GAAG,cAAc,CAoDtF"}
@@ -0,0 +1,205 @@
1
+ // ---------------------------------------------------------------------------
2
+ // Tool: web_search
3
+ // Host-side web search MVP backed by the active model provider.
4
+ // ---------------------------------------------------------------------------
5
+ import Anthropic from '@anthropic-ai/sdk';
6
+ import OpenAI from 'openai';
7
+ import { inferProviderFromModel } from '../llm/factory.js';
8
+ import { DEFAULT_ANTHROPIC_MODEL, DEFAULT_OPENAI_MODEL } from '../config.js';
9
+ export const webSearchTool = createWebSearchTool();
10
+ export function createWebSearchTool(options = {}) {
11
+ return {
12
+ name: 'web_search',
13
+ description: 'Search the public web when repository files, docs, and local tools are not enough to answer the user. This MVP tool is backed by the active model provider\'s hosted web search when available. Use it for current external facts, official product docs outside the repo, news, releases, APIs, or references that are not available locally. Do not use it for questions the workspace can already answer. Input example: { "query": "OpenAI Responses API web search tool" }. Optional field: contextSize ("low", "medium", or "high"). Returns a concise summary plus cited source URLs when available.',
14
+ parameters: {
15
+ type: 'object',
16
+ additionalProperties: false,
17
+ properties: {
18
+ query: {
19
+ type: 'string',
20
+ description: 'The web search query.',
21
+ },
22
+ contextSize: {
23
+ type: 'string',
24
+ enum: ['low', 'medium', 'high'],
25
+ description: 'How much search context to request from the hosted search tool. Defaults to "medium".',
26
+ },
27
+ },
28
+ required: ['query'],
29
+ },
30
+ async execute(raw) {
31
+ if (!isWebSearchInput(raw)) {
32
+ return {
33
+ ok: false,
34
+ error: 'Invalid input for web_search. Required field: query. Optional field: contextSize ("low", "medium", or "high").',
35
+ };
36
+ }
37
+ const input = raw;
38
+ const provider = options.provider ?? inferProviderFromModel(options.model ?? DEFAULT_OPENAI_MODEL);
39
+ try {
40
+ switch (provider) {
41
+ case 'openai':
42
+ return await executeOpenAiWebSearch(input, options);
43
+ case 'anthropic':
44
+ return await executeAnthropicWebSearch(input, options);
45
+ case 'google':
46
+ return {
47
+ ok: false,
48
+ error: 'web_search is not wired for Google models yet.',
49
+ };
50
+ }
51
+ }
52
+ catch (error) {
53
+ return {
54
+ ok: false,
55
+ error: `Web search failed: ${error instanceof Error ? error.message : String(error)}`,
56
+ };
57
+ }
58
+ },
59
+ };
60
+ }
61
+ async function executeOpenAiWebSearch(input, options) {
62
+ const apiKey = firstDefinedNonEmpty(options.apiKey, process.env.OPENAI_API_KEY, process.env.PERSONAL_OPENAI_API_KEY);
63
+ if (!apiKey) {
64
+ return {
65
+ ok: false,
66
+ error: 'web_search requires OPENAI_API_KEY (or PERSONAL_OPENAI_API_KEY) when the active model provider is OpenAI.',
67
+ };
68
+ }
69
+ const client = new OpenAI({ apiKey });
70
+ const model = options.model ?? process.env.OPENAI_WEB_SEARCH_MODEL ?? DEFAULT_OPENAI_MODEL;
71
+ const response = await client.responses.create({
72
+ model,
73
+ input: input.query,
74
+ tools: [{
75
+ type: 'web_search_preview',
76
+ search_context_size: input.contextSize ?? 'medium',
77
+ }],
78
+ });
79
+ return {
80
+ ok: true,
81
+ output: formatOpenAiWebSearchResult(response),
82
+ };
83
+ }
84
+ async function executeAnthropicWebSearch(input, options) {
85
+ const apiKey = firstDefinedNonEmpty(options.apiKey, process.env.ANTHROPIC_API_KEY, process.env.PERSONAL_ANTHROPIC_API_KEY);
86
+ if (!apiKey) {
87
+ return {
88
+ ok: false,
89
+ error: 'web_search requires ANTHROPIC_API_KEY (or PERSONAL_ANTHROPIC_API_KEY) when the active model provider is Anthropic.',
90
+ };
91
+ }
92
+ const client = new Anthropic({ apiKey });
93
+ const model = options.model ?? process.env.ANTHROPIC_WEB_SEARCH_MODEL ?? DEFAULT_ANTHROPIC_MODEL;
94
+ const toolChoice = { type: 'tool', name: 'web_search' };
95
+ const response = await client.messages.create({
96
+ model,
97
+ max_tokens: 1024,
98
+ tool_choice: toolChoice,
99
+ tools: [{
100
+ name: 'web_search',
101
+ type: 'web_search_20250305',
102
+ max_uses: 1,
103
+ }],
104
+ messages: [{
105
+ role: 'user',
106
+ content: `Search the web for the following query and answer concisely with citations when available:\n\n${input.query}`,
107
+ }],
108
+ });
109
+ return {
110
+ ok: true,
111
+ output: formatAnthropicWebSearchResult(response),
112
+ };
113
+ }
114
+ function firstDefinedNonEmpty(...values) {
115
+ return values.find((value) => typeof value === 'string' && value.trim().length > 0);
116
+ }
117
+ function isWebSearchInput(raw) {
118
+ if (!raw || typeof raw !== 'object' || Array.isArray(raw)) {
119
+ return false;
120
+ }
121
+ const input = raw;
122
+ const keys = Object.keys(input);
123
+ if (keys.some((key) => key !== 'query' && key !== 'contextSize')) {
124
+ return false;
125
+ }
126
+ if (typeof input.query !== 'string' || input.query.trim().length === 0) {
127
+ return false;
128
+ }
129
+ return input.contextSize === undefined || input.contextSize === 'low' || input.contextSize === 'medium' || input.contextSize === 'high';
130
+ }
131
+ function formatOpenAiWebSearchResult(response) {
132
+ const summary = response.output_text?.trim() || 'No summary returned.';
133
+ const citations = extractOpenAiUrlCitations(response);
134
+ return {
135
+ provider: 'openai',
136
+ model: response.model,
137
+ summary,
138
+ citations,
139
+ };
140
+ }
141
+ function extractOpenAiUrlCitations(response) {
142
+ const outputItems = response.output ?? [];
143
+ const citations = [];
144
+ const seen = new Set();
145
+ for (const item of outputItems) {
146
+ if (item.type !== 'message') {
147
+ continue;
148
+ }
149
+ for (const content of item.content ?? []) {
150
+ if (content.type !== 'output_text') {
151
+ continue;
152
+ }
153
+ for (const annotation of content.annotations ?? []) {
154
+ if (annotation.type !== 'url_citation') {
155
+ continue;
156
+ }
157
+ const key = `${annotation.title}|${annotation.url}`;
158
+ if (seen.has(key)) {
159
+ continue;
160
+ }
161
+ seen.add(key);
162
+ citations.push({
163
+ title: annotation.title,
164
+ url: annotation.url,
165
+ });
166
+ }
167
+ }
168
+ }
169
+ return citations;
170
+ }
171
+ function formatAnthropicWebSearchResult(response) {
172
+ const textBlocks = response.content.filter((block) => block.type === 'text');
173
+ const summary = textBlocks.map((block) => block.text).join('\n').trim() || 'No summary returned.';
174
+ const citations = extractAnthropicUrlCitations(textBlocks.flatMap((block) => block.citations ?? []));
175
+ return {
176
+ provider: 'anthropic',
177
+ model: response.model,
178
+ summary,
179
+ citations,
180
+ };
181
+ }
182
+ function extractAnthropicUrlCitations(citationsInput) {
183
+ const citations = [];
184
+ const seen = new Set();
185
+ for (const citation of citationsInput) {
186
+ if (citation.type !== 'web_search_result_location') {
187
+ continue;
188
+ }
189
+ if (!citation.url) {
190
+ continue;
191
+ }
192
+ const title = citation.title ?? citation.url;
193
+ const key = `${title}|${citation.url}`;
194
+ if (seen.has(key)) {
195
+ continue;
196
+ }
197
+ seen.add(key);
198
+ citations.push({
199
+ title,
200
+ url: citation.url,
201
+ });
202
+ }
203
+ return citations;
204
+ }
205
+ //# sourceMappingURL=web-search.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"web-search.js","sourceRoot":"","sources":["../../../src/tools/web-search.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,11 +1,24 @@
1
1
  {
2
2
  "name": "@roackb2/heddle",
3
- "version": "0.0.2",
4
- "description": "A minimal TypeScript runtime for tool-using agents",
3
+ "version": "0.0.4",
4
+ "description": "An open-source terminal coding agent runtime and CLI with OpenAI and Anthropic support",
5
+ "author": "Jay / Fienna Liang <roackb2@gmail.com>",
6
+ "license": "MIT",
5
7
  "type": "module",
6
8
  "publishConfig": {
7
9
  "access": "public"
8
10
  },
11
+ "repository": {
12
+ "type": "git",
13
+ "url": "git+https://github.com/roackb2/heddle.git"
14
+ },
15
+ "homepage": "https://github.com/roackb2/heddle#readme",
16
+ "bugs": {
17
+ "url": "https://github.com/roackb2/heddle/issues"
18
+ },
19
+ "engines": {
20
+ "node": ">=20"
21
+ },
9
22
  "bin": {
10
23
  "heddle": "dist/src/cli/main.js"
11
24
  },
@@ -31,12 +44,21 @@
31
44
  },
32
45
  "keywords": [
33
46
  "agent",
47
+ "coding-agent",
48
+ "terminal-agent",
49
+ "cli-agent",
50
+ "ai-cli",
51
+ "developer-tools",
52
+ "workspace-agent",
53
+ "repository-tools",
34
54
  "llm",
35
- "tools",
36
- "runtime",
37
- "trace"
55
+ "open-source",
56
+ "provider-agnostic",
57
+ "openai",
58
+ "anthropic",
59
+ "trace",
60
+ "chat"
38
61
  ],
39
- "license": "MIT",
40
62
  "dependencies": {
41
63
  "@anthropic-ai/sdk": "^0.54.0",
42
64
  "@inkjs/ui": "^2.0.0",