@riotprompt/riotprompt 0.0.13 → 0.0.15
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/README.md +18 -15
- package/dist/chat.d.ts +2 -0
- package/dist/chat.js +2 -0
- package/dist/chat.js.map +1 -1
- package/dist/cli.cjs +118 -20
- package/dist/execution/anthropic.js +27 -3
- package/dist/execution/anthropic.js.map +1 -1
- package/dist/execution/gemini.js +45 -1
- package/dist/execution/gemini.js.map +1 -1
- package/dist/execution/openai.js +2 -1
- package/dist/execution/openai.js.map +1 -1
- package/dist/formatter.js +42 -14
- package/dist/formatter.js.map +1 -1
- package/dist/prompt.d.ts +19 -1
- package/dist/prompt.js +11 -2
- package/dist/prompt.js.map +1 -1
- package/dist/recipes.d.ts +108 -0
- package/dist/recipes.js +195 -30
- package/dist/recipes.js.map +1 -1
- package/dist/riotprompt.cjs +323 -51
- package/dist/riotprompt.cjs.map +1 -1
- package/guide/architecture.md +33 -22
- package/guide/index.md +25 -25
- package/guide/usage.md +96 -39
- package/package.json +3 -2
package/guide/architecture.md
CHANGED
|
@@ -5,47 +5,58 @@
|
|
|
5
5
|
## Core Concepts
|
|
6
6
|
|
|
7
7
|
### Prompt Structure
|
|
8
|
-
A `Prompt` in RiotPrompt is not a string; it is a structured object containing
|
|
8
|
+
A `Prompt` in RiotPrompt is not a string; it is a structured object containing multiple components that map to different aspects of prompt engineering:
|
|
9
9
|
|
|
10
10
|
1. **Persona**: Defines *who* the AI is (System Prompt).
|
|
11
11
|
2. **Instructions**: Defines *what* the AI should do (User Prompt / Task).
|
|
12
12
|
3. **Context**: Background information, data, or documents needed to perform the task.
|
|
13
|
-
4. **Content**: Specific input data to be processed in this execution
|
|
13
|
+
4. **Content**: Specific input data to be processed in this execution.
|
|
14
|
+
5. **Constraints**: Operational boundaries (e.g., word count, format restrictions).
|
|
15
|
+
6. **Tone**: Style guidelines (e.g., professional, humorous).
|
|
16
|
+
7. **Examples**: Few-shot examples to demonstrate desired behavior.
|
|
17
|
+
8. **Reasoning**: Instructions on the thinking process (e.g., Chain of Thought).
|
|
18
|
+
9. **ResponseFormat**: Instructions on the output structure.
|
|
19
|
+
10. **Recap**: Final reminders or summaries.
|
|
20
|
+
11. **Safeguards**: Safety guidelines.
|
|
14
21
|
|
|
15
22
|
### Section System
|
|
16
23
|
The fundamental building block is the `Section<T>`.
|
|
17
24
|
* A `Section` contains a list of items (of type `T`) and can also contain nested `Sections`.
|
|
18
|
-
* This allows for recursive, hierarchical structures
|
|
19
|
-
* **Weighted Items**: Most items extend `Weighted`, allowing them to have associated weights or parameters for advanced optimization
|
|
25
|
+
* This allows for recursive, hierarchical structures.
|
|
26
|
+
* **Weighted Items**: Most items extend `Weighted`, allowing them to have associated weights or parameters for advanced optimization.
|
|
20
27
|
|
|
21
28
|
## Module Structure
|
|
22
29
|
|
|
23
30
|
The project is organized into distinct logical modules:
|
|
24
31
|
|
|
25
32
|
* **`src/riotprompt.ts`**: The main entry point. Exports all sub-modules.
|
|
33
|
+
* **`src/recipes.ts`**: The **Recipes API** implementation (`cook` function). This is the high-level configuration layer that orchestrates the creation of prompts.
|
|
26
34
|
* **`src/prompt.ts`**: Defines the `Prompt` interface and factory.
|
|
27
|
-
* **`src/items/`**: Contains definitions for `Section
|
|
28
|
-
* **`src/loader.ts`**: Logic for loading prompt parts from the filesystem.
|
|
29
|
-
* **`src/formatter.ts`**: Responsible for taking a `Prompt` object and converting it into a specific format (e.g., a Chat Request object or a flat string). It handles model-specific
|
|
35
|
+
* **`src/items/`**: Contains definitions for `Section` and various item types.
|
|
36
|
+
* **`src/loader.ts`**: Logic for loading prompt parts from the filesystem.
|
|
37
|
+
* **`src/formatter.ts`**: Responsible for taking a `Prompt` object and converting it into a specific format (e.g., a Chat Request object or a flat string). It handles model-specific rules via adapters.
|
|
38
|
+
* **`src/execution/`**: Contains provider implementations (OpenAI, Anthropic, Gemini) that handle API calls and structured output adaptation.
|
|
30
39
|
* **`src/serializer.ts`**: Handles converting the internal `Prompt` structure to portable formats like JSON and XML.
|
|
31
|
-
* **`src/cli.ts`**: The command-line interface implementation
|
|
40
|
+
* **`src/cli.ts`**: The command-line interface implementation.
|
|
32
41
|
|
|
33
|
-
## Data Flow (
|
|
42
|
+
## Data Flow (Recipes API)
|
|
34
43
|
|
|
35
|
-
1. **
|
|
36
|
-
2. **
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
44
|
+
1. **Config**: User provides a `RecipeConfig` object (and optionally a template name).
|
|
45
|
+
2. **Cook**: The `cook` function processes the config:
|
|
46
|
+
* Loads templates if specified.
|
|
47
|
+
* Merges overrides.
|
|
48
|
+
* Resolves file paths using `Loader`.
|
|
49
|
+
* Creates `Section` objects for each component (`persona`, `instructions`, etc.).
|
|
50
|
+
* Processes `zod` schemas for structured output.
|
|
40
51
|
3. **Assembly**: Parts are combined into a `Prompt` object.
|
|
41
|
-
4. **
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
|
|
52
|
+
4. **Execution**:
|
|
53
|
+
* `executeChat` takes the `Prompt`.
|
|
54
|
+
* `Formatter` converts it to the provider-specific format (handling roles, schema adaptation).
|
|
55
|
+
* Provider client sends request and returns result.
|
|
45
56
|
|
|
46
57
|
## Design Decisions
|
|
47
58
|
|
|
48
|
-
* **
|
|
49
|
-
* **
|
|
50
|
-
* **
|
|
51
|
-
|
|
59
|
+
* **Configuration over Code**: The Recipes API favors declarative configuration over imperative builder patterns, making prompts easier to read and maintain.
|
|
60
|
+
* **Composition**: By keeping prompt parts separate until the final moment, we allow for dynamic injection, reordering, and model-specific formatting.
|
|
61
|
+
* **FileSystem as Source**: We treat the filesystem as a primary way to organize complex prompts. Folders represent Sections, files represent Items.
|
|
62
|
+
* **Portable Schemas**: We use `zod` as a universal schema definition language, adapting it to provider-specific formats (JSON Schema, Tools) at runtime to prevent vendor lock-in.
|
package/guide/index.md
CHANGED
|
@@ -8,40 +8,41 @@
|
|
|
8
8
|
|
|
9
9
|
`riotprompt` is a library and CLI tool designed to treat LLM prompts as structured code objects rather than simple strings. It allows for the modular assembly, validation, and formatting of prompts.
|
|
10
10
|
|
|
11
|
-
* **Structured Prompts**: Prompts are composed of distinct sections
|
|
12
|
-
* **
|
|
13
|
-
* **
|
|
14
|
-
* **
|
|
15
|
-
* **CLI Tool**: A command-line interface allows for easy processing
|
|
11
|
+
* **Structured Prompts**: Prompts are composed of distinct sections beyond just "System" and "User". Use specialized sections like `Persona`, `Instructions`, `Constraints`, `Tone`, `Examples`, `Reasoning`, and more.
|
|
12
|
+
* **Recipes & Templates**: A declarative API (`cook`) allows you to assemble prompts from configuration objects and reusable templates.
|
|
13
|
+
* **Structured Outputs**: Portable support for structured outputs using `zod` schemas. Write one schema and use it across OpenAI, Anthropic, and Gemini.
|
|
14
|
+
* **Model-Agnostic Formatting**: The library separates the *content* of a prompt from its *format*. It can output prompts optimized for different models (e.g., handling role mapping for OpenAI's O-series vs GPT-4).
|
|
15
|
+
* **CLI Tool**: A command-line interface allows for easy scaffolding, processing, and execution of file-based prompts.
|
|
16
16
|
|
|
17
17
|
## Quick Start Context
|
|
18
18
|
|
|
19
19
|
When analyzing or generating code using `riotprompt`, keep these patterns in mind:
|
|
20
20
|
|
|
21
|
-
1. **
|
|
22
|
-
2. **
|
|
23
|
-
3. **
|
|
21
|
+
1. **Use Recipes**: The `cook` function is the primary entry point for creating prompts programmatically.
|
|
22
|
+
2. **Use Schemas**: For structured data, pass a `zod` schema to `cook`.
|
|
23
|
+
3. **Execute via Provider**: Use `executeChat` to run prompts against LLMs, handling provider-specific details automatically.
|
|
24
24
|
|
|
25
25
|
```typescript
|
|
26
|
-
import
|
|
26
|
+
import { cook, executeChat } from '@riotprompt/riotprompt';
|
|
27
|
+
import { z } from 'zod';
|
|
27
28
|
|
|
28
|
-
//
|
|
29
|
-
const
|
|
30
|
-
.
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
.add(RiotPrompt.createInstruction('Summarize the following text.'));
|
|
29
|
+
// Define output structure
|
|
30
|
+
const ResultSchema = z.object({
|
|
31
|
+
summary: z.string(),
|
|
32
|
+
tags: z.array(z.string())
|
|
33
|
+
});
|
|
34
34
|
|
|
35
|
-
//
|
|
36
|
-
const prompt =
|
|
37
|
-
|
|
38
|
-
|
|
35
|
+
// Create prompt
|
|
36
|
+
const prompt = await cook({
|
|
37
|
+
basePath: __dirname,
|
|
38
|
+
persona: { content: 'You are a summarizer.' },
|
|
39
|
+
instructions: [{ content: 'Summarize the text.' }],
|
|
40
|
+
content: [{ content: 'Long text...' }],
|
|
41
|
+
schema: ResultSchema
|
|
39
42
|
});
|
|
40
43
|
|
|
41
|
-
//
|
|
42
|
-
const
|
|
43
|
-
// chatRequest will be a structured object suitable for API calls (e.g. OpenAI chat completion)
|
|
44
|
-
const chatRequest = formatter.formatPrompt('gpt-4', prompt);
|
|
44
|
+
// Execute
|
|
45
|
+
const result = await executeChat(prompt, { model: 'gpt-4o' });
|
|
45
46
|
```
|
|
46
47
|
|
|
47
48
|
## Documentation Structure
|
|
@@ -49,7 +50,6 @@ const chatRequest = formatter.formatPrompt('gpt-4', prompt);
|
|
|
49
50
|
This guide directory contains specialized documentation for different aspects of the system:
|
|
50
51
|
|
|
51
52
|
* [Architecture](./architecture.md): Internal design, module structure, and data flow.
|
|
52
|
-
* [Usage Patterns](./usage.md): Common patterns for CLI and library usage.
|
|
53
|
+
* [Usage Patterns](./usage.md): Common patterns for CLI and library usage, including the Recipes API and Structured Outputs.
|
|
53
54
|
* [Configuration](./configuration.md): Deep dive into configuration options.
|
|
54
55
|
* [Development](./development.md): Guide for contributing to `riotprompt`.
|
|
55
|
-
|
package/guide/usage.md
CHANGED
|
@@ -8,15 +8,18 @@ The CLI is the primary way to interact with filesystem-based prompts.
|
|
|
8
8
|
|
|
9
9
|
### Directory Structure
|
|
10
10
|
|
|
11
|
-
RiotPrompt expects a specific directory structure for a prompt "package":
|
|
11
|
+
RiotPrompt expects a specific directory structure for a prompt "package". You can now use expanded sections for more control:
|
|
12
12
|
|
|
13
13
|
```
|
|
14
14
|
my-prompt-project/
|
|
15
15
|
├── persona.md # OR directory persona/ containing .md files
|
|
16
16
|
├── instructions.md # OR directory instructions/ containing .md files
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
├── context/ # Directory containing reference files (json, md, txt)
|
|
18
|
+
│ ├── data.json
|
|
19
|
+
│ └── background.md
|
|
20
|
+
├── constraints.md # Optional: Operational constraints
|
|
21
|
+
├── tone.md # Optional: Tone and style guidelines
|
|
22
|
+
└── examples.md # Optional: Few-shot examples
|
|
20
23
|
```
|
|
21
24
|
|
|
22
25
|
### Commands
|
|
@@ -48,52 +51,106 @@ riotprompt process ./my-prompt-project --format json --output prompt.json
|
|
|
48
51
|
riotprompt process ./my-prompt-project --format xml --output prompt.xml
|
|
49
52
|
```
|
|
50
53
|
|
|
51
|
-
## Library Usage
|
|
54
|
+
## Library Usage (Recipes API)
|
|
52
55
|
|
|
53
|
-
|
|
56
|
+
The primary way to use RiotPrompt programmatically is via the **Recipes API** (`cook` function). This provides a declarative, configuration-driven approach.
|
|
54
57
|
|
|
55
|
-
###
|
|
58
|
+
### Basic Recipe
|
|
56
59
|
|
|
57
|
-
|
|
60
|
+
```typescript
|
|
61
|
+
import { cook } from '@riotprompt/riotprompt';
|
|
62
|
+
|
|
63
|
+
const prompt = await cook({
|
|
64
|
+
basePath: __dirname,
|
|
65
|
+
persona: { content: 'You are a helpful AI assistant.' },
|
|
66
|
+
instructions: [
|
|
67
|
+
{ content: 'Summarize the provided text.' }
|
|
68
|
+
],
|
|
69
|
+
content: [
|
|
70
|
+
{ content: 'Text to summarize goes here...' }
|
|
71
|
+
]
|
|
72
|
+
});
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Expanded Prompt Sections
|
|
76
|
+
|
|
77
|
+
RiotPrompt now supports a wide range of specialized sections to give you fine-grained control over the prompt structure. These are inspired by advanced prompting techniques.
|
|
78
|
+
|
|
79
|
+
* **`persona`**: Who the AI is.
|
|
80
|
+
* **`instructions`**: What the AI should do.
|
|
81
|
+
* **`context`**: Background information.
|
|
82
|
+
* **`content`**: The specific input to process.
|
|
83
|
+
* **`constraints`**: Hard rules and limitations (e.g., "Do not use markdown").
|
|
84
|
+
* **`tone`**: Style and voice guidelines (e.g., "Be professional and concise").
|
|
85
|
+
* **`examples`**: Few-shot examples to guide the model.
|
|
86
|
+
* **`reasoning`**: Instructions on how to think (e.g., "Think step-by-step").
|
|
87
|
+
* **`responseFormat`**: Instructions on output structure.
|
|
88
|
+
* **`recap`**: Final reminders or summaries of instructions.
|
|
89
|
+
* **`safeguards`**: Safety guidelines and refusal criteria.
|
|
58
90
|
|
|
59
91
|
```typescript
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
userContext.add(JSON.stringify(userData));
|
|
70
|
-
|
|
71
|
-
// 3. Create Instructions
|
|
72
|
-
const instructions = RiotPrompt.createSection({ title: 'Task' })
|
|
73
|
-
.add(RiotPrompt.createInstruction('Analyze this user data.'));
|
|
74
|
-
|
|
75
|
-
// 4. Assemble
|
|
76
|
-
const prompt = RiotPrompt.createPrompt({
|
|
77
|
-
instructions,
|
|
78
|
-
contexts: RiotPrompt.createSection({ title: 'Context' })
|
|
79
|
-
.add(baseContext)
|
|
80
|
-
.add(userContext) // Inject dynamic part
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
return prompt;
|
|
84
|
-
}
|
|
92
|
+
const prompt = await cook({
|
|
93
|
+
basePath: __dirname,
|
|
94
|
+
persona: { content: 'You are a senior code reviewer.' },
|
|
95
|
+
instructions: [{ content: 'Review this pull request.' }],
|
|
96
|
+
constraints: [{ content: 'Focus on security vulnerabilities.' }],
|
|
97
|
+
tone: [{ content: 'Constructive and empathetic.' }],
|
|
98
|
+
examples: [{ path: './examples/good-review.md' }],
|
|
99
|
+
content: [{ content: prDiff }]
|
|
100
|
+
});
|
|
85
101
|
```
|
|
86
102
|
|
|
87
|
-
###
|
|
103
|
+
### Structured Outputs (Portable Schemas)
|
|
88
104
|
|
|
89
|
-
|
|
105
|
+
RiotPrompt supports portable structured outputs using `zod` schemas. This works across different providers (OpenAI, Anthropic, Gemini) by automatically adapting the schema to the provider's expected format (JSON Schema, Tool Use, etc.).
|
|
90
106
|
|
|
91
107
|
```typescript
|
|
92
|
-
|
|
108
|
+
import { cook, executeChat } from '@riotprompt/riotprompt';
|
|
109
|
+
import { z } from 'zod';
|
|
110
|
+
|
|
111
|
+
// 1. Define your schema using Zod
|
|
112
|
+
const AnalysisSchema = z.object({
|
|
113
|
+
sentiment: z.enum(['positive', 'negative', 'neutral']),
|
|
114
|
+
keyPoints: z.array(z.string()),
|
|
115
|
+
confidence: z.number().min(0).max(1)
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
// 2. Pass it to the cook function
|
|
119
|
+
const prompt = await cook({
|
|
120
|
+
basePath: __dirname,
|
|
121
|
+
persona: { content: 'You are a sentiment analyzer.' },
|
|
122
|
+
content: [{ content: 'I loved this movie! It was fantastic.' }],
|
|
123
|
+
schema: AnalysisSchema // Pass the Zod schema directly
|
|
124
|
+
});
|
|
93
125
|
|
|
94
|
-
//
|
|
95
|
-
prompt
|
|
96
|
-
|
|
126
|
+
// 3. Execute (RiotPrompt handles the provider specifics)
|
|
127
|
+
const result = await executeChat(prompt, {
|
|
128
|
+
model: 'gpt-4o', // or 'claude-3-opus', 'gemini-1.5-pro'
|
|
129
|
+
apiKey: process.env.OPENAI_API_KEY
|
|
97
130
|
});
|
|
131
|
+
|
|
132
|
+
// result.content is validated and typed
|
|
133
|
+
console.log(result.content.sentiment); // "positive"
|
|
98
134
|
```
|
|
99
135
|
|
|
136
|
+
### Templates
|
|
137
|
+
|
|
138
|
+
You can register reusable templates to standardize prompts across your application.
|
|
139
|
+
|
|
140
|
+
```typescript
|
|
141
|
+
import { registerTemplates, cook } from '@riotprompt/riotprompt';
|
|
142
|
+
|
|
143
|
+
registerTemplates({
|
|
144
|
+
'security-audit': {
|
|
145
|
+
persona: { content: 'You are a security auditor.' },
|
|
146
|
+
constraints: [{ content: 'Report only high-severity issues.' }],
|
|
147
|
+
responseFormat: [{ content: 'Output as a CSV list.' }]
|
|
148
|
+
}
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
const prompt = await cook({
|
|
152
|
+
basePath: __dirname,
|
|
153
|
+
template: 'security-audit',
|
|
154
|
+
content: [{ content: sourceCode }]
|
|
155
|
+
});
|
|
156
|
+
```
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@riotprompt/riotprompt",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.15",
|
|
4
4
|
"keywords": [
|
|
5
5
|
"prompt",
|
|
6
6
|
"llm",
|
|
@@ -84,6 +84,7 @@
|
|
|
84
84
|
"marked": "^16.0.0",
|
|
85
85
|
"openai": "^6.15.0",
|
|
86
86
|
"tiktoken": "^1.0.22",
|
|
87
|
-
"zod": "^4.0.2"
|
|
87
|
+
"zod": "^4.0.2",
|
|
88
|
+
"zod-to-json-schema": "^3.25.1"
|
|
88
89
|
}
|
|
89
90
|
}
|