@ours.network/fleet 0.17.8 → 0.17.10

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/spawn.js CHANGED
@@ -5,6 +5,7 @@ import { parse, stringify } from 'yaml';
5
5
  import { agentDir, fleetDDir } from './paths.js';
6
6
  import { validateIsolationConfig } from './isolation/policy.js';
7
7
  import { loadConfig, resolveAuthProxy, resolveModelChain, resolveMonitorConfig, resolveOwnerChannelConfig, resolvePermissions, resolveRoleModel, resolveWorklogPolicy, validateMonitorConfig, } from './config.js';
8
+ import { resolveRoleModelEnv } from './model-env.js';
8
9
  import { applyRole, up } from './ops.js';
9
10
  import { START_STAGGER_FILE } from './runner.js';
10
11
  import { buildProvenance, daemonIdentityProvisioner, ensureIdentity, provenanceOf, withCreationTransaction, writeProvenance, writeRoleFile, } from './creation.js';
@@ -191,7 +192,17 @@ export function spawnDryRun(o) {
191
192
  const harness = raw.harness ?? cfg.defaults.harness ?? 'claude-code';
192
193
  const defaultHarness = cfg.defaults.harness ?? 'claude-code';
193
194
  const inheritsModelDefaults = harness === defaultHarness && raw.model !== null;
194
- const model = resolveRoleModel(raw.model, raw.harness, cfg.defaults);
195
+ const authProxy = resolveAuthProxy(cfg.defaults.auth_proxy, raw.auth_proxy);
196
+ // One resolution for the environment and the model it pins (src/model-env.ts).
197
+ const modelEnv = resolveRoleModelEnv({
198
+ harness,
199
+ model: resolveRoleModel(raw.model, raw.harness, cfg.defaults),
200
+ modelWasExplicit: raw.model !== undefined,
201
+ defaultsEnv: (cfg.defaults.env ?? {}),
202
+ roleEnv: raw.env,
203
+ ...(authProxy ? { authProxyBaseUrl: authProxy.base_url } : {}),
204
+ });
205
+ const model = modelEnv.model;
195
206
  const session = raw.session ?? cfg.defaults.session ?? 'tmux';
196
207
  const resolvedRole = {
197
208
  ...raw,
@@ -212,19 +223,13 @@ export function spawnDryRun(o) {
212
223
  monitor: resolveMonitorConfig(cfg.defaults.monitor, raw.monitor),
213
224
  owner_channel: resolveOwnerChannelConfig(cfg.defaults.owner_channel, raw.owner_channel, session),
214
225
  worklog: resolveWorklogPolicy(cfg.defaults.worklog, raw.worklog),
215
- auth_proxy: resolveAuthProxy(cfg.defaults.auth_proxy, raw.auth_proxy),
216
- };
217
- resolvedRole.env = {
218
- ...(cfg.defaults.env ?? {}),
219
- ...(raw.env ?? {}),
220
- ...(resolvedRole.auth_proxy
221
- ? { ANTHROPIC_BASE_URL: resolvedRole.auth_proxy.base_url }
222
- : {}),
226
+ auth_proxy: authProxy,
223
227
  };
228
+ resolvedRole.env = modelEnv.env;
224
229
  const adapter = getAdapter(resolvedRole.harness);
225
230
  if (resolvedRole.auth_proxy && resolvedRole.harness !== 'claude-code')
226
231
  throw new Error('auth_proxy is supported only by claude-code');
227
- const optionProblems = adapter.validateOptions(resolvedRole.harness_options);
232
+ const optionProblems = adapter.validateOptions(resolvedRole.harness_options, resolvedRole);
228
233
  if (optionProblems.length)
229
234
  throw new Error(optionProblems.map(problem => `${problem.path}: ${problem.message}`).join('; '));
230
235
  return {
@@ -403,7 +408,18 @@ async function spawnTempInner(o, binPath, launch, tx, guarantee, onStage) {
403
408
  };
404
409
  const harness = o.harness ?? defaultHarness ?? 'claude-code';
405
410
  const inheritsModelDefaults = harness === (defaultHarness ?? 'claude-code') && o.model !== null;
406
- const model = resolveRoleModel(o.model, o.harness, cfg.defaults);
411
+ const tempAuthProxy = resolveAuthProxy(cfg.defaults.auth_proxy, fromOpts.auth_proxy);
412
+ // An explicitly requested --model must reach the child, not just the banner
413
+ // (src/model-env.ts).
414
+ const modelEnv = resolveRoleModelEnv({
415
+ harness,
416
+ model: resolveRoleModel(o.model, o.harness, cfg.defaults),
417
+ modelWasExplicit: o.model !== undefined,
418
+ defaultsEnv: (cfg.defaults.env ?? {}),
419
+ roleEnv: fromOpts.env,
420
+ ...(tempAuthProxy ? { authProxyBaseUrl: tempAuthProxy.base_url } : {}),
421
+ });
422
+ const model = modelEnv.model;
407
423
  const session = o.session ?? cfg.defaults.session ?? 'tmux';
408
424
  const role = {
409
425
  ...fromOpts, // includes `isolation` when --isolation-file was given
@@ -422,14 +438,10 @@ async function spawnTempInner(o, binPath, launch, tx, guarantee, onStage) {
422
438
  monitor: resolveMonitorConfig(cfg.defaults.monitor, fromOpts.monitor),
423
439
  owner_channel: resolveOwnerChannelConfig(cfg.defaults.owner_channel, fromOpts.owner_channel, session),
424
440
  worklog: resolveWorklogPolicy(cfg.defaults.worklog, fromOpts.worklog),
425
- auth_proxy: resolveAuthProxy(cfg.defaults.auth_proxy, fromOpts.auth_proxy),
441
+ auth_proxy: tempAuthProxy,
426
442
  sourceFile: '(temp)',
427
443
  };
428
- role.env = {
429
- ...(cfg.defaults.env ?? {}),
430
- ...(fromOpts.env ?? {}),
431
- ...(role.auth_proxy ? { ANTHROPIC_BASE_URL: role.auth_proxy.base_url } : {}),
432
- };
444
+ role.env = modelEnv.env;
433
445
  if (role.auth_proxy && role.harness !== 'claude-code')
434
446
  throw new Error('auth_proxy is supported only by claude-code');
435
447
  onStage?.('writing_role');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ours.network/fleet",
3
- "version": "0.17.8",
3
+ "version": "0.17.10",
4
4
  "description": "Harness-agnostic fleet of persistent, identity-bound AI agents. Declarative fleet.yaml, tmux or ACP sessions, supervision, and ours.network messaging.",
5
5
  "type": "module",
6
6
  "license": "FSL-1.1-Apache-2.0",