@ai-sdk/harness-opencode 1.0.94 → 1.0.96

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.
@@ -12,11 +12,11 @@ importers:
12
12
  specifier: 1.29.0
13
13
  version: 1.29.0(zod@3.25.76)
14
14
  '@opencode-ai/sdk':
15
- specifier: 1.18.3
16
- version: 1.18.3
15
+ specifier: 1.18.23
16
+ version: 1.18.23
17
17
  opencode-ai:
18
- specifier: 1.18.3
19
- version: 1.18.3
18
+ specifier: 1.18.23
19
+ version: 1.18.23
20
20
  ws:
21
21
  specifier: 8.21.0
22
22
  version: 8.21.0
@@ -42,8 +42,8 @@ packages:
42
42
  '@cfworker/json-schema':
43
43
  optional: true
44
44
 
45
- '@opencode-ai/sdk@1.18.3':
46
- resolution: {integrity: sha512-Mevo4e6kQwbvto9E+42KSIVMhp+JBu+SwQhC5AomAvrV6Xkio3U249T+xDILDCXhl5Z/Hi/DlAuVLzpGnuh0gg==}
45
+ '@opencode-ai/sdk@1.18.23':
46
+ resolution: {integrity: sha512-VouYbL8O2ynLq0atr5fjzCv8YLtFi/zKLQ/uYkCvTJ4CmUdA01XwPn8om+u3TvxnGEfQsBfmThGU141vt3sg5w==}
47
47
 
48
48
  accepts@2.0.0:
49
49
  resolution: {integrity: sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==}
@@ -286,72 +286,72 @@ packages:
286
286
  once@1.4.0:
287
287
  resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==}
288
288
 
289
- opencode-ai@1.18.3:
290
- resolution: {integrity: sha512-HnItl/+uhSpj7JV9x6ITiE0XFq4b/PKF5OM03TIyiFoFiLw3MQoJOAXZFTEzC7IOgAIYcysRQBBmCmlXILkxww==}
289
+ opencode-ai@1.18.23:
290
+ resolution: {integrity: sha512-3NkT0XINL7d0HYkTyGV1SPChHXhvRgKqNaTgKRTGb0TXUWszXA7MW/y3zMZw29y1AQuUDAzRvVYmQ9KGRQhroA==}
291
291
  cpu: [arm64, x64]
292
292
  os: [darwin, linux, win32]
293
293
  hasBin: true
294
294
 
