@riotprompt/riotprompt 0.0.12 → 0.0.14

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.
Files changed (61) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +136 -33
  3. package/dist/builder.js +3 -0
  4. package/dist/builder.js.map +1 -1
  5. package/dist/chat.d.ts +2 -0
  6. package/dist/chat.js +2 -0
  7. package/dist/chat.js.map +1 -1
  8. package/dist/cli.cjs +1617 -0
  9. package/dist/cli.d.ts +8 -0
  10. package/dist/config.d.ts +7 -0
  11. package/dist/conversation-logger.js +6 -1
  12. package/dist/conversation-logger.js.map +1 -1
  13. package/dist/execution/anthropic.d.ts +5 -0
  14. package/dist/execution/anthropic.js +70 -0
  15. package/dist/execution/anthropic.js.map +1 -0
  16. package/dist/execution/gemini.d.ts +5 -0
  17. package/dist/execution/gemini.js +122 -0
  18. package/dist/execution/gemini.js.map +1 -0
  19. package/dist/execution/index.d.ts +10 -0
  20. package/dist/execution/index.js +53 -0
  21. package/dist/execution/index.js.map +1 -0
  22. package/dist/execution/openai.d.ts +5 -0
  23. package/dist/execution/openai.js +45 -0
  24. package/dist/execution/openai.js.map +1 -0
  25. package/dist/execution/provider.d.ts +18 -0
  26. package/dist/formatter.js +42 -14
  27. package/dist/formatter.js.map +1 -1
  28. package/dist/loader.js +3 -0
  29. package/dist/loader.js.map +1 -1
  30. package/dist/model-config.d.ts +1 -0
  31. package/dist/model-config.js +19 -18
  32. package/dist/model-config.js.map +1 -1
  33. package/dist/override.js +3 -0
  34. package/dist/override.js.map +1 -1
  35. package/dist/prompt.d.ts +19 -1
  36. package/dist/prompt.js +11 -2
  37. package/dist/prompt.js.map +1 -1
  38. package/dist/recipes.d.ts +108 -0
  39. package/dist/recipes.js +198 -30
  40. package/dist/recipes.js.map +1 -1
  41. package/dist/riotprompt.cjs +930 -123
  42. package/dist/riotprompt.cjs.map +1 -1
  43. package/dist/riotprompt.d.ts +3 -0
  44. package/dist/riotprompt.js +6 -0
  45. package/dist/riotprompt.js.map +1 -1
  46. package/dist/serializer.d.ts +5 -0
  47. package/dist/serializer.js +220 -0
  48. package/dist/serializer.js.map +1 -0
  49. package/dist/writer.d.ts +2 -0
  50. package/dist/writer.js +91 -0
  51. package/dist/writer.js.map +1 -0
  52. package/guide/architecture.md +51 -0
  53. package/guide/configuration.md +51 -0
  54. package/guide/development.md +62 -0
  55. package/guide/index.md +55 -0
  56. package/guide/usage.md +99 -0
  57. package/package.json +15 -3
  58. package/vite.config.cli.ts +49 -0
  59. package/BUG-ANALYSIS.md +0 -523
  60. package/CODE-REVIEW-SUMMARY.md +0 -330
  61. package/FIXES-APPLIED.md +0 -437
@@ -5,10 +5,15 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
5
5
  const zod = require('zod');
6
6
  const fs = require('fs/promises');
7
7
  const path = require('path');
8
+ const zodToJsonSchema = require('zod-to-json-schema');
8
9
  const crypto = require('crypto');
9
10
  const tiktoken = require('tiktoken');
11
+ const OpenAI = require('openai');
12
+ const Anthropic = require('@anthropic-ai/sdk');
13
+ const generativeAi = require('@google/generative-ai');
10
14
  const fs$1 = require('fs');
11
15
  const glob = require('glob');
16
+ const fastXmlParser = require('fast-xml-parser');
12
17
 
