@ank1015/llm-agents 0.0.2 → 0.0.3

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/CHANGELOG.md CHANGED
@@ -4,6 +4,12 @@ All notable changes to this package will be documented in this file.
4
4
 
5
5
  ## Unreleased
6
6
 
7
+ ## 0.0.3 - 2026-03-15
8
+
9
+ - added a local CLI agent runner backed by `Conversation`, the file keys adapter, and an in-memory session manager
10
+ - added section override support in `createSystemPrompt()` and used it for the CLI's directory-only prompt
11
+ - expanded the `ai-images` skill with model-selection guidance and a new `choose-model.md` reference
12
+
7
13
  ## 0.0.2 - 2026-03-15
8
14
 
9
15
  - aligned the package around general-purpose tools, skill runtime, and helper-backed skill APIs
package/README.md CHANGED
@@ -8,6 +8,7 @@ This package is the home of:
8
8
  - system-prompt construction for the monorepo's general-purpose agent
9
9
  - bundled skill packaging and installation
10
10
  - helper-backed skill APIs such as AI image generation/editing
11
+ - a local CLI runner for directory-scoped agent sessions
11
12
 
12
13
  ## What It Exports
13
14
 
@@ -61,7 +62,7 @@ The current bundled skill is:
61
62
 
62
63
  - `ai-images`
63
64
  - overview: [skills/ai-images/SKILL.md](/Users/notacoder/Desktop/agents/llm/packages/agents/skills/ai-images/SKILL.md)
64
- - task-specific references for image creation and image editing
65
+ - task-specific references for model choice, image creation, and image editing
65
66
 
66
67
  ## Helper-Backed Temp Workspace
67
68
 
@@ -97,9 +98,25 @@ These helpers:
97
98
 
98
99
  See the skill docs for the task-specific API guidance:
99
100
 
101
+ - [choose-model.md](/Users/notacoder/Desktop/agents/llm/packages/agents/skills/ai-images/references/choose-model.md)
100
102
  - [create.md](/Users/notacoder/Desktop/agents/llm/packages/agents/skills/ai-images/references/create.md)
101
103
  - [edit.md](/Users/notacoder/Desktop/agents/llm/packages/agents/skills/ai-images/references/edit.md)
102
104
 
105
+ ## Local CLI
106
+
107
+ For local testing and temporary directory-scoped sessions, run:
108
+
109
+ ```bash
110
+ pnpm --filter @ank1015/llm-agents agent:cli
111
+ ```
112
+
113
+ The CLI:
114
+
115
+ - asks which directory Max should work in
116
+ - installs the `ai-images` skill into that directory's `.max/skills/`
117
+ - uses the file keys adapter for credentials
118
+ - uses `codex` / `gpt-5.4` with the package's general-purpose tools
119
+
103
120
  ## Docs
104
121
 
105
122
  - [docs/vision.md](/Users/notacoder/Desktop/agents/llm/packages/agents/docs/vision.md)
@@ -109,6 +126,7 @@ See the skill docs for the task-specific API guidance:
109
126
  ## Commands
110
127
 
111
128
  - `pnpm build`
129
+ - `pnpm agent:cli`
112
130
  - `pnpm test`
113
131
  - `pnpm test:unit`
114
132
  - `pnpm test:integration`
