@n1k1t/pipelain 0.2.0 → 0.2.1
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/package.json +1 -1
- package/skills/basic/SKILL.md +0 -403
package/package.json
CHANGED
package/skills/basic/SKILL.md
DELETED
|
@@ -1,403 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: pipelain-basic
|
|
3
|
-
description: Skill for package @n1k1t/pipelain to build and execute type-safe AI pipelines with structured outputs and tool integration
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# PipelAIn Basic Skill
|
|
7
|
-
|
|
8
|
-
Instructions for building and executing type-safe AI pipelines with structured outputs, context sharing, parallel execution, loops, custom tools, and skills.
|
|
9
|
-
|
|
10
|
-
## When to Use
|
|
11
|
-
|
|
12
|
-
Use this skill when you need to:
|
|
13
|
-
1. Build and run complex workflows as a series of step-by-step execution pipelines.
|
|
14
|
-
2. Enforce AI responses to strictly match specified Zod schemas for full type safety.
|
|
15
|
-
3. Provide LLM tools (web interaction, file system, shell command execution) and register MCP servers.
|
|
16
|
-
4. Manage shared state and configuration across all pipeline steps using a global context.
|
|
17
|
-
5. Execute multiple tasks in parallel using a `swarm` step.
|
|
18
|
-
6. Build iterative workflows (e.g. self-correction, retries, and validations) using a `loop` step.
|
|
19
|
-
7. Inject reusable domain-specific instructions or workflows using LLM skills.
|
|
20
|
-
|
|
21
|
-
## Pipeline Utilities
|
|
22
|
-
|
|
23
|
-
Each pipeline step receives a set of utilities to interact with the environment, AI, and context.
|
|
24
|
-
|
|
25
|
-
### `factory`
|
|
26
|
-
Used to create different types of steps and retrieve tools or skills:
|
|
27
|
-
- `ai(description?)`: Creates a step that executes on the AI side.
|
|
28
|
-
- `self(description?)`: Creates a step that executes on the local machine.
|
|
29
|
-
- `swarm(description?)`: Executes multiple steps or pipelines in parallel.
|
|
30
|
-
- `loop(description?)`: Creates a loop of steps.
|
|
31
|
-
- `tools`: Access to LLM tools factory (e.g., `factory.tools.web()`).
|
|
32
|
-
- `skills`: Access to LLM skills factory (e.g., `factory.skills.all()`).
|
|
33
|
-
|
|
34
|
-
### `utils`
|
|
35
|
-
General-purpose utilities:
|
|
36
|
-
- `content`: `ContentFactory` instance to create structured prompt content (articles, tasks, rules, attachments, files, globs).
|
|
37
|
-
- `bash`: Execute shell commands on the local machine.
|
|
38
|
-
- `log`: Emit log events for the current pipeline session.
|
|
39
|
-
|
|
40
|
-
### `context`
|
|
41
|
-
Shared state and configuration:
|
|
42
|
-
- `input`: The input data provided to the pipeline.
|
|
43
|
-
- `state`: Shared state across all steps (contains results of previous steps).
|
|
44
|
-
- `llm`: Current LLM provider configuration.
|
|
45
|
-
- `project`: Information about the current project.
|
|
46
|
-
|
|
47
|
-
### `utils.content` (ContentFactory)
|
|
48
|
-
Used to create structured prompt content. These methods are available via `utils.content` in pipeline steps.
|
|
49
|
-
|
|
50
|
-
- `article(title, content)`: Creates a `## Title` section with nested markdown content.
|
|
51
|
-
- `rules(list)`: Creates a bulleted list of rules/constraints.
|
|
52
|
-
- `tasks(list)`: Creates a numbered list of tasks for the AI.
|
|
53
|
-
- `sources(list)`: Creates a list of source links.
|
|
54
|
-
- `attachment(title, payload)`: Attaches data (object, string) as a file-like block.
|
|
55
|
-
- `file(title, path)`: Reads a local file and attaches it as context.
|
|
56
|
-
- `glob(title, pattern)`: Reads multiple files by pattern and attaches them.
|
|
57
|
-
- `plain(text)`: Adds raw markdown text.
|
|
58
|
-
|
|
59
|
-
### `factory.tools` (LlmToolsFactory)
|
|
60
|
-
Used to provide tools to the AI. These methods are available via `factory.tools` in pipeline steps.
|
|
61
|
-
|
|
62
|
-
- `all()`: Includes all available tools.
|
|
63
|
-
- `web()`: Tools for web interaction (e.g., `search`, `fetch`).
|
|
64
|
-
- `files('read')`: Read-only file system tools (e.g., `read`, `grep`, `glob`, `ls`).
|
|
65
|
-
- `files('read-write', options?)`: Read and write file system tools (e.g., `read`, `grep`, `glob`, `ls`, `mkdir`, `write`, `edit`, `rm`). Can restrict write/edit/rm to specific glob patterns using the `allowed` parameter.
|
|
66
|
-
- `commands(allowedCmds)`: Package manager tools (e.g., `npm`, `npx`).
|
|
67
|
-
- `custom(tools)`: Includes custom tool implementations compiled with `LlmToolCompiler`.
|
|
68
|
-
|
|
69
|
-
### `factory.skills` (LlmSkillsFactory)
|
|
70
|
-
Used to provide domain-specific instructions and workflows to the AI.
|
|
71
|
-
|
|
72
|
-
- `all()`: Includes all registered skills.
|
|
73
|
-
- `match(pattern)`: Includes skills matching a minimatch pattern.
|
|
74
|
-
- `register(raw)`: Registers a new skill from raw markdown content (with frontmatter).
|
|
75
|
-
- `custom(skills)`: Includes custom skill objects.
|
|
76
|
-
- `provide()`: Returns the list of included skills for LLM configuration.
|
|
77
|
-
|
|
78
|
-
---
|
|
79
|
-
|
|
80
|
-
## Usage Examples
|
|
81
|
-
|
|
82
|
-
### Simple Pipeline
|
|
83
|
-
|
|
84
|
-
```ts
|
|
85
|
-
import z from 'zod';
|
|
86
|
-
import { PipelineCompiler } from '@n1k1t/pipelain';
|
|
87
|
-
|
|
88
|
-
const translate = PipelineCompiler
|
|
89
|
-
.build('Translator')
|
|
90
|
-
.input(z.string())
|
|
91
|
-
.step('translated', ({ factory, context }) => factory
|
|
92
|
-
.ai('Translating')
|
|
93
|
-
.schema(z.object({
|
|
94
|
-
ru: z.string().describe('Russian translation'),
|
|
95
|
-
es: z.string().describe('Spanish translation'),
|
|
96
|
-
en: z.string().describe('English translation'),
|
|
97
|
-
}))
|
|
98
|
-
.prompt([
|
|
99
|
-
`Translate this text to Russian, Spanish and English: ${context.input}`,
|
|
100
|
-
])
|
|
101
|
-
);
|
|
102
|
-
|
|
103
|
-
(async () => {
|
|
104
|
-
const compiled = await translate.compile();
|
|
105
|
-
const result = await compiled.run('Hello');
|
|
106
|
-
console.log(result.translated.es); // Hola
|
|
107
|
-
})();
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
### Structured Prompt Content
|
|
111
|
-
|
|
112
|
-
Create rich, structured prompts for the AI by combining multiple content types.
|
|
113
|
-
|
|
114
|
-
```ts
|
|
115
|
-
.step('complex_task', async ({ factory, utils }) => factory
|
|
116
|
-
.ai('Complex Processing')
|
|
117
|
-
.prompt([
|
|
118
|
-
// 1. Global rules
|
|
119
|
-
utils.content.rules([
|
|
120
|
-
'Use professional tone',
|
|
121
|
-
'Output must be valid JSON'
|
|
122
|
-
]),
|
|
123
|
-
|
|
124
|
-
// 2. Structured article
|
|
125
|
-
utils.content.article('Project Overview', [
|
|
126
|
-
{ p: 'This project is a type-safe pipeline builder.' },
|
|
127
|
-
{ h2: 'Key Goals' },
|
|
128
|
-
{ ul: ['Safety', 'Performance', 'Flexibility'] }
|
|
129
|
-
]),
|
|
130
|
-
|
|
131
|
-
// 3. Attachments
|
|
132
|
-
utils.content.attachment('User Data', {
|
|
133
|
-
content: { id: 1, name: 'John Doe' }
|
|
134
|
-
}),
|
|
135
|
-
|
|
136
|
-
// 4. Local files and glob patterns
|
|
137
|
-
await utils.content.file('Package Info', 'package.json'),
|
|
138
|
-
await utils.content.glob('Source Code', 'src/utils/*.ts'),
|
|
139
|
-
|
|
140
|
-
// 5. External sources
|
|
141
|
-
utils.content.sources(['https://github.com/n1k1t/pipelain']),
|
|
142
|
-
|
|
143
|
-
// 6. Raw markdown
|
|
144
|
-
utils.content.plain('> Note: This is a critical task.'),
|
|
145
|
-
|
|
146
|
-
// 7. Specific tasks for the AI to complete
|
|
147
|
-
utils.content.tasks([
|
|
148
|
-
'Review the `Project Overview` article',
|
|
149
|
-
'Analyze `User Data` and `Source Code`',
|
|
150
|
-
'Generate a summary based on the rules'
|
|
151
|
-
])
|
|
152
|
-
])
|
|
153
|
-
)
|
|
154
|
-
```
|
|
155
|
-
|
|
156
|
-
### AI Step with LLM Configuration and Restricted Tools
|
|
157
|
-
|
|
158
|
-
Customize LLM behavior (temperature, retry limits, tools, restricted paths) for specific steps.
|
|
159
|
-
|
|
160
|
-
```ts
|
|
161
|
-
.step('research', ({ factory, context, utils }) => factory
|
|
162
|
-
.ai('Researching')
|
|
163
|
-
.llm(({ context }) => context.llm.assign({
|
|
164
|
-
temperature: 0.7,
|
|
165
|
-
limit: 10, // Max tool execution attempts
|
|
166
|
-
tools: factory.tools
|
|
167
|
-
.web()
|
|
168
|
-
.files('read-write', {
|
|
169
|
-
allowed: {
|
|
170
|
-
write: ['src/generated/*.ts'],
|
|
171
|
-
edit: ['src/**/*.ts'],
|
|
172
|
-
rm: ['temp/**/*']
|
|
173
|
-
}
|
|
174
|
-
})
|
|
175
|
-
.provide(),
|
|
176
|
-
}))
|
|
177
|
-
.schema(z.object({
|
|
178
|
-
summary: z.string(),
|
|
179
|
-
links: z.array(z.string())
|
|
180
|
-
}))
|
|
181
|
-
.prompt([
|
|
182
|
-
utils.content.tasks([
|
|
183
|
-
`Find information about: ${context.input}`,
|
|
184
|
-
'Summarize findings and provide source links'
|
|
185
|
-
])
|
|
186
|
-
])
|
|
187
|
-
)
|
|
188
|
-
```
|
|
189
|
-
|
|
190
|
-
### AI Step with Fallback
|
|
191
|
-
|
|
192
|
-
Configure fallback providers for an AI step to automatically switch to alternative models or providers if the primary one fails.
|
|
193
|
-
|
|
194
|
-
```ts
|
|
195
|
-
import { llm } from '@n1k1t/pipelain';
|
|
196
|
-
|
|
197
|
-
.step('translation', ({ factory }) => factory
|
|
198
|
-
.ai('Translating with fallback')
|
|
199
|
-
.llm(({ context }) => context.llm.assign({
|
|
200
|
-
temperature: 0.3,
|
|
201
|
-
fallback: {
|
|
202
|
-
// 'continue' - resumes the session with the new provider keeping existing tool calls and reasoning results.
|
|
203
|
-
// 'restart' - restarts the step execution from scratch using the fallback provider.
|
|
204
|
-
strategy: 'continue',
|
|
205
|
-
providers: [
|
|
206
|
-
// Backup 1: If primary provider fails, try this model
|
|
207
|
-
llm.providers.LlmGoogleProvider.build('gemini-1.5-pro', {
|
|
208
|
-
connection: { key: process.env.GOOGLE_API_KEY! }
|
|
209
|
-
}),
|
|
210
|
-
// Backup 2: If the first backup also fails, try this model
|
|
211
|
-
llm.providers.LlmOpenAiProvider.build('gpt-4o', {
|
|
212
|
-
connection: { key: process.env.OPENAI_API_KEY! }
|
|
213
|
-
})
|
|
214
|
-
]
|
|
215
|
-
}
|
|
216
|
-
}))
|
|
217
|
-
.schema(z.object({ text: z.string() }))
|
|
218
|
-
.prompt(['Translate this text into Spanish...'])
|
|
219
|
-
)
|
|
220
|
-
```
|
|
221
|
-
|
|
222
|
-
### Combining `self` and `ai` Steps
|
|
223
|
-
|
|
224
|
-
Use `self` steps to perform local computations, log messages, or modify/transform the shared state.
|
|
225
|
-
|
|
226
|
-
```ts
|
|
227
|
-
const pipeline = PipelineCompiler
|
|
228
|
-
.build('Data Processor')
|
|
229
|
-
.input(z.string())
|
|
230
|
-
.step('extracted', ({ factory, context }) => factory
|
|
231
|
-
.ai('Extracting data')
|
|
232
|
-
.schema(z.object({
|
|
233
|
-
items: z.array(z.string())
|
|
234
|
-
}))
|
|
235
|
-
.prompt([`Extract items from: ${context.input}`])
|
|
236
|
-
)
|
|
237
|
-
// Local self step
|
|
238
|
-
.step(({ context, utils }) => {
|
|
239
|
-
utils.log(`Extracted ${context.state.extracted.items.length} items`);
|
|
240
|
-
|
|
241
|
-
context.merge({
|
|
242
|
-
state: {
|
|
243
|
-
processedCount: context.state.extracted.items.length
|
|
244
|
-
}
|
|
245
|
-
});
|
|
246
|
-
})
|
|
247
|
-
.step('summary', ({ factory, context }) => factory
|
|
248
|
-
.ai('Summarizing')
|
|
249
|
-
.schema(z.object({ text: z.string() }))
|
|
250
|
-
.prompt([
|
|
251
|
-
`Summarize these ${context.state.processedCount} items:`,
|
|
252
|
-
context.state.extracted.items.join(', ')
|
|
253
|
-
])
|
|
254
|
-
);
|
|
255
|
-
```
|
|
256
|
-
|
|
257
|
-
### Parallel Execution with `swarm`
|
|
258
|
-
|
|
259
|
-
Run multiple independent AI tasks in parallel to improve performance.
|
|
260
|
-
|
|
261
|
-
```ts
|
|
262
|
-
.step('analysis', ({ factory }) => factory
|
|
263
|
-
.swarm('Parallel Analysis')
|
|
264
|
-
.subtasks([
|
|
265
|
-
factory
|
|
266
|
-
.ai('Sentiment Analysis')
|
|
267
|
-
.schema(z.object({ score: z.number() }))
|
|
268
|
-
.prompt(({ context }) => [`Analyze sentiment of: ${context.input}`]),
|
|
269
|
-
|
|
270
|
-
factory
|
|
271
|
-
.ai('Keyword Extraction')
|
|
272
|
-
.schema(z.object({ tags: z.array(z.string()) }))
|
|
273
|
-
.prompt(({ context }) => [`Extract keywords from: ${context.input}`]),
|
|
274
|
-
])
|
|
275
|
-
.limit(2) // Limit parallel executions
|
|
276
|
-
)
|
|
277
|
-
// Results will be available in context.state.analysis as an array of PromiseSettledResult
|
|
278
|
-
```
|
|
279
|
-
|
|
280
|
-
### Iterative Execution with `loop` (Self-Correction)
|
|
281
|
-
|
|
282
|
-
Create validation loops where the AI evaluates its own responses or retries until a condition is met.
|
|
283
|
-
|
|
284
|
-
```ts
|
|
285
|
-
.step('refined_answer', ({ factory }) => factory
|
|
286
|
-
.loop('Self-Correction Loop')
|
|
287
|
-
.limit(3) // Max 3 attempts
|
|
288
|
-
.action(({ factory, context, verdict }) => factory
|
|
289
|
-
.ai('Answering')
|
|
290
|
-
.schema(z.object({
|
|
291
|
-
answer: z.string(),
|
|
292
|
-
isCorrect: z.boolean().describe('Self-check result')
|
|
293
|
-
}))
|
|
294
|
-
.prompt([
|
|
295
|
-
`Question: ${context.input}`,
|
|
296
|
-
verdict.status === 'pending' ? verdict.content : ''
|
|
297
|
-
])
|
|
298
|
-
)
|
|
299
|
-
.condition(({ result }) => {
|
|
300
|
-
if (result.isCorrect) {
|
|
301
|
-
return { status: 'fulfilled' };
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
return {
|
|
305
|
-
status: 'pending',
|
|
306
|
-
content: 'Your previous answer was incorrect. Please try again and be more specific.'
|
|
307
|
-
};
|
|
308
|
-
})
|
|
309
|
-
)
|
|
310
|
-
// Result will be { status: 'fulfilled' | 'voided', value: { answer, isCorrect } }
|
|
311
|
-
```
|
|
312
|
-
|
|
313
|
-
### Model Context Protocol (MCP) Integration
|
|
314
|
-
|
|
315
|
-
Integrate MCP servers to allow the AI to use tools provided by external service servers.
|
|
316
|
-
|
|
317
|
-
```ts
|
|
318
|
-
import { LlmMcp } from '@n1k1t/pipelain';
|
|
319
|
-
|
|
320
|
-
pipeline.step('mcp_research', ({ factory }) => factory
|
|
321
|
-
.ai('Researching with MCP')
|
|
322
|
-
.llm(({ context }) => context.llm.assign({
|
|
323
|
-
mcp: [
|
|
324
|
-
LlmMcp.build({
|
|
325
|
-
transport: {
|
|
326
|
-
type: 'stdio',
|
|
327
|
-
command: 'npx',
|
|
328
|
-
args: ['-y', '@modelcontextprotocol/server-gdrive'],
|
|
329
|
-
},
|
|
330
|
-
tools: {
|
|
331
|
-
enabled: ['list-files', 'read-file'], // Limit enabled tools
|
|
332
|
-
},
|
|
333
|
-
}),
|
|
334
|
-
],
|
|
335
|
-
}))
|
|
336
|
-
.prompt(['List my recent files in Google Drive and summarize them.'])
|
|
337
|
-
);
|
|
338
|
-
```
|
|
339
|
-
|
|
340
|
-
### Custom LLM Tools
|
|
341
|
-
|
|
342
|
-
Create and integrate your own custom tools using `LlmToolCompiler`.
|
|
343
|
-
|
|
344
|
-
```ts
|
|
345
|
-
import z from 'zod';
|
|
346
|
-
import { LlmToolCompiler } from '@n1k1t/pipelain';
|
|
347
|
-
|
|
348
|
-
const weatherTool = LlmToolCompiler
|
|
349
|
-
.build('Get current weather for a location')
|
|
350
|
-
.input(z.object({
|
|
351
|
-
city: z.string().describe('The city name')
|
|
352
|
-
}))
|
|
353
|
-
.output(z.object({
|
|
354
|
-
temperature: z.number(),
|
|
355
|
-
condition: z.string()
|
|
356
|
-
}))
|
|
357
|
-
.execute(() => async ({ city }) => {
|
|
358
|
-
return { temperature: 22, condition: 'Sunny' };
|
|
359
|
-
});
|
|
360
|
-
|
|
361
|
-
pipeline.step('weather_report', ({ factory, context }) => factory
|
|
362
|
-
.ai('Checking weather')
|
|
363
|
-
.llm(({ context }) => context.llm.assign({
|
|
364
|
-
tools: factory.tools
|
|
365
|
-
.web()
|
|
366
|
-
.custom({ weather: weatherTool })
|
|
367
|
-
.provide()
|
|
368
|
-
}))
|
|
369
|
-
.prompt([`Check weather in ${context.input}`])
|
|
370
|
-
);
|
|
371
|
-
```
|
|
372
|
-
|
|
373
|
-
---
|
|
374
|
-
|
|
375
|
-
## Steps
|
|
376
|
-
|
|
377
|
-
### 1. Analysis and Planning
|
|
378
|
-
|
|
379
|
-
Review the tasks and workflows that need to be accomplished by the AI:
|
|
380
|
-
- Determine step structure: Can the task be done in a single AI step, or does it require a sequence of steps?
|
|
381
|
-
- Assess if parallel execution (`swarm`) can speed up independent tasks.
|
|
382
|
-
- Assess if validation or correction is needed, requiring an iterative loop step (`loop`).
|
|
383
|
-
- Define inputs and outputs clearly, writing matching Zod schemas for structured responses.
|
|
384
|
-
|
|
385
|
-
### 2. Implementation Workflow
|
|
386
|
-
|
|
387
|
-
1. **Define Input**: Use `.input()` on `PipelineCompiler` to specify the entry schema.
|
|
388
|
-
2. **Chain Steps**: Chain `.step()` operations to orchestrate your workflow:
|
|
389
|
-
- Use `factory.ai()` for AI-driven steps, assigning prompt components (`utils.content`) and Zod schemas.
|
|
390
|
-
- Use local `self` steps (anonymous functions) to log, process outputs, or manipulate pipeline state.
|
|
391
|
-
3. **Configure Tools & Skills**: Use `.llm()` mapping to supply tools (`factory.tools`) or load skills (`factory.skills`) relevant to the current step.
|
|
392
|
-
4. **Compile and Execute**: Compile the pipeline using `.compile({ stdout })` and trigger execution using `.run(input)`.
|
|
393
|
-
|
|
394
|
-
### 3. Verification
|
|
395
|
-
|
|
396
|
-
- Enable debug mode `.debug()` on a step to mock execution and save the generated prompts into `.pipelain/${timestamp}-${session-id}/${step-title}.md` for inspection.
|
|
397
|
-
- Monitor log events by compiling the pipeline with `stdout: stdout.console`.
|
|
398
|
-
- Run TS type checking command `npm run build:check` to ensure correctness of Zod schemas and step definitions.
|
|
399
|
-
|
|
400
|
-
### 4. Refinement
|
|
401
|
-
|
|
402
|
-
- Optimize tokens and context size by restricting tool availability or specific paths (e.g. `allowed` paths in `files('read-write')`).
|
|
403
|
-
- If an AI step behaves inconsistently, split it into smaller, more granular steps or add a `loop` validation step.
|