13
18
  function _interopNamespaceDefault(e) {
14
19
  const n = Object.create(null, { [Symbol.toStringTag]: { value: 'Module' } });
@@ -232,12 +237,21 @@ const create$7 = (text, options = {})=>{
232
237
  return create$c(text, weightedOptions);
233
238
  };
234
239
 
235
- const create$6 = ({ persona, instructions, contents, contexts })=>{
240
+ const create$6 = ({ persona, instructions, contents, contexts, constraints, tone, examples, reasoning, responseFormat, recap, safeguards, schema, validator })=>{
236
241
  return {
237
242
  persona,
238
243
  instructions,
239
244
  contents,
240
- contexts
245
+ contexts,
246
+ constraints,
247
+ tone,
248
+ examples,
249
+ reasoning,
250
+ responseFormat,
251
+ recap,
252
+ safeguards,
253
+ schema,
254
+ validator
241
255
  };
242
256
  };
243
257
 
@@ -305,7 +319,7 @@ const wrapLogger = (toWrap, name)=>{
305
319
  };
306
320
  };
307
321
 
308
- function _define_property$8(obj, key, value) {
322
+ function _define_property$9(obj, key, value) {
309
323
  if (key in obj) {
310
324
  Object.defineProperty(obj, key, {
311
325
  value: value,
@@ -324,23 +338,14 @@ function _define_property$8(obj, key, value) {
324
338
  /**
325
339
  * Register default model configurations
326
340
  */ registerDefaults() {
327
- // GPT-4 family (uses 'system' role)
341
+ // Default fallback (Registered first so it ends up last with unshift)
328
342
  this.register({
329
- pattern: /^gpt-4/i,
343
+ pattern: /.*/,
330
344
  personaRole: 'system',
331
345
  encoding: 'gpt-4o',
332
346
  supportsToolCalls: true,
333
- family: 'gpt-4',
334
- description: 'GPT-4 family models'
335
- });
336
- // O-series models (uses 'developer' role)
337
- this.register({
338
- pattern: /^o\d+/i,
339
- personaRole: 'developer',
340
- encoding: 'gpt-4o',
341
- supportsToolCalls: true,
342
- family: 'o-series',
343
- description: 'O-series reasoning models'
347
+ family: 'unknown',
348
+ description: 'Default fallback configuration'
344
349
  });
345
350
  // Claude family (uses 'system' role)
346
351
  this.register({
@@ -351,27 +356,37 @@ function _define_property$8(obj, key, value) {
351
356
  family: 'claude',
352
357
  description: 'Claude family models'
353
358
  });
354
- // Default fallback
359
+ // O-series models (uses 'developer' role)
355
360
  this.register({
356
- pattern: /.*/,
361
+ pattern: /^o\d+/i,
362
+ personaRole: 'developer',
363
+ encoding: 'gpt-4o',
364
+ supportsToolCalls: true,
365
+ family: 'o-series',
366
+ description: 'O-series reasoning models'
367
+ });
368
+ // GPT-4 family (uses 'system' role)
369
+ this.register({
370
+ pattern: /^gpt-4/i,
357
371
  personaRole: 'system',
358
372
  encoding: 'gpt-4o',
359
373
  supportsToolCalls: true,
360
- family: 'unknown',
361
- description: 'Default fallback configuration'
374
+ family: 'gpt-4',
375
+ description: 'GPT-4 family models'
362
376
  });
363
377
  this.logger.debug('Registered default model configurations');
364
378
  }
365
379
  /**
366
380
  * Register a model configuration
367
381
  * Configs are checked in registration order (first match wins)
382
+ * New configs are added to the beginning of the list (high priority)
368
383
  */ register(config) {
369
384
  var _config_pattern;
370
385
  // Validate config
371
386
  if (!config.pattern && !config.exactMatch) {
372
387
  throw new Error('Model config must have either pattern or exactMatch');
373
388
  }
374
- this.configs.push(config);
389
+ this.configs.unshift(config);
375
390
  this.cache.clear(); // Clear cache when new config is added
376
391
  this.logger.debug('Registered model config', {
377
392
  family: config.family,
@@ -443,9 +458,9 @@ function _define_property$8(obj, key, value) {
443
458
  ];
444
459
  }
445
460
  constructor(logger){
446
- _define_property$8(this, "configs", void 0);
447
- _define_property$8(this, "cache", void 0);
448
- _define_property$8(this, "logger", void 0);
461
+ _define_property$9(this, "configs", void 0);
462
+ _define_property$9(this, "cache", void 0);
463
+ _define_property$9(this, "logger", void 0);
449
464
  this.configs = [];
450
465
  this.cache = new Map();
451
466
  this.logger = wrapLogger(logger || DEFAULT_LOGGER, 'ModelRegistry');
@@ -514,6 +529,8 @@ const createRequest = (model)=>{
514
529
  return {
515
530
  model,
516
531
  messages,
532
+ responseFormat: undefined,
533
+ validator: undefined,
517
534
  addMessage: (message)=>{
518
535
  messages.push(message);
519
536
  }
@@ -666,24 +683,52 @@ const create$5 = (formatterOptions)=>{
666
683
  const formatPrompt = (model, prompt)=>{
667
684
  logger.silly('Formatting prompt');
668
685
  const chatRequest = createRequest(model);
669
- if (prompt.persona) {
670
- [
671
- prompt.persona
672
- ].forEach((persona)=>{
673
- chatRequest.addMessage(formatPersona(model, persona));
686
+ // --- System/Role Message Construction ---
687
+ // Collect sections that belong in the system/developer prompt (Persona, Tone, Constraints, etc.)
688
+ const systemSections = [];
689
+ if (prompt.persona) systemSections.push(prompt.persona);
690
+ if (prompt.tone) systemSections.push(prompt.tone);
691
+ if (prompt.constraints) systemSections.push(prompt.constraints);
692
+ if (prompt.safeguards) systemSections.push(prompt.safeguards);
693
+ if (prompt.responseFormat) systemSections.push(prompt.responseFormat);
694
+ if (systemSections.length > 0) {
695
+ // Combine all system sections into one system message content
696
+ const systemContent = systemSections.map((section)=>formatSection(section)).join('\n\n');
697
+ chatRequest.addMessage({
698
+ role: getPersonaRole(model),
699
+ content: systemContent
700
+ });
701
+ }
702
+ // --- User/Task Message Construction ---
703
+ // Logical flow: Context -> Examples -> Instructions -> Content -> Reasoning -> Recap
704
+ // This structure guides the model through the context and examples before presenting the core task
705
+ const userSections = [
706
+ prompt.contexts,
707
+ prompt.examples,
708
+ prompt.instructions,
709
+ prompt.contents,
710
+ prompt.reasoning,
711
+ prompt.recap
712
+ ];
713
+ let formattedUserContent = "";
714
+ for (const section of userSections){
715
+ if (section) {
716
+ formattedUserContent += formatSection(section) + '\n\n';
717
+ }
718
+ }
719
+ // Ensure we always have a user message, or if we have content to send
720
+ if (formattedUserContent.trim().length > 0 || systemSections.length === 0) {
721
+ chatRequest.addMessage({
722
+ role: "user",
723
+ content: formattedUserContent.trim() || " "
674
724
  });
675
725
  }
676
- let formattedAreas = formatSection(prompt.instructions) + '\n\n';
677
- if (prompt.contents) {
678
- formattedAreas += formatSection(prompt.contents) + '\n\n';
726
+ if (prompt.schema) {
727
+ chatRequest.responseFormat = prompt.schema;
679
728
  }
680
- if (prompt.contexts) {
681
- formattedAreas += formatSection(prompt.contexts) + '\n\n';
729
+ if (prompt.validator) {
730
+ chatRequest.validator = prompt.validator;
682
731
  }
683
- chatRequest.addMessage({
684
- role: "user",
685
- content: formattedAreas
686
- });
687
732
  return chatRequest;
688
733
  };
689
734
  return {
@@ -1593,7 +1638,7 @@ const builder = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({
1593
1638
  create
1594
1639
  }, Symbol.toStringTag, { value: 'Module' }));
1595
1640
 
1596
- function _define_property$7(obj, key, value) {
1641
+ function _define_property$8(obj, key, value) {
1597
1642
  if (key in obj) {
1598
1643
  Object.defineProperty(obj, key, {
1599
1644
  value: value,
@@ -1822,16 +1867,16 @@ function _define_property$7(obj, key, value) {
1822
1867
  return content.replace(/\s+/g, ' ').trim().toLowerCase();
1823
1868
  }
1824
1869
  constructor(logger){
1825
- _define_property$7(this, "items", void 0);
1826
- _define_property$7(this, "hashes", void 0);
1827
- _define_property$7(this, "logger", void 0);
1870
+ _define_property$8(this, "items", void 0);
1871
+ _define_property$8(this, "hashes", void 0);
1872
+ _define_property$8(this, "logger", void 0);
1828
1873
  this.items = new Map();
1829
1874
  this.hashes = new Set();
1830
1875
  this.logger = wrapLogger(logger || DEFAULT_LOGGER, 'ContextManager');
1831
1876
  }
1832
1877
  }
1833
1878
 
1834
- function _define_property$6(obj, key, value) {
1879
+ function _define_property$7(obj, key, value) {
1835
1880
  if (key in obj) {
1836
1881
  Object.defineProperty(obj, key, {
1837
1882
  value: value,
@@ -2004,7 +2049,12 @@ function _define_property$6(obj, key, value) {
2004
2049
  }
2005
2050
  const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
2006
2051
  const filename = this.config.filenameTemplate.replace('{timestamp}', timestamp).replace('{id}', this.conversationId).replace('{template}', this.metadata.template || 'default');
2007
- const ext = this.config.format === 'markdown' ? '.md' : '.json';
2052
+ let ext = '.json';
2053
+ if (this.config.format === 'markdown') {
2054
+ ext = '.md';
2055
+ } else if (this.config.format === 'jsonl') {
2056
+ ext = '.jsonl';
2057
+ }
2008
2058
  const fullPath = path.join(this.config.outputPath, filename + ext);
2009
2059
  // Ensure directory exists
2010
2060
  await fs.mkdir(path.dirname(fullPath), {
@@ -2096,16 +2146,16 @@ function _define_property$6(obj, key, value) {
2096
2146
  return redacted;
2097
2147
  }
2098
2148
  constructor(config, logger){
2099
- _define_property$6(this, "config", void 0);
2100
- _define_property$6(this, "conversationId", void 0);
2101
- _define_property$6(this, "metadata", void 0);
2102
- _define_property$6(this, "messages", void 0);
2103
- _define_property$6(this, "toolCalls", void 0);
2104
- _define_property$6(this, "startTime", void 0);
2105
- _define_property$6(this, "logger", void 0);
2106
- _define_property$6(this, "messageIndex", void 0);
2107
- _define_property$6(this, "cachedOutputPath", void 0);
2108
- _define_property$6(this, "writeQueue", Promise.resolve());
2149
+ _define_property$7(this, "config", void 0);
2150
+ _define_property$7(this, "conversationId", void 0);
2151
+ _define_property$7(this, "metadata", void 0);
2152
+ _define_property$7(this, "messages", void 0);
2153
+ _define_property$7(this, "toolCalls", void 0);
2154
+ _define_property$7(this, "startTime", void 0);
2155
+ _define_property$7(this, "logger", void 0);
2156
+ _define_property$7(this, "messageIndex", void 0);
2157
+ _define_property$7(this, "cachedOutputPath", void 0);
2158
+ _define_property$7(this, "writeQueue", Promise.resolve());
2109
2159
  this.config = {
2110
2160
  outputPath: 'logs/conversations',
2111
2161
  format: 'json',
@@ -2309,14 +2359,14 @@ function _define_property$6(obj, key, value) {
2309
2359
  await fs.writeFile(outputPath, markdown, 'utf-8');
2310
2360
  }
2311
2361
  constructor(conversation, logger){
2312
- _define_property$6(this, "conversation", void 0);
2313
- _define_property$6(this, "logger", void 0);
2362
+ _define_property$7(this, "conversation", void 0);
2363
+ _define_property$7(this, "logger", void 0);
2314
2364
  this.conversation = conversation;
2315
2365
  this.logger = wrapLogger(logger || DEFAULT_LOGGER, 'ConversationReplayer');
2316
2366
  }
2317
2367
  }
2318
2368
 
2319
- function _define_property$5(obj, key, value) {
2369
+ function _define_property$6(obj, key, value) {
2320
2370
  if (key in obj) {
2321
2371
  Object.defineProperty(obj, key, {
2322
2372
  value: value,
@@ -2499,13 +2549,13 @@ function _define_property$5(obj, key, value) {
2499
2549
  return message;
2500
2550
  }
2501
2551
  constructor(role, logger){
2502
- _define_property$5(this, "semanticRole", void 0);
2503
- _define_property$5(this, "contentParts", void 0);
2504
- _define_property$5(this, "metadata", void 0);
2505
- _define_property$5(this, "formatter", void 0);
2506
- _define_property$5(this, "toolCallId", void 0);
2507
- _define_property$5(this, "toolCalls", void 0);
2508
- _define_property$5(this, "logger", void 0);
2552
+ _define_property$6(this, "semanticRole", void 0);
2553
+ _define_property$6(this, "contentParts", void 0);
2554
+ _define_property$6(this, "metadata", void 0);
2555
+ _define_property$6(this, "formatter", void 0);
2556
+ _define_property$6(this, "toolCallId", void 0);
2557
+ _define_property$6(this, "toolCalls", void 0);
2558
+ _define_property$6(this, "logger", void 0);
2509
2559
  this.semanticRole = role;
2510
2560
  this.contentParts = [];
2511
2561
  this.metadata = {};
@@ -2566,7 +2616,7 @@ function _define_property$5(obj, key, value) {
2566
2616
  }
2567
2617
  };
2568
2618
 
2569
- function _define_property$4(obj, key, value) {
2619
+ function _define_property$5(obj, key, value) {
2570
2620
  if (key in obj) {
2571
2621
  Object.defineProperty(obj, key, {
2572
2622
  value: value,
@@ -2682,9 +2732,9 @@ function _define_property$4(obj, key, value) {
2682
2732
  this.encoder.free();
2683
2733
  }
2684
2734
  constructor(model, logger){
2685
- _define_property$4(this, "encoder", void 0);
2686
- _define_property$4(this, "model", void 0);
2687
- _define_property$4(this, "logger", void 0);
2735
+ _define_property$5(this, "encoder", void 0);
2736
+ _define_property$5(this, "model", void 0);
2737
+ _define_property$5(this, "logger", void 0);
2688
2738
  this.model = model;
2689
2739
  this.logger = wrapLogger(logger || DEFAULT_LOGGER, 'TokenCounter');
2690
2740
  // Map RiotPrompt models to Tiktoken models
@@ -2940,9 +2990,9 @@ function _define_property$4(obj, key, value) {
2940
2990
  this.counter.dispose();
2941
2991
  }
2942
2992
  constructor(config, model, logger){
2943
- _define_property$4(this, "config", void 0);
2944
- _define_property$4(this, "counter", void 0);
2945
- _define_property$4(this, "logger", void 0);
2993
+ _define_property$5(this, "config", void 0);
2994
+ _define_property$5(this, "counter", void 0);
2995
+ _define_property$5(this, "logger", void 0);
2946
2996
  this.config = {
2947
2997
  warningThreshold: 0.8,
2948
2998
  preserveRecent: 3,
@@ -2961,7 +3011,7 @@ function _define_property$4(obj, key, value) {
2961
3011
  }
2962
3012
  }
2963
3013
 
2964
- function _define_property$3(obj, key, value) {
3014
+ function _define_property$4(obj, key, value) {
2965
3015
  if (key in obj) {
2966
3016
  Object.defineProperty(obj, key, {
2967
3017
  value: value,
@@ -3575,11 +3625,11 @@ const ConversationBuilderConfigSchema = zod.z.object({
3575
3625
  this.state.metadata.lastModified = new Date();
3576
3626
  }
3577
3627
  constructor(config, logger){
3578
- _define_property$3(this, "state", void 0);
3579
- _define_property$3(this, "config", void 0);
3580
- _define_property$3(this, "logger", void 0);
3581
- _define_property$3(this, "budgetManager", void 0);
3582
- _define_property$3(this, "conversationLogger", void 0);
3628
+ _define_property$4(this, "state", void 0);
3629
+ _define_property$4(this, "config", void 0);
3630
+ _define_property$4(this, "logger", void 0);
3631
+ _define_property$4(this, "budgetManager", void 0);
3632
+ _define_property$4(this, "conversationLogger", void 0);
3583
3633
  this.config = ConversationBuilderConfigSchema.parse(config);
3584
3634
  this.logger = wrapLogger(logger || DEFAULT_LOGGER, 'ConversationBuilder');
3585
3635
  this.state = {
@@ -3600,7 +3650,7 @@ const ConversationBuilderConfigSchema = zod.z.object({
3600
3650
  }
3601
3651
  }
3602
3652
 
3603
- function _define_property$2(obj, key, value) {
3653
+ function _define_property$3(obj, key, value) {
3604
3654
  if (key in obj) {
3605
3655
  Object.defineProperty(obj, key, {
3606
3656
  value: value,
@@ -3907,10 +3957,10 @@ const ToolSchema = zod.z.object({
3907
3957
  });
3908
3958
  }
3909
3959
  constructor(context = {}, logger){
3910
- _define_property$2(this, "tools", void 0);
3911
- _define_property$2(this, "context", void 0);
3912
- _define_property$2(this, "logger", void 0);
3913
- _define_property$2(this, "usageStats", void 0);
3960
+ _define_property$3(this, "tools", void 0);
3961
+ _define_property$3(this, "context", void 0);
3962
+ _define_property$3(this, "logger", void 0);
3963
+ _define_property$3(this, "usageStats", void 0);
3914
3964
  this.tools = new Map();
3915
3965
  this.context = context;
3916
3966
  this.logger = wrapLogger(logger || DEFAULT_LOGGER, 'ToolRegistry');
@@ -3919,7 +3969,7 @@ const ToolSchema = zod.z.object({
3919
3969
  }
3920
3970
  }
3921
3971
 
3922
- function _define_property$1(obj, key, value) {
3972
+ function _define_property$2(obj, key, value) {
3923
3973
  if (key in obj) {
3924
3974
  Object.defineProperty(obj, key, {
3925
3975
  value: value,
@@ -4050,10 +4100,10 @@ function _define_property$1(obj, key, value) {
4050
4100
  return stats;
4051
4101
  }
4052
4102
  constructor(logger){
4053
- _define_property$1(this, "startTime", void 0);
4054
- _define_property$1(this, "toolMetrics", void 0);
4055
- _define_property$1(this, "iterationCount", void 0);
4056
- _define_property$1(this, "logger", void 0);
4103
+ _define_property$2(this, "startTime", void 0);
4104
+ _define_property$2(this, "toolMetrics", void 0);
4105
+ _define_property$2(this, "iterationCount", void 0);
4106
+ _define_property$2(this, "logger", void 0);
4057
4107
  this.startTime = new Date();
4058
4108
  this.toolMetrics = [];
4059
4109
  this.iterationCount = 0;
@@ -4328,12 +4378,12 @@ function _define_property$1(obj, key, value) {
4328
4378
  return markdown;
4329
4379
  }
4330
4380
  constructor(logger){
4331
- _define_property$1(this, "logger", void 0);
4381
+ _define_property$2(this, "logger", void 0);
4332
4382
  this.logger = wrapLogger(logger || DEFAULT_LOGGER, 'ReflectionReportGenerator');
4333
4383
  }
4334
4384
  }
4335
4385
 
4336
- function _define_property(obj, key, value) {
4386
+ function _define_property$1(obj, key, value) {
4337
4387
  if (key in obj) {
4338
4388
  Object.defineProperty(obj, key, {
4339
4389
  value: value,
@@ -4685,10 +4735,10 @@ function _define_property(obj, key, value) {
4685
4735
  };
4686
4736
  }
4687
4737
  constructor(llm, logger){
4688
- _define_property(this, "llm", void 0);
4689
- _define_property(this, "logger", void 0);
4690
- _define_property(this, "metricsCollector", void 0);
4691
- _define_property(this, "reflectionConfig", void 0);
4738
+ _define_property$1(this, "llm", void 0);
4739
+ _define_property$1(this, "logger", void 0);
4740
+ _define_property$1(this, "metricsCollector", void 0);
4741
+ _define_property$1(this, "reflectionConfig", void 0);
4692
4742
  this.llm = llm;
4693
4743
  this.logger = wrapLogger(logger || DEFAULT_LOGGER, 'StrategyExecutor');
4694
4744
  }
@@ -4881,6 +4931,15 @@ const RecipeConfigSchema = zod.z.object({
4881
4931
  instructions: zod.z.array(ContentItemSchema).optional().default([]),
4882
4932
  content: zod.z.array(ContentItemSchema).optional().default([]),
4883
4933
  context: zod.z.array(ContentItemSchema).optional().default([]),
4934
+ // Advanced prompting sections
4935
+ constraints: zod.z.array(ContentItemSchema).optional().default([]),
4936
+ tone: zod.z.array(ContentItemSchema).optional().default([]),
4937
+ examples: zod.z.array(ContentItemSchema).optional().default([]),
4938
+ reasoning: zod.z.array(ContentItemSchema).optional().default([]),
4939
+ responseFormat: zod.z.array(ContentItemSchema).optional().default([]),
4940
+ recap: zod.z.array(ContentItemSchema).optional().default([]),
4941
+ safeguards: zod.z.array(ContentItemSchema).optional().default([]),
4942
+ schema: zod.z.any().optional(),
4884
4943
  // Templates and inheritance
4885
4944
  extends: zod.z.string().optional(),
4886
4945
  template: zod.z.string().optional(),
@@ -5046,6 +5105,13 @@ const cook = async (config)=>{
5046
5105
  instructions: [],
5047
5106
  content: [],
5048
5107
  context: [],
5108
+ constraints: [],
5109
+ tone: [],
5110
+ examples: [],
5111
+ reasoning: [],
5112
+ responseFormat: [],
5113
+ recap: [],
5114
+ safeguards: [],
5049
5115
  ...config
5050
5116
  });
5051
5117
  // Handle template inheritance
@@ -5069,7 +5135,36 @@ const cook = async (config)=>{
5069
5135
  context: [
5070
5136
  ...template.context || [],
5071
5137
  ...validatedConfig.context || []
5072
- ]
5138
+ ],
5139
+ constraints: [
5140
+ ...template.constraints || [],
5141
+ ...validatedConfig.constraints || []
5142
+ ],
5143
+ tone: [
5144
+ ...template.tone || [],
5145
+ ...validatedConfig.tone || []
5146
+ ],
5147
+ examples: [
5148
+ ...template.examples || [],
5149
+ ...validatedConfig.examples || []
5150
+ ],
5151
+ reasoning: [
5152
+ ...template.reasoning || [],
5153
+ ...validatedConfig.reasoning || []
5154
+ ],
5155
+ responseFormat: [
5156
+ ...template.responseFormat || [],
5157
+ ...validatedConfig.responseFormat || []
5158
+ ],
5159
+ recap: [
5160
+ ...template.recap || [],
5161
+ ...validatedConfig.recap || []
5162
+ ],
5163
+ safeguards: [
5164
+ ...template.safeguards || [],
5165
+ ...validatedConfig.safeguards || []
5166
+ ],
5167
+ schema: validatedConfig.schema || template.schema
5073
5168
  };
5074
5169
  }
5075
5170
  }
@@ -5101,6 +5196,39 @@ const cook = async (config)=>{
5101
5196
  const contextSection = create$8({
5102
5197
  title: "Context"
5103
5198
  });
5199
+ // Advanced sections
5200
+ const constraintSection = create$8({
5201
+ title: "Constraints"
5202
+ });
5203
+ const toneSection = create$8({
5204
+ title: "Tone"
5205
+ });
5206
+ const exampleSection = create$8({
5207
+ title: "Examples"
5208
+ });
5209
+ const reasoningSection = create$8({
5210
+ title: "Reasoning"
5211
+ });
5212
+ const responseFormatSection = create$8({
5213
+ title: "Response Format"
5214
+ });
5215
+ const recapSection = create$8({
5216
+ title: "Recap"
5217
+ });
5218
+ const safeguardSection = create$8({
5219
+ title: "Safeguards"
5220
+ });
5221
+ // Helper for processing list items
5222
+ const processList = async (items, section, type)=>{
5223
+ for (const item of items){
5224
+ await processContentItem(item, section, type, {
5225
+ basePath: finalConfig.basePath,
5226
+ parser: parser$1,
5227
+ override: override$1,
5228
+ loader: loader$1,
5229
+ parameters: finalConfig.parameters});
5230
+ }
5231
+ };
5104
5232
  // Process persona
5105
5233
  if (finalConfig.persona) {
5106
5234
  await processContentItem(finalConfig.persona, personaSection, 'persona', {
@@ -5110,15 +5238,18 @@ const cook = async (config)=>{
5110
5238
  loader: loader$1,
5111
5239
  parameters: finalConfig.parameters});
5112
5240
  }
5113
- // Process instructions
5114
- for (const item of finalConfig.instructions || []){
5115
- await processContentItem(item, instructionSection, 'instruction', {
5116
- basePath: finalConfig.basePath,
5117
- parser: parser$1,
5118
- override: override$1,
5119
- loader: loader$1,
5120
- parameters: finalConfig.parameters});
5121
- }
5241
+ // Process standard sections
5242
+ await processList(finalConfig.instructions || [], instructionSection, 'instruction');
5243
+ await processList(finalConfig.content || [], contentSection, 'content');
5244
+ await processList(finalConfig.context || [], contextSection, 'context');
5245
+ // Process advanced sections
5246
+ await processList(finalConfig.constraints || [], constraintSection, 'instruction');
5247
+ await processList(finalConfig.tone || [], toneSection, 'instruction');
5248
+ await processList(finalConfig.examples || [], exampleSection, 'content');
5249
+ await processList(finalConfig.reasoning || [], reasoningSection, 'instruction');
5250
+ await processList(finalConfig.responseFormat || [], responseFormatSection, 'instruction');
5251
+ await processList(finalConfig.recap || [], recapSection, 'instruction');
5252
+ await processList(finalConfig.safeguards || [], safeguardSection, 'instruction');
5122
5253
  // Generate tool guidance if tools are provided
5123
5254
  if (finalConfig.tools) {
5124
5255
  const tools = Array.isArray(finalConfig.tools) ? finalConfig.tools : finalConfig.tools.getAll();
@@ -5132,30 +5263,59 @@ const cook = async (config)=>{
5132
5263
  instructionSection.add(toolSection);
5133
5264
  }
5134
5265
  }
5135
- // Process content
5136
- for (const item of finalConfig.content || []){
5137
- await processContentItem(item, contentSection, 'content', {
5138
- basePath: finalConfig.basePath,
5139
- parser: parser$1,
5140
- override: override$1,
5141
- loader: loader$1,
5142
- parameters: finalConfig.parameters});
5143
- }
5144
- // Process context
5145
- for (const item of finalConfig.context || []){
5146
- await processContentItem(item, contextSection, 'context', {
5147
- basePath: finalConfig.basePath,
5148
- parser: parser$1,
5149
- override: override$1,
5150
- loader: loader$1,
5151
- parameters: finalConfig.parameters});
5266
+ // Process schema
5267
+ let schema = finalConfig.schema;
5268
+ let validator = undefined;
5269
+ if (schema instanceof zod.z.ZodType) {
5270
+ var _jsonSchema_definitions;
5271
+ // It's a Zod schema!
5272
+ validator = schema;
5273
+ const jsonSchema = zodToJsonSchema(schema, "response");
5274
+ // Wrap in OpenAI Structured Output format
5275
+ // zod-to-json-schema returns { "$schema": "...", "definitions": { "response": { ... } }, "$ref": "#/definitions/response" }
5276
+ // We need to extract the schema part.
5277
+ // Simpler usage for OpenAI: just get the schema object.
5278
+ // Actually, zod-to-json-schema produces a full JSON schema object.
5279
+ // OpenAI expects: { type: "json_schema", json_schema: { name: "...", schema: ... } }
5280
+ // Let's create a clean schema object
5281
+ // NOTE: OpenAI requires strict: true and additionalProperties: false
5282
+ // zod-to-json-schema generally produces compatible schemas but strictness might need tweaking if required by OpenAI.
5283
+ // For now, let's assume "response" as the name.
5284
+ // We'll define a simpler conversion if possible, or trust the user to configure Zod strictly if they want strict mode.
5285
+ // Extract the definition if it exists
5286
+ const actualSchema = ((_jsonSchema_definitions = jsonSchema.definitions) === null || _jsonSchema_definitions === void 0 ? void 0 : _jsonSchema_definitions.response) || jsonSchema;
5287
+ schema = {
5288
+ type: "json_schema",
5289
+ json_schema: {
5290
+ name: "response",
5291
+ schema: actualSchema,
5292
+ strict: true // Try to enable strict mode for OpenAI
5293
+ }
5294
+ };
5295
+ } else if (typeof schema === 'string') {
5296
+ const schemaPath = path.resolve(finalConfig.basePath, schema);
5297
+ try {
5298
+ const schemaContent = await fs.readFile(schemaPath, 'utf-8');
5299
+ schema = JSON.parse(schemaContent);
5300
+ } catch (e) {
5301
+ throw new Error(`Failed to load schema from ${schemaPath}: ${e.message}`);
5302
+ }
5152
5303
  }
5153
5304
  // Build and return prompt
5154
5305
  return create$6({
5155
- persona: personaSection,
5306
+ persona: personaSection.items.length > 0 ? personaSection : undefined,
5156
5307
  instructions: instructionSection,
5157
- contents: contentSection,
5158
- contexts: contextSection
5308
+ contents: contentSection.items.length > 0 ? contentSection : undefined,
5309
+ contexts: contextSection.items.length > 0 ? contextSection : undefined,
5310
+ constraints: constraintSection.items.length > 0 ? constraintSection : undefined,
5311
+ tone: toneSection.items.length > 0 ? toneSection : undefined,
5312
+ examples: exampleSection.items.length > 0 ? exampleSection : undefined,
5313
+ reasoning: reasoningSection.items.length > 0 ? reasoningSection : undefined,
5314
+ responseFormat: responseFormatSection.items.length > 0 ? responseFormatSection : undefined,
5315
+ recap: recapSection.items.length > 0 ? recapSection : undefined,
5316
+ safeguards: safeguardSection.items.length > 0 ? safeguardSection : undefined,
5317
+ schema,
5318
+ validator
5159
5319
  });
5160
5320
  };
5161
5321
  const processContentItem = async (item, section, type, ctx)=>{
@@ -5233,6 +5393,59 @@ const recipe = (basePath)=>{
5233
5393
  ];
5234
5394
  return builder;
5235
5395
  },
5396
+ constraints: (...constraints)=>{
5397
+ config.constraints = [
5398
+ ...config.constraints || [],
5399
+ ...constraints
5400
+ ];
5401
+ return builder;
5402
+ },
5403
+ tone: (...tone)=>{
5404
+ config.tone = [
5405
+ ...config.tone || [],
5406
+ ...tone
5407
+ ];
5408
+ return builder;
5409
+ },
5410
+ examples: (...examples)=>{
5411
+ config.examples = [
5412
+ ...config.examples || [],
5413
+ ...examples
5414
+ ];
5415
+ return builder;
5416
+ },
5417
+ reasoning: (...reasoning)=>{
5418
+ config.reasoning = [
5419
+ ...config.reasoning || [],
5420
+ ...reasoning
5421
+ ];
5422
+ return builder;
5423
+ },
5424
+ responseFormat: (...responseFormat)=>{
5425
+ config.responseFormat = [
5426
+ ...config.responseFormat || [],
5427
+ ...responseFormat
5428
+ ];
5429
+ return builder;
5430
+ },
5431
+ recap: (...recap)=>{
5432
+ config.recap = [
5433
+ ...config.recap || [],
5434
+ ...recap
5435
+ ];
5436
+ return builder;
5437
+ },
5438
+ safeguards: (...safeguards)=>{
5439
+ config.safeguards = [
5440
+ ...config.safeguards || [],
5441
+ ...safeguards
5442
+ ];
5443
+ return builder;
5444
+ },
5445
+ schema: (schema)=>{
5446
+ config.schema = schema;
5447
+ return builder;
5448
+ },
5236
5449
  parameters: (parameters)=>{
5237
5450
  config.parameters = {
5238
5451
  ...config.parameters,
@@ -5317,12 +5530,604 @@ const recipes = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({
5317
5530
  registerTemplates
5318
5531
  }, Symbol.toStringTag, { value: 'Module' }));
5319
5532
 
5533
+ const toJSON = (prompt)=>{
5534
+ return JSON.stringify(prompt, null, 2);
5535
+ };
5536
+ const escapeXML = (str)=>{
5537
+ return str.replace(/[<>&'"]/g, (c)=>{
5538
+ switch(c){
5539
+ case '<':
5540
+ return '&lt;';
5541
+ case '>':
5542
+ return '&gt;';
5543
+ case '&':
5544
+ return '&amp;';
5545
+ case '\'':
5546
+ return '&apos;';
5547
+ case '"':
5548
+ return '&quot;';
5549
+ default:
5550
+ return c;
5551
+ }
5552
+ });
5553
+ };
5554
+ const itemToXML = (item)=>{
5555
+ if (typeof item === 'string') {
5556
+ return `<item>${escapeXML(item)}</item>`;
5557
+ }
5558
+ // Check if it's a section
5559
+ if (item && typeof item === 'object' && 'items' in item) {
5560
+ return sectionToXML(item);
5561
+ }
5562
+ // Check if it's a weighted item
5563
+ if (item && typeof item === 'object' && 'text' in item) {
5564
+ const weightAttr = item.weight !== undefined && item.weight !== null ? ` weight="${item.weight}"` : '';
5565
+ return `<item${weightAttr}>${escapeXML(item.text)}</item>`;
5566
+ }
5567
+ return '';
5568
+ };
5569
+ const sectionToXML = (section, tagName = 'section')=>{
5570
+ const titleAttr = section.title ? ` title="${escapeXML(section.title)}"` : '';
5571
+ const weightAttr = section.weight ? ` weight="${section.weight}"` : '';
5572
+ let xml = `<${tagName}${titleAttr}${weightAttr}>`;
5573
+ if (section.items && Array.isArray(section.items)) {
5574
+ xml += section.items.map((item)=>itemToXML(item)).join('');
5575
+ }
5576
+ xml += `</${tagName}>`;
5577
+ return xml;
5578
+ };
5579
+ const toXML = (prompt)=>{
5580
+ let xml = '<?xml version="1.0" encoding="UTF-8"?>\n<prompt>';
5581
+ if (prompt.persona) {
5582
+ xml += sectionToXML(prompt.persona, 'persona');
5583
+ }
5584
+ if (prompt.instructions) {
5585
+ xml += sectionToXML(prompt.instructions, 'instructions');
5586
+ }
5587
+ if (prompt.contents) {
5588
+ xml += sectionToXML(prompt.contents, 'contents');
5589
+ }
5590
+ if (prompt.contexts) {
5591
+ xml += sectionToXML(prompt.contexts, 'contexts');
5592
+ }
5593
+ xml += '</prompt>';
5594
+ return xml;
5595
+ };
5596
+ // ============================================================================
5597
+ // DESERIALIZATION
5598
+ // ============================================================================
5599
+ // --- JSON Parsing ---
5600
+ const parseSectionFromJSON = (jsonSection)=>{
5601
+ if (!jsonSection || !jsonSection.items) {
5602
+ throw new Error("Invalid section structure");
5603
+ }
5604
+ const section = create$8({
5605
+ title: jsonSection.title,
5606
+ weight: jsonSection.weight
5607
+ });
5608
+ for (const item of jsonSection.items){
5609
+ if (typeof item === 'object' && 'items' in item) {
5610
+ // It's a nested section
5611
+ section.add(parseSectionFromJSON(item));
5612
+ } else if (typeof item === 'object' && 'text' in item) {
5613
+ section.add({
5614
+ text: item.text,
5615
+ weight: item.weight
5616
+ });
5617
+ } else if (typeof item === 'string') {
5618
+ section.add(item);
5619
+ }
5620
+ }
5621
+ return section;
5622
+ };
5623
+ const fromJSON = (jsonString)=>{
5624
+ const json = JSON.parse(jsonString);
5625
+ // We treat the root json object as matching Prompt interface
5626
+ // But we need to convert plain objects back to Section instances with methods
5627
+ const persona = json.persona ? parseSectionFromJSON(json.persona) : undefined;
5628
+ const instructions = json.instructions ? parseSectionFromJSON(json.instructions) : create$8({
5629
+ title: 'Instructions'
5630
+ });
5631
+ const contents = json.contents ? parseSectionFromJSON(json.contents) : undefined;
5632
+ const contexts = json.contexts ? parseSectionFromJSON(json.contexts) : undefined;
5633
+ return create$6({
5634
+ persona,
5635
+ instructions,
5636
+ contents,
5637
+ contexts
5638
+ });
5639
+ };
5640
+ // --- XML Parsing ---
5641
+ const parseNodeToSection = (node)=>{
5642
+ // Node structure with preserveOrder: true
5643
+ // It seems attributes can be a sibling property ":@" OR inside the children array depending on version/config/content.
5644
+ // Children are in the array value of the key "section", "persona", etc.
5645
+ const children = node.section || node.persona || node.instructions || node.contents || node.contexts || [];
5646
+ let attributes = node[":@"] || {};
5647
+ // Fallback: check if attributes are inside the children array (as seen in some tests/mocks)
5648
+ if (!node[":@"] && Array.isArray(children)) {
5649
+ for (const child of children){
5650
+ if (child[":@"]) {
5651
+ attributes = child[":@"];
5652
+ break;
5653
+ }
5654
+ }
5655
+ }
5656
+ const title = attributes["@_title"];
5657
+ const weight = attributes["@_weight"] ? Number(attributes["@_weight"]) : undefined;
5658
+ const section = create$8({
5659
+ title,
5660
+ weight
5661
+ });
5662
+ if (Array.isArray(children)) {
5663
+ for (const child of children){
5664
+ const key = Object.keys(child)[0]; // "item" or "section" or ":@"
5665
+ // console.log(`Processing child key: ${key}`);
5666
+ if (key === ":@") continue; // Already handled or just attributes
5667
+ if (key === "item") {
5668
+ // Item structure: [ { "#text": "Value" }, { ":@": ... } ]
5669
+ const itemContent = child.item;
5670
+ let text = "";
5671
+ let itemWeight = undefined;
5672
+ for (const part of itemContent){
5673
+ const keys = Object.keys(part);
5674
+ // console.log('Processing item part keys:', keys);
5675
+ if (keys.includes("#text")) {
5676
+ text = part["#text"];
5677
+ } else if (keys.includes(":@")) {
5678
+ const attrs = part[":@"];
5679
+ // console.log('Found attributes:', attrs);
5680
+ // Check both with and without prefix just in case
5681
+ const w = attrs["@_weight"] || attrs["weight"];
5682
+ if (w !== undefined) itemWeight = Number(w);
5683
+ } else {
5684
+ // Fallback for cases where attributes might be directly on the part (unexpected but possible)
5685
+ const w = part["@_weight"] || part["weight"];
5686
+ if (w !== undefined) itemWeight = Number(w);
5687
+ }
5688
+ }
5689
+ // console.log(`Adding item: ${text}`);
5690
+ section.add({
5691
+ text,
5692
+ weight: itemWeight
5693
+ });
5694
+ } else if (key === "section") {
5695
+ section.add(parseNodeToSection(child));
5696
+ }
5697
+ }
5698
+ }
5699
+ return section;
5700
+ };
5701
+ const fromXML = (xmlString)=>{
5702
+ const parser = new fastXmlParser.XMLParser({
5703
+ ignoreAttributes: false,
5704
+ attributeNamePrefix: "@_",
5705
+ preserveOrder: true,
5706
+ trimValues: true
5707
+ });
5708
+ const parsed = parser.parse(xmlString);
5709
+ // parsed is [ { "?xml": ... }, { "prompt": [ ... ] } ]
5710
+ let promptNode = null;
5711
+ for (const node of parsed){
5712
+ if (node.prompt) {
5713
+ promptNode = node.prompt;
5714
+ break;
5715
+ }
5716
+ }
5717
+ if (!promptNode) throw new Error("Invalid XML: missing <prompt> root");
5718
+ let persona;
5719
+ let instructions = create$8({
5720
+ title: "Instructions"
5721
+ });
5722
+ let contents;
5723
+ let contexts;
5724
+ for (const child of promptNode){
5725
+ if (child.persona) {
5726
+ persona = parseNodeToSection(child);
5727
+ persona.title = "Persona"; // Force title for standard sections?
5728
+ } else if (child.instructions) {
5729
+ instructions = parseNodeToSection(child);
5730
+ instructions.title = "Instructions";
5731
+ } else if (child.contents) {
5732
+ contents = parseNodeToSection(child);
5733
+ contents.title = "Contents";
5734
+ } else if (child.contexts) {
5735
+ contexts = parseNodeToSection(child);
5736
+ contexts.title = "Contexts";
5737
+ }
5738
+ }
5739
+ return create$6({
5740
+ persona,
5741
+ instructions,
5742
+ contents,
5743
+ contexts
5744
+ });
5745
+ };
5746
+
5747
+ const serializer = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({
5748
+ __proto__: null,
5749
+ fromJSON,
5750
+ fromXML,
5751
+ toJSON,
5752
+ toXML
5753
+ }, Symbol.toStringTag, { value: 'Module' }));
5754
+
5755
+ const saveToDirectory = async (prompt, basePath)=>{
5756
+ // Ensure base directory exists
5757
+ await fs__namespace.mkdir(basePath, {
5758
+ recursive: true
5759
+ });
5760
+ // 1. Save Persona
5761
+ if (prompt.persona) {
5762
+ await saveSection(prompt.persona, path__namespace.join(basePath, 'persona'));
5763
+ }
5764
+ // 2. Save Instructions
5765
+ if (prompt.instructions) {
5766
+ await saveSection(prompt.instructions, path__namespace.join(basePath, 'instructions'));
5767
+ }
5768
+ // 3. Save Context
5769
+ if (prompt.contexts) {
5770
+ await saveSection(prompt.contexts, path__namespace.join(basePath, 'context'));
5771
+ }
5772
+ // 4. Save Content (if any)
5773
+ if (prompt.contents) {
5774
+ await saveSection(prompt.contents, path__namespace.join(basePath, 'content'));
5775
+ }
5776
+ };
5777
+ const saveSection = async (section, targetPath)=>{
5778
+ // If section has subsections, create a directory and recurse
5779
+ // If section only has items, check if we can save as single file (e.g. name of section + .md)
5780
+ // Simplification: We will use a mixed approach.
5781
+ // If the section is "flat" (only items), we can write it to a file.
5782
+ // If the section is "nested" (has subsections), we create a directory.
5783
+ // However, to be consistent with Loader logic:
5784
+ // Loader reads files in a directory as subsections.
5785
+ // So if we have a section "Instructions", and we save it as a directory "instructions":
5786
+ // Its items become content of files?
5787
+ // Strategy:
5788
+ // 1. Create directory `targetPath`.
5789
+ // 2. If the section has items (text), verify if they have titles (subsections).
5790
+ // 3. For each item:
5791
+ // - If it's a string/Instruction/Content/Context (leaf):
5792
+ // - If the parent section is the ROOT (e.g. 'persona'), and it's just text, maybe we prefer `persona.md`.
5793
+ // - If it's a subsection:
5794
+ // - Recurse into subdirectory.
5795
+ // Let's refine based on typical usage:
5796
+ // - Persona: usually one big text. -> `persona.md`
5797
+ // - Instructions: usually one big text or list of files. -> `instructions.md` or `instructions/part1.md`
5798
+ // - Context: usually list of files. -> `context/data.json`, `context/info.md`
5799
+ // We need to differentiate based on the targetPath provided by caller.
5800
+ // If targetPath ends in "persona" (directory name), we can choose to write `targetPath.md` instead if it's flat.
5801
+ // But `saveToDirectory` created `basePath/persona` (directory path string).
5802
+ // Let's check complexity:
5803
+ const hasSubsections = section.items.some((item)=>typeof item === 'object' && 'items' in item);
5804
+ if (!hasSubsections) {
5805
+ // Flat section.
5806
+ // If it has multiple items, we can join them? Or write as numbered files?
5807
+ // Usually, a flat section implies content for a single file.
5808
+ // We prefer to write to `targetPath.md`.
5809
+ const content = section.items.map((item)=>{
5810
+ if (typeof item === 'string') return item;
5811
+ return item.text;
5812
+ }).join('\n\n');
5813
+ // Check if we should write to .md file instead of directory
5814
+ // targetPath is e.g. ".../persona". We want ".../persona.md".
5815
+ await fs__namespace.writeFile(`${targetPath}.md`, content);
5816
+ return;
5817
+ }
5818
+ // Nested section
5819
+ await fs__namespace.mkdir(targetPath, {
5820
+ recursive: true
5821
+ });
5822
+ for(let i = 0; i < section.items.length; i++){
5823
+ const item = section.items[i];
5824
+ if (typeof item === 'object' && 'items' in item) {
5825
+ // Subsection
5826
+ // Use title as filename/dirname
5827
+ const subTitle = item.title || `part-${i + 1}`;
5828
+ const subPath = path__namespace.join(targetPath, subTitle);
5829
+ await saveSection(item, subPath);
5830
+ } else {
5831
+ // Leaf item mixed with subsections.
5832
+ // Write to a file.
5833
+ // If it's just text, we need a filename.
5834
+ const fileName = `item-${i + 1}.md`;
5835
+ const content = typeof item === 'string' ? item : item.text;
5836
+ await fs__namespace.writeFile(path__namespace.join(targetPath, fileName), content);
5837
+ }
5838
+ }
5839
+ };
5840
+
5841
+ const writer = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({
5842
+ __proto__: null,
5843
+ saveToDirectory
5844
+ }, Symbol.toStringTag, { value: 'Module' }));
5845
+
5846
+ class OpenAIProvider {
5847
+ async execute(request, options = {}) {
5848
+ const apiKey = options.apiKey || process.env.OPENAI_API_KEY;
5849
+ if (!apiKey) throw new Error('OpenAI API key is required');
5850
+ const client = new OpenAI({
5851
+ apiKey
5852
+ });
5853
+ const model = options.model || request.model || 'gpt-4';
5854
+ // Convert RiotPrompt messages to OpenAI messages
5855
+ const messages = request.messages.map((msg)=>{
5856
+ const role = msg.role === 'developer' ? 'system' : msg.role; // OpenAI uses system, not developer usually (except o1)
5857
+ // But wait, o1 uses developer. Let's respect what formatter gave us if valid.
5858
+ // OpenAI Node SDK types expect specific roles.
5859
+ // RiotPrompt roles: "user" | "assistant" | "system" | "developer"
5860
+ // OpenAI roles: "system" | "user" | "assistant" | "tool" | "function" | "developer" (recent versions)
5861
+ // We'll cast to any to avoid strict type issues with older/newer SDK versions mismatch
5862
+ return {
5863
+ role: role,
5864
+ content: typeof msg.content === 'string' ? msg.content : JSON.stringify(msg.content),
5865
+ name: msg.name
5866
+ };
5867
+ });
5868
+ const response = await client.chat.completions.create({
5869
+ model: model,
5870
+ messages: messages,
5871
+ temperature: options.temperature,
5872
+ max_tokens: options.maxTokens,
5873
+ response_format: request.responseFormat
5874
+ });
5875
+ const choice = response.choices[0];
5876
+ return {
5877
+ content: choice.message.content || '',
5878
+ model: response.model,
5879
+ usage: response.usage ? {
5880
+ inputTokens: response.usage.prompt_tokens,
5881
+ outputTokens: response.usage.completion_tokens
5882
+ } : undefined
5883
+ };
5884
+ }
5885
+ }
5886
+
5887
+ class AnthropicProvider {
5888
+ async execute(request, options = {}) {
5889
+ var _request_responseFormat, _request_responseFormat1;
5890
+ const apiKey = options.apiKey || process.env.ANTHROPIC_API_KEY;
5891
+ if (!apiKey) throw new Error('Anthropic API key is required');
5892
+ const client = new Anthropic({
5893
+ apiKey
5894
+ });
5895
+ const model = options.model || request.model || 'claude-3-opus-20240229';
5896
+ // Anthropic separates system prompt from messages
5897
+ let systemPrompt = '';
5898
+ const messages = [];
5899
+ for (const msg of request.messages){
5900
+ if (msg.role === 'system' || msg.role === 'developer') {
5901
+ systemPrompt += (typeof msg.content === 'string' ? msg.content : JSON.stringify(msg.content)) + '\n\n';
5902
+ } else {
5903
+ messages.push({
5904
+ role: msg.role,
5905
+ content: typeof msg.content === 'string' ? msg.content : JSON.stringify(msg.content)
5906
+ });
5907
+ }
5908
+ }
5909
+ const response = await client.messages.create({
5910
+ model: model,
5911
+ system: systemPrompt.trim() || undefined,
5912
+ messages: messages,
5913
+ max_tokens: options.maxTokens || 4096,
5914
+ temperature: options.temperature,
5915
+ ...((_request_responseFormat = request.responseFormat) === null || _request_responseFormat === void 0 ? void 0 : _request_responseFormat.type) === 'json_schema' ? {
5916
+ tools: [
5917
+ {
5918
+ name: request.responseFormat.json_schema.name,
5919
+ description: request.responseFormat.json_schema.description || "Output data in this structured format",
5920
+ input_schema: request.responseFormat.json_schema.schema
5921
+ }
5922
+ ],
5923
+ tool_choice: {
5924
+ type: 'tool',
5925
+ name: request.responseFormat.json_schema.name
5926
+ }
5927
+ } : {}
5928
+ });
5929
+ // Handle ContentBlock
5930
+ // Check for tool_use first if we requested structured output
5931
+ let text = '';
5932
+ if (((_request_responseFormat1 = request.responseFormat) === null || _request_responseFormat1 === void 0 ? void 0 : _request_responseFormat1.type) === 'json_schema') {
5933
+ const toolUseBlock = response.content.find((block)=>block.type === 'tool_use');
5934
+ if (toolUseBlock && toolUseBlock.type === 'tool_use') {
5935
+ // Return the structured data as a JSON string to match OpenAI behavior
5936
+ text = JSON.stringify(toolUseBlock.input, null, 2);
5937
+ }
5938
+ } else {
5939
+ const contentBlock = response.content[0];
5940
+ text = contentBlock.type === 'text' ? contentBlock.text : '';
5941
+ }
5942
+ return {
5943
+ content: text,
5944
+ model: response.model,
5945
+ usage: {
5946
+ inputTokens: response.usage.input_tokens,
5947
+ outputTokens: response.usage.output_tokens
5948
+ }
5949
+ };
5950
+ }
5951
+ }
5952
+
5953
+ class GeminiProvider {
5954
+ async execute(request, options = {}) {
5955
+ var _request_responseFormat;
5956
+ const apiKey = options.apiKey || process.env.GEMINI_API_KEY; // or GOOGLE_API_KEY
5957
+ if (!apiKey) throw new Error('Gemini API key is required');
5958
+ const genAI = new generativeAi.GoogleGenerativeAI(apiKey);
5959
+ const modelName = options.model || request.model || 'gemini-1.5-pro';
5960
+ // Handle generation config for structured output
5961
+ const generationConfig = {};
5962
+ if (((_request_responseFormat = request.responseFormat) === null || _request_responseFormat === void 0 ? void 0 : _request_responseFormat.type) === 'json_schema') {
5963
+ generationConfig.responseMimeType = "application/json";
5964
+ // Map OpenAI JSON schema to Gemini Schema
5965
+ // OpenAI: { name: "...", schema: { type: "object", properties: ... } }
5966
+ // Gemini expects the schema object directly
5967
+ const openAISchema = request.responseFormat.json_schema.schema;
5968
+ // We need to recursively map the types because Gemini uses uppercase enums
5969
+ // SchemaType.OBJECT, SchemaType.STRING, etc.
5970
+ // But the SDK also accepts string types "OBJECT", "STRING" etc.
5971
+ // Let's implement a simple converter or pass it if compatible.
5972
+ // Zod-to-json-schema produces lowercase types ("object", "string").
5973
+ // Google's SDK might need them to be uppercase or mapped.
5974
+ // Helper to clean up schema for Gemini
5975
+ // Removes $schema, strict, and additionalProperties if not supported or formatted differently
5976
+ // And maps 'type' to uppercase.
5977
+ const mapSchema = (s)=>{
5978
+ if (!s) return undefined;
5979
+ const newSchema = {
5980
+ ...s
5981
+ };
5982
+ if (newSchema.type) {
5983
+ newSchema.type = typeof newSchema.type === 'string' ? newSchema.type.toUpperCase() : newSchema.type;
5984
+ }
5985
+ if (newSchema.properties) {
5986
+ const newProps = {};
5987
+ for (const [key, val] of Object.entries(newSchema.properties)){
5988
+ newProps[key] = mapSchema(val);
5989
+ }
5990
+ newSchema.properties = newProps;
5991
+ }
5992
+ if (newSchema.items) {
5993
+ newSchema.items = mapSchema(newSchema.items);
5994
+ }
5995
+ // Remove unsupported OpenAI-specific fields if Gemini complains
5996
+ delete newSchema.additionalProperties;
5997
+ delete newSchema['$schema'];
5998
+ return newSchema;
5999
+ };
6000
+ generationConfig.responseSchema = mapSchema(openAISchema);
6001
+ }
6002
+ // Gemini format: system instruction is separate, history is separate from last message
6003
+ // generateContent accepts a string or parts.
6004
+ // We need to construct the prompt.
6005
+ // Simple approach: Concat system instructions + chat history
6006
+ let systemInstruction = '';
6007
+ // Extract system prompt
6008
+ for (const msg of request.messages){
6009
+ if (msg.role === 'system' || msg.role === 'developer') {
6010
+ systemInstruction += (typeof msg.content === 'string' ? msg.content : JSON.stringify(msg.content)) + '\n\n';
6011
+ }
6012
+ }
6013
+ // Configure model with system instruction if available (newer Gemini versions support this)
6014
+ // Or just prepend to first user message.
6015
+ // Let's try to prepend for compatibility if needed, but 'systemInstruction' param exists in getGenerativeModel config.
6016
+ const configuredModel = genAI.getGenerativeModel({
6017
+ model: modelName,
6018
+ systemInstruction: systemInstruction ? systemInstruction.trim() : undefined,
6019
+ generationConfig
6020
+ });
6021
+ // Build history/messages
6022
+ // Gemini `generateContent` takes the *last* user message.
6023
+ // `startChat` takes history.
6024
+ const chatHistory = [];
6025
+ let lastUserMessage = '';
6026
+ for (const msg of request.messages){
6027
+ if (msg.role === 'system' || msg.role === 'developer') continue;
6028
+ const content = typeof msg.content === 'string' ? msg.content : JSON.stringify(msg.content);
6029
+ if (msg.role === 'user') {
6030
+ lastUserMessage = content; // Assuming strictly alternating or we just want the prompt?
6031
+ // If there are multiple messages, we should build a chat.
6032
+ }
6033
+ chatHistory.push({
6034
+ role: msg.role === 'assistant' ? 'model' : 'user',
6035
+ parts: [
6036
+ {
6037
+ text: content
6038
+ }
6039
+ ]
6040
+ });
6041
+ }
6042
+ // If we are just running a prompt (single turn), we can use generateContent with the full text.
6043
+ // But let's support multi-turn by using startChat if history > 1.
6044
+ // If it's a typical "Prompt" execution, it's usually System + 1 User message.
6045
+ let result;
6046
+ if (chatHistory.length > 1) {
6047
+ // Remove last message from history to send it
6048
+ const lastMsg = chatHistory.pop();
6049
+ const chat = configuredModel.startChat({
6050
+ history: chatHistory
6051
+ });
6052
+ result = await chat.sendMessage((lastMsg === null || lastMsg === void 0 ? void 0 : lastMsg.parts[0].text) || '');
6053
+ } else {
6054
+ // Just one message (or none?)
6055
+ result = await configuredModel.generateContent(lastUserMessage || ' ');
6056
+ }
6057
+ const response = await result.response;
6058
+ const text = response.text();
6059
+ return {
6060
+ content: text,
6061
+ model: modelName,
6062
+ // Gemini usage metadata usageMetadata
6063
+ usage: response.usageMetadata ? {
6064
+ inputTokens: response.usageMetadata.promptTokenCount,
6065
+ outputTokens: response.usageMetadata.candidatesTokenCount
6066
+ } : undefined
6067
+ };
6068
+ }
6069
+ }
6070
+
6071
+ function _define_property(obj, key, value) {
6072
+ if (key in obj) {
6073
+ Object.defineProperty(obj, key, {
6074
+ value: value,
6075
+ enumerable: true,
6076
+ configurable: true,
6077
+ writable: true
6078
+ });
6079
+ } else {
6080
+ obj[key] = value;
6081
+ }
6082
+ return obj;
6083
+ }
6084
+ class ExecutionManager {
6085
+ getProvider(model) {
6086
+ if (!model) {
6087
+ // Default to OpenAI if model is undefined
6088
+ return this.providers.get('openai');
6089
+ }
6090
+ if (model.startsWith('gpt') || model.startsWith('o1')) {
6091
+ return this.providers.get('openai');
6092
+ } else if (model.startsWith('claude')) {
6093
+ return this.providers.get('anthropic');
6094
+ } else if (model.startsWith('gemini')) {
6095
+ return this.providers.get('gemini');
6096
+ }
6097
+ // Fallback or default?
6098
+ return this.providers.get('openai');
6099
+ }
6100
+ async execute(request, options = {}) {
6101
+ const model = options.model || request.model;
6102
+ const provider = this.getProvider(model);
6103
+ return provider.execute(request, options);
6104
+ }
6105
+ constructor(){
6106
+ _define_property(this, "providers", void 0);
6107
+ this.providers = new Map();
6108
+ this.providers.set('openai', new OpenAIProvider());
6109
+ this.providers.set('anthropic', new AnthropicProvider());
6110
+ this.providers.set('gemini', new GeminiProvider());
6111
+ }
6112
+ }
6113
+ const execute = async (request, options = {})=>{
6114
+ const manager = new ExecutionManager();
6115
+ return manager.execute(request, options);
6116
+ };
6117
+
6118
+ const index = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({
6119
+ __proto__: null,
6120
+ ExecutionManager,
6121
+ execute
6122
+ }, Symbol.toStringTag, { value: 'Module' }));
6123
+
5320
6124
  exports.Builder = builder;
5321
6125
  exports.Chat = chat;
5322
6126
  exports.ContextManager = ContextManager;
5323
6127
  exports.ConversationBuilder = ConversationBuilder;
5324
6128
  exports.ConversationLogger = ConversationLogger;
5325
6129
  exports.ConversationReplayer = ConversationReplayer;
6130
+ exports.Execution = index;
5326
6131
  exports.Formatter = formatter;
5327
6132
  exports.IterationStrategyFactory = IterationStrategyFactory;
5328
6133
  exports.Loader = loader;
@@ -5334,10 +6139,12 @@ exports.Override = override;
5334
6139
  exports.Parser = parser;
5335
6140
  exports.Recipes = recipes;
5336
6141
  exports.ReflectionReportGenerator = ReflectionReportGenerator;
6142
+ exports.Serializer = serializer;
5337
6143
  exports.StrategyExecutor = StrategyExecutor;
5338
6144
  exports.TokenBudgetManager = TokenBudgetManager;
5339
6145
  exports.TokenCounter = TokenCounter;
5340
6146
  exports.ToolRegistry = ToolRegistry;
6147
+ exports.Writer = writer;
5341
6148
  exports.clearTemplates = clearTemplates;
5342
6149
  exports.configureModel = configureModel;
5343
6150
  exports.cook = cook;