@lov3kaizen/agentsea-prompts 0.5.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 lovekaizen
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,518 @@
1
+ # @lov3kaizen/agentsea-prompts
2
+
3
+ Self-hosted prompt management with Git-like version control, environment promotion, A/B testing, and team collaboration. Treat prompts as first-class software artifacts with proper DevOps workflows.
4
+
5
+ ## Features
6
+
7
+ - **Version Control** - Git-like versioning with diff, history, branches, and merge
8
+ - **Environment Promotion** - Dev → Staging → Production workflows with approvals
9
+ - **Template Engine** - Handlebars-based templates with partials and helpers
10
+ - **A/B Testing** - Run experiments with statistical significance analysis
11
+ - **Multiple Backends** - File, SQLite, PostgreSQL, and S3 storage adapters
12
+ - **SDK Client** - Runtime prompt loading with caching and auto-refresh
13
+ - **AgentSea Integration** - Dynamic prompts for AI agents
14
+
15
+ ## Installation
16
+
17
+ ```bash
18
+ pnpm add @lov3kaizen/agentsea-prompts
19
+ ```
20
+
21
+ ## Quick Start
22
+
23
+ ```typescript
24
+ import { PromptRegistry, FileStorage } from '@lov3kaizen/agentsea-prompts';
25
+
26
+ // Create registry with file storage
27
+ const registry = new PromptRegistry({
28
+ storage: new FileStorage({ path: './prompts' }),
29
+ defaultEnvironment: 'development',
30
+ });
31
+
32
+ await registry.initialize();
33
+
34
+ // Create a prompt
35
+ const prompt = await registry.create({
36
+ name: 'customer-support',
37
+ description: 'Main customer support system prompt',
38
+ template: `You are a helpful customer support agent for {{company_name}}.
39
+
40
+ Your responsibilities:
41
+ - Answer questions about {{product_name}}
42
+ - Help with billing and account issues
43
+ - Escalate complex issues to human agents
44
+
45
+ Customer name: {{customer_name}}
46
+ Account type: {{account_type}}`,
47
+ variables: {
48
+ company_name: { type: 'string', required: true },
49
+ product_name: { type: 'string', required: true },
50
+ customer_name: { type: 'string', required: true },
51
+ account_type: { type: 'enum', values: ['free', 'pro', 'enterprise'] },
52
+ },
53
+ metadata: {
54
+ author: 'product-team',
55
+ tags: ['support', 'customer-facing'],
56
+ },
57
+ });
58
+
59
+ // Render with variables
60
+ const rendered = await registry.render('customer-support', {
61
+ company_name: 'Acme Corp',
62
+ product_name: 'Widget Pro',
63
+ customer_name: 'John Doe',
64
+ account_type: 'pro',
65
+ });
66
+
67
+ console.log(rendered.content);
68
+ ```
69
+
70
+ ## Version Control
71
+
72
+ ### Update Prompts
73
+
74
+ ```typescript
75
+ // Update creates a new version
76
+ const updated = await registry.update('customer-support', {
77
+ template: `${existingTemplate}
78
+
79
+ Additional guideline:
80
+ - Offer a 10% discount for frustrated customers`,
81
+ message: 'Added discount guideline for retention',
82
+ });
83
+
84
+ console.log(`Updated to ${updated.version}`); // v2
85
+ ```
86
+
87
+ ### View History
88
+
89
+ ```typescript
90
+ const history = await registry.history('customer-support');
91
+
92
+ for (const version of history) {
93
+ console.log(`${version.version}: ${version.message} (${version.author})`);
94
+ }
95
+ ```
96
+
97
+ ### Compare Versions
98
+
99
+ ```typescript
100
+ const diff = await registry.diff('customer-support', {
101
+ from: 'v1',
102
+ to: 'v2',
103
+ });
104
+
105
+ console.log(`+${diff.additions} -${diff.deletions}`);
106
+ console.log(`Similarity: ${(diff.similarity * 100).toFixed(1)}%`);
107
+ ```
108
+
109
+ ### Rollback
110
+
111
+ ```typescript
112
+ await registry.rollback('customer-support', {
113
+ to: 'v1',
114
+ reason: 'User complaints about new guideline',
115
+ });
116
+ ```
117
+
118
+ ### Branching
119
+
120
+ ```typescript
121
+ // Create a branch for experimentation
122
+ await registry.branch('customer-support', {
123
+ name: 'experiment/shorter-prompt',
124
+ from: 'v2',
125
+ });
126
+
127
+ // Make changes on the branch...
128
+
129
+ // Merge back to main
130
+ await registry.merge('customer-support', {
131
+ from: 'experiment/shorter-prompt',
132
+ strategy: 'squash',
133
+ message: 'Merged shorter prompt experiment',
134
+ });
135
+ ```
136
+
137
+ ## Environment Management
138
+
139
+ ### Define Environments
140
+
141
+ ```typescript
142
+ const registry = new PromptRegistry({
143
+ storage,
144
+ environments: [
145
+ { name: 'development', label: 'Dev', order: 1 },
146
+ { name: 'staging', label: 'Staging', order: 2 },
147
+ { name: 'production', label: 'Prod', protected: true, order: 3 },
148
+ ],
149
+ });
150
+ ```
151
+
152
+ ### Promote Prompts
153
+
154
+ ```typescript
155
+ // Promote from dev to staging
156
+ await registry.promote('customer-support', {
157
+ from: 'development',
158
+ to: 'staging',
159
+ version: 'v3',
160
+ message: 'Ready for QA testing',
161
+ });
162
+
163
+ // Promote to production (requires approver for protected env)
164
+ await registry.promote('customer-support', {
165
+ from: 'staging',
166
+ to: 'production',
167
+ version: 'v3',
168
+ approver: 'lead-engineer',
169
+ message: 'Approved after QA sign-off',
170
+ });
171
+ ```
172
+
173
+ ### Get Prompt by Environment
174
+
175
+ ```typescript
176
+ const prodPrompt = await registry.get('customer-support', {
177
+ environment: 'production',
178
+ });
179
+ ```
180
+
181
+ ## Template System
182
+
183
+ ### Variables
184
+
185
+ ```typescript
186
+ const prompt = await registry.create({
187
+ name: 'greeting',
188
+ template: 'Hello, {{name}}! Welcome to {{company}}.',
189
+ variables: {
190
+ name: { type: 'string', required: true },
191
+ company: { type: 'string', default: 'Acme Corp' },
192
+ },
193
+ });
194
+
195
+ // Render with validation
196
+ const result = await registry.render('greeting', { name: 'Alice' });
197
+ // "Hello, Alice! Welcome to Acme Corp."
198
+ ```
199
+
200
+ ### Partials (Reusable Snippets)
201
+
202
+ ```typescript
203
+ import { Partial } from '@lov3kaizen/agentsea-prompts';
204
+
205
+ // Register partials
206
+ await registry.registerPartial(
207
+ new Partial({
208
+ name: 'safety-guidelines',
209
+ template: `Safety Guidelines:
210
+ - Never provide harmful information
211
+ - Decline requests for illegal activities
212
+ - Protect user privacy at all times`,
213
+ }),
214
+ );
215
+
216
+ // Use in prompts
217
+ const prompt = await registry.create({
218
+ name: 'assistant',
219
+ template: `You are a helpful assistant.
220
+
221
+ {{> safety-guidelines}}
222
+
223
+ Task: {{task}}`,
224
+ });
225
+ ```
226
+
227
+ ### Built-in Helpers
228
+
229
+ ```typescript
230
+ // Available helpers
231
+ const template = `
232
+ {{upper name}} // JOHN
233
+ {{lower name}} // john
234
+ {{capitalize name}} // John
235
+ {{truncate text 50}} // Truncated text...
236
+ {{default value "N/A"}} // Default if undefined
237
+ {{json object}} // JSON stringified
238
+ {{join array ", "}} // Array to string
239
+ {{date timestamp "iso"}} // Date formatting
240
+ {{number value 2}} // Number with decimals
241
+ `;
242
+ ```
243
+
244
+ ## A/B Testing
245
+
246
+ ### Create Test
247
+
248
+ ```typescript
249
+ import { ABTest } from '@lov3kaizen/agentsea-prompts';
250
+
251
+ const test = await registry.createABTest({
252
+ name: 'concise-vs-detailed',
253
+ prompt: 'customer-support',
254
+ variants: [
255
+ { name: 'control', version: 'v1', weight: 0.5 },
256
+ { name: 'treatment', version: 'v2', weight: 0.5 },
257
+ ],
258
+ metrics: ['user_satisfaction', 'resolution_time'],
259
+ targetSampleSize: 1000,
260
+ confidenceLevel: 0.95,
261
+ });
262
+ ```
263
+
264
+ ### Assign Variants
265
+
266
+ ```typescript
267
+ // Get variant for user (consistent assignment)
268
+ const variant = await test.getVariant({ userId: 'user-123' });
269
+ const prompt = await registry.get('customer-support', {
270
+ version: variant.version,
271
+ });
272
+ ```
273
+
274
+ ### Record Metrics
275
+
276
+ ```typescript
277
+ await test.recordMetric('control', 'user_satisfaction', 4.5, {
278
+ userId: 'user-123',
279
+ });
280
+ ```
281
+
282
+ ### Get Results
283
+
284
+ ```typescript
285
+ const results = await test.getResults();
286
+
287
+ console.log('Total samples:', results.totalSamples);
288
+ console.log('Significant?', results.isSignificant);
289
+ console.log('Winner:', results.winner);
290
+ console.log('P-value:', results.pValue);
291
+ console.log('Recommendation:', results.recommendation);
292
+ ```
293
+
294
+ ## SDK Client
295
+
296
+ ### Runtime Loading
297
+
298
+ ```typescript
299
+ import { PromptClient } from '@lov3kaizen/agentsea-prompts/client';
300
+
301
+ const client = new PromptClient({
302
+ registryUrl: 'https://prompts.example.com',
303
+ apiKey: process.env.PROMPT_API_KEY,
304
+ environment: 'production',
305
+ cache: {
306
+ enabled: true,
307
+ ttl: 300, // 5 minutes
308
+ },
309
+ });
310
+
311
+ // Load and render prompt
312
+ const result = await client.render('customer-support', {
313
+ company_name: 'Acme Corp',
314
+ customer_name: 'John',
315
+ });
316
+ ```
317
+
318
+ ### Local Prompts
319
+
320
+ ```typescript
321
+ // Register local prompts (no API needed)
322
+ client.register('greeting', 'Hello, {{name}}!', {
323
+ variables: { name: { type: 'string', required: true } },
324
+ });
325
+
326
+ const result = await client.render('greeting', { name: 'Alice' });
327
+ ```
328
+
329
+ ### Auto-Refresh
330
+
331
+ ```typescript
332
+ // Listen for updates
333
+ client.on('prompt:updated', ({ name, version }) => {
334
+ console.log(`Prompt ${name} updated to ${version}`);
335
+ });
336
+ ```
337
+
338
+ ## AgentSea Integration
339
+
340
+ ### Dynamic Prompts
341
+
342
+ ```typescript
343
+ import { Agent } from '@lov3kaizen/agentsea-core';
344
+ import { PromptProvider } from '@lov3kaizen/agentsea-prompts';
345
+
346
+ const provider = new PromptProvider({
347
+ registry,
348
+ environment: 'production',
349
+ autoRefresh: true,
350
+ });
351
+
352
+ // Create agent with managed prompt
353
+ const agent = new Agent({
354
+ name: 'support-agent',
355
+ model: 'claude-sonnet-4-20250514',
356
+ provider: 'anthropic',
357
+ // Dynamic prompt from registry
358
+ systemPrompt: provider.dynamic('customer-support', {
359
+ company_name: 'Acme Corp',
360
+ product_name: 'Widget Pro',
361
+ }),
362
+ });
363
+
364
+ // Prompt updates automatically when registry changes!
365
+ ```
366
+
367
+ ### Helper Functions
368
+
369
+ ```typescript
370
+ import { createSystemPrompt } from '@lov3kaizen/agentsea-prompts';
371
+
372
+ const agent = new Agent({
373
+ systemPrompt: createSystemPrompt(provider, 'customer-support', {
374
+ company_name: 'Acme Corp',
375
+ }),
376
+ });
377
+ ```
378
+
379
+ ## Storage Adapters
380
+
381
+ ### File Storage (Git-friendly)
382
+
383
+ ```typescript
384
+ import { FileStorage } from '@lov3kaizen/agentsea-prompts';
385
+
386
+ const storage = new FileStorage({
387
+ path: './prompts',
388
+ format: 'json',
389
+ });
390
+ ```
391
+
392
+ ### In-Memory (Testing)
393
+
394
+ ```typescript
395
+ import { BufferStorage } from '@lov3kaizen/agentsea-prompts';
396
+
397
+ const storage = new BufferStorage();
398
+ ```
399
+
400
+ ### PostgreSQL (Coming Soon)
401
+
402
+ ```typescript
403
+ import { PostgresStorage } from '@lov3kaizen/agentsea-prompts';
404
+
405
+ const storage = new PostgresStorage({
406
+ connectionString: process.env.DATABASE_URL,
407
+ });
408
+ ```
409
+
410
+ ## API Reference
411
+
412
+ ### PromptRegistry
413
+
414
+ ```typescript
415
+ interface PromptRegistry {
416
+ // CRUD
417
+ create(input: CreatePromptInput): Promise<Prompt>;
418
+ get(
419
+ name: string,
420
+ options?: { environment?: string; version?: string },
421
+ ): Promise<Prompt | null>;
422
+ update(name: string, updates: UpdatePromptInput): Promise<Prompt>;
423
+ delete(name: string): Promise<boolean>;
424
+ query(options: PromptQueryOptions): Promise<Prompt[]>;
425
+
426
+ // Rendering
427
+ render(
428
+ name: string,
429
+ variables: Record<string, unknown>,
430
+ ): Promise<RenderedPrompt>;
431
+
432
+ // Version Control
433
+ history(name: string, options?: { limit?: number }): Promise<PromptVersion[]>;
434
+ diff(name: string, options: DiffOptions): Promise<DiffResult>;
435
+ rollback(name: string, options: RollbackOptions): Promise<RollbackResult>;
436
+ branch(name: string, input: CreateBranchInput): Promise<BranchInfo>;
437
+ merge(name: string, options: MergeOptions): Promise<MergeResult>;
438
+
439
+ // Environments
440
+ promote(name: string, options: PromoteInput): Promise<PromotionResult>;
441
+ getEnvironments(): EnvironmentConfig[];
442
+
443
+ // Partials
444
+ registerPartial(partial: Partial): Promise<void>;
445
+ getPartial(name: string): Partial | undefined;
446
+
447
+ // A/B Testing
448
+ createABTest(config: ABTestConfig): Promise<ABTestData>;
449
+
450
+ // Reviews
451
+ requestReview(name: string, input: CreateReviewInput): Promise<ReviewRequest>;
452
+
453
+ // Audit
454
+ getAuditLog(options?: AuditLogQueryOptions): Promise<AuditLogEntry[]>;
455
+ }
456
+ ```
457
+
458
+ ### Prompt
459
+
460
+ ```typescript
461
+ interface Prompt {
462
+ id: string;
463
+ name: string;
464
+ description?: string;
465
+ template: string;
466
+ variables: VariableDefinitions;
467
+ metadata: PromptMetadata;
468
+ status: PromptStatus;
469
+ version: string;
470
+ environment: string;
471
+ hash: string;
472
+
473
+ render(
474
+ variables: Record<string, unknown>,
475
+ options?: RenderOptions,
476
+ ): RenderedPrompt;
477
+ getVariableNames(): string[];
478
+ getRequiredVariables(): string[];
479
+ clone(overrides?: Partial<PromptData>): Prompt;
480
+ }
481
+ ```
482
+
483
+ ### PromptClient
484
+
485
+ ```typescript
486
+ interface PromptClient {
487
+ get(name: string, options?: { version?: string }): Promise<Prompt | null>;
488
+ render(
489
+ name: string,
490
+ variables: Record<string, unknown>,
491
+ ): Promise<RenderedPrompt>;
492
+ register(
493
+ name: string,
494
+ template: string,
495
+ options?: { variables?: VariableDefinitions },
496
+ ): Prompt;
497
+ has(name: string): Promise<boolean>;
498
+ list(): string[];
499
+ invalidate(name: string): void;
500
+ clearCache(): void;
501
+ }
502
+ ```
503
+
504
+ ## Best Practices
505
+
506
+ 1. **Use descriptive names** - `customer-support-v2` not `cs2`
507
+ 2. **Add commit messages** - Document why changes were made
508
+ 3. **Test in staging** - Always promote through environments
509
+ 4. **Use partials** - Share common prompt sections
510
+ 5. **Version variables** - Update variable definitions with templates
511
+ 6. **Monitor A/B tests** - Wait for statistical significance
512
+ 7. **Cache in production** - Use SDK client with caching
513
+
514
+ ## Links
515
+
516
+ - [Documentation](https://github.com/lov3kaizen/agentsea)
517
+ - [Examples](../../examples)
518
+ - [API Reference](../../docs/API.md)
@@ -0,0 +1,117 @@
1
+ import { EventEmitter } from 'eventemitter3';
2
+ import { P as PromptData, V as VariableDefinitions, a as PromptMetadata, b as PromptStatus, R as RenderOptions, c as RenderedPrompt } from './prompt.types-UpghZJIu.js';
3
+
4
+ declare class Prompt implements PromptData {
5
+ readonly id: string;
6
+ readonly name: string;
7
+ description?: string;
8
+ template: string;
9
+ variables: VariableDefinitions;
10
+ metadata: PromptMetadata;
11
+ status: PromptStatus;
12
+ version: string;
13
+ environment: string;
14
+ createdAt: Date;
15
+ updatedAt: Date;
16
+ createdBy?: string;
17
+ hash: string;
18
+ private compiledTemplate?;
19
+ constructor(data: Partial<PromptData> & {
20
+ name: string;
21
+ template: string;
22
+ });
23
+ private inferVariables;
24
+ render(variables: Record<string, unknown>, options?: RenderOptions): RenderedPrompt;
25
+ getVariableNames(): string[];
26
+ hasVariable(name: string): boolean;
27
+ getRequiredVariables(): string[];
28
+ getOptionalVariables(): string[];
29
+ clone(overrides?: Partial<PromptData>): Prompt;
30
+ toData(): PromptData;
31
+ toJSON(): string;
32
+ static fromData(data: PromptData): Prompt;
33
+ static fromJSON(json: string): Prompt;
34
+ update(updates: {
35
+ template?: string;
36
+ description?: string;
37
+ variables?: VariableDefinitions;
38
+ metadata?: PromptMetadata;
39
+ status?: PromptStatus;
40
+ }): Prompt;
41
+ hasChanges(other: Prompt): boolean;
42
+ getDisplayName(): string;
43
+ getPreview(maxLength?: number): string;
44
+ }
45
+
46
+ interface PromptClientConfig {
47
+ registryUrl?: string;
48
+ apiKey?: string;
49
+ environment?: string;
50
+ cache?: {
51
+ enabled: boolean;
52
+ ttl?: number;
53
+ maxSize?: number;
54
+ };
55
+ pollInterval?: number;
56
+ fetch?: typeof fetch;
57
+ }
58
+ interface ClientEvents {
59
+ 'prompt:updated': {
60
+ name: string;
61
+ version: string;
62
+ };
63
+ 'prompt:loaded': {
64
+ name: string;
65
+ version: string;
66
+ };
67
+ error: {
68
+ message: string;
69
+ cause?: unknown;
70
+ };
71
+ }
72
+ declare class PromptClient extends EventEmitter<ClientEvents> {
73
+ private config;
74
+ private cache;
75
+ private pollTimer?;
76
+ private prompts;
77
+ private initialized;
78
+ constructor(config?: PromptClientConfig);
79
+ initialize(): Promise<void>;
80
+ close(): void;
81
+ get(name: string, options?: {
82
+ version?: string;
83
+ forceRefresh?: boolean;
84
+ }): Promise<Prompt | null>;
85
+ render(name: string, variables: Record<string, unknown>, options?: RenderOptions & {
86
+ version?: string;
87
+ }): Promise<RenderedPrompt>;
88
+ register(name: string, template: string, options?: {
89
+ variables?: VariableDefinitions;
90
+ description?: string;
91
+ }): Prompt;
92
+ registerMany(prompts: Record<string, {
93
+ template: string;
94
+ variables?: VariableDefinitions;
95
+ }>): void;
96
+ has(name: string): Promise<boolean>;
97
+ list(): string[];
98
+ private fetchPrompt;
99
+ private getCached;
100
+ private setCached;
101
+ private startPolling;
102
+ private checkForUpdates;
103
+ invalidate(name: string): void;
104
+ clearCache(): void;
105
+ }
106
+ declare class PromptLoader {
107
+ private client;
108
+ private name;
109
+ private defaultVariables;
110
+ constructor(client: PromptClient, name: string, defaultVariables?: Record<string, unknown>);
111
+ render(variables?: Record<string, unknown>, options?: RenderOptions): Promise<string>;
112
+ getPrompt(): Promise<Prompt | null>;
113
+ getVariables(): Promise<string[]>;
114
+ }
115
+ declare function createDynamicPrompt(client: PromptClient, name: string, defaultVariables?: Record<string, unknown>): () => Promise<string>;
116
+
117
+ export { type ClientEvents as C, Prompt as P, PromptClient as a, PromptLoader as b, createDynamicPrompt as c, type PromptClientConfig as d };