orizu 0.5.21 → 0.5.22

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 (41) hide show
  1. package/README.md +9 -6
  2. package/dist/gepa-engine-dispatch.d.ts.map +1 -1
  3. package/dist/gepa-engine-dispatch.js +20 -1
  4. package/dist/gepa-python-paths.d.ts.map +1 -1
  5. package/dist/gepa-python-paths.js +25 -6
  6. package/dist/help.d.ts.map +1 -1
  7. package/dist/help.js +36 -14
  8. package/dist/index.d.ts.map +1 -1
  9. package/dist/index.js +4 -39
  10. package/dist/instruction-set-loader.d.ts.map +1 -1
  11. package/dist/instruction-set-loader.js +57 -5
  12. package/dist/instruction-sets-cli.d.ts +5 -2
  13. package/dist/instruction-sets-cli.d.ts.map +1 -1
  14. package/dist/instruction-sets-cli.js +134 -24
  15. package/dist/skilled-proposer-config.d.ts +2 -0
  16. package/dist/skilled-proposer-config.d.ts.map +1 -0
  17. package/dist/skilled-proposer-config.js +212 -0
  18. package/dist/skilled-proposer-launch.d.ts +4 -0
  19. package/dist/skilled-proposer-launch.d.ts.map +1 -1
  20. package/dist/skilled-proposer-launch.js +65 -1
  21. package/package.json +1 -1
  22. package/src/gepa-engine-dispatch.ts +21 -1
  23. package/src/gepa-python-paths.ts +24 -6
  24. package/src/help.ts +36 -14
  25. package/src/index.ts +6 -53
  26. package/src/instruction-set-loader.ts +55 -5
  27. package/src/instruction-sets-cli.ts +173 -19
  28. package/src/skilled-proposer-config.ts +191 -0
  29. package/src/skilled-proposer-launch.ts +59 -1
  30. package/vendor/orizu-gepa/src/orizu_gepa_connector/engine.py +36 -3
  31. package/vendor/orizu-gepa/src/orizu_gepa_connector/instruction_set_loader.py +31 -3
  32. package/vendor/orizu-gepa/src/orizu_gepa_connector/skilled_proposer_bridge.py +354 -5
  33. package/vendor/skills/orizu-cli/SKILL.md +50 -16
  34. package/vendor/skills/orizu-cli/references/building-judges.md +2 -2
  35. package/vendor/skills/orizu-cli/references/cli-reference.md +57 -28
  36. package/vendor/skills/orizu-cli/references/instructions-after-prompts.md +120 -0
  37. package/vendor/skills/orizu-cli/references/migrate-existing-gepa-setup.md +109 -49
  38. package/vendor/skills/orizu-cli/references/optimization-reports.md +16 -11
  39. package/vendor/skills/orizu-cli/references/optimization-with-gepa.md +29 -28
  40. package/vendor/skills/orizu-cli/references/primer.md +21 -5
  41. package/vendor/skills/orizu-cli/references/prompt-control-plane.md +132 -85
package/README.md CHANGED
@@ -9,7 +9,7 @@ Orizu is a platform that helps you build continually learning agents and other L
9
9
  There are 3 key pillars to Orizu:
10
10
  1. **Human evaluation:** We consider human evaluation to be the gold standard, particularly when the humans involved are people with deep context and understanding of the output being evaluated. This is often the cross-functional team behind a product (product managers, engineers, designers, content writers, researchers, etc) or external experts (lawyers, engineers, writers, etc). Any good evaluation system relies on the presence of such high quality judgment to compare to. We provide tools that simplify the process of collecting the feedback from this audience.
11
11
  2. **Auto evaluation:** Ultimately, human experts can only review so much. As your data scales, you need to encode their knowledge, their opinions, their taste and judgment into auto-evaluations. We automate this for you using the data we help you collect above.
12
- 3. **Optimization:** We turn your evals into an asset for you by building an automated hill-climbing workflow. We've started with prompt optimization because multiple studies and our own experience with our customers has shown strong measurable lifts with even relatively small datasets. Over time, we'll introduce additional capabilities, including optimizing your skills and other contextual information, and even model weights if your model provider allows finetuning.
12
+ 3. **Optimization:** We turn your evals into an asset for you by building an automated hill-climbing workflow. We've started with instruction optimization because multiple studies and our own experience with our customers has shown strong measurable lifts with even relatively small datasets. Over time, we'll introduce additional capabilities, including optimizing your skills and other contextual information, and even model weights if your model provider allows finetuning.
13
13
 
14
14
  ## CLI and Agent Skills
15
15
 
@@ -109,6 +109,9 @@ Agents are first-class users of this CLI: **every command supports `--json`**
109
109
  (as a prefix, `orizu --json teams list`, or a trailing flag) and emits a single
110
110
  machine-readable JSON document instead of formatted text. Discover the full
111
111
  command surface, including global options, with `orizu capabilities --json`.
112
+ Hosted agents may read and sync instruction sets and prepare complete manifests,
113
+ but a human curator using the local CLI with a user token must run instruction
114
+ create, push, shape, archive, restore, and production/default pointer mutations.
112
115
 
113
116
  ## Authentication
114
117
 
@@ -186,19 +189,19 @@ orizu logout
186
189
  <td><code>orizu projects create --name "Support QA" --team ops-eval</code></td>
