@output.ai/cli 0.0.7 → 0.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/generated/api.d.ts +0 -20
- package/dist/api/generated/api.js +1 -10
- package/dist/services/workflow_planner.js +6 -6
- package/dist/services/workflow_planner.spec.js +6 -22
- package/dist/templates/agent_instructions/commands/build_workflow.md.template +10 -9
- package/dist/templates/agent_instructions/commands/plan_workflow.md.template +8 -7
- package/dist/templates/workflow/README.md.template +3 -5
- package/dist/templates/workflow/steps.ts.template +4 -3
- package/package.json +18 -23
|
@@ -198,26 +198,6 @@ export type getWorkflowIdOutputResponseError = (getWorkflowIdOutputResponse404)
|
|
|
198
198
|
export type getWorkflowIdOutputResponse = (getWorkflowIdOutputResponseSuccess | getWorkflowIdOutputResponseError);
|
|
199
199
|
export declare const getGetWorkflowIdOutputUrl: (id: string) => string;
|
|
200
200
|
export declare const getWorkflowIdOutput: (id: string, options?: RequestInit) => Promise<getWorkflowIdOutputResponse>;
|
|
201
|
-
/**
|
|
202
|
-
* @summary Return the trace of a workflow execution
|
|
203
|
-
*/
|
|
204
|
-
export type getWorkflowIdTraceResponse200 = {
|
|
205
|
-
data: string[];
|
|
206
|
-
status: 200;
|
|
207
|
-
};
|
|
208
|
-
export type getWorkflowIdTraceResponse404 = {
|
|
209
|
-
data: void;
|
|
210
|
-
status: 404;
|
|
211
|
-
};
|
|
212
|
-
export type getWorkflowIdTraceResponseSuccess = (getWorkflowIdTraceResponse200) & {
|
|
213
|
-
headers: Headers;
|
|
214
|
-
};
|
|
215
|
-
export type getWorkflowIdTraceResponseError = (getWorkflowIdTraceResponse404) & {
|
|
216
|
-
headers: Headers;
|
|
217
|
-
};
|
|
218
|
-
export type getWorkflowIdTraceResponse = (getWorkflowIdTraceResponseSuccess | getWorkflowIdTraceResponseError);
|
|
219
|
-
export declare const getGetWorkflowIdTraceUrl: (id: string) => string;
|
|
220
|
-
export declare const getWorkflowIdTrace: (id: string, options?: RequestInit) => Promise<getWorkflowIdTraceResponse>;
|
|
221
201
|
/**
|
|
222
202
|
* @summary Get a specific workflow catalog by ID
|
|
223
203
|
*/
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Generated by orval v7.13.
|
|
2
|
+
* Generated by orval v7.13.2 🍺
|
|
3
3
|
* Do not edit manually.
|
|
4
4
|
* Output.ai SDK API
|
|
5
5
|
* API for managing and executing Temporal workflows through Output SDK
|
|
@@ -78,15 +78,6 @@ export const getWorkflowIdOutput = async (id, options) => {
|
|
|
78
78
|
method: 'GET'
|
|
79
79
|
});
|
|
80
80
|
};
|
|
81
|
-
export const getGetWorkflowIdTraceUrl = (id) => {
|
|
82
|
-
return `/workflow/${id}/trace`;
|
|
83
|
-
};
|
|
84
|
-
export const getWorkflowIdTrace = async (id, options) => {
|
|
85
|
-
return customFetchInstance(getGetWorkflowIdTraceUrl(id), {
|
|
86
|
-
...options,
|
|
87
|
-
method: 'GET'
|
|
88
|
-
});
|
|
89
|
-
};
|
|
90
81
|
;
|
|
91
82
|
export const getGetWorkflowCatalogIdUrl = (id) => {
|
|
92
83
|
return `/workflow/catalog/${id}`;
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { initializeAgentConfig } from './coding_agents.js';
|
|
2
|
-
import { generateText } from '
|
|
3
|
-
import { loadPrompt } from 'local_prompt';
|
|
4
|
-
import { format } from 'date-fns';
|
|
2
|
+
import { generateText } from '@output.ai/llm';
|
|
5
3
|
import fs from 'node:fs/promises';
|
|
6
4
|
import path from 'node:path';
|
|
7
5
|
import { AGENT_CONFIG_DIR } from '#config.js';
|
|
8
6
|
export async function generatePlanName(description, date = new Date()) {
|
|
9
|
-
const datePrefix =
|
|
10
|
-
const
|
|
11
|
-
|
|
7
|
+
const datePrefix = new Date(date).toISOString().split('T')[0].replaceAll('-', '_');
|
|
8
|
+
const planNameSlug = await generateText({
|
|
9
|
+
prompt: 'generate_plan_name@v1',
|
|
10
|
+
variables: { description }
|
|
11
|
+
});
|
|
12
12
|
const cleanedName = planNameSlug
|
|
13
13
|
.trim()
|
|
14
14
|
.toLowerCase()
|
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
import { describe, it, expect, beforeEach, vi } from 'vitest';
|
|
2
2
|
import { generatePlanName, writePlanFile, updateAgentTemplates } from './workflow_planner.js';
|
|
3
3
|
import { initializeAgentConfig } from './coding_agents.js';
|
|
4
|
-
import { generateText } from '
|
|
5
|
-
import { loadPrompt } from 'local_prompt';
|
|
4
|
+
import { generateText } from '@output.ai/llm';
|
|
6
5
|
import fs from 'node:fs/promises';
|
|
7
6
|
vi.mock('./coding_agents.js');
|
|
8
|
-
vi.mock('
|
|
9
|
-
vi.mock('local_prompt');
|
|
7
|
+
vi.mock('@output.ai/llm');
|
|
10
8
|
vi.mock('node:fs/promises');
|
|
11
9
|
describe('workflow-planner service', () => {
|
|
12
10
|
beforeEach(() => {
|
|
@@ -14,25 +12,17 @@ describe('workflow-planner service', () => {
|
|
|
14
12
|
});
|
|
15
13
|
describe('generatePlanName', () => {
|
|
16
14
|
it('should generate plan name with date prefix using LLM', async () => {
|
|
17
|
-
const mockPrompt = {
|
|
18
|
-
config: { model: 'claude-sonnet-4-20250514', provider: 'anthropic' },
|
|
19
|
-
messages: [
|
|
20
|
-
{ role: 'system', content: 'You are a technical writing assistant...' },
|
|
21
|
-
{ role: 'user', content: 'Generate a snake_case plan name...' }
|
|
22
|
-
]
|
|
23
|
-
};
|
|
24
|
-
vi.mocked(loadPrompt).mockReturnValue(mockPrompt);
|
|
25
15
|
vi.mocked(generateText).mockResolvedValue('customer_order_processing');
|
|
26
16
|
const testDate = new Date(2025, 9, 6);
|
|
27
17
|
const planName = await generatePlanName('A workflow that processes customer orders', testDate);
|
|
28
18
|
expect(planName).toMatch(/^2025_10_06_/);
|
|
29
19
|
expect(planName).toBe('2025_10_06_customer_order_processing');
|
|
30
|
-
expect(
|
|
31
|
-
|
|
20
|
+
expect(generateText).toHaveBeenCalledWith({
|
|
21
|
+
prompt: 'generate_plan_name@v1',
|
|
22
|
+
variables: { description: 'A workflow that processes customer orders' }
|
|
23
|
+
});
|
|
32
24
|
});
|
|
33
25
|
it('should clean and validate LLM response', async () => {
|
|
34
|
-
const mockPrompt = { config: { provider: 'anthropic', model: 'claude-sonnet-4-20250514' }, messages: [] };
|
|
35
|
-
vi.mocked(loadPrompt).mockReturnValue(mockPrompt);
|
|
36
26
|
vi.mocked(generateText).mockResolvedValue(' User-Auth & Security!@# ');
|
|
37
27
|
const testDate = new Date(2025, 9, 6);
|
|
38
28
|
const planName = await generatePlanName('User authentication workflow', testDate);
|
|
@@ -40,14 +30,10 @@ describe('workflow-planner service', () => {
|
|
|
40
30
|
expect(planName).toMatch(/^[0-9_a-z]+$/);
|
|
41
31
|
});
|
|
42
32
|
it('should handle LLM errors gracefully', async () => {
|
|
43
|
-
const mockPrompt = { config: { provider: 'anthropic', model: 'claude-sonnet-4-20250514' }, messages: [] };
|
|
44
|
-
vi.mocked(loadPrompt).mockReturnValue(mockPrompt);
|
|
45
33
|
vi.mocked(generateText).mockRejectedValue(new Error('API rate limit exceeded'));
|
|
46
34
|
await expect(generatePlanName('Test workflow')).rejects.toThrow('API rate limit exceeded');
|
|
47
35
|
});
|
|
48
36
|
it('should limit plan name length to 50 characters', async () => {
|
|
49
|
-
const mockPrompt = { config: { provider: 'anthropic', model: 'claude-sonnet-4-20250514' }, messages: [] };
|
|
50
|
-
vi.mocked(loadPrompt).mockReturnValue(mockPrompt);
|
|
51
37
|
vi.mocked(generateText).mockResolvedValue('this_is_an_extremely_long_plan_name_that_exceeds_the_maximum_allowed_length_for_file_names');
|
|
52
38
|
const testDate = new Date(2025, 9, 6);
|
|
53
39
|
const planName = await generatePlanName('Long workflow description', testDate);
|
|
@@ -55,8 +41,6 @@ describe('workflow-planner service', () => {
|
|
|
55
41
|
expect(namePart.length).toBeLessThanOrEqual(50);
|
|
56
42
|
});
|
|
57
43
|
it('should handle multiple underscores correctly', async () => {
|
|
58
|
-
const mockPrompt = { config: { provider: 'anthropic', model: 'claude-sonnet-4-20250514' }, messages: [] };
|
|
59
|
-
vi.mocked(loadPrompt).mockReturnValue(mockPrompt);
|
|
60
44
|
vi.mocked(generateText).mockResolvedValue('user___auth___workflow');
|
|
61
45
|
const testDate = new Date(2025, 9, 6);
|
|
62
46
|
const planName = await generatePlanName('Test', testDate);
|
|
@@ -47,7 +47,7 @@ Read and understand the plan document.
|
|
|
47
47
|
Update `$3/workflow.ts` with the workflow definition.
|
|
48
48
|
|
|
49
49
|
<implementation_checklist>
|
|
50
|
-
- Import required dependencies (workflow, z from 'output.ai/core')
|
|
50
|
+
- Import required dependencies (workflow, z from '@output.ai/core')
|
|
51
51
|
- Define inputSchema based on plan specifications
|
|
52
52
|
- Define outputSchema based on plan specifications
|
|
53
53
|
- Import step functions from steps.ts
|
|
@@ -58,7 +58,7 @@ Update `$3/workflow.ts` with the workflow definition.
|
|
|
58
58
|
|
|
59
59
|
<workflow_template>
|
|
60
60
|
```typescript
|
|
61
|
-
import { workflow, z } from 'output.ai/core';
|
|
61
|
+
import { workflow, z } from '@output.ai/core';
|
|
62
62
|
import { stepName } from './steps.js';
|
|
63
63
|
|
|
64
64
|
const inputSchema = z.object( {
|
|
@@ -92,7 +92,7 @@ export default workflow( {
|
|
|
92
92
|
Update `$3/steps.ts` with all step definitions from the plan.
|
|
93
93
|
|
|
94
94
|
<implementation_checklist>
|
|
95
|
-
- Import required dependencies (step, z from 'output.ai/core')
|
|
95
|
+
- Import required dependencies (step, z from '@output.ai/core')
|
|
96
96
|
- Implement each step with proper schema validation
|
|
97
97
|
- Add error handling and retry logic as specified
|
|
98
98
|
- Ensure step names match plan specifications
|
|
@@ -101,7 +101,7 @@ Update `$3/steps.ts` with all step definitions from the plan.
|
|
|
101
101
|
|
|
102
102
|
<step_template>
|
|
103
103
|
```typescript
|
|
104
|
-
import { step, z } from 'output.ai/core';
|
|
104
|
+
import { step, z } from '@output.ai/core';
|
|
105
105
|
|
|
106
106
|
export const stepName = step( {
|
|
107
107
|
name: 'stepName',
|
|
@@ -138,9 +138,8 @@ If the plan includes LLM-based steps, create prompt templates in `$3/prompts/`.
|
|
|
138
138
|
|
|
139
139
|
<llm_step_template>
|
|
140
140
|
```typescript
|
|
141
|
-
import { step, z } from 'output.ai/core';
|
|
142
|
-
import {
|
|
143
|
-
import { generateText } from 'output.ai/llm';
|
|
141
|
+
import { step, z } from '@output.ai/core';
|
|
142
|
+
import { generateText } from '@output.ai/llm';
|
|
144
143
|
|
|
145
144
|
export const llmStep = step( {
|
|
146
145
|
name: 'llmStep',
|
|
@@ -150,8 +149,10 @@ export const llmStep = step( {
|
|
|
150
149
|
} ),
|
|
151
150
|
outputSchema: z.string(),
|
|
152
151
|
fn: async ( { param } ) => {
|
|
153
|
-
const
|
|
154
|
-
|
|
152
|
+
const response = await generateText( {
|
|
153
|
+
prompt: 'prompt_name@v1',
|
|
154
|
+
variables: { param }
|
|
155
|
+
} );
|
|
155
156
|
return response;
|
|
156
157
|
}
|
|
157
158
|
} );
|
|
@@ -85,7 +85,7 @@ Design the workflow with clear single purpose steps and sound orchestration logi
|
|
|
85
85
|
|
|
86
86
|
<workflow_template>
|
|
87
87
|
```typescript
|
|
88
|
-
import { workflow, z } from 'output.ai/core';
|
|
88
|
+
import { workflow, z } from '@output.ai/core';
|
|
89
89
|
import { sumValues } from './steps.js';
|
|
90
90
|
|
|
91
91
|
const inputSchema = z.object( {
|
|
@@ -116,7 +116,7 @@ Design the steps with clear boundaries.
|
|
|
116
116
|
|
|
117
117
|
<step_template>
|
|
118
118
|
```typescript
|
|
119
|
-
import { step, z } from 'output.ai/core';
|
|
119
|
+
import { step, z } from '@output.ai/core';
|
|
120
120
|
|
|
121
121
|
export const sumValues = step( {
|
|
122
122
|
name: 'sumValues',
|
|
@@ -145,9 +145,8 @@ If any of the steps use an LLM, design the prompts for the steps.
|
|
|
145
145
|
|
|
146
146
|
<prompt_step_template>
|
|
147
147
|
```typescript
|
|
148
|
-
import { step, z } from 'output.ai/core';
|
|
149
|
-
import {
|
|
150
|
-
import { generateText } from 'output.ai/llm';
|
|
148
|
+
import { step, z } from '@output.ai/core';
|
|
149
|
+
import { generateText } from '@output.ai/llm';
|
|
151
150
|
|
|
152
151
|
export const aiSdkPrompt = step( {
|
|
153
152
|
name: 'aiSdkPrompt',
|
|
@@ -157,8 +156,10 @@ export const aiSdkPrompt = step( {
|
|
|
157
156
|
} ),
|
|
158
157
|
outputSchema: z.string(),
|
|
159
158
|
fn: async ( { topic } ) => {
|
|
160
|
-
const
|
|
161
|
-
|
|
159
|
+
const response = await generateText( {
|
|
160
|
+
prompt: 'prompt@v1',
|
|
161
|
+
variables: { topic }
|
|
162
|
+
} );
|
|
162
163
|
return response;
|
|
163
164
|
}
|
|
164
165
|
} );
|
|
@@ -144,9 +144,7 @@ const result = await myStep( { value: 42 } );
|
|
|
144
144
|
The template includes an example of using LLM with prompts:
|
|
145
145
|
|
|
146
146
|
```typescript
|
|
147
|
-
import { loadPrompt } from '@output.ai/prompt';
|
|
148
147
|
import { generateText } from '@output.ai/llm';
|
|
149
|
-
import type { Prompt } from '@output.ai/llm';
|
|
150
148
|
|
|
151
149
|
export const llmStep = step( {
|
|
152
150
|
name: 'llmStep',
|
|
@@ -159,10 +157,10 @@ export const llmStep = step( {
|
|
|
159
157
|
},
|
|
160
158
|
outputSchema: { type: 'string' },
|
|
161
159
|
fn: async ( input: { userInput: string } ) => {
|
|
162
|
-
const
|
|
163
|
-
|
|
160
|
+
const response = await generateText( {
|
|
161
|
+
prompt: 'prompt@v1',
|
|
162
|
+
variables: { userInput: input.userInput }
|
|
164
163
|
} );
|
|
165
|
-
const response = await generateText( prompt as Prompt );
|
|
166
164
|
return response;
|
|
167
165
|
}
|
|
168
166
|
} );
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { step, z } from '@output.ai/core';
|
|
2
|
-
import { loadPrompt } from '@output.ai/prompt';
|
|
3
2
|
import { generateText } from '@output.ai/llm';
|
|
4
3
|
|
|
5
4
|
// Example step using LLM
|
|
@@ -11,8 +10,10 @@ export const exampleLLMStep = step( {
|
|
|
11
10
|
} ),
|
|
12
11
|
outputSchema: z.string(),
|
|
13
12
|
fn: async ( { userInput } ) => {
|
|
14
|
-
const
|
|
15
|
-
|
|
13
|
+
const response = await generateText( {
|
|
14
|
+
prompt: 'prompt@v1',
|
|
15
|
+
variables: { userInput }
|
|
16
|
+
} );
|
|
16
17
|
return response;
|
|
17
18
|
}
|
|
18
19
|
} );
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@output.ai/cli",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.8",
|
|
4
4
|
"description": "CLI for Output.ai workflow generation",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -20,30 +20,25 @@
|
|
|
20
20
|
"prebuild": "npm run generate:api"
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@anthropic-ai/claude-agent-sdk": "
|
|
24
|
-
"@inquirer/prompts": "
|
|
25
|
-
"@oclif/core": "
|
|
26
|
-
"@oclif/plugin-help": "
|
|
27
|
-
"@oclif/plugin-plugins": "
|
|
28
|
-
"
|
|
29
|
-
"
|
|
30
|
-
"cli-
|
|
31
|
-
"
|
|
32
|
-
"handlebars": "
|
|
33
|
-
"json-schema-library": "
|
|
34
|
-
"ky": "
|
|
35
|
-
"
|
|
36
|
-
"local_prompt": "file:../prompt"
|
|
23
|
+
"@anthropic-ai/claude-agent-sdk": "0.1.19",
|
|
24
|
+
"@inquirer/prompts": "7.9.0",
|
|
25
|
+
"@oclif/core": "4.5.6",
|
|
26
|
+
"@oclif/plugin-help": "6.2.33",
|
|
27
|
+
"@oclif/plugin-plugins": "5.4.50",
|
|
28
|
+
"@output.ai/llm": ">=0.0.1",
|
|
29
|
+
"change-case": "5.4.4",
|
|
30
|
+
"cli-progress": "3.12.0",
|
|
31
|
+
"cli-table3": "0.6.5",
|
|
32
|
+
"handlebars": "4.7.8",
|
|
33
|
+
"json-schema-library": "10.3.0",
|
|
34
|
+
"ky": "1.12.0",
|
|
35
|
+
"validator": "13.15.20"
|
|
37
36
|
},
|
|
38
37
|
"devDependencies": {
|
|
39
|
-
"@
|
|
40
|
-
"@types/
|
|
41
|
-
"
|
|
42
|
-
"
|
|
43
|
-
"copyfiles": "^2.4.1",
|
|
44
|
-
"oclif": "^4",
|
|
45
|
-
"orval": "^7.13.0",
|
|
46
|
-
"slash": "^5.1.0"
|
|
38
|
+
"@types/cli-progress": "3.11.6",
|
|
39
|
+
"@types/handlebars": "4.1.0",
|
|
40
|
+
"copyfiles": "2.4.1",
|
|
41
|
+
"orval": "7.13.2"
|
|
47
42
|
},
|
|
48
43
|
"license": "UNLICENSED",
|
|
49
44
|
"imports": {
|