snipara-companion 3.4.0 → 3.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +9 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.js +165 -11
- package/docs/FULL_REFERENCE.md +25 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
Release notes for `snipara-companion`, newest first.
|
|
4
4
|
|
|
5
|
+
## New In 3.4.1
|
|
6
|
+
|
|
7
|
+
- Declares provider API keys by environment-variable name and supports
|
|
8
|
+
`authorization` or `x-api-key` headers without persisting secret values.
|
|
9
|
+
- Resolves declared Codex and Claude CLI workers to explicit native adapters;
|
|
10
|
+
unsupported generic CLI profiles fail closed.
|
|
11
|
+
- Preserves opt-in local routing behavior while forwarding provider auth metadata
|
|
12
|
+
to the orchestrator catalog.
|
|
13
|
+
|
|
5
14
|
## New In 3.4.0
|
|
6
15
|
|
|
7
16
|
- Adds repeatable `workers execute --output-fragment` contracts.
|
package/dist/index.d.ts
CHANGED
|
@@ -4478,6 +4478,8 @@ interface LocalWorkerDeclaration {
|
|
|
4478
4478
|
endpointType: "local";
|
|
4479
4479
|
provider: string;
|
|
4480
4480
|
baseUrl: string;
|
|
4481
|
+
apiKeyEnv?: string;
|
|
4482
|
+
apiKeyHeader?: "authorization" | "x-api-key";
|
|
4481
4483
|
command?: string;
|
|
4482
4484
|
model?: string;
|
|
4483
4485
|
preferModel?: string;
|
|
@@ -4496,11 +4498,16 @@ interface LocalWorkersConfig {
|
|
|
4496
4498
|
interface LocalWorkerRoutingDefaults {
|
|
4497
4499
|
worker: LocalWorkerDeclaration;
|
|
4498
4500
|
routeLocalWorkers: true;
|
|
4501
|
+
routingLocalTransport: "openai_http" | "cli";
|
|
4502
|
+
routingLocalAdapter?: "codex_app_server" | "claude_cli";
|
|
4503
|
+
routingLocalCommand?: string;
|
|
4499
4504
|
routingWorkerRole: string;
|
|
4500
4505
|
routingLocalBaseUrl: string;
|
|
4501
4506
|
routingLocalModel?: string;
|
|
4502
4507
|
routingLocalPreferModel?: string;
|
|
4503
4508
|
routingLocalProvider: string;
|
|
4509
|
+
routingLocalApiKeyEnv?: string;
|
|
4510
|
+
routingLocalApiKeyHeader?: "authorization" | "x-api-key";
|
|
4504
4511
|
routingPreferredEndpoints: string[];
|
|
4505
4512
|
routingAllowedEndpoints: string[];
|
|
4506
4513
|
plannerRetainsReasoning: true;
|
|
@@ -4520,6 +4527,8 @@ interface LocalWorkerAddOptions {
|
|
|
4520
4527
|
json?: boolean;
|
|
4521
4528
|
transport?: "openai_http" | "cli";
|
|
4522
4529
|
command?: string;
|
|
4530
|
+
apiKeyEnv?: string;
|
|
4531
|
+
apiKeyHeader?: "authorization" | "x-api-key";
|
|
4523
4532
|
}
|
|
4524
4533
|
interface LocalWorkerStatusOptions {
|
|
4525
4534
|
json?: boolean;
|
|
@@ -4542,6 +4551,8 @@ interface LocalWorkerProbeOptions {
|
|
|
4542
4551
|
writeScope?: string[];
|
|
4543
4552
|
reasoning?: "low" | "medium" | "high";
|
|
4544
4553
|
contextWindow?: number;
|
|
4554
|
+
apiKeyEnv?: string;
|
|
4555
|
+
apiKeyHeader?: "authorization" | "x-api-key";
|
|
4545
4556
|
json?: boolean;
|
|
4546
4557
|
}
|
|
4547
4558
|
declare function workersLocalAddCommand(options: LocalWorkerAddOptions): void;
|
package/dist/index.js
CHANGED
|
@@ -9755,7 +9755,9 @@ function normalizeWorkerProfileTransport(value) {
|
|
|
9755
9755
|
baseUrl,
|
|
9756
9756
|
...stringValue(value.model) ? { model: stringValue(value.model) } : {},
|
|
9757
9757
|
...stringValue(value.preferModel) ? { preferModel: stringValue(value.preferModel) } : {},
|
|
9758
|
-
...stringValue(value.provider) ? { provider: stringValue(value.provider) } : {}
|
|
9758
|
+
...stringValue(value.provider) ? { provider: stringValue(value.provider) } : {},
|
|
9759
|
+
...safeEnvironmentVariableName(value.apiKeyEnv) ? { apiKeyEnv: safeEnvironmentVariableName(value.apiKeyEnv) } : {},
|
|
9760
|
+
...value.apiKeyHeader === "authorization" || value.apiKeyHeader === "x-api-key" ? { apiKeyHeader: value.apiKeyHeader } : {}
|
|
9759
9761
|
};
|
|
9760
9762
|
}
|
|
9761
9763
|
if (kind === "cli") {
|
|
@@ -9897,6 +9899,10 @@ function numberValue(value) {
|
|
|
9897
9899
|
function booleanValue(value) {
|
|
9898
9900
|
return value === true;
|
|
9899
9901
|
}
|
|
9902
|
+
function safeEnvironmentVariableName(value) {
|
|
9903
|
+
const normalized = stringValue(value);
|
|
9904
|
+
return normalized && /^[A-Za-z_][A-Za-z0-9_]*$/.test(normalized) ? normalized : void 0;
|
|
9905
|
+
}
|
|
9900
9906
|
function stringValue(value) {
|
|
9901
9907
|
if (value === null || value === void 0) {
|
|
9902
9908
|
return void 0;
|
|
@@ -19627,6 +19633,9 @@ function workersLocalAddCommand(options) {
|
|
|
19627
19633
|
printKeyValue("Role:", result.worker.workerRole);
|
|
19628
19634
|
printKeyValue("Provider:", result.worker.provider);
|
|
19629
19635
|
printKeyValue("Base URL:", result.worker.baseUrl);
|
|
19636
|
+
if (result.worker.apiKeyEnv) {
|
|
19637
|
+
printKeyValue("API key env:", result.worker.apiKeyEnv);
|
|
19638
|
+
}
|
|
19630
19639
|
if (result.worker.model) {
|
|
19631
19640
|
printKeyValue("Model:", result.worker.model);
|
|
19632
19641
|
} else if (result.worker.preferModel) {
|
|
@@ -19718,7 +19727,9 @@ function workersLocalProbeCommand(options) {
|
|
|
19718
19727
|
capabilities: normalizeStringList3(options.capabilities),
|
|
19719
19728
|
writeScope: normalizeStringList3(options.writeScope),
|
|
19720
19729
|
model,
|
|
19721
|
-
preferModel
|
|
19730
|
+
preferModel,
|
|
19731
|
+
apiKeyEnv: options.apiKeyEnv,
|
|
19732
|
+
apiKeyHeader: options.apiKeyHeader
|
|
19722
19733
|
});
|
|
19723
19734
|
const catalogContextWindow = resolveContextWindowFromCatalog(catalog, model, preferModel);
|
|
19724
19735
|
const contextWindow = normalizeContextWindow(
|
|
@@ -19737,7 +19748,9 @@ function workersLocalProbeCommand(options) {
|
|
|
19737
19748
|
baseUrl,
|
|
19738
19749
|
...model ? { model } : {},
|
|
19739
19750
|
...preferModel ? { preferModel } : {},
|
|
19740
|
-
provider
|
|
19751
|
+
provider,
|
|
19752
|
+
...options.apiKeyEnv ? { apiKeyEnv: options.apiKeyEnv } : {},
|
|
19753
|
+
...options.apiKeyHeader ? { apiKeyHeader: options.apiKeyHeader } : {}
|
|
19741
19754
|
},
|
|
19742
19755
|
capabilities: {
|
|
19743
19756
|
roles: [role],
|
|
@@ -19891,7 +19904,26 @@ function resolveLocalWorkerRoutingDefaults(options = {}) {
|
|
|
19891
19904
|
throw new Error(`Local worker ${requestedId} is not declared.`);
|
|
19892
19905
|
}
|
|
19893
19906
|
if (!worker.baseUrl || worker.baseUrl === "cli://command") {
|
|
19894
|
-
|
|
19907
|
+
const command = worker.command?.toLowerCase() ?? "";
|
|
19908
|
+
const adapter = command.includes("codex") ? "codex_app_server" : command.includes("claude") ? "claude_cli" : void 0;
|
|
19909
|
+
if (!adapter) {
|
|
19910
|
+
throw new Error(
|
|
19911
|
+
`CLI worker ${worker.id} is not mapped to a supported native adapter; use a Codex or Claude command.`
|
|
19912
|
+
);
|
|
19913
|
+
}
|
|
19914
|
+
return {
|
|
19915
|
+
worker,
|
|
19916
|
+
routeLocalWorkers: true,
|
|
19917
|
+
routingLocalTransport: "cli",
|
|
19918
|
+
routingLocalBaseUrl: "cli://command",
|
|
19919
|
+
routingLocalAdapter: adapter,
|
|
19920
|
+
routingLocalCommand: worker.command,
|
|
19921
|
+
routingWorkerRole: worker.workerRole,
|
|
19922
|
+
routingLocalProvider: worker.provider,
|
|
19923
|
+
routingPreferredEndpoints: ["local"],
|
|
19924
|
+
routingAllowedEndpoints: ["local"],
|
|
19925
|
+
plannerRetainsReasoning: true
|
|
19926
|
+
};
|
|
19895
19927
|
}
|
|
19896
19928
|
if (!worker.model && !worker.preferModel) {
|
|
19897
19929
|
const hasCatalogHint = true;
|
|
@@ -19900,11 +19932,14 @@ function resolveLocalWorkerRoutingDefaults(options = {}) {
|
|
|
19900
19932
|
return {
|
|
19901
19933
|
worker,
|
|
19902
19934
|
routeLocalWorkers: true,
|
|
19935
|
+
routingLocalTransport: "openai_http",
|
|
19903
19936
|
routingWorkerRole: worker.workerRole,
|
|
19904
19937
|
routingLocalBaseUrl: worker.baseUrl,
|
|
19905
19938
|
...worker.model ? { routingLocalModel: worker.model } : {},
|
|
19906
19939
|
...worker.preferModel ? { routingLocalPreferModel: worker.preferModel } : {},
|
|
19907
19940
|
routingLocalProvider: worker.provider,
|
|
19941
|
+
...worker.apiKeyEnv ? { routingLocalApiKeyEnv: worker.apiKeyEnv } : {},
|
|
19942
|
+
...worker.apiKeyHeader ? { routingLocalApiKeyHeader: worker.apiKeyHeader } : {},
|
|
19908
19943
|
routingPreferredEndpoints: ["local"],
|
|
19909
19944
|
routingAllowedEndpoints: ["local"],
|
|
19910
19945
|
plannerRetainsReasoning: true
|
|
@@ -20012,7 +20047,9 @@ function normalizeWorkerProfileRecord(value) {
|
|
|
20012
20047
|
transport: {
|
|
20013
20048
|
...transport,
|
|
20014
20049
|
baseUrl,
|
|
20015
|
-
provider: normalizeProvider(transport.provider ?? "lm-studio")
|
|
20050
|
+
provider: normalizeProvider(transport.provider ?? "lm-studio"),
|
|
20051
|
+
...transport.apiKeyEnv ? { apiKeyEnv: transport.apiKeyEnv } : {},
|
|
20052
|
+
...transport.apiKeyHeader ? { apiKeyHeader: transport.apiKeyHeader } : {}
|
|
20016
20053
|
}
|
|
20017
20054
|
};
|
|
20018
20055
|
}
|
|
@@ -20047,7 +20084,9 @@ function toProfileFromLegacyWorker(worker) {
|
|
|
20047
20084
|
baseUrl: worker.baseUrl,
|
|
20048
20085
|
...worker.model ? { model: worker.model } : {},
|
|
20049
20086
|
...worker.preferModel ? { preferModel: worker.preferModel } : {},
|
|
20050
|
-
provider: worker.provider
|
|
20087
|
+
provider: worker.provider,
|
|
20088
|
+
...worker.apiKeyEnv ? { apiKeyEnv: worker.apiKeyEnv } : {},
|
|
20089
|
+
...worker.apiKeyHeader ? { apiKeyHeader: worker.apiKeyHeader } : {}
|
|
20051
20090
|
},
|
|
20052
20091
|
capabilities: {
|
|
20053
20092
|
roles: [normalizeWorkerRole(worker.workerRole)],
|
|
@@ -20090,6 +20129,8 @@ function toLocalWorkerDeclaration(profile) {
|
|
|
20090
20129
|
endpointType: "local",
|
|
20091
20130
|
provider: normalizeProvider(profile.transport.provider ?? "lm-studio"),
|
|
20092
20131
|
baseUrl: profile.transport.baseUrl,
|
|
20132
|
+
...profile.transport.apiKeyEnv ? { apiKeyEnv: profile.transport.apiKeyEnv } : {},
|
|
20133
|
+
...profile.transport.apiKeyHeader ? { apiKeyHeader: profile.transport.apiKeyHeader } : {},
|
|
20093
20134
|
...stringValue6(profile.transport.model) ? { model: stringValue6(profile.transport.model) } : {},
|
|
20094
20135
|
...stringValue6(profile.transport.preferModel) && !profile.transport.model ? { preferModel: stringValue6(profile.transport.preferModel) } : {},
|
|
20095
20136
|
capabilities: normalizeWorkerCapabilities(profile.capabilities.roles),
|
|
@@ -20195,6 +20236,12 @@ function runOrchestratorLocalCatalog(options) {
|
|
|
20195
20236
|
if (options.preferModel) {
|
|
20196
20237
|
args.push("--prefer-model", options.preferModel);
|
|
20197
20238
|
}
|
|
20239
|
+
if (options.apiKeyEnv) {
|
|
20240
|
+
args.push("--api-key-env", options.apiKeyEnv);
|
|
20241
|
+
}
|
|
20242
|
+
if (options.apiKeyHeader) {
|
|
20243
|
+
args.push("--api-key-header", options.apiKeyHeader);
|
|
20244
|
+
}
|
|
20198
20245
|
try {
|
|
20199
20246
|
const result = (0, import_node_child_process9.execFileSync)("snipara-orchestrator", args, {
|
|
20200
20247
|
encoding: "utf8",
|
|
@@ -20330,12 +20377,15 @@ function normalizeWorkerTransport(options) {
|
|
|
20330
20377
|
const baseUrl = normalizeBaseUrl(options.baseUrl ?? "http://127.0.0.1:1234");
|
|
20331
20378
|
const model = stringValue6(options.model);
|
|
20332
20379
|
const preferModel = stringValue6(options.preferModel);
|
|
20380
|
+
const apiKeyEnv = normalizeApiKeyEnvironmentName(options.apiKeyEnv);
|
|
20333
20381
|
return {
|
|
20334
20382
|
kind: "openai_http",
|
|
20335
20383
|
baseUrl,
|
|
20336
20384
|
...model ? { model } : {},
|
|
20337
20385
|
...preferModel ? { preferModel } : {},
|
|
20338
|
-
provider: normalizeProvider(stringValue6(options.provider) ?? "lm-studio")
|
|
20386
|
+
provider: normalizeProvider(stringValue6(options.provider) ?? "lm-studio"),
|
|
20387
|
+
...apiKeyEnv ? { apiKeyEnv } : {},
|
|
20388
|
+
...options.apiKeyHeader ? { apiKeyHeader: options.apiKeyHeader } : {}
|
|
20339
20389
|
};
|
|
20340
20390
|
}
|
|
20341
20391
|
function normalizeProvider(value) {
|
|
@@ -20357,6 +20407,8 @@ function normalizeLegacyWorkerDeclaration(value) {
|
|
|
20357
20407
|
endpointType: "local",
|
|
20358
20408
|
provider: normalizeProvider(stringValue6(value.provider) ?? "lm-studio"),
|
|
20359
20409
|
baseUrl,
|
|
20410
|
+
...stringValue6(value.apiKeyEnv) ? { apiKeyEnv: stringValue6(value.apiKeyEnv) } : {},
|
|
20411
|
+
...value.apiKeyHeader === "authorization" || value.apiKeyHeader === "x-api-key" ? { apiKeyHeader: value.apiKeyHeader } : {},
|
|
20360
20412
|
...stringValue6(value.model) ? { model: stringValue6(value.model) } : {},
|
|
20361
20413
|
...stringValue6(value.preferModel) ? { preferModel: stringValue6(value.preferModel) } : {},
|
|
20362
20414
|
capabilities: normalizeStringList3(value.capabilities).length > 0 ? normalizeStringList3(value.capabilities) : defaultCapabilitiesForWorker(normalizeWorkerRole(value.workerRole)),
|
|
@@ -20434,6 +20486,16 @@ function stringValue6(value) {
|
|
|
20434
20486
|
const stringified = String(value).trim();
|
|
20435
20487
|
return stringified || void 0;
|
|
20436
20488
|
}
|
|
20489
|
+
function normalizeApiKeyEnvironmentName(value) {
|
|
20490
|
+
const normalized = stringValue6(value);
|
|
20491
|
+
if (!normalized) {
|
|
20492
|
+
return void 0;
|
|
20493
|
+
}
|
|
20494
|
+
if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(normalized)) {
|
|
20495
|
+
throw new Error("API key env must be a shell-safe environment variable name.");
|
|
20496
|
+
}
|
|
20497
|
+
return normalized;
|
|
20498
|
+
}
|
|
20437
20499
|
function isRecord10(value) {
|
|
20438
20500
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
20439
20501
|
}
|
|
@@ -25425,7 +25487,7 @@ function shouldResolveAdaptiveRoutingLocally(options, routing) {
|
|
|
25425
25487
|
return preferred.includes("local") || allowed.length === 0 || allowed.includes("local");
|
|
25426
25488
|
}
|
|
25427
25489
|
function hasLocalRoutingRequest(options) {
|
|
25428
|
-
return options.routeLocalWorkers === true || Boolean(options.routingLocalWorker) || Boolean(options.routingLocalBaseUrl) || Boolean(options.routingLocalModel) || Boolean(options.routingLocalPreferModel) || Boolean(options.routingLocalProvider) || normalizeRoutingEndpointTypes(options.routingPreferredEndpoints).includes("local") || normalizeRoutingEndpointTypes(options.routingAllowedEndpoints).includes("local");
|
|
25490
|
+
return options.routeLocalWorkers === true || Boolean(options.routingLocalWorker) || Boolean(options.routingLocalBaseUrl) || Boolean(options.routingLocalModel) || Boolean(options.routingLocalPreferModel) || Boolean(options.routingLocalProvider) || Boolean(options.routingLocalApiKeyEnv) || normalizeRoutingEndpointTypes(options.routingPreferredEndpoints).includes("local") || normalizeRoutingEndpointTypes(options.routingAllowedEndpoints).includes("local");
|
|
25429
25491
|
}
|
|
25430
25492
|
function applyLocalWorkerRoutingDefaults(options, defaults) {
|
|
25431
25493
|
if (!defaults) {
|
|
@@ -25434,6 +25496,9 @@ function applyLocalWorkerRoutingDefaults(options, defaults) {
|
|
|
25434
25496
|
return {
|
|
25435
25497
|
...options,
|
|
25436
25498
|
routeLocalWorkers: options.routeLocalWorkers ?? defaults.routeLocalWorkers,
|
|
25499
|
+
routingLocalTransport: options.routingLocalTransport ?? defaults.routingLocalTransport,
|
|
25500
|
+
routingLocalAdapter: options.routingLocalAdapter ?? defaults.routingLocalAdapter,
|
|
25501
|
+
routingLocalCommand: options.routingLocalCommand ?? defaults.routingLocalCommand,
|
|
25437
25502
|
routingWorkerRole: options.routingWorkerRole ?? defaults.routingWorkerRole,
|
|
25438
25503
|
routingPreferredEndpoints: options.routingPreferredEndpoints && options.routingPreferredEndpoints.length > 0 ? options.routingPreferredEndpoints : defaults.routingPreferredEndpoints,
|
|
25439
25504
|
routingAllowedEndpoints: options.routingAllowedEndpoints && options.routingAllowedEndpoints.length > 0 ? options.routingAllowedEndpoints : defaults.routingAllowedEndpoints,
|
|
@@ -25441,6 +25506,8 @@ function applyLocalWorkerRoutingDefaults(options, defaults) {
|
|
|
25441
25506
|
routingLocalModel: options.routingLocalModel ?? defaults.routingLocalModel,
|
|
25442
25507
|
routingLocalPreferModel: options.routingLocalPreferModel ?? defaults.routingLocalPreferModel,
|
|
25443
25508
|
routingLocalProvider: options.routingLocalProvider ?? defaults.routingLocalProvider,
|
|
25509
|
+
routingLocalApiKeyEnv: options.routingLocalApiKeyEnv ?? defaults.routingLocalApiKeyEnv,
|
|
25510
|
+
routingLocalApiKeyHeader: options.routingLocalApiKeyHeader ?? defaults.routingLocalApiKeyHeader,
|
|
25444
25511
|
plannerRetainsReasoning: options.plannerRetainsReasoning ?? defaults.plannerRetainsReasoning
|
|
25445
25512
|
};
|
|
25446
25513
|
}
|
|
@@ -25455,6 +25522,67 @@ function runOrchestratorJsonCommand(args, cwd = process.cwd()) {
|
|
|
25455
25522
|
}
|
|
25456
25523
|
function enrichAdaptiveRoutingWithLocalOrchestrator(routing, options, cwd = process.cwd()) {
|
|
25457
25524
|
try {
|
|
25525
|
+
if (options.routingLocalTransport === "cli") {
|
|
25526
|
+
const candidateId = options.routingLocalAdapter ?? options.routingLocalCommand ?? "declared-cli";
|
|
25527
|
+
const candidate = {
|
|
25528
|
+
candidateId,
|
|
25529
|
+
workerClass: routing.requirements.workerRole,
|
|
25530
|
+
catalogSource: "declared_cli_worker",
|
|
25531
|
+
endpointType: "local",
|
|
25532
|
+
workerRoles: [routing.requirements.workerRole],
|
|
25533
|
+
capabilities: routing.requirements.capabilities ?? [],
|
|
25534
|
+
writeScope: routing.requirements.writeScope ?? [],
|
|
25535
|
+
reasoning: routing.requirements.reasoning,
|
|
25536
|
+
speed: "normal",
|
|
25537
|
+
cost: "balanced",
|
|
25538
|
+
contextBudget: routing.requirements.contextBudget,
|
|
25539
|
+
qualityScore: null,
|
|
25540
|
+
isAvailable: true,
|
|
25541
|
+
requiresApiKey: false,
|
|
25542
|
+
metadata: {
|
|
25543
|
+
adapter: options.routingLocalAdapter,
|
|
25544
|
+
command: options.routingLocalCommand
|
|
25545
|
+
}
|
|
25546
|
+
};
|
|
25547
|
+
const resolution2 = normalizeAdaptiveRoutingResolution(
|
|
25548
|
+
runOrchestratorJsonCommand(
|
|
25549
|
+
[
|
|
25550
|
+
"route",
|
|
25551
|
+
"--dry-run",
|
|
25552
|
+
"--json",
|
|
25553
|
+
"--work-profile-json",
|
|
25554
|
+
JSON.stringify(routing.workProfile),
|
|
25555
|
+
"--requirements-json",
|
|
25556
|
+
JSON.stringify(routing.requirements),
|
|
25557
|
+
"--candidate-json",
|
|
25558
|
+
JSON.stringify(candidate)
|
|
25559
|
+
],
|
|
25560
|
+
cwd
|
|
25561
|
+
)
|
|
25562
|
+
);
|
|
25563
|
+
return {
|
|
25564
|
+
...routing,
|
|
25565
|
+
gateway: {
|
|
25566
|
+
source: "local_orchestrator",
|
|
25567
|
+
success: true,
|
|
25568
|
+
resolutionStatus: resolution2?.status ?? "resolved",
|
|
25569
|
+
candidateCount: 1,
|
|
25570
|
+
fallback: "main_agent",
|
|
25571
|
+
warnings: []
|
|
25572
|
+
},
|
|
25573
|
+
runtimeCatalog: {
|
|
25574
|
+
source: "declared_cli_worker",
|
|
25575
|
+
candidates: [candidate],
|
|
25576
|
+
workerEndpoints: {
|
|
25577
|
+
[candidateId]: {
|
|
25578
|
+
adapter: options.routingLocalAdapter,
|
|
25579
|
+
command: options.routingLocalCommand
|
|
25580
|
+
}
|
|
25581
|
+
}
|
|
25582
|
+
},
|
|
25583
|
+
resolution: resolution2
|
|
25584
|
+
};
|
|
25585
|
+
}
|
|
25458
25586
|
const catalogArgs = [
|
|
25459
25587
|
"local-model-catalog",
|
|
25460
25588
|
"--json",
|
|
@@ -25477,6 +25605,12 @@ function enrichAdaptiveRoutingWithLocalOrchestrator(routing, options, cwd = proc
|
|
|
25477
25605
|
if (options.routingLocalProvider) {
|
|
25478
25606
|
catalogArgs.push("--provider", options.routingLocalProvider);
|
|
25479
25607
|
}
|
|
25608
|
+
if (options.routingLocalApiKeyEnv) {
|
|
25609
|
+
catalogArgs.push("--api-key-env", options.routingLocalApiKeyEnv);
|
|
25610
|
+
}
|
|
25611
|
+
if (options.routingLocalApiKeyHeader) {
|
|
25612
|
+
catalogArgs.push("--api-key-header", options.routingLocalApiKeyHeader);
|
|
25613
|
+
}
|
|
25480
25614
|
const runtimeCatalog = normalizeAdaptiveRoutingCatalog(
|
|
25481
25615
|
runOrchestratorJsonCommand(catalogArgs, cwd)
|
|
25482
25616
|
);
|
|
@@ -27367,7 +27501,7 @@ async function workflowRunCommand(options) {
|
|
|
27367
27501
|
}
|
|
27368
27502
|
function shouldBuildAdaptiveRouting(options) {
|
|
27369
27503
|
return Boolean(
|
|
27370
|
-
options.adaptiveRoutingDryRun || options.routeLocalWorkers || options.routingLocalWorker || options.routingWorkerRole || options.routingPreferredEndpoints?.length || options.routingAllowedEndpoints?.length || options.routingLocalBaseUrl || options.routingLocalModel || options.routingLocalPreferModel || options.routingLocalProvider || options.plannerRetainsReasoning
|
|
27504
|
+
options.adaptiveRoutingDryRun || options.routeLocalWorkers || options.routingLocalWorker || options.routingWorkerRole || options.routingPreferredEndpoints?.length || options.routingAllowedEndpoints?.length || options.routingLocalBaseUrl || options.routingLocalModel || options.routingLocalPreferModel || options.routingLocalProvider || options.routingLocalApiKeyEnv || options.plannerRetainsReasoning
|
|
27371
27505
|
);
|
|
27372
27506
|
}
|
|
27373
27507
|
function buildWorkflowAdaptiveRouting(options, policy = null, intentWarnings = []) {
|
|
@@ -38817,6 +38951,12 @@ workflow.command("run").description("Run a LITE/STANDARD/FULL/orchestrate workfl
|
|
|
38817
38951
|
"--routing-local-prefer-model <text>",
|
|
38818
38952
|
"Prefer a local /v1/models entry containing this text during worker routing"
|
|
38819
38953
|
).option("--routing-local-provider <provider>", "Provider label for local worker routing").option(
|
|
38954
|
+
"--routing-local-api-key-env <env>",
|
|
38955
|
+
"Environment variable containing the local/remote provider API key"
|
|
38956
|
+
).option(
|
|
38957
|
+
"--routing-local-api-key-header <header>",
|
|
38958
|
+
"Provider API key header: authorization or x-api-key"
|
|
38959
|
+
).option(
|
|
38820
38960
|
"--planner-retains-reasoning",
|
|
38821
38961
|
"Mark the main planner as retaining deep reasoning while the worker executes scoped work"
|
|
38822
38962
|
).option("--write-plan-file <file>", "Write the generated FULL-mode plan as workflow JSON").option(
|
|
@@ -38844,6 +38984,8 @@ workflow.command("run").description("Run a LITE/STANDARD/FULL/orchestrate workfl
|
|
|
38844
38984
|
routingLocalModel: options.routingLocalModel,
|
|
38845
38985
|
routingLocalPreferModel: options.routingLocalPreferModel,
|
|
38846
38986
|
routingLocalProvider: options.routingLocalProvider,
|
|
38987
|
+
routingLocalApiKeyEnv: options.routingLocalApiKeyEnv,
|
|
38988
|
+
routingLocalApiKeyHeader: options.routingLocalApiKeyHeader,
|
|
38847
38989
|
plannerRetainsReasoning: options.plannerRetainsReasoning ? true : void 0,
|
|
38848
38990
|
writePlanFile: options.writePlanFile,
|
|
38849
38991
|
startWorkflowFromPlan: Boolean(options.startWorkflowFromPlan),
|
|
@@ -38944,7 +39086,11 @@ localWorkers.command("add").description("Declare a local worker and enable local
|
|
|
38944
39086
|
"--role <role>",
|
|
38945
39087
|
"Worker role, for example coding, documentation, tests, or review",
|
|
38946
39088
|
"coding"
|
|
38947
|
-
).option("--provider <provider>", "Provider label", "lm-studio").option("--base-url <url>", "OpenAI-compatible local runtime base URL", "http://127.0.0.1:1234").option("--
|
|
39089
|
+
).option("--provider <provider>", "Provider label", "lm-studio").option("--base-url <url>", "OpenAI-compatible local runtime base URL", "http://127.0.0.1:1234").option("--api-key-env <env>", "Environment variable containing the provider API key").option(
|
|
39090
|
+
"--api-key-header <header>",
|
|
39091
|
+
"Provider API key header: authorization or x-api-key",
|
|
39092
|
+
"authorization"
|
|
39093
|
+
).option("--model <id>", "Exact model id exposed by the local runtime").option(
|
|
38948
39094
|
"--prefer-model <text>",
|
|
38949
39095
|
"Fallback model id substring to prefer when no exact model is set"
|
|
38950
39096
|
).option("--transport <openai_http|cli>", "Worker transport: openai_http (default) or cli").option("--command <command>", "CLI command to execute when transport is cli").option("--capability <capability>", "Worker capability; repeatable", collectOption, []).option(
|
|
@@ -38971,6 +39117,8 @@ localWorkers.command("add").description("Declare a local worker and enable local
|
|
|
38971
39117
|
preferModel: options.preferModel,
|
|
38972
39118
|
transport: options.transport,
|
|
38973
39119
|
command: options.command,
|
|
39120
|
+
apiKeyEnv: options.apiKeyEnv,
|
|
39121
|
+
apiKeyHeader: options.apiKeyHeader,
|
|
38974
39122
|
capabilities: options.capability,
|
|
38975
39123
|
reasoning: options.reasoning ? options.reasoning.toLowerCase() : void 0,
|
|
38976
39124
|
contextWindow: options.contextWindow,
|
|
@@ -38988,7 +39136,11 @@ localWorkers.command("list").description("List declared local workers").option("
|
|
|
38988
39136
|
localWorkers.command("remove").description("Remove a declared local worker").argument("id", "Local worker id").option("--json", "Print raw JSON").action((id, options) => {
|
|
38989
39137
|
workersLocalRemoveCommand({ id, json: options.json });
|
|
38990
39138
|
});
|
|
38991
|
-
localWorkers.command("probe").description("Probe an OpenAI-compatible endpoint and draft a worker suggestion").option("--base-url <url>", "OpenAI-compatible local runtime base URL", "http://127.0.0.1:1234").option("--
|
|
39139
|
+
localWorkers.command("probe").description("Probe an OpenAI-compatible endpoint and draft a worker suggestion").option("--base-url <url>", "OpenAI-compatible local runtime base URL", "http://127.0.0.1:1234").option("--api-key-env <env>", "Environment variable containing the provider API key").option(
|
|
39140
|
+
"--api-key-header <header>",
|
|
39141
|
+
"Provider API key header: authorization or x-api-key",
|
|
39142
|
+
"authorization"
|
|
39143
|
+
).option("--provider <provider>", "Provider label", "lm-studio").option("--model <id>", "Exact model id exposed by the local runtime").option("--prefer-model <text>", "Fallback local model substring when exact model is unset").option(
|
|
38992
39144
|
"--role <role>",
|
|
38993
39145
|
"Worker role; for example coding, documentation, tests, or review",
|
|
38994
39146
|
"coding"
|
|
@@ -39019,6 +39171,8 @@ localWorkers.command("probe").description("Probe an OpenAI-compatible endpoint a
|
|
|
39019
39171
|
reasoning: options.reasoning ? options.reasoning.toLowerCase() : void 0,
|
|
39020
39172
|
contextWindow: options.contextWindow,
|
|
39021
39173
|
writeScope: options.writeScope,
|
|
39174
|
+
apiKeyEnv: options.apiKeyEnv,
|
|
39175
|
+
apiKeyHeader: options.apiKeyHeader,
|
|
39022
39176
|
json: options.json
|
|
39023
39177
|
});
|
|
39024
39178
|
});
|
package/docs/FULL_REFERENCE.md
CHANGED
|
@@ -464,7 +464,8 @@ snipara-companion workers local add \
|
|
|
464
464
|
--role coding \
|
|
465
465
|
--provider lm-studio \
|
|
466
466
|
--base-url http://127.0.0.1:1234 \
|
|
467
|
-
--model openai/gpt-oss-20b
|
|
467
|
+
--model openai/gpt-oss-20b \
|
|
468
|
+
--api-key-env LM_STUDIO_API_KEY
|
|
468
469
|
```
|
|
469
470
|
|
|
470
471
|
The declaration is written under `.snipara/workers/<worker-id>.json`; Companion
|
|
@@ -499,7 +500,11 @@ Do not store secrets in worker profiles. Local endpoints such as
|
|
|
499
500
|
`http://127.0.0.1:1234` are safe to commit when they contain no credentials, but
|
|
500
501
|
cloud CLI transports or authenticated endpoints must reference secrets through
|
|
501
502
|
environment variables rather than embedding API keys, bearer tokens, passwords,
|
|
502
|
-
or private URLs directly in `.snipara/workers/*.json`.
|
|
503
|
+
or private URLs directly in `.snipara/workers/*.json`. `--api-key-env` stores
|
|
504
|
+
only the variable name; pair it with `--api-key-header authorization` (default)
|
|
505
|
+
or `--api-key-header x-api-key`. Native Codex and Claude profiles use their
|
|
506
|
+
host-managed credentials. A generic `cli://command` profile fails closed unless
|
|
507
|
+
the command maps to a supported Codex or Claude adapter.
|
|
503
508
|
|
|
504
509
|
Use `workers local probe` to query a local endpoint and preview a declaration
|
|
505
510
|
proposal before committing it:
|
|
@@ -559,6 +564,24 @@ snipara-orchestrator local-model-catalog \
|
|
|
559
564
|
--json > .snipara/local-devstral-runtime-catalog.json
|
|
560
565
|
```
|
|
561
566
|
|
|
567
|
+
For a remote OpenAI-compatible runtime, use an explicit allowlist and an
|
|
568
|
+
environment-backed key when running the native host:
|
|
569
|
+
|
|
570
|
+
```bash
|
|
571
|
+
snipara-orchestrator host run \
|
|
572
|
+
--adapter openai_compatible \
|
|
573
|
+
--base-url https://provider.example.com --allow-remote \
|
|
574
|
+
--api-key-env PROVIDER_API_KEY --api-key-header authorization \
|
|
575
|
+
--model provider/coder --task "Bounded task" --workspace . \
|
|
576
|
+
--write-scope docs/** --proof "git diff --check" --execute
|
|
577
|
+
```
|
|
578
|
+
|
|
579
|
+
Native host proof commands run automatically after dispatch. Use
|
|
580
|
+
`--no-run-proof` only when a reviewer will validate the receipt; the state then
|
|
581
|
+
remains `verification_required`. Use `--require-approval` with both an approval
|
|
582
|
+
receipt id and `--approval-receipt-file <json>` for unattended execution; an id
|
|
583
|
+
alone never bypasses the approval gate.
|
|
584
|
+
|
|
562
585
|
The local catalog records the OpenAI-compatible routes exposed by LM Studio:
|
|
563
586
|
`GET /v1/models`, `POST /v1/responses`, `POST /v1/chat/completions`,
|
|
564
587
|
`POST /v1/completions`, and `POST /v1/embeddings`. `--prefer-model devstral`
|