orizu 0.5.30 → 0.5.31
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/gepa-engine-dispatch.d.ts.map +1 -1
- package/dist/gepa-engine-dispatch.js +16 -1
- package/dist/help.js +2 -2
- package/dist/hosted-gepa-cli.d.ts.map +1 -1
- package/dist/hosted-gepa-cli.js +7 -1
- package/dist/hosted-harness-claude.d.ts.map +1 -1
- package/dist/hosted-harness-claude.js +4 -1
- package/dist/hosted-harness-opencode.d.ts +1 -0
- package/dist/hosted-harness-opencode.d.ts.map +1 -1
- package/dist/hosted-harness-opencode.js +23 -7
- package/dist/hosted-harness.d.ts +30 -1
- package/dist/hosted-harness.d.ts.map +1 -1
- package/dist/hosted-harness.js +5 -0
- package/dist/hosted-tool-hints.d.ts +56 -0
- package/dist/hosted-tool-hints.d.ts.map +1 -0
- package/dist/hosted-tool-hints.js +105 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -5
- package/dist/instruction-set-gepa-launch.d.ts +21 -2
- package/dist/instruction-set-gepa-launch.d.ts.map +1 -1
- package/dist/instruction-set-gepa-launch.js +123 -3
- package/dist/optimizations-promote-cli.d.ts.map +1 -1
- package/dist/optimizations-promote-cli.js +19 -0
- package/dist/seed-against-production.d.ts +11 -0
- package/dist/seed-against-production.d.ts.map +1 -0
- package/dist/seed-against-production.js +1 -0
- package/package.json +1 -1
- package/src/gepa-engine-dispatch.ts +18 -1
- package/src/help.ts +2 -2
- package/src/hosted-gepa-cli.ts +7 -1
- package/src/hosted-harness-claude.ts +4 -1
- package/src/hosted-harness-opencode.ts +24 -7
- package/src/hosted-harness.ts +32 -1
- package/src/hosted-tool-hints.ts +153 -0
- package/src/index.ts +2 -5
- package/src/instruction-set-gepa-launch.ts +161 -3
- package/src/optimizations-promote-cli.ts +20 -2
- package/src/seed-against-production.ts +10 -0
- package/vendor/skills/orizu/references/cli-reference.md +1 -1
- package/vendor/skills/orizu/references/migrate-existing-gepa-setup.md +1 -2
- package/vendor/skills/orizu/references/optimization-reports.md +1 -1
- package/vendor/skills/orizu/references/optimization-with-gepa.md +1 -1
- package/vendor/skills/orizu/references/prompt-control-plane.md +6 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gepa-engine-dispatch.d.ts","sourceRoot":"","sources":["../src/gepa-engine-dispatch.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"gepa-engine-dispatch.d.ts","sourceRoot":"","sources":["../src/gepa-engine-dispatch.ts"],"names":[],"mappings":"AAMA,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;AAsWD,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 { gepaSeedSelector } from './instruction-set-gepa-launch.js';
|
|
2
3
|
import { providerFromIdentity, protocolRequiresOutputCap } from './provider-registry.js';
|
|
3
4
|
import { normalizedSkilledProposerConfig } from './skilled-proposer-config.js';
|
|
4
5
|
const VALUE_OPTIONS = [
|
|
@@ -39,6 +40,7 @@ const VALUE_OPTIONS = [
|
|
|
39
40
|
{ flag: '--log-dir', environment: 'ORIZU_LOCAL_LOG_DIR' },
|
|
40
41
|
{ flag: '--instruction-set', environment: 'ORIZU_INSTRUCTION_SET_NAME' },
|
|
41
42
|
{ flag: '--model-config', environment: 'ORIZU_MODEL_CONFIG_IDENTITY' },
|
|
43
|
+
{ flag: '--profile-version', environment: 'ORIZU_INSTRUCTION_SET_PROFILE_VERSION_NUMBER' },
|
|
42
44
|
];
|
|
43
45
|
const BOOLEAN_OPTIONS = [
|
|
44
46
|
['--allow-degenerate-seed', 'ORIZU_ALLOW_DEGENERATE_SEED', '1'],
|
|
@@ -267,6 +269,19 @@ function translateOfficialOptions(args, project, environment) {
|
|
|
267
269
|
}
|
|
268
270
|
if (hasInstructionSet && hasCandidateVersion)
|
|
269
271
|
throw new Error('--instruction-set and --candidate-version-id are mutually exclusive');
|
|
272
|
+
if (!hasInstructionSet && connectorEnvironment.ORIZU_INSTRUCTION_SET_PROFILE_VERSION_NUMBER !== undefined) {
|
|
273
|
+
throw new Error('--profile-version requires --instruction-set');
|
|
274
|
+
}
|
|
275
|
+
if (hasInstructionSet) {
|
|
276
|
+
// ORI-2128: the Seed may be named by a full specifier, by flags, or both;
|
|
277
|
+
// normalise to the set reference, the profile, and the version number.
|
|
278
|
+
const seed = gepaSeedSelector(connectorEnvironment.ORIZU_INSTRUCTION_SET_NAME, connectorEnvironment.ORIZU_MODEL_CONFIG_IDENTITY, connectorEnvironment.ORIZU_INSTRUCTION_SET_PROFILE_VERSION_NUMBER);
|
|
279
|
+
connectorEnvironment.ORIZU_INSTRUCTION_SET_NAME = seed.instructionSetName;
|
|
280
|
+
if (seed.modelConfigIdentity !== undefined)
|
|
281
|
+
connectorEnvironment.ORIZU_MODEL_CONFIG_IDENTITY = seed.modelConfigIdentity;
|
|
282
|
+
if (seed.versionNumber !== undefined)
|
|
283
|
+
connectorEnvironment.ORIZU_INSTRUCTION_SET_PROFILE_VERSION_NUMBER = String(seed.versionNumber);
|
|
284
|
+
}
|
|
270
285
|
if (hasInstructionSet && connectorEnvironment.ORIZU_MODEL_CONFIG_IDENTITY === undefined)
|
|
271
286
|
throw new Error('--instruction-set requires --model-config');
|
|
272
287
|
if (hasInstructionSet && connectorEnvironment.ORIZU_COMPONENT_SELECTOR === undefined)
|
|
@@ -318,7 +333,7 @@ function validatedMetadata(raw) {
|
|
|
318
333
|
export function dispatchGepaEngine(args, project, environment) {
|
|
319
334
|
const selected = removeEngine(args);
|
|
320
335
|
if (selected.engine === 'legacy') {
|
|
321
|
-
for (const flag of ['--instruction-set', '--model-config', '--component-selector', '--max-candidate-proposals', '--candidate-proposer', '--candidate-proposer-config', '--proposal-max-calls', '--proposal-max-tokens']) {
|
|
336
|
+
for (const flag of ['--instruction-set', '--model-config', '--profile-version', '--component-selector', '--max-candidate-proposals', '--candidate-proposer', '--candidate-proposer-config', '--proposal-max-calls', '--proposal-max-tokens']) {
|
|
322
337
|
if (selected.args.some(argument => argument === flag || argument.startsWith(`${flag}=`))) {
|
|
323
338
|
throw new Error(`${flag} is supported by the official GEPA engine only`);
|
|
324
339
|
}
|
package/dist/help.js
CHANGED
|
@@ -655,8 +655,8 @@ export const COMMAND_DOCS = [
|
|
|
655
655
|
},
|
|
656
656
|
{
|
|
657
657
|
path: ['optimizations', 'run-gepa'],
|
|
658
|
-
usage: 'orizu optimizations run-gepa [--hosted [--launch-intent-id <uuid>]] --project <team/project> --optimizer-version-id <id> (--candidate-version-id <id> | --instruction-set <
|
|
659
|
-
summary: 'Run official GEPA locally and stream events, or use --hosted for a queued Orizu-managed sandbox launch. Hosted eligibility requires a staff-enabled team, capacity below its concurrent-run cap, a launch-project optimizer version whose validated manifest.optimizer_family is gepa, registered candidate/scorer runners, a reflection model from a registered provider, and a named --budget preset within the team ceiling. Hosted eligibility catalog refusals use stable code/remediation JSON with optional bounded detail, and capacity refusals include monitor URLs for running runs. A successful launch prints a durable monitor URL; queued means accepted, not completed. Hosted mode does not require --candidate-runner-dir or --scorer-runner-dir; when supplied, those directories must byte-match their registered versions. Retry response loss with the same --launch-intent-id. Local runner version ids materialize registered bytes, while optional runner dirs are additionally byte-verified before execution. 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
|
|
658
|
+
usage: 'orizu optimizations run-gepa [--hosted [--launch-intent-id <uuid>]] --project <team/project> --optimizer-version-id <id> (--candidate-version-id <id> | --instruction-set <set[/profile[@vN]]> [--model-config <identity>] [--profile-version <N>] [--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] [--seed <n>] --dataset-version-id <id> --split-set-id <id> [--train-split train] [--val-split validation] [--minibatch-size <n>] [--candidate-selection-strategy pareto|current_best|epsilon_greedy] [--epsilon <n>] [--objective <text>] [--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-model <provider/model>] [--reflection-temperature <n>] [--reflection-prompt-template <text|@file>] [--reflection-max-tokens N] [--reflection-provider-settings <json|@file>] [--reflection-retry-attempts N] [--reflection-http-timeout-seconds N] [--skip-perfect-parent-reflection|--no-skip-perfect-parent-reflection] [--disable-evaluation-cache] [--auto-promote] [--promotion-label <label>] [--log-row-snapshots] [--metadata <json>] [--python <command>] [--log-dir logs] [--no-local-log] [--json]',
|
|
659
|
+
summary: 'Run official GEPA locally and stream events, or use --hosted for a queued Orizu-managed sandbox launch. Hosted eligibility requires a staff-enabled team, capacity below its concurrent-run cap, a launch-project optimizer version whose validated manifest.optimizer_family is gepa, registered candidate/scorer runners, a reflection model from a registered provider, and a named --budget preset within the team ceiling. Hosted eligibility catalog refusals use stable code/remediation JSON with optional bounded detail, and capacity refusals include monitor URLs for running runs. A successful launch prints a durable monitor URL; queued means accepted, not completed. Hosted mode does not require --candidate-runner-dir or --scorer-runner-dir; when supplied, those directories must byte-match their registered versions. Retry response loss with the same --launch-intent-id. Local runner version ids materialize registered bytes, while optional runner dirs are additionally byte-verified before execution. 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 needs a profile, named by --model-config or a set/profile specifier, and cannot be combined with --candidate-version-id. The run starts from the production version of that profile unless @vN or --profile-version <N> names another version (the seed, promoted or not); a specifier and flags that name different values are refused; 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).',
|
|
660
660
|
group: 'Optimizations',
|
|
661
661
|
},
|
|
662
662
|
{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hosted-gepa-cli.d.ts","sourceRoot":"","sources":["../src/hosted-gepa-cli.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"hosted-gepa-cli.d.ts","sourceRoot":"","sources":["../src/hosted-gepa-cli.ts"],"names":[],"mappings":"AAaA,OAAO,EAGL,yBAAyB,EAC1B,MAAM,wBAAwB,CAAA;AAE/B,UAAU,iBAAiB;IACzB,IAAI,EAAE,MAAM,EAAE,CAAA;IACd,OAAO,EAAE,MAAM,CAAA;IACf,WAAW,EAAE,MAAM,CAAC,UAAU,CAAA;IAC9B,IAAI,EAAE,OAAO,CAAA;IACb,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAA;IACnD,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IAClC,6FAA6F;IAC7F,eAAe,CAAC,EAAE,OAAO,yBAAyB,CAAA;CACnD;AAmBD,wBAAsB,yBAAyB,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CA2MzF"}
|
package/dist/hosted-gepa-cli.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { randomUUID } from 'node:crypto';
|
|
2
2
|
import { dispatchGepaEngine } from './gepa-engine-dispatch.js';
|
|
3
|
+
import { resolveGepaSeedFromEnvironment } from './instruction-set-gepa-launch.js';
|
|
3
4
|
import { parseHostedGepaNumericValue } from './hosted-gepa-numeric-values.js';
|
|
4
5
|
import { authedFetch } from './http.js';
|
|
5
6
|
import { hostedProviderFromModel, hostedProviderSettingsError, unsupportedHostedProviderMessage } from './hosted-provider-settings.js';
|
|
@@ -193,11 +194,16 @@ export async function runHostedGepaOptimization(options) {
|
|
|
193
194
|
: kind === 'json' ? JSON.parse(env[name]) : kind === 'boolean' ? env[name] === '1' : env[name];
|
|
194
195
|
}
|
|
195
196
|
const launchIntentId = explicitLaunchIntent || randomUUID();
|
|
197
|
+
// ORI-2128: a named Seed version is resolved here exactly as a local run
|
|
198
|
+
// resolves it, and pinned in the body; without one the server keeps its
|
|
199
|
+
// one-call production lookup.
|
|
200
|
+
const seedProfileVersionId = await resolveGepaSeedFromEnvironment(env, options.project, 'server');
|
|
196
201
|
const body = {
|
|
197
202
|
hosted: true, launchIntentId, optimizerVersionId: env.ORIZU_OPTIMIZER_VERSION_ID,
|
|
198
203
|
promptVersionIds: env.ORIZU_PROMPT_VERSION_ID ? [env.ORIZU_PROMPT_VERSION_ID] : [],
|
|
199
204
|
...(env.ORIZU_INSTRUCTION_SET_NAME ? { instructionSetName: env.ORIZU_INSTRUCTION_SET_NAME,
|
|
200
|
-
modelConfigIdentity: env.ORIZU_MODEL_CONFIG_IDENTITY, componentSelector: env.ORIZU_COMPONENT_SELECTOR
|
|
205
|
+
modelConfigIdentity: env.ORIZU_MODEL_CONFIG_IDENTITY, componentSelector: env.ORIZU_COMPONENT_SELECTOR,
|
|
206
|
+
...(seedProfileVersionId ? { instructionSetProfileVersionId: seedProfileVersionId } : {}) } : {}),
|
|
201
207
|
runnerVersionId: env.ORIZU_RUNNER_VERSION_ID,
|
|
202
208
|
scorers: [{ scorerVersionId: env.ORIZU_SCORER_VERSION_ID,
|
|
203
209
|
scorerRunnerVersionId: env.ORIZU_SCORER_RUNNER_VERSION_ID, role: 'selection', scorerConfig: {} }],
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hosted-harness-claude.d.ts","sourceRoot":"","sources":["../src/hosted-harness-claude.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6FG;
|
|
1
|
+
{"version":3,"file":"hosted-harness-claude.d.ts","sourceRoot":"","sources":["../src/hosted-harness-claude.ts"],"names":[],"mappings":"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"}
|
|
@@ -93,6 +93,7 @@
|
|
|
93
93
|
* stripped). Other providers pass through unchanged for the SDK to judge.
|
|
94
94
|
*/
|
|
95
95
|
import { parseModelIdentity } from './provider-registry.js';
|
|
96
|
+
import { HARNESS_NAMES } from './hosted-harness.js';
|
|
96
97
|
// The package name lives in a variable so TypeScript treats the dynamic import as
|
|
97
98
|
// `any` (no static module resolution / ts2307 at app-build time) and no bundler
|
|
98
99
|
// traces it — this keeps the SDK genuinely optional, loaded only when the
|
|
@@ -193,7 +194,7 @@ export function createClaudeAgentHarness(options = {}) {
|
|
|
193
194
|
return sdk;
|
|
194
195
|
}
|
|
195
196
|
return {
|
|
196
|
-
name:
|
|
197
|
+
name: HARNESS_NAMES.claudeAgentSdk,
|
|
197
198
|
async start(opts) {
|
|
198
199
|
startModel = opts.model;
|
|
199
200
|
startWorkspaceDir = opts.workspaceDir;
|
|
@@ -338,6 +339,7 @@ export function createClaudeAgentHarness(options = {}) {
|
|
|
338
339
|
args: asRecord(block.input),
|
|
339
340
|
callId,
|
|
340
341
|
status: 'running',
|
|
342
|
+
harness: HARNESS_NAMES.claudeAgentSdk,
|
|
341
343
|
},
|
|
342
344
|
};
|
|
343
345
|
}
|
|
@@ -363,6 +365,7 @@ export function createClaudeAgentHarness(options = {}) {
|
|
|
363
365
|
callId,
|
|
364
366
|
status: block.is_error === true ? 'error' : 'completed',
|
|
365
367
|
output: toolResultOutput(block.content),
|
|
368
|
+
harness: HARNESS_NAMES.claudeAgentSdk,
|
|
366
369
|
},
|
|
367
370
|
};
|
|
368
371
|
}
|
|
@@ -67,6 +67,7 @@ export interface OpenCodeHarnessOptions {
|
|
|
67
67
|
/** Distinct terminal reason emitted when a prompt breaches PROMPT_MAX_DURATION,
|
|
68
68
|
* so the bridge/tests can tell a duration abort from a model error. */
|
|
69
69
|
export declare const PROMPT_MAX_DURATION_ERROR = "prompt exceeded max duration";
|
|
70
|
+
export declare function ascendingId(prefix: 'ses' | 'msg' | 'prt', nowMs?: number): string;
|
|
70
71
|
/**
|
|
71
72
|
* Split a possibly provider-qualified model string into provider + model id,
|
|
72
73
|
* through THE registry parse (`parseModelIdentity`, ORI-2031): the provider is
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hosted-harness-opencode.d.ts","sourceRoot":"","sources":["../src/hosted-harness-opencode.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiDG;
|
|
1
|
+
{"version":3,"file":"hosted-harness-opencode.d.ts","sourceRoot":"","sources":["../src/hosted-harness-opencode.ts"],"names":[],"mappings":"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"}
|
|
@@ -50,6 +50,7 @@
|
|
|
50
50
|
*/
|
|
51
51
|
import { readFileSync } from 'fs';
|
|
52
52
|
import { findProvider, parseModelIdentity } from './provider-registry.js';
|
|
53
|
+
import { HARNESS_NAMES } from './hosted-harness.js';
|
|
53
54
|
// OpenCode is HARD-PINNED to this version everywhere it is installed/launched.
|
|
54
55
|
// AUDIT RISK #1 (SSE fragility): the entire event model rides OpenCode's
|
|
55
56
|
// undocumented `/event` SSE part schema (`message.part.updated`, `session.idle`,
|
|
@@ -89,7 +90,9 @@ class PromptAbortedError extends Error {
|
|
|
89
90
|
// -- OpenCode ascending id generator (port of OpenCode's id.ts) --------------
|
|
90
91
|
// Monotonic so our user-message id always sorts AFTER any prior assistant
|
|
91
92
|
// message id — this is what prevents OpenCode's prompt loop from early-exiting
|
|
92
|
-
// on `lastUser.id < lastAssistant.id`.
|
|
93
|
+
// on `lastUser.id < lastAssistant.id`. Shape (opencode-ai@1.14.41): prefix, `_`,
|
|
94
|
+
// 12 hex digits holding the low 48 bits of `ms * 4096 + counter`, then 14
|
|
95
|
+
// base62 characters. `nowMs` is a parameter only so tests can pin the clock.
|
|
93
96
|
const BASE62 = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
|
|
94
97
|
let idLastTimestamp = 0;
|
|
95
98
|
let idCounter = 0;
|
|
@@ -100,14 +103,15 @@ function randomBase62(length) {
|
|
|
100
103
|
}
|
|
101
104
|
return out;
|
|
102
105
|
}
|
|
103
|
-
function ascendingId(prefix) {
|
|
104
|
-
const nowMs = Date.now();
|
|
106
|
+
export function ascendingId(prefix, nowMs = Date.now()) {
|
|
105
107
|
if (nowMs !== idLastTimestamp) {
|
|
106
108
|
idLastTimestamp = nowMs;
|
|
107
109
|
idCounter = 0;
|
|
108
110
|
}
|
|
109
111
|
idCounter += 1;
|
|
110
|
-
|
|
112
|
+
// BigInt, as OpenCode does: the JS `&` operator works on 32 bits, which made
|
|
113
|
+
// short, sometimes negative ids that sorted before OpenCode's own (ORI-2116).
|
|
114
|
+
const encoded = (BigInt(nowMs) * BigInt(0x1000) + BigInt(idCounter)) & BigInt(0xffffffffffff);
|
|
111
115
|
const hex = encoded.toString(16).padStart(12, '0');
|
|
112
116
|
return `${prefix}_${hex}${randomBase62(14)}`;
|
|
113
117
|
}
|
|
@@ -443,7 +447,7 @@ export function createOpenCodeHarness(options) {
|
|
|
443
447
|
}
|
|
444
448
|
}
|
|
445
449
|
return {
|
|
446
|
-
name:
|
|
450
|
+
name: HARNESS_NAMES.opencode,
|
|
447
451
|
async start(opts) {
|
|
448
452
|
startModel = opts.model;
|
|
449
453
|
startReasoningEffort = opts.reasoningEffort;
|
|
@@ -541,9 +545,21 @@ export function createOpenCodeHarness(options) {
|
|
|
541
545
|
args: input,
|
|
542
546
|
callId,
|
|
543
547
|
status,
|
|
548
|
+
harness: HARNESS_NAMES.opencode,
|
|
544
549
|
};
|
|
545
|
-
|
|
546
|
-
|
|
550
|
+
// A failed call keeps its message in `state.error`, not `state.output`
|
|
551
|
+
// (opencode-ai@1.14.41 ToolStateError); it is that call's output.
|
|
552
|
+
if (terminal) {
|
|
553
|
+
payload.output = typeof state.output === 'string' ? state.output
|
|
554
|
+
: typeof state.error === 'string' ? state.error : '';
|
|
555
|
+
}
|
|
556
|
+
// OpenCode's own one-line title and structured extras (ORI-2160),
|
|
557
|
+
// passed through as given; absent when the state has none.
|
|
558
|
+
if (typeof state.title === 'string' && state.title.length > 0)
|
|
559
|
+
payload.title = state.title;
|
|
560
|
+
if (state.metadata && typeof state.metadata === 'object' && !Array.isArray(state.metadata)) {
|
|
561
|
+
payload.metadata = state.metadata;
|
|
562
|
+
}
|
|
547
563
|
events.push({ kind: terminal ? 'tool_result' : 'tool_call', messageId: msgId, payload });
|
|
548
564
|
}
|
|
549
565
|
else if (partType === 'step-start') {
|
package/dist/hosted-harness.d.ts
CHANGED
|
@@ -99,8 +99,36 @@ export interface HarnessEvent {
|
|
|
99
99
|
/** Requires guaranteed delivery (execution_complete / error / push_*). */
|
|
100
100
|
critical?: boolean;
|
|
101
101
|
}
|
|
102
|
+
/** The drivers' stable names. A tool event's `harness` field is one of these. */
|
|
103
|
+
export declare const HARNESS_NAMES: {
|
|
104
|
+
readonly opencode: "opencode";
|
|
105
|
+
readonly claudeAgentSdk: "claude-agent-sdk";
|
|
106
|
+
};
|
|
107
|
+
type HarnessName = (typeof HARNESS_NAMES)[keyof typeof HARNESS_NAMES];
|
|
108
|
+
/**
|
|
109
|
+
* Payload of a `tool_call` / `tool_result` event (ORI-2160). One chat renderer
|
|
110
|
+
* shows every tool call whatever harness produced it, so the payload carries:
|
|
111
|
+
* • `title` — the harness's one-line summary of the call (OpenCode's
|
|
112
|
+
* `state.title`). Absent when the harness has none.
|
|
113
|
+
* • `metadata` — structured extras such as a diff, an exit code or match
|
|
114
|
+
* counts (OpenCode's `state.metadata`). Absent when none.
|
|
115
|
+
* • `harness` — which driver produced the event.
|
|
116
|
+
* All three are optional: an event without them is still a valid tool event.
|
|
117
|
+
* The sink and the digest pass them through unchanged.
|
|
118
|
+
*/
|
|
119
|
+
export interface HarnessToolPayload {
|
|
120
|
+
[key: string]: unknown;
|
|
121
|
+
tool?: string;
|
|
122
|
+
args?: Record<string, unknown>;
|
|
123
|
+
callId: string;
|
|
124
|
+
status: string;
|
|
125
|
+
output?: string;
|
|
126
|
+
title?: string;
|
|
127
|
+
metadata?: Record<string, unknown>;
|
|
128
|
+
harness?: HarnessName;
|
|
129
|
+
}
|
|
102
130
|
export interface AgentHarness {
|
|
103
|
-
/** Stable driver name —
|
|
131
|
+
/** Stable driver name — one of HARNESS_NAMES. */
|
|
104
132
|
readonly name: string;
|
|
105
133
|
/** Boot the agent process/session; returns the resumable agent session id. */
|
|
106
134
|
start(opts: HarnessStartOptions): Promise<{
|
|
@@ -118,4 +146,5 @@ export interface AgentHarness {
|
|
|
118
146
|
/** Release all resources; the harness is unusable afterward. */
|
|
119
147
|
shutdown(): Promise<void>;
|
|
120
148
|
}
|
|
149
|
+
export {};
|
|
121
150
|
//# sourceMappingURL=hosted-harness.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hosted-harness.d.ts","sourceRoot":"","sources":["../src/hosted-harness.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH;8DAC8D;AAC9D,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAA;IACZ,qEAAqE;IACrE,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IACxB,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAC7B;AAED,MAAM,WAAW,mBAAmB;IAClC,yEAAyE;IACzE,YAAY,EAAE,MAAM,CAAA;IACpB,kEAAkE;IAClE,KAAK,EAAE,MAAM,CAAA;IACb,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,UAAU,CAAC,EAAE,SAAS,eAAe,EAAE,CAAA;IACvC,wEAAwE;IACxE,oBAAoB,CAAC,EAAE,MAAM,CAAA;CAC9B;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAA;IACb,0DAA0D;IAC1D,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,EAAE,MAAM,CAAA;IACf,kEAAkE;IAClE,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAA;CACxC;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;CA+BtB,CAAA;AAEV,MAAM,MAAM,gBAAgB,GAAG,MAAM,OAAO,mBAAmB,CAAA;AAE/D;iDACiD;AACjD,eAAO,MAAM,sBAAsB;;;CAGzB,CAAA;AAEV,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAErE;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,gBAAgB,CAAA;IACtB,wEAAwE;IACxE,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAChC,0EAA0E;IAC1E,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,
|
|
1
|
+
{"version":3,"file":"hosted-harness.d.ts","sourceRoot":"","sources":["../src/hosted-harness.ts"],"names":[],"mappings":"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"}
|
package/dist/hosted-harness.js
CHANGED
|
@@ -70,3 +70,8 @@ export const HARNESS_TERMINAL_KINDS = {
|
|
|
70
70
|
export function isHarnessTerminalKind(kind) {
|
|
71
71
|
return kind in HARNESS_TERMINAL_KINDS;
|
|
72
72
|
}
|
|
73
|
+
/** The drivers' stable names. A tool event's `harness` field is one of these. */
|
|
74
|
+
export const HARNESS_NAMES = {
|
|
75
|
+
opencode: 'opencode',
|
|
76
|
+
claudeAgentSdk: 'claude-agent-sdk',
|
|
77
|
+
};
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/** What kind of thing a tool does — the renderer picks an icon/layout from
|
|
2
|
+
* this, never from the tool name. */
|
|
3
|
+
export declare const TOOL_CATEGORIES: {
|
|
4
|
+
readonly file: "file";
|
|
5
|
+
readonly command: "command";
|
|
6
|
+
readonly search: "search";
|
|
7
|
+
readonly network: "network";
|
|
8
|
+
readonly question: "question";
|
|
9
|
+
readonly subAgent: "sub-agent";
|
|
10
|
+
readonly list: "list";
|
|
11
|
+
readonly plug: "plug";
|
|
12
|
+
readonly other: "other";
|
|
13
|
+
};
|
|
14
|
+
export type ToolCategory = (typeof TOOL_CATEGORIES)[keyof typeof TOOL_CATEGORIES];
|
|
15
|
+
/** How the tool's output text should be shown. */
|
|
16
|
+
export declare const TOOL_OUTPUT_KINDS: {
|
|
17
|
+
readonly text: "text";
|
|
18
|
+
readonly diff: "diff";
|
|
19
|
+
readonly markdown: "markdown";
|
|
20
|
+
readonly json: "json";
|
|
21
|
+
readonly list: "list";
|
|
22
|
+
};
|
|
23
|
+
type ToolOutputKind = (typeof TOOL_OUTPUT_KINDS)[keyof typeof TOOL_OUTPUT_KINDS];
|
|
24
|
+
/** Per-tool display hint. Each driver owns a table of these for its built-in
|
|
25
|
+
* tools, so tool-name knowledge lives behind the seam. */
|
|
26
|
+
export interface ToolHint {
|
|
27
|
+
category: ToolCategory;
|
|
28
|
+
/** The verb the chat row shows ("Read", "Ran"). A tool without a hint shows
|
|
29
|
+
* its own name instead. */
|
|
30
|
+
label?: string;
|
|
31
|
+
/** The input key whose value summarizes the call (e.g. `command`), or null
|
|
32
|
+
* when the tool takes no input worth summarizing. */
|
|
33
|
+
summaryKey: string | null;
|
|
34
|
+
outputKind: ToolOutputKind;
|
|
35
|
+
/** Input keys whose values must not be shown as-is (large bodies such as a
|
|
36
|
+
* file's full new content, or likely secrets). */
|
|
37
|
+
redactKeys: readonly string[];
|
|
38
|
+
}
|
|
39
|
+
export type ToolHintTable = Readonly<Record<string, ToolHint>>;
|
|
40
|
+
/**
|
|
41
|
+
* Look a tool up in a driver's hint table. A tool the table does not know (an
|
|
42
|
+
* MCP tool, a plug-in) falls back to the `plug` category, summarized by its
|
|
43
|
+
* first non-empty string argument that does not look like a secret.
|
|
44
|
+
*/
|
|
45
|
+
export declare function resolveToolHint(table: ToolHintTable, tool: string, args?: Record<string, unknown>): ToolHint;
|
|
46
|
+
export declare const OPENCODE_TOOL_HINTS: ToolHintTable;
|
|
47
|
+
export declare const CLAUDE_TOOL_HINTS: ToolHintTable;
|
|
48
|
+
/**
|
|
49
|
+
* The hint table for the harness that produced an event. Events recorded
|
|
50
|
+
* before the seam named its harness came from OpenCode, the default driver.
|
|
51
|
+
* A harness with no table here (a future pi driver, say) gets none, so every
|
|
52
|
+
* tool falls back to its own name and first string argument.
|
|
53
|
+
*/
|
|
54
|
+
export declare function toolHintsFor(harness: string | undefined): ToolHintTable;
|
|
55
|
+
export {};
|
|
56
|
+
//# sourceMappingURL=hosted-tool-hints.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hosted-tool-hints.d.ts","sourceRoot":"","sources":["../src/hosted-tool-hints.ts"],"names":[],"mappings":"AAmBA;sCACsC;AACtC,eAAO,MAAM,eAAe;;;;;;;;;;CAUlB,CAAA;AAEV,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,OAAO,eAAe,CAAC,CAAA;AAEjF,kDAAkD;AAClD,eAAO,MAAM,iBAAiB;;;;;;CAMpB,CAAA;AAEV,KAAK,cAAc,GAAG,CAAC,OAAO,iBAAiB,CAAC,CAAC,MAAM,OAAO,iBAAiB,CAAC,CAAA;AAEhF;2DAC2D;AAC3D,MAAM,WAAW,QAAQ;IACvB,QAAQ,EAAE,YAAY,CAAA;IACtB;gCAC4B;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd;0DACsD;IACtD,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,UAAU,EAAE,cAAc,CAAA;IAC1B;uDACmD;IACnD,UAAU,EAAE,SAAS,MAAM,EAAE,CAAA;CAC9B;AAED,MAAM,MAAM,aAAa,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAA;AAM9D;;;;GAIG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,aAAa,EACpB,IAAI,EAAE,MAAM,EACZ,IAAI,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GACjC,QAAQ,CAWV;AAKD,eAAO,MAAM,mBAAmB,EAAE,aAiBjC,CAAA;AAQD,eAAO,MAAM,iBAAiB,EAAE,aAoB/B,CAAA;AAID;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,aAAa,CAIvE"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
const OPENCODE = 'opencode';
|
|
2
|
+
const CLAUDE_AGENT_SDK = 'claude-agent-sdk';
|
|
3
|
+
/** What kind of thing a tool does — the renderer picks an icon/layout from
|
|
4
|
+
* this, never from the tool name. */
|
|
5
|
+
export const TOOL_CATEGORIES = {
|
|
6
|
+
file: 'file',
|
|
7
|
+
command: 'command',
|
|
8
|
+
search: 'search',
|
|
9
|
+
network: 'network',
|
|
10
|
+
question: 'question',
|
|
11
|
+
subAgent: 'sub-agent',
|
|
12
|
+
list: 'list',
|
|
13
|
+
plug: 'plug',
|
|
14
|
+
other: 'other',
|
|
15
|
+
};
|
|
16
|
+
/** How the tool's output text should be shown. */
|
|
17
|
+
export const TOOL_OUTPUT_KINDS = {
|
|
18
|
+
text: 'text',
|
|
19
|
+
diff: 'diff',
|
|
20
|
+
markdown: 'markdown',
|
|
21
|
+
json: 'json',
|
|
22
|
+
list: 'list',
|
|
23
|
+
};
|
|
24
|
+
// Argument names that look like they hold a credential. Redacted for every
|
|
25
|
+
// tool, and never used as the fallback summary.
|
|
26
|
+
const SECRET_LOOKING_KEY = /token|secret|password|passwd|api[_-]?key|authorization|credential/i;
|
|
27
|
+
/**
|
|
28
|
+
* Look a tool up in a driver's hint table. A tool the table does not know (an
|
|
29
|
+
* MCP tool, a plug-in) falls back to the `plug` category, summarized by its
|
|
30
|
+
* first non-empty string argument that does not look like a secret.
|
|
31
|
+
*/
|
|
32
|
+
export function resolveToolHint(table, tool, args = {}) {
|
|
33
|
+
const known = Object.hasOwn(table, tool) ? table[tool] : undefined;
|
|
34
|
+
const secretKeys = Object.keys(args).filter(key => SECRET_LOOKING_KEY.test(key));
|
|
35
|
+
const redactKeys = [...new Set([...(known?.redactKeys ?? []), ...secretKeys])];
|
|
36
|
+
if (known)
|
|
37
|
+
return { ...known, redactKeys };
|
|
38
|
+
const summaryKey = Object.keys(args).find(key => {
|
|
39
|
+
const value = args[key];
|
|
40
|
+
return typeof value === 'string' && value.length > 0 && !redactKeys.includes(key);
|
|
41
|
+
}) ?? null;
|
|
42
|
+
return { category: TOOL_CATEGORIES.plug, summaryKey, outputKind: TOOL_OUTPUT_KINDS.text, redactKeys };
|
|
43
|
+
}
|
|
44
|
+
// OpenCode's built-in tools, as the pinned opencode-ai@1.14.41 tool registry
|
|
45
|
+
// lists them, with the input key that summarizes each call. Tools not listed
|
|
46
|
+
// here (MCP tools, plug-ins) resolve to `plug` through resolveToolHint.
|
|
47
|
+
export const OPENCODE_TOOL_HINTS = {
|
|
48
|
+
read: { category: 'file', label: 'Read', summaryKey: 'filePath', outputKind: 'text', redactKeys: [] },
|
|
49
|
+
edit: { category: 'file', label: 'Edited', summaryKey: 'filePath', outputKind: 'diff', redactKeys: ['oldString', 'newString'] },
|
|
50
|
+
write: { category: 'file', label: 'Wrote', summaryKey: 'filePath', outputKind: 'text', redactKeys: ['content'] },
|
|
51
|
+
apply_patch: { category: 'file', label: 'Edited', summaryKey: 'patchText', outputKind: 'diff', redactKeys: [] },
|
|
52
|
+
lsp: { category: 'file', label: 'Checked', summaryKey: 'filePath', outputKind: 'json', redactKeys: [] },
|
|
53
|
+
bash: { category: 'command', label: 'Ran', summaryKey: 'command', outputKind: 'text', redactKeys: [] },
|
|
54
|
+
glob: { category: 'search', label: 'Listed', summaryKey: 'pattern', outputKind: 'list', redactKeys: [] },
|
|
55
|
+
grep: { category: 'search', label: 'Searched', summaryKey: 'pattern', outputKind: 'text', redactKeys: [] },
|
|
56
|
+
webfetch: { category: 'network', label: 'Fetched', summaryKey: 'url', outputKind: 'markdown', redactKeys: [] },
|
|
57
|
+
websearch: { category: 'network', label: 'Searched', summaryKey: 'query', outputKind: 'text', redactKeys: [] },
|
|
58
|
+
question: { category: 'question', label: 'Asked', summaryKey: 'questions', outputKind: 'text', redactKeys: [] },
|
|
59
|
+
plan_exit: { category: 'question', label: 'Asked', summaryKey: null, outputKind: 'text', redactKeys: [] },
|
|
60
|
+
task: { category: 'sub-agent', label: 'Sub-agent', summaryKey: 'description', outputKind: 'markdown', redactKeys: [] },
|
|
61
|
+
todowrite: { category: 'list', label: 'Planned', summaryKey: 'todos', outputKind: 'json', redactKeys: [] },
|
|
62
|
+
skill: { category: 'other', label: 'Loaded', summaryKey: 'name', outputKind: 'markdown', redactKeys: [] },
|
|
63
|
+
invalid: { category: 'other', label: 'Invalid', summaryKey: 'tool', outputKind: 'text', redactKeys: [] },
|
|
64
|
+
};
|
|
65
|
+
// The Claude Agent SDK's built-in tools (SDK 0.3.201: input types in
|
|
66
|
+
// sdk-tools.d.ts, names from the SDK; `Task` is the older name of `Agent`),
|
|
67
|
+
// with the input key that summarizes each call. MCP tools
|
|
68
|
+
// (`mcp__<server>__<tool>`) are not listed and resolve to `plug` through
|
|
69
|
+
// resolveToolHint. This driver sends no `title` or `metadata`: the SDK has no
|
|
70
|
+
// equivalent of OpenCode's.
|
|
71
|
+
export const CLAUDE_TOOL_HINTS = {
|
|
72
|
+
Read: { category: 'file', label: 'Read', summaryKey: 'file_path', outputKind: 'text', redactKeys: [] },
|
|
73
|
+
Edit: { category: 'file', label: 'Edited', summaryKey: 'file_path', outputKind: 'text', redactKeys: ['old_string', 'new_string'] },
|
|
74
|
+
Write: { category: 'file', label: 'Wrote', summaryKey: 'file_path', outputKind: 'text', redactKeys: ['content'] },
|
|
75
|
+
NotebookEdit: { category: 'file', label: 'Edited', summaryKey: 'notebook_path', outputKind: 'text', redactKeys: ['new_source'] },
|
|
76
|
+
Bash: { category: 'command', label: 'Ran', summaryKey: 'command', outputKind: 'text', redactKeys: [] },
|
|
77
|
+
TaskOutput: { category: 'command', label: 'Checked', summaryKey: 'task_id', outputKind: 'text', redactKeys: [] },
|
|
78
|
+
TaskStop: { category: 'command', label: 'Stopped', summaryKey: 'task_id', outputKind: 'text', redactKeys: [] },
|
|
79
|
+
Glob: { category: 'search', label: 'Listed', summaryKey: 'pattern', outputKind: 'list', redactKeys: [] },
|
|
80
|
+
Grep: { category: 'search', label: 'Searched', summaryKey: 'pattern', outputKind: 'text', redactKeys: [] },
|
|
81
|
+
WebFetch: { category: 'network', label: 'Fetched', summaryKey: 'url', outputKind: 'markdown', redactKeys: [] },
|
|
82
|
+
WebSearch: { category: 'network', label: 'Searched', summaryKey: 'query', outputKind: 'text', redactKeys: [] },
|
|
83
|
+
AskUserQuestion: { category: 'question', label: 'Asked', summaryKey: 'questions', outputKind: 'text', redactKeys: [] },
|
|
84
|
+
ExitPlanMode: { category: 'question', label: 'Asked', summaryKey: null, outputKind: 'markdown', redactKeys: [] },
|
|
85
|
+
Agent: { category: 'sub-agent', label: 'Sub-agent', summaryKey: 'description', outputKind: 'markdown', redactKeys: [] },
|
|
86
|
+
Task: { category: 'sub-agent', label: 'Sub-agent', summaryKey: 'description', outputKind: 'markdown', redactKeys: [] },
|
|
87
|
+
TodoWrite: { category: 'list', label: 'Planned', summaryKey: 'todos', outputKind: 'text', redactKeys: [] },
|
|
88
|
+
ListMcpResourcesTool: { category: 'plug', label: 'Listed', summaryKey: 'server', outputKind: 'json', redactKeys: [] },
|
|
89
|
+
ReadMcpResourceTool: { category: 'plug', label: 'Read', summaryKey: 'uri', outputKind: 'text', redactKeys: [] },
|
|
90
|
+
Skill: { category: 'other', label: 'Loaded', summaryKey: 'skill', outputKind: 'markdown', redactKeys: [] },
|
|
91
|
+
};
|
|
92
|
+
const NO_HINTS = {};
|
|
93
|
+
/**
|
|
94
|
+
* The hint table for the harness that produced an event. Events recorded
|
|
95
|
+
* before the seam named its harness came from OpenCode, the default driver.
|
|
96
|
+
* A harness with no table here (a future pi driver, say) gets none, so every
|
|
97
|
+
* tool falls back to its own name and first string argument.
|
|
98
|
+
*/
|
|
99
|
+
export function toolHintsFor(harness) {
|
|
100
|
+
if (harness === undefined || harness === OPENCODE)
|
|
101
|
+
return OPENCODE_TOOL_HINTS;
|
|
102
|
+
if (harness === CLAUDE_AGENT_SDK)
|
|
103
|
+
return CLAUDE_TOOL_HINTS;
|
|
104
|
+
return NO_HINTS;
|
|
105
|
+
}
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAsLA,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAA;AAEhE,eAAO,MAAM,wBAAwB,GAAI,iBAAiB,MAAM;;;EACJ,CAAA;AAE5D,OAAO,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAA;AAC5E,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAsLA,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAA;AAEhE,eAAO,MAAM,wBAAwB,GAAI,iBAAiB,MAAM;;;EACJ,CAAA;AAE5D,OAAO,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAA;AAC5E,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAA;AA4tCtD,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,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,iBAAiB,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC,UAAU,CAexH;AAmMD,wBAAsB,IAAI,CAAC,OAAO,WAAwB,iBAyhBzD;AA6DD,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAA;AAEhF,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -31,7 +31,7 @@ import { resolveAuthTokenForBaseUrl } from './credentials.js';
|
|
|
31
31
|
import { applyHostedInstructionSetProfileOverride, dispatchHostedCommands } from './hosted-commands.js';
|
|
32
32
|
import { dispatchGepaEngine } from './gepa-engine-dispatch.js';
|
|
33
33
|
import { getGepaPythonPathEntries } from './gepa-python-paths.js';
|
|
34
|
-
import {
|
|
34
|
+
import { resolveGepaSeedFromEnvironment } from './instruction-set-gepa-launch.js';
|
|
35
35
|
import { prepareSkilledProposerLaunch, spawnSkilledProposerChild } from './skilled-proposer-launch.js';
|
|
36
36
|
import { reportCommentsCommand, throwDeprecatedPromptCommentsCommand } from './report-comments-cli.js';
|
|
37
37
|
import { getCapabilities, renderHelpForArgs } from './help.js';
|
|
@@ -997,10 +997,7 @@ async function runGepaOptimization() {
|
|
|
997
997
|
PYTHONPATH: getGepaPythonPathEntries(process.env.PYTHONPATH).join(delimiter),
|
|
998
998
|
PYTHONUNBUFFERED: process.env.PYTHONUNBUFFERED || '1',
|
|
999
999
|
}));
|
|
1000
|
-
const
|
|
1001
|
-
const modelConfigIdentity = dispatch.environment.ORIZU_MODEL_CONFIG_IDENTITY;
|
|
1002
|
-
const instructionSetProfileVersionId = instructionSetName && modelConfigIdentity
|
|
1003
|
-
? await resolveGepaInstructionSetProfileVersion(instructionSetName, modelConfigIdentity, project) : undefined;
|
|
1000
|
+
const instructionSetProfileVersionId = await resolveGepaSeedFromEnvironment(dispatch.environment, project, 'production');
|
|
1004
1001
|
if (instructionSetProfileVersionId)
|
|
1005
1002
|
dispatch.environment.ORIZU_INSTRUCTION_SET_PROFILE_VERSION_ID = instructionSetProfileVersionId;
|
|
1006
1003
|
selectedEngine = dispatch.engine;
|
|
@@ -1,3 +1,22 @@
|
|
|
1
|
-
/**
|
|
2
|
-
export
|
|
1
|
+
/** The Seed a run-gepa launch names: set reference, profile, and optional version. */
|
|
2
|
+
export interface GepaSeedSelector {
|
|
3
|
+
instructionSetName: string;
|
|
4
|
+
modelConfigIdentity?: string;
|
|
5
|
+
versionNumber?: number;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Combine `--instruction-set`, `--model-config` and `--profile-version` into
|
|
9
|
+
* one Seed. A value with `/` or `@` is a specifier (`set/profile@vN`); any
|
|
10
|
+
* other value is a set slug or exact name, passed through unchanged. Values
|
|
11
|
+
* named twice must agree, the same rule `sync` applies to `--version`.
|
|
12
|
+
*/
|
|
13
|
+
export declare function gepaSeedSelector(instructionSetArg: string, modelConfigFlag: string | undefined, versionFlag: string | undefined): GepaSeedSelector;
|
|
14
|
+
/**
|
|
15
|
+
* Resolve the Seed that dispatch normalised into the connector environment.
|
|
16
|
+
* Returns undefined when no instruction set was selected. When no version is
|
|
17
|
+
* named, `unversioned: 'production'` resolves the profile's Production here
|
|
18
|
+
* (local runs); `unversioned: 'server'` leaves it to the hosted launch route,
|
|
19
|
+
* which resolves Production itself in the same call that queues the run.
|
|
20
|
+
*/
|
|
21
|
+
export declare function resolveGepaSeedFromEnvironment(environment: NodeJS.ProcessEnv, project: string, unversioned: 'production' | 'server'): Promise<string | undefined>;
|
|
3
22
|
//# sourceMappingURL=instruction-set-gepa-launch.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"instruction-set-gepa-launch.d.ts","sourceRoot":"","sources":["../src/instruction-set-gepa-launch.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"instruction-set-gepa-launch.d.ts","sourceRoot":"","sources":["../src/instruction-set-gepa-launch.ts"],"names":[],"mappings":"AAsFA,sFAAsF;AACtF,MAAM,WAAW,gBAAgB;IAC/B,kBAAkB,EAAE,MAAM,CAAA;IAC1B,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB;AAWD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,iBAAiB,EAAE,MAAM,EACzB,eAAe,EAAE,MAAM,GAAG,SAAS,EACnC,WAAW,EAAE,MAAM,GAAG,SAAS,GAC9B,gBAAgB,CAiBlB;AAqCD;;;;;;GAMG;AACH,wBAAsB,8BAA8B,CAClD,WAAW,EAAE,MAAM,CAAC,UAAU,EAC9B,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,YAAY,GAAG,QAAQ,GACnC,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAQ7B"}
|