295
- opencode-darwin-arm64@1.18.3:
296
- resolution: {integrity: sha512-BkfJf4E502OVwpDXgaVz8eqTDOy2B9xXPefYebT+xv8TXYvEo1wtby4eu4MoN51o4o1qpzcvCCXDqUDXu1pBGQ==}
295
+ opencode-darwin-arm64@1.18.23:
296
+ resolution: {integrity: sha512-QP9PjwpHtZoLVXw2WvUmPZecz7mWbQkT4t3K36B//fCaDG+zWa+SsztIeaW5azujNwwtUemLA5icE/zINng48Q==}
297
297
  cpu: [arm64]
298
298
  os: [darwin]
299
299
 
300
- opencode-darwin-x64-baseline@1.18.3:
301
- resolution: {integrity: sha512-8qQ9Ig7Zp7LEKaKGRL+OIlDb/uTLYkeAq6SGsN0fLHR2rHZRHyb61KrpkS5TgUlGwSWPtb5uCeVtTA9rGbEAKw==}
300
+ opencode-darwin-x64-baseline@1.18.23:
301
+ resolution: {integrity: sha512-QGx6I/nFYur7qJ/Nx2L3fC4XYQt44cyDsm7p8twNA+cdjGX3ndnPbMdAl5ikdZyAfSMUGYK8VWY2JMxv0rmfjw==}
302
302
  cpu: [x64]
303
303
  os: [darwin]
304
304
 
305
- opencode-darwin-x64@1.18.3:
306
- resolution: {integrity: sha512-ujy61O3WUEHjPqk+qXMBl97zR9q3crOzHbm2VLmXLHUWbqB5ZtN1HToODbuI1SBMKVR8GyZwPygRQVMfON4DHg==}
305
+ opencode-darwin-x64@1.18.23:
306
+ resolution: {integrity: sha512-R9nWP3edz/0FnEfwmuxtiWBB7bS4NtZCyCffJyiMlrbwdDC+bIXYrWxWXVrzaP1mJujs6g2MAwTCUSx/qpBhDw==}
307
307
  cpu: [x64]
308
308
  os: [darwin]
309
309
 
310
- opencode-linux-arm64-musl@1.18.3:
311
- resolution: {integrity: sha512-s1vNP8dpIH3vFs8aoMzgHViBNVz6xtR7n24gGg0WOw4uSZVM+sRUmZKc3Hj56XjHQSsVBg5AkwR2Xm0nFSfIUQ==}
310
+ opencode-linux-arm64-musl@1.18.23:
311
+ resolution: {integrity: sha512-VyDkzUJfJgkx9h9RhazTW9xeTgSXBmVFPblsbPGBW9tR612f6gjQxfOfu4cpHnQHK1qjuW9ClzLKHWqv3EcJTA==}
312
312
  cpu: [arm64]
313
313
  os: [linux]
314
314
  libc: [musl]
315
315
 
316
- opencode-linux-arm64@1.18.3:
317
- resolution: {integrity: sha512-K+1SPkfrYFUufPUYpbSurlB2ogpjv5in2usA1FwOM7HCOpNxR3ap7K+X4uQXnOV8AtsON+Vr9W5uYXQJA1yKlA==}
316
+ opencode-linux-arm64@1.18.23:
317
+ resolution: {integrity: sha512-g1zDFhuE9FOYwjSGderlu69wfd4GQzS0xsDiIY11QUciuBmM6DrHqLvmhlLFsUVHYVnCPY1YeN1pq5ewE3x72Q==}
318
318
  cpu: [arm64]
319
319
  os: [linux]
320
320
 
321
- opencode-linux-x64-baseline-musl@1.18.3:
322
- resolution: {integrity: sha512-F2nNPqYPdTCydLvNH1rvSXdlX3pfmOmOOfsFl+pqi3W0iE3Alyxmv28AjrIGUw4/6EfWhMKYcyxKjNIKLFyaZQ==}
321
+ opencode-linux-x64-baseline-musl@1.18.23:
322
+ resolution: {integrity: sha512-c1DPxauhzAurlIBhJBr/rokDpc65l084T4qTl36gDDT9Xzc/Nk5Q5yMDaPm1DDI3WeHKDt11MDlxT5AjQW5gtw==}
323
323
  cpu: [x64]
324
324
  os: [linux]
325
325
  libc: [musl]
326
326
 
327
- opencode-linux-x64-baseline@1.18.3:
328
- resolution: {integrity: sha512-DDfspGSQ123yhsFhAlbpF+tsvje5kHOS2/PYUpWJroTlvgtqRLGmET51Anrxd5BrAFrqB6PXYA2kGh5QStPU/g==}
327
+ opencode-linux-x64-baseline@1.18.23:
328
+ resolution: {integrity: sha512-yUhBOXfTQour2JCdAkwD3DDqSnyxB0grefwdPqEhYmJHIkYxfJIIzyy6V//pyouvkE0XMouFtiuZXw8S6Wo0iQ==}
329
329
  cpu: [x64]
330
330
  os: [linux]
331
331
 
332
- opencode-linux-x64-musl@1.18.3:
333
- resolution: {integrity: sha512-SSp2zSpAM4dntcPZw8ISl3CmXYrWPftLc8u0HuAIeNWJOo6G4xAHPoXhNnXI3tQYqqGcppArf/3EMPnF9WnyFw==}
332
+ opencode-linux-x64-musl@1.18.23:
333
+ resolution: {integrity: sha512-t/5mlnTBZKdZpqKHwdwxlWqGakntauvMSmXtyJc17M7XJRmZaaGHtNSaSefbbYFIL4agoQCXTvIkhhyxOvr7zQ==}
334
334
  cpu: [x64]
335
335
  os: [linux]
336
336
  libc: [musl]
337
337
 
338
- opencode-linux-x64@1.18.3:
339
- resolution: {integrity: sha512-p+19dSTf3pWL3+Rh/Ym94DvS9mNxNG94HJnR5oMCDhQvgimdT5tSdoK4ETtk4XOoCKz3OcTQDPHTdYKcJg32KQ==}
338
+ opencode-linux-x64@1.18.23:
339
+ resolution: {integrity: sha512-5x9d1Cm/YtqzR6lAlNbgVprTQ3R3hx7qGTWCzm5l5u6lBNkhYTrhy2s8k25dxKKuxqZ9Kngqz9JYWvSVHy2Lmw==}
340
340
  cpu: [x64]
341
341
  os: [linux]
342
342
 
343
- opencode-windows-arm64@1.18.3:
344
- resolution: {integrity: sha512-qkz9/r6kUhhgLycQv71MoSQ2m5UI2QnZZx8SeZgyYD7oB8pDH6DIGbDWcs6BJ02ND1Y5hmgYWlP+rOrMkGlMJw==}
343
+ opencode-windows-arm64@1.18.23:
344
+ resolution: {integrity: sha512-QtJQcLU0yPz6on3jjks3f/EHgZuIDFw7FvAKu3wsHhL09NYDh7GczfRXDPRHa3NgqnU8dkB8p9mhqgaPRPogoQ==}
345
345
  cpu: [arm64]
346
346
  os: [win32]
347
347
 
348
- opencode-windows-x64-baseline@1.18.3:
349
- resolution: {integrity: sha512-+tyoxwSfY7msfZNY1IoA0ZWRL9XfdqY+ash6U3ldfE+GfF2WNAdhewmmYiUsC4lHjkdSmLt2brdWgoebQK9HAg==}
348
+ opencode-windows-x64-baseline@1.18.23:
349
+ resolution: {integrity: sha512-AqXsTKaPcDx3rrid5bLUwJbQ/3vr9rJ6fvOStIznTzwrbOgP8wy5G4jCoIzu6KB/WxGx/d1MrV4cGaJ73qnjBA==}
350
350
  cpu: [x64]
351
351
  os: [win32]
352
352
 
353
- opencode-windows-x64@1.18.3:
354
- resolution: {integrity: sha512-V/Q4VkyZ7TkotLbpTCX/s5wP8MoFj5UnRqBHFJ8WGptb/+oYw36kamUUt1P1wN8iRjmw+8vwYhuYdAe+3xbgpQ==}
353
+ opencode-windows-x64@1.18.23:
354
+ resolution: {integrity: sha512-mMaIITuXzkNfjdcYL8uZaZuMDjulFyH/UCq9bxblam2mUZf9uWisoi5J6CXFsS/mkN7CZfTAt6PttSp4n3PH4g==}
355
355
  cpu: [x64]
356
356
  os: [win32]
357
357
 
@@ -508,7 +508,7 @@ snapshots:
508
508
  transitivePeerDependencies:
509
509
  - supports-color
510
510
 
511
- '@opencode-ai/sdk@1.18.3':
511
+ '@opencode-ai/sdk@1.18.23':
512
512
  dependencies:
513
513
  cross-spawn: 7.0.6
514
514
 
@@ -752,55 +752,55 @@ snapshots:
752
752
  dependencies:
753
753
  wrappy: 1.0.2
754
754
 
755
- opencode-ai@1.18.3:
755
+ opencode-ai@1.18.23:
756
756
  optionalDependencies:
757
- opencode-darwin-arm64: 1.18.3
758
- opencode-darwin-x64: 1.18.3
759
- opencode-darwin-x64-baseline: 1.18.3
760
- opencode-linux-arm64: 1.18.3
761
- opencode-linux-arm64-musl: 1.18.3
762
- opencode-linux-x64: 1.18.3
763
- opencode-linux-x64-baseline: 1.18.3
764
- opencode-linux-x64-baseline-musl: 1.18.3
765
- opencode-linux-x64-musl: 1.18.3
766
- opencode-windows-arm64: 1.18.3
767
- opencode-windows-x64: 1.18.3
768
- opencode-windows-x64-baseline: 1.18.3
769
-
770
- opencode-darwin-arm64@1.18.3:
757
+ opencode-darwin-arm64: 1.18.23
758
+ opencode-darwin-x64: 1.18.23
759
+ opencode-darwin-x64-baseline: 1.18.23
760
+ opencode-linux-arm64: 1.18.23
761
+ opencode-linux-arm64-musl: 1.18.23
762
+ opencode-linux-x64: 1.18.23
763
+ opencode-linux-x64-baseline: 1.18.23
764
+ opencode-linux-x64-baseline-musl: 1.18.23
765
+ opencode-linux-x64-musl: 1.18.23
766
+ opencode-windows-arm64: 1.18.23
767
+ opencode-windows-x64: 1.18.23
768
+ opencode-windows-x64-baseline: 1.18.23
769
+
770
+ opencode-darwin-arm64@1.18.23:
771
771
  optional: true
772
772
 
773
- opencode-darwin-x64-baseline@1.18.3:
773
+ opencode-darwin-x64-baseline@1.18.23:
774
774
  optional: true
775
775
 
776
- opencode-darwin-x64@1.18.3:
776
+ opencode-darwin-x64@1.18.23:
777
777
  optional: true
778
778
 
779
- opencode-linux-arm64-musl@1.18.3:
779
+ opencode-linux-arm64-musl@1.18.23:
780
780
  optional: true
781
781
 
782
- opencode-linux-arm64@1.18.3:
782
+ opencode-linux-arm64@1.18.23:
783
783
  optional: true
784
784
 
785
- opencode-linux-x64-baseline-musl@1.18.3:
785
+ opencode-linux-x64-baseline-musl@1.18.23:
786
786
  optional: true
787
787
 
788
- opencode-linux-x64-baseline@1.18.3:
788
+ opencode-linux-x64-baseline@1.18.23:
789
789
  optional: true
790
790
 
791
- opencode-linux-x64-musl@1.18.3:
791
+ opencode-linux-x64-musl@1.18.23:
792
792
  optional: true
793
793
 
794
- opencode-linux-x64@1.18.3:
794
+ opencode-linux-x64@1.18.23:
795
795
  optional: true
796
796
 
797
- opencode-windows-arm64@1.18.3:
797
+ opencode-windows-arm64@1.18.23:
798
798
  optional: true
799
799
 
800
- opencode-windows-x64-baseline@1.18.3:
800
+ opencode-windows-x64-baseline@1.18.23:
801
801
  optional: true
802
802
 
803
- opencode-windows-x64@1.18.3:
803
+ opencode-windows-x64@1.18.23:
804
804
  optional: true
805
805
 
806
806
  parseurl@1.3.3: {}
@@ -1,2 +1,2 @@
1
1
  allowBuilds:
2
- 'opencode-ai@1.18.3': true
2
+ 'opencode-ai@1.18.23': true
@@ -14,7 +14,9 @@ export const startMessageSchema = harnessV1BridgeStartBaseSchema.extend({
14
14
  provider: z.string().optional(),
15
15
  variant: z.string().optional(),
16
16
  instructions: z.string().optional(),
17
+ skillsChanged: z.boolean().optional(),
17
18
  resumeSessionId: z.string().optional(),
19
+ openCodeConfig: z.record(z.string(), z.unknown()).optional(),
18
20
  mcpServers: z.record(z.string(), z.unknown()).optional(),
19
21
  });
20
22
 
@@ -38,6 +38,7 @@ import {
38
38
  warnCredentialBrokeringUnavailable,
39
39
  waitForBridgeReady,
40
40
  writeSkills as writeHarnessSkills,
41
+ type WriteSkillsResult,
41
42
  } from '@ai-sdk/harness/utils';
42
43
  import {
43
44
  safeParseJSON,
@@ -69,10 +70,6 @@ import { VERSION } from './version';
69
70
  type OpenCodeChannel = SandboxChannel<OutboundMessage, InboundMessage>;
70
71
  type OpenCodeRespawnStrategy = 'replay' | 'rerun';
71
72
 
72
- type WriteSkillsResult = {
73
- readonly skillsDir: string;
74
- };
75
-
76
73
  /**
77
74
  * Value to use in User-Agent and `x-client-app` headers.
78
75
  */
@@ -86,11 +83,20 @@ export type OpenCodeHarnessSettings = {
86
83
  * discover, read, or otherwise access in the host process.
87
84
  */
88
85
  readonly credentialForwarding?: HarnessV1CredentialForwarding;
86
+ /**
87
+ * Additional configuration passed through to OpenCode as-is. OpenCode
88
+ * config keys must use their native names. Values managed by this adapter
89
+ * take precedence over conflicting entries.
90
+ */
91
+ readonly openCodeConfig?: Record<string, unknown>;
89
92
  /**
90
93
  * MCP server definitions keyed by server name. Each definition uses the
91
94
  * underlying runtime's native MCP server configuration format.
92
95
  */
93
96
  readonly mcpServers?: Record<string, unknown>;
97
+ /**
98
+ * @deprecated Use `model` on `HarnessAgent` instead.
99
+ */
94
100
  readonly model?: string;
95
101
  readonly provider?: string;
96
102
  /**
@@ -250,6 +256,7 @@ export function createOpenCode(
250
256
  lifecycleStateSchema: openCodeResumeStateSchema,
251
257
  getBootstrap: getOpenCodeBootstrap,
252
258
  doStart: async startOpts => {
259
+ const configuredModel = settings.model;
253
260
  const sandboxSession = startOpts.sandboxSession;
254
261
  const toolSafeSandboxSession =
255
262
  getRestrictedSandboxSession(sandboxSession);
@@ -290,12 +297,12 @@ export function createOpenCode(
290
297
  const coords = resumeData?.bridge;
291
298
  const authenticationMode = resolveOpenCodeAuthenticationMode({
292
299
  auth: settings.auth,
293
- model: settings.model,
300
+ model: configuredModel,
294
301
  provider: settings.provider,
295
302
  });
296
303
  const resolvedAuthEnvironment = resolveOpenCodeEnv({
297
304
  auth: settings.auth,
298
- model: settings.model,
305
+ model: configuredModel,
299
306
  provider: settings.provider,
300
307
  });
301
308
  let sandboxAuthEnvironment = resolvedAuthEnvironment;
@@ -336,10 +343,18 @@ export function createOpenCode(
336
343
  BOOTSTRAP_DIR,
337
344
  );
338
345
  const workDir = startOpts.sessionWorkDir;
346
+ const sandboxHomeDir = await resolveSandboxHomeDir({
347
+ sandbox: toolSafeSandboxSession,
348
+ abortSignal: startOpts.abortSignal,
349
+ });
350
+ const skillsDir = path.posix.join(sandboxHomeDir, '.agents', 'skills');
339
351
  const sessionDataDir = `${defaultWorkingDirectory}/.agent-runs/${startOpts.sessionId}`;
340
352
  const bridgeStateDir = `${sessionDataDir}/bridge`;
341
353
  const timeoutMs = settings.startupTimeoutMs ?? 120_000;
342
- const model = splitOpenCodeModel(settings.model, settings.provider).model;
354
+ const model = splitOpenCodeModel(
355
+ configuredModel,
356
+ settings.provider,
357
+ ).model;
343
358
 
344
359
  const report = startOpts.observability?.report;
345
360
  const onDiagnostic = report
@@ -390,6 +405,7 @@ export function createOpenCode(
390
405
  model,
391
406
  provider: settings.provider,
392
407
  reasoningVariant: settings.reasoningVariant,
408
+ openCodeConfig: settings.openCodeConfig,
393
409
  mcpServers: settings.mcpServers,
394
410
  openCodeSessionId: resumeSessionId,
395
411
  isResume: true,
@@ -402,6 +418,8 @@ export function createOpenCode(
402
418
  debug: startOpts.observability?.debug,
403
419
  permissionMode: startOpts.permissionMode,
404
420
  builtinToolFiltering: startOpts.builtinToolFiltering,
421
+ sandbox: toolSafeSandboxSession,
422
+ sandboxHomeDir,
405
423
  supportsUserMessageResponses: () => supportsUserMessageResponses,
406
424
  });
407
425
  } catch {}
@@ -430,23 +448,6 @@ export function createOpenCode(
430
448
  settings.mintBridgeToken == null
431
449
  ? randomBytes(32).toString('hex')
432
450
  : settings.mintBridgeToken(sandboxId!);
433
- const sandboxHomeDir = await resolveSandboxHomeDir({
434
- sandbox: toolSafeSandboxSession,
435
- abortSignal: startOpts.abortSignal,
436
- });
437
- const xdgConfigHome = `${sandboxHomeDir}/.config`;
438
- const xdgCacheHome = `${sandboxHomeDir}/.cache`;
439
- const xdgDataHome = `${sandboxHomeDir}/.local/share`;
440
- const xdgStateHome = `${sandboxHomeDir}/.local/state`;
441
- const skillSetup =
442
- startOpts.skills && startOpts.skills.length > 0
443
- ? await writeOpenCodeSkills({
444
- sandbox: toolSafeSandboxSession,
445
- skills: startOpts.skills,
446
- homeDir: sandboxHomeDir,
447
- abortSignal: startOpts.abortSignal,
448
- })
449
- : undefined;
450
451
  const forwardedAuthEnvironment = credentialsBrokered
451
452
  ? sandboxAuthEnvironment
452
453
  : await applyCredentialForwarding({
@@ -460,12 +461,6 @@ export function createOpenCode(
460
461
  AI_SDK_HARNESS_CLIENT_APP: OPENCODE_CLIENT_APP,
461
462
  BRIDGE_CHANNEL_TOKEN: token,
462
463
  BRIDGE_WS_PORT: String(port),
463
- HOME: sandboxHomeDir,
464
- USERPROFILE: sandboxHomeDir,
465
- XDG_CONFIG_HOME: xdgConfigHome,
466
- XDG_CACHE_HOME: xdgCacheHome,
467
- XDG_DATA_HOME: xdgDataHome,
468
- XDG_STATE_HOME: xdgStateHome,
469
464
  ...(respawnStrategy === 'replay'
470
465
  ? { BRIDGE_REPLAY_FROM_DISK: '1' }
471
466
  : {}),
@@ -473,7 +468,7 @@ export function createOpenCode(
473
468
 
474
469
  if (respawnStrategy === undefined) {
475
470
  await toolSafeSandboxSession.run({
476
- command: `mkdir -p ${shellQuote(workDir)} ${shellQuote(bridgeStateDir)} ${shellQuote(xdgConfigHome)} ${shellQuote(xdgCacheHome)} ${shellQuote(xdgDataHome)} ${shellQuote(xdgStateHome)}`,
471
+ command: `mkdir -p ${shellQuote(workDir)} ${shellQuote(bridgeStateDir)}`,
477
472
  abortSignal: startOpts.abortSignal,
478
473
  });
479
474
  }
@@ -486,7 +481,7 @@ export function createOpenCode(
486
481
  });
487
482
 
488
483
  const proc = await toolSafeSandboxSession.spawn({
489
- command: `node ${shellQuote(`${bootstrapDir}/bridge.mjs`)} --workdir ${shellQuote(workDir)} --bridge-state-dir ${shellQuote(bridgeStateDir)} --bootstrap-dir ${shellQuote(bootstrapDir)}${skillSetup ? ` --skills-dir ${shellQuote(skillSetup.skillsDir)}` : ''}`,
484
+ command: `node ${shellQuote(`${bootstrapDir}/bridge.mjs`)} --workdir ${shellQuote(workDir)} --bridge-state-dir ${shellQuote(bridgeStateDir)} --bootstrap-dir ${shellQuote(bootstrapDir)} --skills-dir ${shellQuote(skillsDir)}`,
490
485
  env,
491
486
  abortSignal: startOpts.abortSignal,
492
487
  });
@@ -559,6 +554,7 @@ export function createOpenCode(
559
554
  model,
560
555
  provider: settings.provider,
561
556
  reasoningVariant: settings.reasoningVariant,
557
+ openCodeConfig: settings.openCodeConfig,
562
558
  mcpServers: settings.mcpServers,
563
559
  openCodeSessionId: resumeSessionId,
564
560
  isResume: respawnStrategy !== undefined,
@@ -571,6 +567,8 @@ export function createOpenCode(
571
567
  debug: startOpts.observability?.debug,
572
568
  permissionMode: startOpts.permissionMode,
573
569
  builtinToolFiltering: startOpts.builtinToolFiltering,
570
+ sandbox: toolSafeSandboxSession,
571
+ sandboxHomeDir,
574
572
  supportsUserMessageResponses: () => supportsUserMessageResponses,
575
573
  });
576
574
  },
@@ -654,7 +652,7 @@ async function writeOpenCodeSkills({
654
652
  abortSignal?: AbortSignal;
655
653
  }): Promise<WriteSkillsResult> {
656
654
  const skillsDir = path.posix.join(homeDir, '.agents', 'skills');
657
- await writeHarnessSkills({
655
+ return writeHarnessSkills({
658
656
  sandbox,
659
657
  rootDir: skillsDir,
660
658
  skills,
@@ -664,8 +662,6 @@ async function writeOpenCodeSkills({
664
662
  invalidSkillFilePathMessage: ({ skillName, filePath }) =>
665
663
  `Invalid OpenCode skill file path for ${skillName}: ${filePath}`,
666
664
  });
667
-
668
- return { skillsDir };
669
665
  }
670
666
 
671
667
  function openWebSocket({
@@ -787,6 +783,7 @@ function createSession({
787
783
  model,
788
784
  provider,
789
785
  reasoningVariant,
786
+ openCodeConfig,
790
787
  mcpServers,
791
788
  openCodeSessionId,
792
789
  isResume,
@@ -799,6 +796,8 @@ function createSession({
799
796
  debug,
800
797
  permissionMode,
801
798
  builtinToolFiltering,
799
+ sandbox,
800
+ sandboxHomeDir,
802
801
  supportsUserMessageResponses,
803
802
  }: {
804
803
  sessionId: string;
@@ -807,6 +806,7 @@ function createSession({
807
806
  model: string | undefined;
808
807
  provider: string | undefined;
809
808
  reasoningVariant: string | undefined;
809
+ openCodeConfig: Record<string, unknown> | undefined;
810
810
  mcpServers: Record<string, unknown> | undefined;
811
811
  openCodeSessionId: string | undefined;
812
812
  isResume: boolean;
@@ -819,6 +819,8 @@ function createSession({
819
819
  debug: HarnessV1DebugConfig | undefined;
820
820
  permissionMode: HarnessV1PermissionMode | undefined;
821
821
  builtinToolFiltering: HarnessV1BuiltinToolFiltering | undefined;
822
+ sandbox: SandboxSession;
823
+ sandboxHomeDir: string;
822
824
  supportsUserMessageResponses: () => boolean;
823
825
  }): HarnessV1Session {
824
826
  let stopped = false;
@@ -827,6 +829,7 @@ function createSession({
827
829
  let pendingResumeSessionId = seedResumeSessionOnFirstPrompt
828
830
  ? openCodeSessionId
829
831
  : undefined;
832
+ let selectedModel = model;
830
833
  let activeTurn = false;
831
834
  const pendingCompactionParts: HarnessV1StreamPart[] = [];
832
835
 
@@ -977,10 +980,11 @@ function createSession({
977
980
  };
978
981
  };
979
982
 
980
- const startBase = () => ({
981
- model,
983
+ const startBase = (turnModel: string | undefined) => ({
984
+ model: turnModel,
982
985
  provider,
983
986
  ...(reasoningVariant ? { variant: reasoningVariant } : {}),
987
+ ...(openCodeConfig == null ? {} : { openCodeConfig }),
984
988
  ...(mcpServers == null ? {} : { mcpServers }),
985
989
  ...(permissionMode ? { permissionMode } : {}),
986
990
  ...(builtinToolFiltering ? { builtinToolFiltering } : {}),
@@ -995,7 +999,6 @@ function createSession({
995
999
  return {
996
1000
  sessionId,
997
1001
  isResume,
998
- modelId: model,
999
1002
  doPromptTurn: async promptOpts => {
1000
1003
  if (
1001
1004
  promptOpts.responseFormat?.type === 'json' &&
@@ -1007,10 +1010,18 @@ function createSession({
1007
1010
  harnessId: 'opencode',
1008
1011
  });
1009
1012
  }
1013
+ const skillWriteResult = await writeOpenCodeSkills({
1014
+ sandbox,
1015
+ skills: promptOpts.skills,
1016
+ homeDir: sandboxHomeDir,
1017
+ abortSignal: promptOpts.abortSignal,
1018
+ });
1010
1019
  const control = wireTurn({
1011
1020
  emit: promptOpts.emit,
1012
1021
  abortSignal: promptOpts.abortSignal,
1013
1022
  });
1023
+ const turnModel = promptOpts.model ?? selectedModel;
1024
+ if (turnModel) selectedModel = turnModel;
1014
1025
  channel.send({
1015
1026
  type: 'start',
1016
1027
  operation: 'prompt',
@@ -1026,7 +1037,8 @@ function createSession({
1026
1037
  ...(promptOpts.instructions
1027
1038
  ? { instructions: promptOpts.instructions }
1028
1039
  : {}),
1029
- ...startBase(),
1040
+ skillsChanged: skillWriteResult.changed,
1041
+ ...startBase(turnModel),
1030
1042
  });
1031
1043
  pendingResumeSessionId = undefined;
1032
1044
  return control;
@@ -1042,11 +1054,19 @@ function createSession({
1042
1054
  harnessId: 'opencode',
1043
1055
  });
1044
1056
  }
1057
+ const skillWriteResult = await writeOpenCodeSkills({
1058
+ sandbox,
1059
+ skills: continueOpts.skills,
1060
+ homeDir: sandboxHomeDir,
1061
+ abortSignal: continueOpts.abortSignal,
1062
+ });
1045
1063
  const control = wireTurn({
1046
1064
  emit: continueOpts.emit,
1047
1065
  abortSignal: continueOpts.abortSignal,
1048
1066
  });
1049
1067
  if (rerunContinue) {
1068
+ const turnModel = continueOpts.model ?? selectedModel;
1069
+ if (turnModel) selectedModel = turnModel;
1050
1070
  channel.send({
1051
1071
  type: 'start',
1052
1072
  operation: 'prompt',
@@ -1062,7 +1082,8 @@ function createSession({
1062
1082
  ...(continueOpts.instructions
1063
1083
  ? { instructions: continueOpts.instructions }
1064
1084
  : {}),
1065
- ...startBase(),
1085
+ skillsChanged: skillWriteResult.changed,
1086
+ ...startBase(turnModel),
1066
1087
  });
1067
1088
  pendingResumeSessionId = undefined;
1068
1089
  }
@@ -1085,10 +1106,11 @@ function createSession({
1085
1106
  }
1086
1107
  await runCompactOperation({
1087
1108
  channel,
1088
- model,
1109
+ model: selectedModel,
1089
1110
  provider,
1090
1111
  permissionMode,
1091
1112
  debug,
1113
+ openCodeConfig,
1092
1114
  mcpServers,
1093
1115
  resumeSessionId: latestOpenCodeSessionId,
1094
1116
  onCompaction: part => pendingCompactionParts.push(part),
@@ -1261,6 +1283,7 @@ async function runCompactOperation({
1261
1283
  provider,
1262
1284
  permissionMode,
1263
1285
  debug,
1286
+ openCodeConfig,
1264
1287
  mcpServers,
1265
1288
  resumeSessionId,
1266
1289
  onCompaction,
@@ -1270,6 +1293,7 @@ async function runCompactOperation({
1270
1293
  provider: string | undefined;
1271
1294
  permissionMode: HarnessV1PermissionMode | undefined;
1272
1295
  debug: HarnessV1DebugConfig | undefined;
1296
+ openCodeConfig: Record<string, unknown> | undefined;
1273
1297
  mcpServers: Record<string, unknown> | undefined;
1274
1298
  resumeSessionId: string | undefined;
1275
1299
  onCompaction: (part: HarnessV1StreamPart) => void;
@@ -1298,6 +1322,7 @@ async function runCompactOperation({
1298
1322
  tools: [],
1299
1323
  model,
1300
1324
  provider,
1325
+ ...(openCodeConfig == null ? {} : { openCodeConfig }),
1301
1326
  ...(mcpServers == null ? {} : { mcpServers }),
1302
1327
  ...(permissionMode ? { permissionMode } : {}),
1303
1328
  ...(resumeSessionId ? { resumeSessionId } : {}),