@@ -363,7 +363,7 @@ function normalizeObjectRecord(value) {
363
363
  async function readCurrentPackageVersion() {
364
364
  const packageJsonPath = join(packageRoot, 'package.json');
365
365
  const parsed = JSON.parse(await readFile(packageJsonPath, 'utf-8'));
366
- return parsed.version ?? '0.0.2';
366
+ return parsed.version ?? '0.0.3';
367
367
  }
368
368
  async function readCurrentTsxVersion() {
369
369
  const packageJsonPath = join(packageRoot, 'package.json');
@@ -1,7 +1,16 @@
1
- export declare function createSystemPrompt({ projectName, projectDir, artifactName, artifactDir, }: {
1
+ export interface CreateSystemPromptOptions {
2
2
  projectName: string;
3
3
  projectDir: string;
4
4
  artifactName: string;
5
5
  artifactDir: string;
6
- }): Promise<string>;
6
+ identity?: string;
7
+ tools?: string;
8
+ tools_guidelines?: string;
9
+ skills?: string;
10
+ project_information?: string;
11
+ working_dir?: string;
12
+ agent_state?: string;
13
+ current_date?: string;
14
+ }
15
+ export declare function createSystemPrompt({ projectName, projectDir, artifactName, artifactDir, identity, tools, tools_guidelines, skills, project_information, working_dir, agent_state, current_date, }: CreateSystemPromptOptions): Promise<string>;
7
16
  //# sourceMappingURL=system-prompt.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"system-prompt.d.ts","sourceRoot":"","sources":["../../src/agents/system-prompt.ts"],"names":[],"mappings":"AAIA,wBAAsB,kBAAkB,CAAC,EACvC,WAAW,EACX,UAAU,EACV,YAAY,EACZ,WAAW,GACZ,EAAE;IACD,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;CACrB,GAAG,OAAO,CAAC,MAAM,CAAC,CA6FlB"}
1
+ {"version":3,"file":"system-prompt.d.ts","sourceRoot":"","sources":["../../src/agents/system-prompt.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,yBAAyB;IACxC,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAQD,wBAAsB,kBAAkB,CAAC,EACvC,WAAW,EACX,UAAU,EACV,YAAY,EACZ,WAAW,EACX,QAAQ,EACR,KAAK,EACL,gBAAgB,EAChB,MAAM,EACN,mBAAmB,EACnB,WAAW,EACX,WAAW,EACX,YAAY,GACb,EAAE,yBAAyB,GAAG,OAAO,CAAC,MAAM,CAAC,CAiH7C"}
@@ -1,6 +1,11 @@
1
1
  import { join } from 'node:path';
2
2
  import { listInstalledSkills } from './skills/index.js';
3
- export async function createSystemPrompt({ projectName, projectDir, artifactName, artifactDir, }) {
3
+ function renderSection(name, content) {
4
+ return `<${name}>
5
+ ${content}
6
+ </${name}>`;
7
+ }
8
+ export async function createSystemPrompt({ projectName, projectDir, artifactName, artifactDir, identity, tools, tools_guidelines, skills, project_information, working_dir, agent_state, current_date, }) {
4
9
  const now = new Date();
5
10
  const artifactMaxDir = join(artifactDir, '.max');
6
11
  const artifactSkillsDir = join(artifactMaxDir, 'skills');
@@ -12,20 +17,18 @@ export async function createSystemPrompt({ projectName, projectDir, artifactName
12
17
  day: 'numeric',
13
18
  });
14
19
  const availableSkills = await formatInstalledSkills(artifactDir);
15
- const prompt = `You are Max. Max is an intelligent assistant. Max is an expert generalist and helps the user with all sorts of tasks. Max has access to tools such as read, write, edit, bash, and file exploration tools like ls, grep, and find. Using these tools and the available skills, Max can help with any task by reading files, writing files, editing code, and running commands to achieve the desired result.
16
-
17
- <tools>
18
- - read: Read file contents
20
+ const identitySection = identity ??
21
+ 'You are Max. Max is an intelligent assistant. Max is an expert generalist and helps the user with all sorts of tasks. Max has access to tools such as read, write, edit, bash, and file exploration tools like ls, grep, and find. Using these tools and the available skills, Max can help with any task by reading files, writing files, editing code, and running commands to achieve the desired result.';
22
+ const toolsSection = tools ??
23
+ `- read: Read file contents
19
24
  - bash: Execute bash commands
20
25
  - edit: Make precise edits to files by replacing exact text
21
26
  - write: Create or overwrite files
22
27
  - grep: Search file contents for patterns (respects .gitignore)
23
28
  - find: Find files by glob pattern (respects .gitignore)
24
- - ls: List directory contents
25
- </tools>
26
-
27
- <tools_guidelines>
28
- - Prefer grep, find, and ls over bash for file exploration because they are faster and respect .gitignore.
29
+ - ls: List directory contents`;
30
+ const toolsGuidelinesSection = tools_guidelines ??
31
+ `- Prefer grep, find, and ls over bash for file exploration because they are faster and respect .gitignore.
29
32
  - Use read to inspect files before editing them. Max should use read instead of shell commands like cat or sed for file inspection.
30
33
  - Use edit for precise changes when the existing text is known.
31
34
  - Use write only for creating new files or completely rewriting a file.
@@ -33,11 +36,9 @@ export async function createSystemPrompt({ projectName, projectDir, artifactName
33
36
  - When helpful, Max should verify changes by reading the updated file or running an appropriate command.
34
37
  - When summarizing actions, Max should respond in plain text and should not use bash to print the summary.
35
38
  - Max should be concise in responses.
36
- - Max should show file paths clearly when working with files.
37
- </tools_guidelines>
38
-
39
- <skills>
40
- - Max is a generalist and can help with any kind of task. Skills help Max perform specialized tasks in the way the user expects.
39
+ - Max should show file paths clearly when working with files.`;
40
+ const skillsSection = skills ??
41
+ `- Max is a generalist and can help with any kind of task. Skills help Max perform specialized tasks in the way the user expects.
41
42
  - A skill is an artifact-local folder containing a SKILL.md plus optional scripts, references, or assets.
42
43
  - Only the skills listed below are available for this artifact.
43
44
  - The user may explicitly mention a skill during a conversation, or Max may decide to load a relevant skill from the available skills list.
@@ -51,18 +52,14 @@ export async function createSystemPrompt({ projectName, projectDir, artifactName
51
52
  - If a relevant skill applies, Max should trust it and follow it closely unless it conflicts with the user's explicit instructions or the available tools.
52
53
  <available_skills>
53
54
  ${availableSkills}
54
- </available_skills>
55
- </skills>
56
-
57
- <project_information>
58
- - The user is currently working in the Project named: ${projectName} and the Artifact named: ${artifactName}.
55
+ </available_skills>`;
56
+ const projectInformationSection = project_information ??
57
+ `- The user is currently working in the Project named: ${projectName} and the Artifact named: ${artifactName}.
59
58
  - A Project is a top-level folder that contains related Artifacts.
60
59
  - An Artifact is a folder inside the Project that contains files related to one part of the overall work.
61
- - The current Artifact is the default place where Max should do its work unless the user says otherwise.
62
- </project_information>
63
-
64
- <working_dir>
65
- Max is currently working in the following project:
60
+ - The current Artifact is the default place where Max should do its work unless the user says otherwise.`;
61
+ const workingDirSection = working_dir ??
62
+ `Max is currently working in the following project:
66
63
  - project name: ${projectName}
67
64
  - project dir: ${projectDir}
68
65
 
@@ -72,10 +69,9 @@ and the following artifact:
72
69
 
73
70
  - The tools are initialized in the current artifact directory, and Max should treat this artifact as the default working area.
74
71
  - If the user mentions files or directories from other artifacts, Max should explicitly read them.
75
- - Max must not modify files in other artifacts unless the user explicitly asks for changes there.
76
-
77
- <agent_state>
78
- - Artifact-local agent state lives under: ${artifactMaxDir}
72
+ - Max must not modify files in other artifacts unless the user explicitly asks for changes there.`;
73
+ const agentStateSection = agent_state ??
74
+ `- Artifact-local agent state lives under: ${artifactMaxDir}
79
75
  - Installed artifact skills live under: ${artifactSkillsDir}
80
76
  - Max may use ${artifactTempDir} as a writable scratchpad for temporary files, helper projects, scripts, installs, previews, logs, JSON summaries, unpacked folders, and other ephemeral outputs.
81
77
  - ${artifactTempDir} may already be initialized as a lightweight TypeScript workspace for helper-backed skills, including a \`package.json\`, \`tsconfig.json\`, and \`scripts/\` folder.
@@ -84,10 +80,24 @@ and the following artifact:
84
80
  - If the user wants code or scripts to live in the artifact project itself, Max may write them in ${artifactDir} instead and import helper functions from \`@ank1015/llm-agents\` there.
85
81
  - Final user-facing outputs should be written to ${artifactDir} unless the user explicitly asks for a different location.
86
82
  - Max should treat ${artifactTempDir} as ephemeral scratch space. Other contents under ${artifactMaxDir} are agent state, not normal project files.
87
- - Max should keep bundled skill files inside installed skill directories unchanged unless the user explicitly asks to modify them.
88
- </agent_state>
83
+ - Max should keep bundled skill files inside installed skill directories unchanged unless the user explicitly asks to modify them.`;
84
+ const currentDateSection = current_date ?? `Current date: ${dateTime}`;
85
+ const prompt = `${identitySection}
86
+
87
+ ${renderSection('tools', toolsSection)}
88
+
89
+ ${renderSection('tools_guidelines', toolsGuidelinesSection)}
90
+
91
+ ${renderSection('skills', skillsSection)}
92
+
93
+ ${renderSection('project_information', projectInformationSection)}
94
+
95
+ <working_dir>
96
+ ${workingDirSection}
97
+
98
+ ${renderSection('agent_state', agentStateSection)}
89
99
 
90
- Current date: ${dateTime}
100
+ ${currentDateSection}
91
101
  </working_dir>
92
102
  `;
93
103
  return prompt;
@@ -1 +1 @@
1
- {"version":3,"file":"system-prompt.js","sourceRoot":"","sources":["../../src/agents/system-prompt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAExD,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,EACvC,WAAW,EACX,UAAU,EACV,YAAY,EACZ,WAAW,GAMZ;IACC,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;IACvB,MAAM,cAAc,GAAG,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;IACjD,MAAM,iBAAiB,GAAG,IAAI,CAAC,cAAc,EAAE,QAAQ,CAAC,CAAC;IACzD,MAAM,eAAe,GAAG,IAAI,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC;IACrD,MAAM,QAAQ,GAAG,GAAG,CAAC,cAAc,CAAC,OAAO,EAAE;QAC3C,OAAO,EAAE,MAAM;QACf,IAAI,EAAE,SAAS;QACf,KAAK,EAAE,MAAM;QACb,GAAG,EAAE,SAAS;KACf,CAAC,CAAC;IACH,MAAM,eAAe,GAAG,MAAM,qBAAqB,CAAC,WAAW,CAAC,CAAC;IAEjE,MAAM,MAAM,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;sJAmCqI,eAAe;;;EAGnK,eAAe;;;;;wDAKuC,WAAW,4BAA4B,YAAY;;;;;;;;kBAQzF,WAAW;iBACZ,UAAU;;;mBAGR,YAAY;kBACb,WAAW;;;;;;;4CAOe,cAAc;0CAChB,iBAAiB;gBAC3C,eAAe;IAC3B,eAAe;;2DAEwC,eAAe,8BAA8B,eAAe;oGACnB,WAAW;mDAC5D,WAAW;qBACzC,eAAe,qDAAqD,cAAc;;;;gBAIvF,QAAQ;;CAEvB,CAAC;IAEA,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,KAAK,UAAU,qBAAqB,CAAC,WAAmB;IACtD,MAAM,eAAe,GAAG,MAAM,mBAAmB,CAAC,WAAW,CAAC,CAAC;IAE/D,IAAI,eAAe,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACjC,OAAO,kBAAkB,CAAC;IAC5B,CAAC;IAED,OAAO,eAAe;SACnB,GAAG,CACF,CAAC,KAAK,EAAE,EAAE,CACR,WAAW,KAAK,CAAC,IAAI;iBACZ,KAAK,CAAC,WAAW;UACxB,KAAK,CAAC,IAAI,EAAE,CACjB;SACA,IAAI,CAAC,IAAI,CAAC,CAAC;AAChB,CAAC"}
1
+ {"version":3,"file":"system-prompt.js","sourceRoot":"","sources":["../../src/agents/system-prompt.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env node
2
+ import type { Api, BaseAssistantMessage } from '@ank1015/llm-sdk';
3
+ export interface CliDirectoryContext {
4
+ projectName: string;
5
+ projectDir: string;
6
+ artifactName: string;
7
+ artifactDir: string;
8
+ }
9
+ export declare function isExitCommand(input: string): boolean;
10
+ export declare function resolveCliDirectoryContext(directory: string): CliDirectoryContext;
11
+ export declare function extractAssistantText(message: BaseAssistantMessage<Api>): string;
12
+ export declare function runAgentCli(): Promise<void>;
13
+ //# sourceMappingURL=agent-cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-cli.d.ts","sourceRoot":"","sources":["../../src/cli/agent-cli.ts"],"names":[],"mappings":";AAeA,OAAO,KAAK,EAGV,GAAG,EAEH,oBAAoB,EAGrB,MAAM,kBAAkB,CAAC;AAY1B,MAAM,WAAW,mBAAmB;IAClC,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEpD;AAED,wBAAgB,0BAA0B,CAAC,SAAS,EAAE,MAAM,GAAG,mBAAmB,CAYjF;AA+BD,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,oBAAoB,CAAC,GAAG,CAAC,GAAG,MAAM,CA2B/E;AAkFD,wBAAsB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAoHjD"}
@@ -0,0 +1,264 @@
1
+ #!/usr/bin/env node
2
+ import { realpath, stat } from 'node:fs/promises';
3
+ import { basename, dirname, join, resolve } from 'node:path';
4
+ import { stdin, stdout } from 'node:process';
5
+ import { createInterface } from 'node:readline/promises';
6
+ import { pathToFileURL } from 'node:url';
7
+ import { Conversation, createSessionManager, getModel } from '@ank1015/llm-sdk';
8
+ import { createFileKeysAdapter, InMemorySessionsAdapter } from '@ank1015/llm-sdk-adapters';
9
+ import { addSkill } from '../agents/skills/index.js';
10
+ import { createSystemPrompt } from '../agents/system-prompt.js';
11
+ import { createAllTools } from '../tools/index.js';
12
+ const CLI_API = 'codex';
13
+ const CLI_MODEL_ID = 'gpt-5.4';
14
+ const CLI_PROVIDER_OPTIONS = {
15
+ reasoning: {
16
+ effort: 'high',
17
+ summary: 'detailed',
18
+ },
19
+ };
20
+ const EXIT_COMMANDS = new Set(['exit', 'quit', ':q']);
21
+ export function isExitCommand(input) {
22
+ return EXIT_COMMANDS.has(input.trim().toLowerCase());
23
+ }
24
+ export function resolveCliDirectoryContext(directory) {
25
+ const artifactDir = resolve(directory);
26
+ const artifactName = basename(artifactDir) || 'artifact';
27
+ const projectDir = dirname(artifactDir);
28
+ const projectName = basename(projectDir) || artifactName;
29
+ return {
30
+ projectName,
31
+ projectDir,
32
+ artifactName,
33
+ artifactDir,
34
+ };
35
+ }
36
+ function createCliSystemPromptOverrides(context) {
37
+ const stateDir = join(context.artifactDir, '.max');
38
+ const skillsDir = join(stateDir, 'skills');
39
+ const tempDir = join(stateDir, 'temp');
40
+ return {
41
+ project_information: `- Max is working in this directory: ${context.artifactDir}.`,
42
+ working_dir: `Max is currently working in the following directory:
43
+ - working dir: ${context.artifactDir}
44
+
45
+ - The tools are initialized in this directory, and Max should treat it as the default working area.
46
+ - Max should read and write files relative to this directory unless the user explicitly asks for another location.
47
+ - If Max needs to inspect files outside this directory, Max should do so explicitly and avoid modifying them unless the user asks.`,
48
+ agent_state: `- Agent-local state lives under: ${stateDir}
49
+ - Installed skills live under: ${skillsDir}
50
+ - Max may use ${tempDir} as writable scratch space for temporary files, helper projects, scripts, installs, previews, logs, JSON summaries, unpacked folders, and other ephemeral outputs.
51
+ - ${tempDir} may already be initialized as a lightweight TypeScript workspace for helper-backed skills, including a \`package.json\`, \`tsconfig.json\`, and \`scripts/\` folder.
52
+ - When that temp workspace already exists, Max should inspect it and reuse it instead of creating a new scratch setup.
53
+ - Max may place one-off TypeScript helper scripts inside ${tempDir}/scripts and run them from ${tempDir} when that workspace fits the task.
54
+ - Final user-facing outputs should be written inside ${context.artifactDir} unless the user explicitly asks for a different location.
55
+ - Max should treat ${tempDir} as ephemeral scratch space. Other contents under ${stateDir} are agent state, not normal project files.
56
+ - Max should keep bundled skill files inside installed skill directories unchanged unless the user explicitly asks to modify them.`,
57
+ };
58
+ }
59
+ export function extractAssistantText(message) {
60
+ const textParts = [];
61
+ let sawNonTextContent = false;
62
+ for (const block of message.content) {
63
+ if (block.type !== 'response') {
64
+ continue;
65
+ }
66
+ for (const item of block.content) {
67
+ if (item.type === 'text') {
68
+ textParts.push(item.content);
69
+ }
70
+ else {
71
+ sawNonTextContent = true;
72
+ }
73
+ }
74
+ }
75
+ if (textParts.length > 0) {
76
+ return textParts.join('\n\n').trim();
77
+ }
78
+ if (sawNonTextContent) {
79
+ return '[assistant returned non-text content]';
80
+ }
81
+ return '';
82
+ }
83
+ function isReadlineInterruptError(error) {
84
+ return (error instanceof Error &&
85
+ 'code' in error &&
86
+ (error.code === 'ERR_USE_AFTER_CLOSE' || error.code === 'ABORT_ERR'));
87
+ }
88
+ function isAssistantStreamEvent(message) {
89
+ return 'type' in message;
90
+ }
91
+ async function resolveExistingDirectory(directoryInput) {
92
+ const requestedPath = directoryInput.trim() || process.cwd();
93
+ const resolvedPath = resolve(requestedPath);
94
+ const stats = await stat(resolvedPath);
95
+ if (!stats.isDirectory()) {
96
+ throw new Error(`Path is not a directory: ${resolvedPath}`);
97
+ }
98
+ return resolveCliDirectoryContext(await realpath(resolvedPath));
99
+ }
100
+ function createEventPrinter() {
101
+ let sawAssistantText = false;
102
+ let assistantLineOpen = false;
103
+ return (event) => {
104
+ switch (event.type) {
105
+ case 'message_start': {
106
+ if (event.messageType === 'assistant') {
107
+ sawAssistantText = false;
108
+ assistantLineOpen = true;
109
+ stdout.write('\nassistant> ');
110
+ }
111
+ break;
112
+ }
113
+ case 'message_update': {
114
+ if (event.messageType === 'assistant' &&
115
+ isAssistantStreamEvent(event.message) &&
116
+ event.message.type === 'text_delta') {
117
+ sawAssistantText = true;
118
+ stdout.write(event.message.delta);
119
+ }
120
+ break;
121
+ }
122
+ case 'tool_execution_start': {
123
+ if (assistantLineOpen) {
124
+ stdout.write('\n');
125
+ assistantLineOpen = false;
126
+ }
127
+ stdout.write(`[tool:${event.toolName}] running\n`);
128
+ break;
129
+ }
130
+ case 'tool_execution_end': {
131
+ stdout.write(`[tool:${event.toolName}] ${event.isError ? 'failed' : 'done'}\n`);
132
+ break;
133
+ }
134
+ case 'message_end': {
135
+ if (event.messageType === 'assistant') {
136
+ if (!sawAssistantText) {
137
+ const text = extractAssistantText(event.message);
138
+ if (text) {
139
+ stdout.write(text);
140
+ }
141
+ }
142
+ stdout.write('\n');
143
+ sawAssistantText = false;
144
+ assistantLineOpen = false;
145
+ }
146
+ break;
147
+ }
148
+ }
149
+ };
150
+ }
151
+ export async function runAgentCli() {
152
+ const readline = createInterface({ input: stdin, output: stdout });
153
+ let conversation;
154
+ let isRunning = false;
155
+ const handleSigint = () => {
156
+ if (isRunning && conversation) {
157
+ stdout.write('\nAborting current run...\n');
158
+ conversation.abort();
159
+ return;
160
+ }
161
+ stdout.write('\nExiting.\n');
162
+ readline.close();
163
+ process.exit(0);
164
+ };
165
+ process.on('SIGINT', handleSigint);
166
+ try {
167
+ let directoryInput;
168
+ try {
169
+ directoryInput = await readline.question(`Run agent in directory [${process.cwd()}]: `);
170
+ }
171
+ catch (error) {
172
+ if (isReadlineInterruptError(error)) {
173
+ return;
174
+ }
175
+ throw error;
176
+ }
177
+ const context = await resolveExistingDirectory(directoryInput);
178
+ stdout.write(`\nPreparing agent for ${context.artifactDir}\n`);
179
+ await addSkill('ai-images', context.artifactDir);
180
+ const tools = Object.values(createAllTools(context.artifactDir));
181
+ const systemPrompt = await createSystemPrompt({
182
+ ...context,
183
+ ...createCliSystemPromptOverrides(context),
184
+ });
185
+ const model = getModel(CLI_API, CLI_MODEL_ID);
186
+ if (!model) {
187
+ throw new Error(`Model "${CLI_MODEL_ID}" not found for API "${CLI_API}"`);
188
+ }
189
+ const keysAdapter = createFileKeysAdapter();
190
+ const sessionManager = createSessionManager(new InMemorySessionsAdapter());
191
+ const { sessionId, header } = await sessionManager.createSession({
192
+ projectName: context.projectName,
193
+ sessionName: `${context.artifactName} CLI Session`,
194
+ });
195
+ let currentLeafNodeId = header.id;
196
+ conversation = new Conversation({
197
+ keysAdapter,
198
+ streamAssistantMessage: true,
199
+ initialState: {
200
+ tools,
201
+ },
202
+ });
203
+ conversation.setProvider({
204
+ model,
205
+ providerOptions: CLI_PROVIDER_OPTIONS,
206
+ });
207
+ conversation.setSystemPrompt(systemPrompt);
208
+ conversation.setTools(tools);
209
+ conversation.subscribe(createEventPrinter());
210
+ stdout.write(`Session ${sessionId} ready.\n`);
211
+ stdout.write(`Using ${CLI_API}/${CLI_MODEL_ID} with directory-local tools in ${context.artifactDir}\n`);
212
+ stdout.write('Type a prompt and press Enter. Type "exit" to quit.\n');
213
+ while (true) {
214
+ let promptText;
215
+ try {
216
+ promptText = await readline.question('\nyou> ');
217
+ }
218
+ catch (error) {
219
+ if (isReadlineInterruptError(error)) {
220
+ break;
221
+ }
222
+ throw error;
223
+ }
224
+ if (!promptText.trim()) {
225
+ continue;
226
+ }
227
+ if (isExitCommand(promptText)) {
228
+ break;
229
+ }
230
+ isRunning = true;
231
+ try {
232
+ await conversation.prompt(promptText, undefined, async (message) => {
233
+ const { node } = await sessionManager.appendMessage({
234
+ projectName: context.projectName,
235
+ path: '',
236
+ sessionId,
237
+ parentId: currentLeafNodeId,
238
+ branch: 'main',
239
+ message,
240
+ api: CLI_API,
241
+ modelId: CLI_MODEL_ID,
242
+ providerOptions: CLI_PROVIDER_OPTIONS,
243
+ });
244
+ currentLeafNodeId = node.id;
245
+ });
246
+ }
247
+ catch (error) {
248
+ const message = error instanceof Error ? error.message : String(error);
249
+ stdout.write(`\nerror> ${message}\n`);
250
+ }
251
+ finally {
252
+ isRunning = false;
253
+ }
254
+ }
255
+ }
256
+ finally {
257
+ process.off('SIGINT', handleSigint);
258
+ readline.close();
259
+ }
260
+ }
261
+ if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {
262
+ void runAgentCli();
263
+ }
264
+ //# sourceMappingURL=agent-cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-cli.js","sourceRoot":"","sources":["../../src/cli/agent-cli.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * Agent toolkit for the LLM SDK.
5
5
  */
6
- export declare const VERSION = "0.0.2";
6
+ export declare const VERSION = "0.0.3";
7
7
  export * from './tools/index.js';
8
8
  export * from './agents/system-prompt.js';
9
9
  export * from './agents/tools.js';
package/dist/index.js CHANGED
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * Agent toolkit for the LLM SDK.
5
5
  */
6
- export const VERSION = '0.0.2';
6
+ export const VERSION = '0.0.3';
7
7
  export * from './tools/index.js';
8
8
  export * from './agents/system-prompt.js';
9
9
  export * from './agents/tools.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ank1015/llm-agents",
3
- "version": "0.0.2",
3
+ "version": "0.0.3",
4
4
  "description": "Node-only general-purpose agent toolkit with bundled skills and helper-backed workflows",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -21,6 +21,7 @@
21
21
  "scripts": {
22
22
  "build": "rm -rf dist coverage *.tsbuildinfo && tsc",
23
23
  "dev": "tsc --watch",
24
+ "agent:cli": "tsx src/cli/agent-cli.ts",
24
25
  "test": "pnpm run test:unit && pnpm run test:integration",
25
26
  "test:watch": "vitest",
26
27
  "test:unit": "vitest run tests/unit",
@@ -17,9 +17,10 @@ Use this skill when the user wants to:
17
17
  ## Required Reading Order
18
18
 
19
19
  1. Read this file first.
20
- 2. If the task is generating a new image, read [references/create.md](references/create.md).
21
- 3. If the task is editing or transforming an existing image, read [references/edit.md](references/edit.md).
22
- 4. Do not read both reference files unless the task genuinely includes both create and edit flows.
20
+ 2. If the task needs model selection help or the best image model is not obvious, read [references/choose-model.md](references/choose-model.md).
21
+ 3. If the task is generating a new image, read [references/create.md](references/create.md).
22
+ 4. If the task is editing or transforming an existing image, read [references/edit.md](references/edit.md).
23
+ 5. Do not read both task references unless the task genuinely includes both create and edit flows.
23
24
 
24
25
  ## Available Functions
25
26
 
@@ -38,6 +39,7 @@ import { createImage, editImage } from '@ank1015/llm-agents';
38
39
 
39
40
  ## Choose The Next Reference
40
41
 
42
+ - Read [references/choose-model.md](references/choose-model.md) when you need to choose between `gpt-5.4`, `gemini-3.1-flash-image-preview`, and `gemini-3-pro-image-preview`.
41
43
  - Read [references/create.md](references/create.md) for request shape, model-specific create options, output behavior, and example usage of `createImage()`.
42
44
  - Read [references/edit.md](references/edit.md) for request shape, supported inputs, model-specific edit options, output behavior, and example usage of `editImage()`.
43
45
 
@@ -0,0 +1,54 @@
1
+ # Choose An Image Model
2
+
3
+ Use this reference when the task needs model-selection help before you call `createImage()` or
4
+ `editImage()`.
5
+
6
+ ## Model Priority
7
+
8
+ - If the user explicitly names a model, use that model.
9
+ - If the task is serious, high-stakes, detail-sensitive, or likely to need the best typography,
10
+ precise edits, or careful composition, prefer `gemini-3-pro-image-preview`.
11
+ - If the task is normal or exploratory, `gpt-5.4` and `gemini-3.1-flash-image-preview` are both
12
+ good defaults.
13
+ - `gemini-3-pro-image-preview` is the strongest overall model of the three, but it is a bit more
14
+ expensive than the other two.
15
+
16
+ ## When To Prefer `gemini-3-pro-image-preview`
17
+
18
+ Prefer `gemini-3-pro-image-preview` when the task needs:
19
+
20
+ - precise text rendering inside the image
21
+ - small visual details to survive edits
22
+ - careful local changes or cleaner instruction-following
23
+ - a serious deliverable where quality matters more than cost
24
+
25
+ This is the safest “best quality” choice when the user cares about polish.
26
+
27
+ ## When `gpt-5.4` Or `gemini-3.1-flash-image-preview` Are Good
28
+
29
+ Use `gpt-5.4` or `gemini-3.1-flash-image-preview` when:
30
+
31
+ - the task is normal importance
32
+ - you want a faster or cheaper first pass
33
+ - the required provider-specific image options line up better with one of those models
34
+ - you want to try multiple candidates before spending more on the final pass
35
+
36
+ Neither is far behind for typical work.
37
+
38
+ ## Option Matching Matters
39
+
40
+ Model choice is not only about raw quality. Also look at `provider.imageOptions`.
41
+
42
+ - If the desired size, aspect ratio, fidelity, background, or other image controls fit a Google
43
+ model better, choose the Google model that matches the task.
44
+ - If the desired controls fit `gpt-5.4` better, choose `gpt-5.4`.
45
+ - When the user’s constraints clearly match one provider’s options better than another, prefer the
46
+ better fit even if another model is stronger in the abstract.
47
+
48
+ ## Iteration Strategy
49
+
50
+ - For important work, it is valid to try more than one model and keep the best result.
51
+ - A common pattern is to start with `gpt-5.4` or `gemini-3.1-flash-image-preview`, then rerun with
52
+ `gemini-3-pro-image-preview` if the result needs more polish.
53
+ - If the first result misses on text, precision, or edit fidelity, switch to
54
+ `gemini-3-pro-image-preview`.
@@ -3,6 +3,8 @@
3
3
  Use this reference when the user wants to generate a brand-new image or create a new image while
4
4
  optionally conditioning on reference images.
5
5
 
6
+ If you are not sure which model to use, read [choose-model.md](choose-model.md) first.
7
+
6
8
  ## Import
7
9
 
8
10
  ```ts
@@ -3,6 +3,8 @@
3
3
  Use this reference when the user wants to modify, transform, or extend one or more existing
4
4
  images.
5
5
 
6
+ If you are not sure which model to use, read [choose-model.md](choose-model.md) first.
7
+
6
8
  ## Import
7
9
 
8
10
  ```ts