@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.
@@ -5,8 +5,8 @@
5
5
  "type": "module",
6
6
  "dependencies": {
7
7
  "@modelcontextprotocol/sdk": "1.29.0",
8
- "@opencode-ai/sdk": "1.18.3",
9
- "opencode-ai": "1.18.3",
8
+ "@opencode-ai/sdk": "1.18.23",
9
+ "opencode-ai": "1.18.23",
10
10
  "ws": "8.21.0",
11
11
  "zod": "3.25.76"
12
12
  }
@@ -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
package/dist/index.d.ts CHANGED
@@ -12,11 +12,20 @@ type OpenCodeHarnessSettings = {
12
12
  * discover, read, or otherwise access in the host process.
13
13
  */
14
14
  readonly credentialForwarding?: HarnessV1CredentialForwarding;
15
+ /**
16
+ * Additional configuration passed through to OpenCode as-is. OpenCode
17
+ * config keys must use their native names. Values managed by this adapter
18
+ * take precedence over conflicting entries.
19
+ */
20
+ readonly openCodeConfig?: Record<string, unknown>;
15
21
  /**
16
22
  * MCP server definitions keyed by server name. Each definition uses the
17
23
  * underlying runtime's native MCP server configuration format.
18
24
  */
19
25
  readonly mcpServers?: Record<string, unknown>;
26
+ /**
27
+ * @deprecated Use `model` on `HarnessAgent` instead.
28
+ */
20
29
  readonly model?: string;
21
30
  readonly provider?: string;
22
31
  /**
package/dist/index.js CHANGED
@@ -308,7 +308,9 @@ var startMessageSchema = harnessV1BridgeStartBaseSchema.extend({
308
308
  provider: z.string().optional(),
309
309
  variant: z.string().optional(),
310
310
  instructions: z.string().optional(),
311
+ skillsChanged: z.boolean().optional(),
311
312
  resumeSessionId: z.string().optional(),
313
+ openCodeConfig: z.record(z.string(), z.unknown()).optional(),
312
314
  mcpServers: z.record(z.string(), z.unknown()).optional()
313
315
  });
314
316
  var inboundMessageSchema = z.discriminatedUnion("type", [
@@ -317,7 +319,7 @@ var inboundMessageSchema = z.discriminatedUnion("type", [
317
319
  ]);
318
320
 
319
321
  // src/version.ts
320
- var VERSION = true ? "1.0.94" : "0.0.0-test";
322
+ var VERSION = true ? "1.0.96" : "0.0.0-test";
321
323
 
322
324
  // src/opencode-harness.ts
323
325
  var OPENCODE_CLIENT_APP = `ai-sdk/harness-opencode/${VERSION}`;
@@ -445,6 +447,7 @@ function createOpenCode(settings = {}) {
445
447
  lifecycleStateSchema: openCodeResumeStateSchema,
446
448
  getBootstrap: getOpenCodeBootstrap,
447
449
  doStart: async (startOpts) => {
450
+ const configuredModel = settings.model;
448
451
  const sandboxSession = startOpts.sandboxSession;
449
452
  const toolSafeSandboxSession = getRestrictedSandboxSession(sandboxSession);
450
453
  const sandboxId = "id" in sandboxSession ? sandboxSession.id : void 0;
@@ -471,12 +474,12 @@ function createOpenCode(settings = {}) {
471
474
  const coords = resumeData?.bridge;
472
475
  const authenticationMode = resolveOpenCodeAuthenticationMode({
473
476
  auth: settings.auth,
474
- model: settings.model,
477
+ model: configuredModel,
475
478
  provider: settings.provider
476
479
  });
477
480
  const resolvedAuthEnvironment = resolveOpenCodeEnv({
478
481
  auth: settings.auth,
479
- model: settings.model,
482
+ model: configuredModel,
480
483
  provider: settings.provider
481
484
  });
482
485
  let sandboxAuthEnvironment = resolvedAuthEnvironment;
@@ -511,10 +514,18 @@ function createOpenCode(settings = {}) {
511
514
  OPENCODE_BOOTSTRAP_DIR
512
515
  );
513
516
  const workDir = startOpts.sessionWorkDir;
517
+ const sandboxHomeDir = await resolveSandboxHomeDir({
518
+ sandbox: toolSafeSandboxSession,
519
+ abortSignal: startOpts.abortSignal
520
+ });
521
+ const skillsDir = path.posix.join(sandboxHomeDir, ".agents", "skills");
514
522
  const sessionDataDir = `${defaultWorkingDirectory}/.agent-runs/${startOpts.sessionId}`;
515
523
  const bridgeStateDir = `${sessionDataDir}/bridge`;
516
524
  const timeoutMs = settings.startupTimeoutMs ?? 12e4;
517
- const model = splitOpenCodeModel(settings.model, settings.provider).model;
525
+ const model = splitOpenCodeModel(
526
+ configuredModel,
527
+ settings.provider
528
+ ).model;
518
529
  const report = startOpts.observability?.report;
519
530
  const onDiagnostic = report ? (frame) => report(
520
531
  harnessV1DiagnosticFromBridgeFrame(frame, {
@@ -559,6 +570,7 @@ function createOpenCode(settings = {}) {
559
570
  model,
560
571
  provider: settings.provider,
561
572
  reasoningVariant: settings.reasoningVariant,
573
+ openCodeConfig: settings.openCodeConfig,
562
574
  mcpServers: settings.mcpServers,
563
575
  openCodeSessionId: resumeSessionId,
564
576
  isResume: true,
@@ -571,6 +583,8 @@ function createOpenCode(settings = {}) {
571
583
  debug: startOpts.observability?.debug,
572
584
  permissionMode: startOpts.permissionMode,
573
585
  builtinToolFiltering: startOpts.builtinToolFiltering,
586
+ sandbox: toolSafeSandboxSession,
587
+ sandboxHomeDir,
574
588
  supportsUserMessageResponses: () => supportsUserMessageResponses2
575
589
  });
576
590
  } catch {
@@ -593,20 +607,6 @@ function createOpenCode(settings = {}) {
593
607
  override: settings.port
594
608
  });
595
609
  const token = settings.mintBridgeToken == null ? randomBytes(32).toString("hex") : settings.mintBridgeToken(sandboxId);
596
- const sandboxHomeDir = await resolveSandboxHomeDir({
597
- sandbox: toolSafeSandboxSession,
598
- abortSignal: startOpts.abortSignal
599
- });
600
- const xdgConfigHome = `${sandboxHomeDir}/.config`;
601
- const xdgCacheHome = `${sandboxHomeDir}/.cache`;
602
- const xdgDataHome = `${sandboxHomeDir}/.local/share`;
603
- const xdgStateHome = `${sandboxHomeDir}/.local/state`;
604
- const skillSetup = startOpts.skills && startOpts.skills.length > 0 ? await writeOpenCodeSkills({
605
- sandbox: toolSafeSandboxSession,
606
- skills: startOpts.skills,
607
- homeDir: sandboxHomeDir,
608
- abortSignal: startOpts.abortSignal
609
- }) : void 0;
610
610
  const forwardedAuthEnvironment = credentialsBrokered ? sandboxAuthEnvironment : await applyCredentialForwarding({
611
611
  environment: sandboxAuthEnvironment,
612
612
  credentialEnvironmentVariables: OPENCODE_CREDENTIAL_ENVIRONMENT_VARIABLES,
@@ -617,17 +617,11 @@ function createOpenCode(settings = {}) {
617
617
  AI_SDK_HARNESS_CLIENT_APP: OPENCODE_CLIENT_APP,
618
618
  BRIDGE_CHANNEL_TOKEN: token,
619
619
  BRIDGE_WS_PORT: String(port),
620
- HOME: sandboxHomeDir,
621
- USERPROFILE: sandboxHomeDir,
622
- XDG_CONFIG_HOME: xdgConfigHome,
623
- XDG_CACHE_HOME: xdgCacheHome,
624
- XDG_DATA_HOME: xdgDataHome,
625
- XDG_STATE_HOME: xdgStateHome,
626
620
  ...respawnStrategy === "replay" ? { BRIDGE_REPLAY_FROM_DISK: "1" } : {}
627
621
  };
628
622
  if (respawnStrategy === void 0) {
629
623
  await toolSafeSandboxSession.run({
630
- command: `mkdir -p ${shellQuote(workDir)} ${shellQuote(bridgeStateDir)} ${shellQuote(xdgConfigHome)} ${shellQuote(xdgCacheHome)} ${shellQuote(xdgDataHome)} ${shellQuote(xdgStateHome)}`,
624
+ command: `mkdir -p ${shellQuote(workDir)} ${shellQuote(bridgeStateDir)}`,
631
625
  abortSignal: startOpts.abortSignal
632
626
  });
633
627
  }
@@ -638,7 +632,7 @@ function createOpenCode(settings = {}) {
638
632
  abortSignal: startOpts.abortSignal
639
633
  });
640
634
  const proc = await toolSafeSandboxSession.spawn({
641
- command: `node ${shellQuote(`${bootstrapDir}/bridge.mjs`)} --workdir ${shellQuote(workDir)} --bridge-state-dir ${shellQuote(bridgeStateDir)} --bootstrap-dir ${shellQuote(bootstrapDir)}${skillSetup ? ` --skills-dir ${shellQuote(skillSetup.skillsDir)}` : ""}`,
635
+ command: `node ${shellQuote(`${bootstrapDir}/bridge.mjs`)} --workdir ${shellQuote(workDir)} --bridge-state-dir ${shellQuote(bridgeStateDir)} --bootstrap-dir ${shellQuote(bootstrapDir)} --skills-dir ${shellQuote(skillsDir)}`,
642
636
  env,
643
637
  abortSignal: startOpts.abortSignal
644
638
  });
@@ -702,6 +696,7 @@ function createOpenCode(settings = {}) {
702
696
  model,
703
697
  provider: settings.provider,
704
698
  reasoningVariant: settings.reasoningVariant,
699
+ openCodeConfig: settings.openCodeConfig,
705
700
  mcpServers: settings.mcpServers,
706
701
  openCodeSessionId: resumeSessionId,
707
702
  isResume: respawnStrategy !== void 0,
@@ -714,6 +709,8 @@ function createOpenCode(settings = {}) {
714
709
  debug: startOpts.observability?.debug,
715
710
  permissionMode: startOpts.permissionMode,
716
711
  builtinToolFiltering: startOpts.builtinToolFiltering,
712
+ sandbox: toolSafeSandboxSession,
713
+ sandboxHomeDir,
717
714
  supportsUserMessageResponses: () => supportsUserMessageResponses
718
715
  });
719
716
  }
@@ -772,7 +769,7 @@ async function writeOpenCodeSkills({
772
769
  abortSignal
773
770
  }) {
774
771
  const skillsDir = path.posix.join(homeDir, ".agents", "skills");
775
- await writeHarnessSkills({
772
+ return writeHarnessSkills({
776
773
  sandbox,
777
774
  rootDir: skillsDir,
778
775
  skills,
@@ -780,7 +777,6 @@ async function writeOpenCodeSkills({
780
777
  invalidSkillNameMessage: ({ name }) => `Invalid OpenCode skill name: ${name}`,
781
778
  invalidSkillFilePathMessage: ({ skillName, filePath }) => `Invalid OpenCode skill file path for ${skillName}: ${filePath}`
782
779
  });
783
- return { skillsDir };
784
780
  }
785
781
  function openWebSocket({
786
782
  endpoint,
@@ -880,6 +876,7 @@ function createSession({
880
876
  model,
881
877
  provider,
882
878
  reasoningVariant,
879
+ openCodeConfig,
883
880
  mcpServers,
884
881
  openCodeSessionId,
885
882
  isResume,
@@ -892,12 +889,15 @@ function createSession({
892
889
  debug,
893
890
  permissionMode,
894
891
  builtinToolFiltering,
892
+ sandbox,
893
+ sandboxHomeDir,
895
894
  supportsUserMessageResponses
896
895
  }) {
897
896
  let stopped = false;
898
897
  let stopPromise;
899
898
  let latestOpenCodeSessionId = openCodeSessionId;
900
899
  let pendingResumeSessionId = seedResumeSessionOnFirstPrompt ? openCodeSessionId : void 0;
900
+ let selectedModel = model;
901
901
  let activeTurn = false;
902
902
  const pendingCompactionParts = [];
903
903
  channel.on("bridge-thread", (msg) => {
@@ -1033,10 +1033,11 @@ function createSession({
1033
1033
  done
1034
1034
  };
1035
1035
  };
1036
- const startBase = () => ({
1037
- model,
1036
+ const startBase = (turnModel) => ({
1037
+ model: turnModel,
1038
1038
  provider,
1039
1039
  ...reasoningVariant ? { variant: reasoningVariant } : {},
1040
+ ...openCodeConfig == null ? {} : { openCodeConfig },
1040
1041
  ...mcpServers == null ? {} : { mcpServers },
1041
1042
  ...permissionMode ? { permissionMode } : {},
1042
1043
  ...builtinToolFiltering ? { builtinToolFiltering } : {},
@@ -1046,7 +1047,6 @@ function createSession({
1046
1047
  return {
1047
1048
  sessionId,
1048
1049
  isResume,
1049
- modelId: model,
1050
1050
  doPromptTurn: async (promptOpts) => {
1051
1051
  if (promptOpts.responseFormat?.type === "json" && promptOpts.responseFormat.schema == null) {
1052
1052
  throw new HarnessCapabilityUnsupportedError({
@@ -1054,10 +1054,18 @@ function createSession({
1054
1054
  harnessId: "opencode"
1055
1055
  });
1056
1056
  }
1057
+ const skillWriteResult = await writeOpenCodeSkills({
1058
+ sandbox,
1059
+ skills: promptOpts.skills,
1060
+ homeDir: sandboxHomeDir,
1061
+ abortSignal: promptOpts.abortSignal
1062
+ });
1057
1063
  const control = wireTurn({
1058
1064
  emit: promptOpts.emit,
1059
1065
  abortSignal: promptOpts.abortSignal
1060
1066
  });
1067
+ const turnModel = promptOpts.model ?? selectedModel;
1068
+ if (turnModel) selectedModel = turnModel;
1061
1069
  channel.send({
1062
1070
  type: "start",
1063
1071
  operation: "prompt",
@@ -1069,7 +1077,8 @@ function createSession({
1069
1077
  })),
1070
1078
  ...promptOpts.responseFormat == null ? {} : { responseFormat: promptOpts.responseFormat },
1071
1079
  ...promptOpts.instructions ? { instructions: promptOpts.instructions } : {},
1072
- ...startBase()
1080
+ skillsChanged: skillWriteResult.changed,
1081
+ ...startBase(turnModel)
1073
1082
  });
1074
1083
  pendingResumeSessionId = void 0;
1075
1084
  return control;
@@ -1081,11 +1090,19 @@ function createSession({
1081
1090
  harnessId: "opencode"
1082
1091
  });
1083
1092
  }
1093
+ const skillWriteResult = await writeOpenCodeSkills({
1094
+ sandbox,
1095
+ skills: continueOpts.skills,
1096
+ homeDir: sandboxHomeDir,
1097
+ abortSignal: continueOpts.abortSignal
1098
+ });
1084
1099
  const control = wireTurn({
1085
1100
  emit: continueOpts.emit,
1086
1101
  abortSignal: continueOpts.abortSignal
1087
1102
  });
1088
1103
  if (rerunContinue) {
1104
+ const turnModel = continueOpts.model ?? selectedModel;
1105
+ if (turnModel) selectedModel = turnModel;
1089
1106
  channel.send({
1090
1107
  type: "start",
1091
1108
  operation: "prompt",
@@ -1097,7 +1114,8 @@ function createSession({
1097
1114
  })),
1098
1115
  ...continueOpts.responseFormat == null ? {} : { responseFormat: continueOpts.responseFormat },
1099
1116
  ...continueOpts.instructions ? { instructions: continueOpts.instructions } : {},
1100
- ...startBase()
1117
+ skillsChanged: skillWriteResult.changed,
1118
+ ...startBase(turnModel)
1101
1119
  });
1102
1120
  pendingResumeSessionId = void 0;
1103
1121
  }
@@ -1118,10 +1136,11 @@ function createSession({
1118
1136
  }
1119
1137
  await runCompactOperation({
1120
1138
  channel,
1121
- model,
1139
+ model: selectedModel,
1122
1140
  provider,
1123
1141
  permissionMode,
1124
1142
  debug,
1143
+ openCodeConfig,
1125
1144
  mcpServers,
1126
1145
  resumeSessionId: latestOpenCodeSessionId,
1127
1146
  onCompaction: (part) => pendingCompactionParts.push(part)
@@ -1279,6 +1298,7 @@ async function runCompactOperation({
1279
1298
  provider,
1280
1299
  permissionMode,
1281
1300
  debug,
1301
+ openCodeConfig,
1282
1302
  mcpServers,
1283
1303
  resumeSessionId,
1284
1304
  onCompaction
@@ -1307,6 +1327,7 @@ async function runCompactOperation({
1307
1327
  tools: [],
1308
1328
  model,
1309
1329
  provider,
1330
+ ...openCodeConfig == null ? {} : { openCodeConfig },
1310
1331
  ...mcpServers == null ? {} : { mcpServers },
1311
1332
  ...permissionMode ? { permissionMode } : {},
1312
1333
  ...resumeSessionId ? { resumeSessionId } : {},