187
190
  </tr>
188
191
  <tr>
189
- <td colspan="2"><strong>Prompts</strong></td>
192
+ <td colspan="2"><strong>Instruction sets and prompt reads</strong></td>
190
193
  </tr>
191
194
  <tr>
192
195
  <td>List prompts</td>
193
196
  <td><code>orizu prompts list --project ops-eval/support-qa [--status active|archived|all]</code></td>
194
197
  </tr>
195
198
  <tr>
196
- <td>Archive or restore a prompt</td>
197
- <td><code>orizu prompts archive &lt;promptIdOrName&gt; --project ops-eval/support-qa</code><br><code>orizu prompts restore &lt;promptIdOrName&gt; --project ops-eval/support-qa</code></td>
199
+ <td>Archive or restore an instruction set (human/local CLI only)</td>
200
+ <td><code>orizu instructions archive &lt;slug-or-exact-name&gt; --project ops-eval/support-qa</code><br><code>orizu instructions restore &lt;slug-or-exact-name&gt; --project ops-eval/support-qa</code></td>
198
201
  </tr>
199
202
  <tr>
200
- <td>Push a prompt with a report</td>
201
- <td><code>orizu prompts push ./prompts/support --project ops-eval/support-qa --report-file ./prompt-report.md</code></td>
203
+ <td>Push an instruction-set manifest (human/local CLI only)</td>
204
+ <td><code>orizu instructions push ./orizu.instruction-set.json --project ops-eval/support-qa --set &lt;slug-or-exact-name&gt;</code></td>
202
205
  </tr>
203
206
  <tr>
204
207
  <td>Upload a report for an existing prompt version</td>
@@ -1 +1 @@
1
- {"version":3,"file":"gepa-engine-dispatch.d.ts","sourceRoot":"","sources":["../src/gepa-engine-dispatch.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,UAAU,GAAG,UAAU,GAAG,QAAQ,CAAA;AAE9C,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,UAAU,CAAA;IAClB,IAAI,EAAE,MAAM,EAAE,CAAA;IACd,WAAW,EAAE,MAAM,CAAC,UAAU,CAAA;IAC9B,MAAM,EAAE,MAAM,CAAA;CACf;AAuTD,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,CAAC,UAAU,GAAG,kBAAkB,CAmBtH"}
1
+ {"version":3,"file":"gepa-engine-dispatch.d.ts","sourceRoot":"","sources":["../src/gepa-engine-dispatch.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,UAAU,GAAG,UAAU,GAAG,QAAQ,CAAA;AAE9C,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,UAAU,CAAA;IAClB,IAAI,EAAE,MAAM,EAAE,CAAA;IACd,WAAW,EAAE,MAAM,CAAC,UAAU,CAAA;IAC9B,MAAM,EAAE,MAAM,CAAA;CACf;AAyUD,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,CAAC,UAAU,GAAG,kBAAkB,CAmBtH"}
@@ -1,4 +1,5 @@
1
1
  import { existsSync, readFileSync } from 'fs';
2
+ import { normalizedSkilledProposerConfig } from './skilled-proposer-config.js';
2
3
  const VALUE_OPTIONS = [
3
4
  { flag: '--optimizer-version-id', environment: 'ORIZU_OPTIMIZER_VERSION_ID' },
4
5
  { flag: '--candidate-version-id', environment: 'ORIZU_PROMPT_VERSION_ID' },
@@ -148,6 +149,7 @@ const CONTROLLED_ENVIRONMENT_NAMES = new Set([
148
149
  // translation prevents an inherited environment from selecting a proposer
149
150
  // on an otherwise byte-for-byte normal official-GEPA launch.
150
151
  'ORIZU_CANDIDATE_PROPOSER',
152
+ 'ORIZU_SKILLED_PROPOSER_CONFIG',
151
153
  'ORIZU_COMPONENT_SELECTOR',
152
154
  ]);
153
155
  function optionValueOrThrow(args, index, flag, allowEmpty = false) {
@@ -173,6 +175,7 @@ function translateOfficialOptions(args, project, environment) {
173
175
  }
174
176
  connectorEnvironment.ORIZU_PROJECT = project;
175
177
  let metadata;
178
+ let candidateProposerConfig;
176
179
  let hasInstructionSet = false;
177
180
  let hasCandidateVersion = false;
178
181
  const budgetFlags = [];
@@ -205,6 +208,12 @@ function translateOfficialOptions(args, project, environment) {
205
208
  index = parsed.nextIndex;
206
209
  continue;
207
210
  }
211
+ if (flag === '--candidate-proposer-config') {
212
+ const parsed = optionValueOrThrow(args, index, flag);
213
+ candidateProposerConfig = parsed.value;
214
+ index = parsed.nextIndex;
215
+ continue;
216
+ }
208
217
  const option = VALUE_OPTIONS_BY_FLAG.get(flag);
209
218
  if (option) {
210
219
  const parsed = optionValueOrThrow(args, index, flag, option.allowEmpty);
@@ -266,6 +275,16 @@ function translateOfficialOptions(args, project, environment) {
266
275
  && connectorEnvironment.ORIZU_CANDIDATE_PROPOSER !== 'skilled-proposer') {
267
276
  throw new Error('--proposal-max-calls and --proposal-max-tokens require --candidate-proposer skilled-proposer');
268
277
  }
278
+ if (candidateProposerConfig !== undefined) {
279
+ if (connectorEnvironment.ORIZU_CANDIDATE_PROPOSER !== 'skilled-proposer') {
280
+ throw new Error('--candidate-proposer-config requires --candidate-proposer skilled-proposer');
281
+ }
282
+ connectorEnvironment.ORIZU_SKILLED_PROPOSER_CONFIG = normalizedSkilledProposerConfig(candidateProposerConfig);
283
+ }
284
+ if (connectorEnvironment.ORIZU_CANDIDATE_PROPOSER === 'skilled-proposer'
285
+ && connectorEnvironment.ORIZU_REFLECTION_PROMPT_TEMPLATE !== undefined) {
286
+ throw new Error('--reflection-prompt-template is incompatible with --candidate-proposer skilled-proposer');
287
+ }
269
288
  const reflectionModel = connectorEnvironment.ORIZU_REFLECTION_MODEL ?? 'anthropic/claude-opus-4-7';
270
289
  if (!reflectionModel.startsWith('openai/') && connectorEnvironment.ORIZU_REFLECTION_MAX_TOKENS === undefined) {
271
290
  throw new Error('--reflection-max-tokens is required for Anthropic reflection models');
@@ -289,7 +308,7 @@ function validatedMetadata(raw) {
289
308
  export function dispatchGepaEngine(args, project, environment) {
290
309
  const selected = removeEngine(args);
291
310
  if (selected.engine === 'legacy') {
292
- for (const flag of ['--instruction-set', '--model-config', '--component-selector', '--max-candidate-proposals', '--candidate-proposer', '--proposal-max-calls', '--proposal-max-tokens']) {
311
+ for (const flag of ['--instruction-set', '--model-config', '--component-selector', '--max-candidate-proposals', '--candidate-proposer', '--candidate-proposer-config', '--proposal-max-calls', '--proposal-max-tokens']) {
293
312
  if (selected.args.some(argument => argument === flag || argument.startsWith(`${flag}=`))) {
294
313
  throw new Error(`${flag} is supported by the official GEPA engine only`);
295
314
  }
@@ -1 +1 @@
1
- {"version":3,"file":"gepa-python-paths.d.ts","sourceRoot":"","sources":["../src/gepa-python-paths.ts"],"names":[],"mappings":"AAYA,wBAAgB,qBAAqB,CACnC,UAAU,EAAE,MAAM,EAAE,EACpB,UAAU,GAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAoB,GACtD,MAAM,GAAG,IAAI,CAEf;AAED,wBAAgB,0BAA0B,IAAI,MAAM,GAAG,IAAI,CAM1D;AAED,wBAAgB,mCAAmC,IAAI,MAAM,GAAG,IAAI,CAMnE;AAED,wBAAgB,6BAA6B,IAAI,MAAM,GAAG,IAAI,CAS7D;AAED,wBAAgB,wBAAwB,CAAC,kBAAkB,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,EAAE,CASzF"}
1
+ {"version":3,"file":"gepa-python-paths.d.ts","sourceRoot":"","sources":["../src/gepa-python-paths.ts"],"names":[],"mappings":"AAaA,wBAAgB,qBAAqB,CACnC,UAAU,EAAE,MAAM,EAAE,EACpB,UAAU,GAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAoB,GACtD,MAAM,GAAG,IAAI,CAEf;AAED,wBAAgB,0BAA0B,IAAI,MAAM,GAAG,IAAI,CAM1D;AAED,wBAAgB,mCAAmC,IAAI,MAAM,GAAG,IAAI,CAMnE;AAED,wBAAgB,6BAA6B,IAAI,MAAM,GAAG,IAAI,CA0B7D;AAED,wBAAgB,wBAAwB,CAAC,kBAAkB,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,EAAE,CASzF"}
@@ -1,4 +1,5 @@
1
1
  import { existsSync } from 'fs';
2
+ import { execFileSync } from 'child_process';
2
3
  import { fileURLToPath } from 'url';
3
4
  import { isOrizuSourceCheckout } from '../scripts/orizu-source-checkout.mjs';
4
5
  function prefersLiveSource() {
@@ -23,13 +24,31 @@ export function bundledOrizuGepaConnectorPythonPath() {
23
24
  return resolveGepaPythonPath(candidates);
24
25
  }
25
26
  export function bundledOfficialGepaPythonPath() {
26
- const sourceArchive = fileURLToPath(new URL('../gepa-python-source.zip', import.meta.url));
27
27
  const vendor = fileURLToPath(new URL('../vendor/gepa-python/src', import.meta.url));
28
- // The checked-in pinned wheel is directly importable from PYTHONPATH in a
29
- // source checkout. Published packages intentionally omit that archive and
30
- // must resolve only the verified tree materialized by prepack.
31
- const candidates = prefersLiveSource() ? [sourceArchive, vendor] : [vendor];
32
- return resolveGepaPythonPath(candidates);
28
+ if (prefersLiveSource()) {
29
+ const requiredVendorFiles = [
30
+ fileURLToPath(new URL('../vendor/gepa-python/manifest.json', import.meta.url)),
31
+ fileURLToPath(new URL('../vendor/gepa-python/src/gepa/__init__.py', import.meta.url)),
32
+ fileURLToPath(new URL('../vendor/gepa-python/src/gepa/adapters/optimize_anything_adapter/optimize_anything_adapter.py', import.meta.url)),
33
+ ];
34
+ if (!requiredVendorFiles.every(existsSync)) {
35
+ const vendoringScript = fileURLToPath(new URL('../scripts/vendor-gepa-python.mjs', import.meta.url));
36
+ try {
37
+ execFileSync(process.execPath, [vendoringScript], { stdio: 'pipe' });
38
+ }
39
+ catch (error) {
40
+ const details = error instanceof Error ? error.message : String(error);
41
+ throw new Error(`Unable to materialize bundled official GEPA: ${details}`);
42
+ }
43
+ if (!requiredVendorFiles.every(existsSync)) {
44
+ throw new Error('Unable to materialize bundled official GEPA: extracted tree is incomplete');
45
+ }
46
+ }
47
+ }
48
+ // zipimport cannot resolve GEPA's namespace-package adapters on every
49
+ // supported Python minor. Both source and published CLIs execute only the
50
+ // verified tree materialized from the pinned wheel.
51
+ return resolveGepaPythonPath([vendor]);
33
52
  }
34
53
  export function getGepaPythonPathEntries(existingPythonPath) {
35
54
  const pythonPathEntries = [
@@ -1 +1 @@
1
- {"version":3,"file":"help.d.ts","sourceRoot":"","sources":["../src/help.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;CACnB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,EAAE,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,MAAM,CAAA;IACf,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,CAAC,EAAE,MAAM,EAAE,EAAE,CAAA;IACpB,OAAO,CAAC,EAAE,YAAY,EAAE,CAAA;IACxB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;CACpB;AAoCD,eAAO,MAAM,YAAY,EAAE,aAAa,EAumCvC,CAAA;AAUD,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,aAAa,GAAG,SAAS,CAMxE;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,aAAa,EAAE,CAWrE;AAOD,wBAAgB,cAAc,IAAI,MAAM,CA0CvC;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,CAoBtD;AAED,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CA4B5D;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,CAgBxD;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;EAoB9C"}
1
+ {"version":3,"file":"help.d.ts","sourceRoot":"","sources":["../src/help.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;CACnB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,EAAE,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,MAAM,CAAA;IACf,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,CAAC,EAAE,MAAM,EAAE,EAAE,CAAA;IACpB,OAAO,CAAC,EAAE,YAAY,EAAE,CAAA;IACxB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;CACpB;AAoCD,eAAO,MAAM,YAAY,EAAE,aAAa,EA6nCvC,CAAA;AAUD,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,aAAa,GAAG,SAAS,CAMxE;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,aAAa,EAAE,CAWrE;AAOD,wBAAgB,cAAc,IAAI,MAAM,CA0CvC;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,CAoBtD;AAED,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CA4B5D;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,CAgBxD;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;EAoB9C"}
package/dist/help.js CHANGED
@@ -64,6 +64,40 @@ export const COMMAND_DOCS = [
64
64
  },
65
65
  { path: ['instructions', 'archive'], aliases: [['instruction-sets', 'archive']], usage: 'orizu instructions archive <slug-or-exact-name> --project <team/project> [--json]', summary: 'Archive an instruction set without changing resolution or sync.', group: 'Instruction sets', options: [{ name: '--project <team/project>', help: 'Project slug.', required: true }, { name: '--json', help: 'Print JSON.' }], examples: ['orizu instructions archive planner --project core/evals'] },
66
66
  { path: ['instructions', 'restore'], aliases: [['instruction-sets', 'restore']], usage: 'orizu instructions restore <slug-or-exact-name> --project <team/project> [--json]', summary: 'Restore an archived instruction set.', group: 'Instruction sets', options: [{ name: '--project <team/project>', help: 'Project slug.', required: true }, { name: '--json', help: 'Print JSON.' }], examples: ['orizu instructions restore planner --project core/evals'] },
67
+ {
68
+ path: ['instructions', 'scorers', 'set-headline'],
69
+ aliases: [['instruction-sets', 'scorers', 'set-headline']],
70
+ usage: 'orizu instructions scorers set-headline <set> --key <component-key> --scorer-version <id> [--dataset-version <id> --split-set <id> --split <name>] [--project <team/project>] [--json]',
71
+ summary: 'Bind the headline scorer for one instruction-set component.',
72
+ group: 'Instruction sets',
73
+ options: [
74
+ { name: '--key <component-key>', help: 'Instruction-set component key.', required: true },
75
+ { name: '--scorer-version <id>', help: 'Scorer version to bind.', required: true },
76
+ { name: '--dataset-version <id>', help: 'Default dataset version.' },
77
+ { name: '--split-set <id>', help: 'Default dataset split set.' },
78
+ { name: '--split <name>', help: 'Default split name.' },
79
+ { name: '--project <team/project>', help: 'Project slug.' },
80
+ { name: '--json', help: 'Print JSON.' },
81
+ ],
82
+ examples: ['orizu instructions scorers set-headline planner --key system --scorer-version <id> --project core/evals'],
83
+ },
84
+ {
85
+ path: ['instructions', 'scorers', 'add'],
86
+ aliases: [['instruction-sets', 'scorers', 'add']],
87
+ usage: 'orizu instructions scorers add <set> --key <component-key> --scorer-version <id> [--dataset-version <id> --split-set <id> --split <name>] [--project <team/project>] [--json]',
88
+ summary: 'Track an additional scorer for one instruction-set component.',
89
+ group: 'Instruction sets',
90
+ options: [
91
+ { name: '--key <component-key>', help: 'Instruction-set component key.', required: true },
92
+ { name: '--scorer-version <id>', help: 'Scorer version to bind.', required: true },
93
+ { name: '--dataset-version <id>', help: 'Default dataset version.' },
94
+ { name: '--split-set <id>', help: 'Default dataset split set.' },
95
+ { name: '--split <name>', help: 'Default split name.' },
96
+ { name: '--project <team/project>', help: 'Project slug.' },
97
+ { name: '--json', help: 'Print JSON.' },
98
+ ],
99
+ examples: ['orizu instructions scorers add planner --key system --scorer-version <id> --project core/evals'],
100
+ },
67
101
  {
68
102
  path: ['login'],
69
103
  usage: 'orizu login [--no-prompt-if-logged-in]',
@@ -388,18 +422,6 @@ export const COMMAND_DOCS = [
388
422
  summary: 'Move or set a non-production prompt label; use instructions profiles promote for production.',
389
423
  group: 'Prompts and judges',
390
424
  },
391
- {
392
- path: ['prompts', 'scorers', 'set-headline'],
393
- usage: 'orizu prompts scorers set-headline <prompt-id> --scorer-version <id> [--dataset-version <id> --split-set <id> --split <name>] [--project <team/project>] [--json]',
394
- summary: 'Bind the headline scorer for a prompt.',
395
- group: 'Scorers and runners',
396
- },
397
- {
398
- path: ['prompts', 'scorers', 'add'],
399
- usage: 'orizu prompts scorers add <prompt-id> --scorer-version <id> [--dataset-version <id> --split-set <id> --split <name>] [--project <team/project>] [--json]',
400
- summary: 'Track an additional scorer for a prompt.',
401
- group: 'Scorers and runners',
402
- },
403
425
  {
404
426
  path: ['judges', 'list'],
405
427
  usage: 'orizu judges list --project <team/project> [--status active|archived|all]',
@@ -553,8 +575,8 @@ export const COMMAND_DOCS = [
553
575
  },
554
576
  {
555
577
  path: ['optimizations', 'run-gepa'],
556
- usage: 'orizu optimizations run-gepa --project <team/project> --optimizer-version-id <id> (--candidate-version-id <id> | --instruction-set <name> --model-config <identity> [--component-selector round-robin|all]) --runner-version-id <id> --candidate-runner-dir <dir> --scorer-version-id <id> --scorer-runner-version-id <id> --scorer-runner-dir <dir> [--engine official|legacy] [--scorer-input-contract gepa|flat_row] [--scorer-candidate-field <row-field>] [--allow-degenerate-seed] --dataset-version-id <id> --split-set-id <id> [--train-split train] [--val-split validation] [--budget auto|light|medium|heavy | --max-metric-calls <n> | --max-full-evals <n> | --max-iterations <n> | --max-candidate-proposals <n>] [--num-threads auto|N] [--reflection-retry-attempts N] [--reflection-http-timeout-seconds N] [--log-dir logs]',
557
- summary: 'Run official GEPA locally and stream events; pass --engine legacy only for the frozen safety hatch. --instruction-set requires --model-config and cannot be combined with --candidate-version-id; round-robin updates one component-map entry per round and all updates every component. --max-candidate-proposals is official-engine-only. Validates the scorer contract on the seed before iterating; judge runners built for flat-row score runs need --scorer-input-contract flat_row (ALI-1158).',
578
+ usage: 'orizu optimizations run-gepa --project <team/project> --optimizer-version-id <id> (--candidate-version-id <id> | --instruction-set <name> --model-config <identity> [--component-selector round-robin|all]) --runner-version-id <id> --candidate-runner-dir <dir> --scorer-version-id <id> --scorer-runner-version-id <id> --scorer-runner-dir <dir> [--engine official|legacy] [--candidate-proposer skilled-proposer [--candidate-proposer-config <@file|path>] [--proposal-max-calls <n>] [--proposal-max-tokens <n>]] [--scorer-input-contract gepa|flat_row] [--scorer-candidate-field <row-field>] [--allow-degenerate-seed] --dataset-version-id <id> --split-set-id <id> [--train-split train] [--val-split validation] [--budget auto|light|medium|heavy | --max-metric-calls <n> | --max-full-evals <n> | --max-iterations <n> | --max-candidate-proposals <n>] [--num-threads auto|N] [--reflection-max-tokens N] [--reflection-retry-attempts N] [--reflection-http-timeout-seconds N] [--log-dir logs]',
579
+ summary: 'Run official GEPA locally and stream events; pass --engine legacy only for the frozen safety hatch. Skilled-proposer is official-only, its config requires that selection, and the selection cannot be combined with --reflection-prompt-template. --instruction-set requires --model-config and cannot be combined with --candidate-version-id; round-robin updates one component-map entry per round and all updates every component. --max-candidate-proposals is official-engine-only. Validates the scorer contract on the seed before iterating; judge runners built for flat-row score runs need --scorer-input-contract flat_row (ALI-1158).',
558
580
  group: 'Optimizations',
559
581
  },
560
582
  {
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AA2FgF,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAA;AA8BhJ,OAAO,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAA;AAgU5E,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEvD;AAUD,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAOnD;AAyBD,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE5D;AAcD,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,MAAM,GAAG,GAAG,CAqB5E;AA6BD,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAgBtD;AA+jKD,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG;IAAE,OAAO,EAAE,MAAM,EAAE,CAAC;IAAC,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,CA0B1G;AAED,eAAO,MAAM,iBAAiB,SAAU,CAAA;AACxC,eAAO,MAAM,uBAAuB,QAAkB,CAAA;AACtD,eAAO,MAAM,oBAAoB,aAgB/B,CAAA;AAEF,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,iBAAiB,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC,UAAU,CAaxH;AAWD,wBAAsB,wBAAwB,CAAC,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,IAAI,CAAA;CAAE,CAAC,CA6B3H;AA0LD,wBAAsB,IAAI,CAAC,OAAO,WAAwB,iBA0gBzD"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AA2FgF,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAA;AA8BhJ,OAAO,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAA;AAgU5E,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEvD;AAUD,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAOnD;AAyBD,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE5D;AAcD,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,MAAM,GAAG,GAAG,CAqB5E;AA6BD,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAgBtD;AAkhKD,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG;IAAE,OAAO,EAAE,MAAM,EAAE,CAAC;IAAC,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,CA0B1G;AAED,eAAO,MAAM,iBAAiB,SAAU,CAAA;AACxC,eAAO,MAAM,uBAAuB,QAAkB,CAAA;AACtD,eAAO,MAAM,oBAAoB,aAgB/B,CAAA;AAEF,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,iBAAiB,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC,UAAU,CAaxH;AAWD,wBAAsB,wBAAwB,CAAC,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,IAAI,CAAA;CAAE,CAAC,CA6B3H;AA0LD,wBAAsB,IAAI,CAAC,OAAO,WAAwB,iBAwgBzD"}
package/dist/index.js CHANGED
@@ -65,7 +65,7 @@ import { dispatchGepaEngine } from './gepa-engine-dispatch.js';
65
65
  import { resolveGepaInstructionSetProfileVersion } from './instruction-set-gepa-launch.js';
66
66
  import { getGepaPythonCommand } from './gepa-python-command.js';
67
67
  import { getGepaPythonPathEntries } from './gepa-python-paths.js';
68
- import { prepareSkilledProposerLaunch } from './skilled-proposer-launch.js';
68
+ import { prepareSkilledProposerLaunch, spawnSkilledProposerChild } from './skilled-proposer-launch.js';
69
69
  export { parseJsonResponse, sanitizeTerminalText } from './json-response.js';
70
70
  function getErrorMessage(error) {
71
71
  return error instanceof Error ? error.message : String(error);
@@ -1205,39 +1205,6 @@ function refusePromptMutation(replacement) {
1205
1205
  process.exitCode = 1;
1206
1206
  throw new Error(`Use: orizu instructions ${replacement}`);
1207
1207
  }
1208
- async function bindPromptScorer(role) {
1209
- const promptId = getPositionalArg(3);
1210
- const project = getArg('--project') || await resolveProjectSlug(null);
1211
- const scorerVersionId = getArg('--scorer-version');
1212
- if (!promptId || !scorerVersionId) {
1213
- throw new Error(`Usage: orizu prompts scorers ${role === 'headline' ? 'set-headline' : 'add'} <prompt-id> --scorer-version <id> [--dataset-version <id> --split-set <id> --split <name>] [--project <team/project>] [--json]`);
1214
- }
1215
- const response = await authedFetch(`/api/cli/prompts/scorers?project=${encodeURIComponent(project)}`, {
1216
- method: 'POST',
1217
- headers: { 'Content-Type': 'application/json' },
1218
- body: JSON.stringify({
1219
- promptId,
1220
- scorerVersionId,
1221
- role,
1222
- datasetVersionId: getArg('--dataset-version') || undefined,
1223
- splitSetId: getArg('--split-set') || undefined,
1224
- splitName: getArg('--split') || undefined,
1225
- }),
1226
- });
1227
- if (!response.ok) {
1228
- throw new Error(`Failed to bind prompt scorer: ${await response.text()}`);
1229
- }
1230
- const data = await parseJsonResponse(response, 'Prompt scorer bind');
1231
- if (hasJsonFlag()) {
1232
- printJson(data);
1233
- return;
1234
- }
1235
- printLine(`${role === 'headline' ? 'Set headline' : 'Added'} scorer ${sanitizeTerminalText(scorerVersionId)} for ${sanitizeTerminalText(promptId)}`);
1236
- if (data.owner) {
1237
- printLine(`Owner: ${sanitizeTerminalText(promptId)} -> ` +
1238
- `${sanitizeTerminalText(data.owner.instructionSetSlug)} / ${sanitizeTerminalText(data.owner.componentKey)}`);
1239
- }
1240
- }
1241
1208
  function getPositionalArg(index) {
1242
1209
  const value = cliArgs[index];
1243
1210
  return value && !value.startsWith('--') ? value : null;
@@ -1827,7 +1794,7 @@ async function runGepaOptimization() {
1827
1794
  dispatch.environment.ORIZU_INSTRUCTION_SET_PROFILE_VERSION_ID = instructionSetProfileVersionId;
1828
1795
  selectedEngine = dispatch.engine;
1829
1796
  const launch = prepareSkilledProposerLaunch(python, dispatch.engine, dispatch.environment);
1830
- result = spawnSync(launch.python, ['-m', dispatch.module, ...dispatch.args], { stdio: 'inherit', env: launch.environment });
1797
+ result = await spawnSkilledProposerChild(launch.python, ['-m', dispatch.module, ...dispatch.args], dispatch.engine, launch.environment);
1831
1798
  }
1832
1799
  finally {
1833
1800
  verified.cleanup();
@@ -4854,12 +4821,10 @@ export async function main(rawArgs = process.argv.slice(2)) {
4854
4821
  return;
4855
4822
  }
4856
4823
  if (command === 'prompts' && subcommand === 'scorers' && cliArgs[2] === 'set-headline') {
4857
- await bindPromptScorer('headline');
4858
- return;
4824
+ refusePromptMutation('scorers set-headline <set> --key <component-key> --scorer-version <id> --project <team/project>');
4859
4825
  }
4860
4826
  if (command === 'prompts' && subcommand === 'scorers' && cliArgs[2] === 'add') {
4861
- await bindPromptScorer('tracked');
4862
- return;
4827
+ refusePromptMutation('scorers add <set> --key <component-key> --scorer-version <id> --project <team/project>');
4863
4828
  }
4864
4829
  if (command === 'judges' && subcommand === 'list') {
4865
4830
  await listJudges();
@@ -1 +1 @@
1
- {"version":3,"file":"instruction-set-loader.d.ts","sourceRoot":"","sources":["../src/instruction-set-loader.ts"],"names":[],"mappings":"AAGA,qBAAa,yBAA0B,SAAQ,KAAK;IACtC,QAAQ,CAAC,IAAI,EAAE,MAAM;gBAAZ,IAAI,EAAE,MAAM;CAClC;AAOD,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,mBAAmB,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAwBvH"}
1
+ {"version":3,"file":"instruction-set-loader.d.ts","sourceRoot":"","sources":["../src/instruction-set-loader.ts"],"names":[],"mappings":"AAGA,qBAAa,yBAA0B,SAAQ,KAAK;IACtC,QAAQ,CAAC,IAAI,EAAE,MAAM;gBAAZ,IAAI,EAAE,MAAM;CAClC;AA2DD,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,mBAAmB,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAsBvH"}
@@ -1,4 +1,4 @@
1
- import { existsSync, realpathSync, readFileSync, statSync } from 'node:fs';
1
+ import { existsSync, realpathSync, readFileSync, readdirSync, statSync } from 'node:fs';
2
2
  import { resolve, sep } from 'node:path';
3
3
  export class InstructionSetLoaderError extends Error {
4
4
  code;
@@ -9,11 +9,63 @@ export class InstructionSetLoaderError extends Error {
9
9
  }
10
10
  }
11
11
  function inside(root, candidate) { return candidate === root || candidate.startsWith(`${root}${sep}`); }
12
- export function loadInstructionSet(directory, name, modelConfigIdentity) {
13
- const unresolvedRoot = resolve(directory, name);
14
- if (!existsSync(unresolvedRoot) || !statSync(unresolvedRoot).isDirectory())
12
+ function manifestMatchesReference(candidate, reference) {
13
+ try {
14
+ const manifest = JSON.parse(readFileSync(resolve(candidate, 'manifest.json'), 'utf8'));
15
+ return manifest.name === reference || manifest.slug === reference;
16
+ }
17
+ catch {
18
+ return false;
19
+ }
20
+ }
21
+ function resolveSetRoot(directory, reference) {
22
+ let directoryRoot;
23
+ try {
24
+ directoryRoot = realpathSync(directory);
25
+ }
26
+ catch {
15
27
  throw new InstructionSetLoaderError('instruction_set_not_synced');
16
- const setRoot = realpathSync(unresolvedRoot);
28
+ }
29
+ const direct = resolve(directoryRoot, reference);
30
+ try {
31
+ if (inside(directoryRoot, direct) && existsSync(direct) && statSync(direct).isDirectory()) {
32
+ const realDirect = realpathSync(direct);
33
+ if (inside(directoryRoot, realDirect)) {
34
+ try {
35
+ const manifest = JSON.parse(readFileSync(resolve(realDirect, 'manifest.json'), 'utf8'));
36
+ if (manifest.name === reference || manifest.slug === reference) {
37
+ return realDirect;
38
+ }
39
+ }
40
+ catch {
41
+ // Preserve the exact-path loader's specific missing/invalid manifest error.
42
+ return realDirect;
43
+ }
44
+ }
45
+ }
46
+ }
47
+ catch {
48
+ // A stale or unreadable direct-path candidate must not shadow a valid set.
49
+ }
50
+ const matches = readdirSync(directoryRoot, { withFileTypes: true }).flatMap(entry => {
51
+ try {
52
+ if (entry.name.startsWith('.') || !entry.isDirectory())
53
+ return [];
54
+ const candidate = realpathSync(resolve(directoryRoot, entry.name));
55
+ return inside(directoryRoot, candidate) && manifestMatchesReference(candidate, reference)
56
+ ? [candidate]
57
+ : [];
58
+ }
59
+ catch {
60
+ return [];
61
+ }
62
+ });
63
+ if (matches.length !== 1)
64
+ throw new InstructionSetLoaderError(matches.length > 1 ? 'instruction_set_reference_ambiguous' : 'instruction_set_not_synced');
65
+ return matches[0];
66
+ }
67
+ export function loadInstructionSet(directory, name, modelConfigIdentity) {
68
+ const setRoot = resolveSetRoot(directory, name);
17
69
  const manifestPath = resolve(setRoot, 'manifest.json');
18
70
  if (!existsSync(manifestPath))
19
71
  throw new InstructionSetLoaderError('instruction_set_manifest_missing');
@@ -1,4 +1,4 @@
1
- import { renameSync, writeFileSync } from 'node:fs';
1
+ import { renameSync, rmSync, writeFileSync } from 'node:fs';
2
2
  export interface InstructionSetsCommandIo {
3
3
  json: boolean;
4
4
  print: (line: string) => void;
@@ -23,6 +23,8 @@ export interface SyncProfile {
23
23
  production: SyncMaterial | null;
24
24
  }
25
25
  export interface SyncSet {
26
+ projectId?: string;
27
+ instructionSetId?: string;
26
28
  name: string;
27
29
  slug?: string;
28
30
  description?: string | null;
@@ -34,7 +36,8 @@ export interface SyncSet {
34
36
  export interface SyncFileOps {
35
37
  writeFileSync: typeof writeFileSync;
36
38
  renameSync?: typeof renameSync;
39
+ rmSync?: typeof rmSync;
37
40
  }
38
- export declare function syncToDisk(out: string, set: SyncSet, fileOps?: SyncFileOps): void;
41
+ export declare function syncToDisk(out: string, set: SyncSet, fileOps?: SyncFileOps): string;
39
42
  export declare function instructionSetsCommand(args: string[], io: InstructionSetsCommandIo): Promise<number>;
40
43
  //# sourceMappingURL=instruction-sets-cli.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"instruction-sets-cli.d.ts","sourceRoot":"","sources":["../src/instruction-sets-cli.ts"],"names":[],"mappings":"AAGA,OAAO,EAAuC,UAAU,EAAoB,aAAa,EAAE,MAAM,SAAS,CAAA;AAI1G,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,OAAO,CAAA;IACb,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IAC7B,kBAAkB,EAAE,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,KAAK,OAAO,CAAC,MAAM,CAAC,CAAA;CACjE;AA+BD,MAAM,WAAW,aAAa;IAAG,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE;AAC5G,MAAM,WAAW,YAAY;IAAG,gBAAgB,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAC;IAAC,mBAAmB,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAA;CAAE;AAC/K,MAAM,WAAW,WAAW;IAAG,mBAAmB,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,YAAY,GAAG,IAAI,CAAA;CAAE;AACnH,MAAM,WAAW,OAAO;IAAG,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,EAAE,CAAC;IAAC,OAAO,EAAE,YAAY,CAAC;IAAC,QAAQ,EAAE,WAAW,EAAE,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE;AAM7K,MAAM,WAAW,WAAW;IAAG,aAAa,EAAE,OAAO,aAAa,CAAC;IAAC,UAAU,CAAC,EAAE,OAAO,UAAU,CAAA;CAAE;AAoCpG,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,OAAO,GAAE,WAA+B,QAyC7F;AAED,wBAAsB,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,wBAAwB,GAAG,OAAO,CAAC,MAAM,CAAC,CA+K1G"}
1
+ {"version":3,"file":"instruction-sets-cli.d.ts","sourceRoot":"","sources":["../src/instruction-sets-cli.ts"],"names":[],"mappings":"AAGA,OAAO,EAAuC,UAAU,EAAE,MAAM,EAAY,aAAa,EAAE,MAAM,SAAS,CAAA;AAI1G,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,OAAO,CAAA;IACb,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IAC7B,kBAAkB,EAAE,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,KAAK,OAAO,CAAC,MAAM,CAAC,CAAA;CACjE;AA+BD,MAAM,WAAW,aAAa;IAAG,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE;AAC5G,MAAM,WAAW,YAAY;IAAG,gBAAgB,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAC;IAAC,mBAAmB,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAA;CAAE;AAC/K,MAAM,WAAW,WAAW;IAAG,mBAAmB,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,YAAY,GAAG,IAAI,CAAA;CAAE;AACnH,MAAM,WAAW,OAAO;IACtB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,KAAK,EAAE,MAAM,EAAE,CAAA;IACf,OAAO,EAAE,YAAY,CAAA;IACrB,QAAQ,EAAE,WAAW,EAAE,CAAA;IACvB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAA;CACtB;AASD,MAAM,WAAW,WAAW;IAC1B,aAAa,EAAE,OAAO,aAAa,CAAA;IACnC,UAAU,CAAC,EAAE,OAAO,UAAU,CAAA;IAC9B,MAAM,CAAC,EAAE,OAAO,MAAM,CAAA;CACvB;AA0FD,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,OAAO,GAAE,WAA+B,UAsF7F;AAED,wBAAsB,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,wBAAwB,GAAG,OAAO,CAAC,MAAM,CAAC,CAqN1G"}