dsh-opencode-go 0.1.6 → 0.1.7

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/lib/index.js CHANGED
@@ -308,9 +308,13 @@ function flattenText(message) {
308
308
  function toolResultText(blocks) {
309
309
  return blocks.map((block) => block.type === "text" ? block.text : block.type === "tool-result" ? toolResultText(block.content) : "").join("");
310
310
  }
311
+ function toolMessage(message) {
312
+ if (message.role !== "tool") return void 0;
313
+ return message;
314
+ }
311
315
  function assertSupportedImageRoles(messages) {
312
316
  for (const message of messages) {
313
- if (message.role !== "user" && contentHasImage(message.content)) {
317
+ if (message.role !== "user" && !toolMessage(message) && contentHasImage(message.content)) {
314
318
  throw new LlmError3(
315
319
  `pi-ai cannot represent an image in an in-history ${message.role} message`,
316
320
  "UNSUPPORTED_CONTENT"
@@ -417,6 +421,18 @@ function textOnlyContext(options, onReplayDegrade) {
417
421
  if (contentHasImage(message.content)) {
418
422
  throw new LlmError3("pi-ai image conversion requires the durable attachment service", "UNSUPPORTED_CONTENT");
419
423
  }
424
+ const tool = toolMessage(message);
425
+ if (tool) {
426
+ messages.push({
427
+ role: "toolResult",
428
+ toolCallId: tool.toolCallId,
429
+ toolName: toolNames.get(tool.toolCallId) ?? "unknown",
430
+ content: [{ type: "text", text: toolResultText(tool.content) || "(no output)" }],
431
+ isError: tool.isError ?? false,
432
+ timestamp: 0
433
+ });
434
+ continue;
435
+ }
420
436
  if (message.role === "system") {
421
437
  messages.push({ role: "user", content: flattenText(message), timestamp: 0 });
422
438
  continue;
@@ -480,6 +496,19 @@ async function toPiContextWithImages(options, images, onReplayDegrade) {
480
496
  const toolNames = /* @__PURE__ */ new Map();
481
497
  const messages = [];
482
498
  for (const message of exactMessages) {
499
+ const tool = toolMessage(message);
500
+ if (tool) {
501
+ const content2 = await userContent(tool.content, requestImages, resolveImageAccess);
502
+ messages.push({
503
+ role: "toolResult",
504
+ toolCallId: tool.toolCallId,
505
+ toolName: toolNames.get(tool.toolCallId) ?? "unknown",
506
+ content: typeof content2 === "string" ? [{ type: "text", text: content2 || "(no output)" }] : content2,
507
+ isError: tool.isError ?? false,
508
+ timestamp: 0
509
+ });
510
+ continue;
511
+ }
483
512
  if (message.role === "system") {
484
513
  messages.push({ role: "user", content: flattenText(message), timestamp: 0 });
485
514
  continue;
@@ -953,7 +982,7 @@ import z from "@deepseek-ai/schemastery";
953
982
  var DEFAULT_API_KEY_ENV = "OPENCODE_API_KEY";
954
983
  var DEFAULT_REFRESH_MINUTES = 60;
955
984
  var DEFAULT_STREAM_IDLE_TIMEOUT_MS = 3e5;
956
- var Config = z.object({
985
+ var fields = {
957
986
  enabled: z.boolean().default(true),
958
987
  apiKeyEnv: z.string().role("credential-ref").default(DEFAULT_API_KEY_ENV),
959
988
  baseURL: z.string().default(DEFAULT_BASE_URL),
@@ -963,8 +992,20 @@ var Config = z.object({
963
992
  // request image fits the budget, and fifteen of them fit the payload cap.
964
993
  maxRequestImageBytes: z.number().step(1).min(1).default(DEFAULT_MAX_REQUEST_IMAGE_BYTES),
965
994
  requestImagePixelBudget: z.number().step(1).min(1).default(DEFAULT_REQUEST_IMAGE_PIXEL_BUDGET),
966
- requestImageMaxBytes: z.number().step(1).min(1).default(DEFAULT_REQUEST_IMAGE_MAX_BYTES)
967
- });
995
+ requestImageMaxBytes: z.number().step(1).min(1).default(DEFAULT_REQUEST_IMAGE_MAX_BYTES),
996
+ // null explicitly selects catalog values, overriding even inherited profile limits.
997
+ modelLimits: z.dict(z.union([z.const(null), z.object({
998
+ contextWindow: z.union([z.const(null), z.number().step(1).min(1).max(Number.MAX_SAFE_INTEGER)]),
999
+ maxTokens: z.union([z.const(null), z.number().step(1).min(1).max(Number.MAX_SAFE_INTEGER)])
1000
+ })])).default({})
1001
+ };
1002
+ var PlainConfig = z.object(fields);
1003
+ var Config = z.object(Object.fromEntries(
1004
+ Object.entries(fields).map(([key, schema]) => [key, schema.volatile()])
1005
+ ));
1006
+ function readConfig(config) {
1007
+ return Object.fromEntries(Object.entries(config).map(([key, value]) => [key, value.get()]));
1008
+ }
968
1009
  function assertBaseURL(raw) {
969
1010
  let url;
970
1011
  try {
@@ -982,6 +1023,15 @@ function assertBaseURL(raw) {
982
1023
  }
983
1024
 
984
1025
  // src/adapter.ts
1026
+ function withModelLimit(model, limits) {
1027
+ const limit = limits[model.id];
1028
+ if (limit == null) return model;
1029
+ return {
1030
+ ...model,
1031
+ contextWindow: limit.contextWindow ?? model.contextWindow,
1032
+ maxTokens: limit.maxTokens ?? model.maxTokens
1033
+ };
1034
+ }
985
1035
  function opencodeSessionValue(sessionId) {
986
1036
  return sessionId !== void 0 && sessionId.length > 0 ? sessionId : randomUUID();
987
1037
  }
@@ -1001,9 +1051,8 @@ var OpencodeGoAdapter = class extends LlmAdapter {
1001
1051
  * The catalog resolver for one configuration, rebuilding on the facts it
1002
1052
  * owns. Public for the plugin's discovery registration, which resolves the
1003
1053
  * current configuration the same way the adapter does.
1004
- * @param config - the configuration whose endpoint and refresh interval the
1005
- * resolver serves; a change to either yields a fresh resolver.
1006
- * @returns the resolver caching one snapshot per endpoint/refresh pair.
1054
+ * @param config - the endpoint and refresh interval for the raw catalog.
1055
+ * @returns the resolver caching catalog values, independent of deployment limits.
1007
1056
  */
1008
1057
  catalogOf(config) {
1009
1058
  const key = `${config.baseURL}|${String(config.refreshMinutes)}`;
@@ -1037,12 +1086,13 @@ var OpencodeGoAdapter = class extends LlmAdapter {
1037
1086
  }));
1038
1087
  }
1039
1088
  async resolveModel(_provider, model, _signal) {
1040
- const snapshot = await this.catalogOf(this.options.config()).forModel(model);
1089
+ const config = this.options.config();
1090
+ const snapshot = await this.catalogOf(config).forModel(model);
1041
1091
  const resolved = snapshot.models.get(model);
1042
1092
  if (resolved === void 0) {
1043
1093
  throw new LlmError6(`opencode-go has no model "${model}"`, "UNKNOWN_MODEL");
1044
1094
  }
1045
- return this.modelInfo(resolved);
1095
+ return this.modelInfo(withModelLimit(resolved, config.modelLimits));
1046
1096
  }
1047
1097
  /** Describe one model: capacities plus the reasoning levels it actually offers. */
1048
1098
  modelInfo(model) {
@@ -1083,10 +1133,13 @@ var OpencodeGoAdapter = class extends LlmAdapter {
1083
1133
  }
1084
1134
  const config = this.options.config();
1085
1135
  const snapshot = await this.catalogOf(config).forModel(options.model);
1086
- const model = snapshot.models.get(options.model);
1087
- if (model === void 0) {
1136
+ const advertised = snapshot.models.get(options.model);
1137
+ if (advertised === void 0) {
1088
1138
  throw new LlmError6(`opencode-go has no model "${options.model}"`, "UNKNOWN_MODEL");
1089
1139
  }
1140
+ const model = withModelLimit(advertised, config.modelLimits);
1141
+ const outputLimit = config.modelLimits[model.id]?.maxTokens;
1142
+ const maxTokens = outputLimit == null ? options.maxTokens : Math.min(options.maxTokens ?? outputLimit, outputLimit);
1090
1143
  const apiKey = await this.options.resolveApiKey();
1091
1144
  if (apiKey === void 0 || apiKey.length === 0) {
1092
1145
  throw new LlmError6("llm-opencode-go: no credential resolved for the route", "MISSING_CREDENTIAL");
@@ -1122,7 +1175,7 @@ var OpencodeGoAdapter = class extends LlmAdapter {
1122
1175
  apiKey,
1123
1176
  ...reasoning === void 0 || reasoning === "off" ? {} : { reasoning },
1124
1177
  ...options.temperature === void 0 ? {} : { temperature: options.temperature },
1125
- ...options.maxTokens === void 0 ? {} : { maxTokens: options.maxTokens },
1178
+ ...maxTokens === void 0 ? {} : { maxTokens },
1126
1179
  ...options.sessionId === void 0 ? {} : { sessionId: String(options.sessionId) },
1127
1180
  signal: watchdog.signal,
1128
1181
  // Harness-owned request identity: the gateway refuses requests without
@@ -1248,9 +1301,10 @@ var name = "llm-opencode-go";
1248
1301
  var inject = ["llm"];
1249
1302
  var NS = "llm-opencode-go";
1250
1303
  function apply(ctx, raw) {
1251
- const entry = Config(raw);
1304
+ const config = raw && typeof raw.enabled === "object" ? raw : Config(raw);
1305
+ const entry = readConfig(config);
1252
1306
  assertBaseURL(entry.baseURL);
1253
- let current = () => entry;
1307
+ let current = () => readConfig(config);
1254
1308
  const resolveApiKey = async () => {
1255
1309
  const ref = current().apiKeyEnv;
1256
1310
  const credentials = ctx.get("credentials");
@@ -1330,7 +1384,12 @@ function apply(ctx, raw) {
1330
1384
  undiscover();
1331
1385
  });
1332
1386
  ctx.inject(["settings"], (settingsCtx) => {
1333
- settingsCtx.settings.installSection(ctx, NS, Config, entry, {
1387
+ if ("configure" in settingsCtx.settings) {
1388
+ const settings = settingsCtx.settings;
1389
+ settingsCtx.effect(() => settings.configure({ auto: false }, ctx.fiber));
1390
+ return;
1391
+ }
1392
+ settingsCtx.settings.installSection(ctx, NS, PlainConfig, entry, {
1334
1393
  validate: (value) => {
1335
1394
  assertBaseURL(value.baseURL);
1336
1395
  },
@@ -1342,6 +1401,12 @@ function apply(ctx, raw) {
1342
1401
  }
1343
1402
  });
1344
1403
  });
1404
+ ctx.on("internal/config", function(_raw, next) {
1405
+ const value = next();
1406
+ if (this === ctx.fiber) assertBaseURL(PlainConfig(value).baseURL);
1407
+ return value;
1408
+ });
1409
+ ctx.on("loader/volatile-update", syncRoute);
1345
1410
  ctx.inject(["credentials"], (credentialsCtx) => {
1346
1411
  credentialsCtx.on("credentials/reference-updated", (ref) => {
1347
1412
  if (ref === current().apiKeyEnv) syncRoute();
@@ -1358,6 +1423,7 @@ export {
1358
1423
  OpencodeGoAdapter,
1359
1424
  OpencodeGoCatalog,
1360
1425
  PROVIDER_ID,
1426
+ PlainConfig,
1361
1427
  apply,
1362
1428
  assertBaseURL,
1363
1429
  discoverCatalogModels,
@@ -82,9 +82,8 @@ export declare class OpencodeGoAdapter extends LlmAdapter {
82
82
  * The catalog resolver for one configuration, rebuilding on the facts it
83
83
  * owns. Public for the plugin's discovery registration, which resolves the
84
84
  * current configuration the same way the adapter does.
85
- * @param config - the configuration whose endpoint and refresh interval the
86
- * resolver serves; a change to either yields a fresh resolver.
87
- * @returns the resolver caching one snapshot per endpoint/refresh pair.
85
+ * @param config - the endpoint and refresh interval for the raw catalog.
86
+ * @returns the resolver caching catalog values, independent of deployment limits.
88
87
  */
89
88
  catalogOf(config: OpencodeGoConfig): OpencodeGoCatalog;
90
89
  providerInfo(provider: string): {
@@ -28,6 +28,21 @@ export declare const en: {
28
28
  modelsFailed: string;
29
29
  modelsEmpty: string;
30
30
  modelsCount: string;
31
+ limitsLabel: string;
32
+ limitsHint: string;
33
+ limitsFilterLabel: string;
34
+ limitsFilterPlaceholder: string;
35
+ limitsSummary: string;
36
+ limitsModel: string;
37
+ limitsContext: string;
38
+ limitsOutput: string;
39
+ limitsAdvertised: string;
40
+ limitsResetModel: string;
41
+ limitsResetAll: string;
42
+ limitsNoMatches: string;
43
+ limitsEmpty: string;
44
+ limitsContextLabel: string;
45
+ limitsOutputLabel: string;
31
46
  advancedLabel: string;
32
47
  advancedHint: string;
33
48
  apiKeyEnvLabel: string;
@@ -9,8 +9,9 @@
9
9
  * covers everything the page shows.
10
10
  */
11
11
  import type { Context as ClientContext } from '@deepseek-ai/cordis';
12
+ import type { LlmDiscoveredModel } from '@deepseek-ai/dsh-api-remotes/client';
12
13
  import type { SnapshotStore } from '@deepseek-ai/dsh-client-store';
13
- import type { SettingsScope } from '@deepseek-ai/dsh-client-ui-settings/client';
14
+ import type { SettingsScope } from './settings.ts';
14
15
  import { type FieldState, type FormActions, type FormShell } from './staged-form.ts';
15
16
  /** Namespace of the OpenCode Go adapter. Spelled here rather than imported: a client package must not depend on a Host package. */
16
17
  export declare const OPENCODE_GO_NS = "llm-opencode-go";
@@ -32,7 +33,15 @@ export interface OpencodeGoSettings {
32
33
  requestImagePixelBudget?: number;
33
34
  /** Raw encoded-byte target for one request image. */
34
35
  requestImageMaxBytes?: number;
36
+ /** Per-model capacity overrides, keyed by the gateway model id. */
37
+ modelLimits?: OpencodeGoModelLimits;
35
38
  }
39
+ /** The two capacity values the settings table can override. */
40
+ export interface OpencodeGoModelLimit {
41
+ contextWindow?: number | null;
42
+ maxTokens?: number | null;
43
+ }
44
+ export type OpencodeGoModelLimits = Record<string, OpencodeGoModelLimit | null>;
36
45
  /** The gateway's model listing as the page reports it. */
37
46
  export type OpencodeGoModels =
38
47
  /** Not asked for yet; the page asks once it mounts. */
@@ -43,11 +52,15 @@ export type OpencodeGoModels =
43
52
  | {
44
53
  readonly status: 'loading';
45
54
  }
46
- /** The gateway answered: how many models it serves, and a preview of their names. */
55
+ /**
56
+ * The gateway answered: a count/preview for the compact summary plus every
57
+ * discovered entry used by the capacity editor.
58
+ */
47
59
  | {
48
60
  readonly status: 'ready';
49
61
  readonly count: number;
50
62
  readonly preview: readonly string[];
63
+ readonly entries: readonly LlmDiscoveredModel[];
51
64
  }
52
65
  /** The listing could not be read; `message` is the Host's own diagnostic. */
53
66
  | {
@@ -84,6 +97,10 @@ export interface OpencodeGoSectionState extends FormShell {
84
97
  apiKeyWritable: boolean;
85
98
  /** The gateway's current model listing. */
86
99
  models: OpencodeGoModels;
100
+ /** The staged JSON field backing the capacity table. */
101
+ modelLimits: FieldState;
102
+ /** The parsed overrides currently shown by the capacity table. */
103
+ modelLimitDraft: OpencodeGoModelLimits;
87
104
  }
88
105
  /** The registration-side face the page's slot entry injects. */
89
106
  export interface OpencodeGoSectionFace extends FormActions {
@@ -109,13 +126,22 @@ export declare class OpencodeGoSectionController {
109
126
  private models;
110
127
  private modelsRequest;
111
128
  private face;
129
+ private readonly unsubscribe;
112
130
  /**
113
131
  * @param scope - the bound settings scope for the `llm-opencode-go` namespace.
114
132
  * @param ctx - the page plugin's context, whose `remote.credentials` namespace
115
133
  * answers for the credential the section references.
116
134
  */
117
135
  constructor(scope: SettingsScope<OpencodeGoSettings>, ctx: ClientContext);
136
+ /** Release subscriptions without disposing the host's shared form. */
137
+ dispose(): void;
118
138
  private projection;
139
+ /**
140
+ * Read the overrides as the page currently shows them. A staged JSON draft
141
+ * wins while it is valid; malformed text falls back to the last accepted
142
+ * settings value so the table never renders phantom rows.
143
+ */
144
+ private limitDraft;
119
145
  /**
120
146
  * The adapter's effective switch state: the resolved section's value, over
121
147
  * the Host's own default when the section carries none.
@@ -0,0 +1,18 @@
1
+ import type { SettingsPathOpView } from '@deepseek-ai/dsh-api-remotes/client';
2
+ /** Common read/write contract of legacy SettingsScope and 0.1.7 ConfigForm. */
3
+ export interface SettingsScopeSnapshot<T> {
4
+ status: 'loading' | 'ready' | 'unavailable';
5
+ value: T | undefined;
6
+ base: unknown;
7
+ user: unknown;
8
+ revision: number | undefined;
9
+ writable: boolean;
10
+ mode: 'host' | 'memory';
11
+ }
12
+ export interface SettingsScope<T> {
13
+ getSnapshot(): SettingsScopeSnapshot<T>;
14
+ subscribe(listener: () => void): () => void;
15
+ mutate(ops: readonly SettingsPathOpView[], expectedRevision?: number): Promise<void | boolean>;
16
+ set(field: string, value: unknown): Promise<void | boolean>;
17
+ unset(field: string): Promise<void | boolean>;
18
+ }
@@ -17,7 +17,7 @@
17
17
  * forms evolve independently anyway.
18
18
  */
19
19
  import { type SnapshotStore } from '@deepseek-ai/dsh-client-store';
20
- import type { SettingsScope } from '@deepseek-ai/dsh-client-ui-settings/client';
20
+ import type { SettingsScope } from './settings.ts';
21
21
  /** The write one field's staged text performs when the page is saved. */
22
22
  export type FieldWrite = {
23
23
  kind: 'set';
@@ -111,6 +111,13 @@ export declare function booleanField(field: string): FieldSpec;
111
111
  * @returns the field's conversion spec.
112
112
  */
113
113
  export declare function textField(field: string): FieldSpec;
114
+ /**
115
+ * A structured field edited as JSON text. Empty text clears the field and
116
+ * malformed JSON blocks the save instead of reaching the Host as a string.
117
+ * @param field - field name inside the namespace section.
118
+ * @returns the field's conversion spec.
119
+ */
120
+ export declare function jsonField(field: string): FieldSpec;
114
121
  /**
115
122
  * Stages the page's edits over the `llm-opencode-go` namespace and writes them
116
123
  * on save.
@@ -125,6 +132,7 @@ export declare class StagedForm {
125
132
  private readonly secretSpecs;
126
133
  private readonly staged;
127
134
  private readonly listeners;
135
+ private readonly unsubscribe;
128
136
  private saving;
129
137
  private failed;
130
138
  /**
@@ -133,6 +141,8 @@ export declare class StagedForm {
133
141
  * @param secrets - the page's write-only controls, written outside the section.
134
142
  */
135
143
  constructor(scope: SettingsScope<Record<string, unknown>>, specs: FieldSpec[], secrets?: SecretSpec[]);
144
+ /** Shared 0.1.7 forms outlive individual settings pages. */
145
+ dispose(): void;
136
146
  /**
137
147
  * Publish a projection of this form, rebuilt whenever the scope or a draft changes.
138
148
  * @param project - build the page state from the form's current reads.
@@ -1,8 +1,8 @@
1
1
  /**
2
2
  * Configuration schema for the OpenCode Go adapter plugin. The section is
3
- * installed under the `llm-opencode-go` settings namespace: a cordis.yml
4
- * entry supplies the composition base and the settings document overrides it
5
- * field by field, hot-reloaded without a restart. Self-contained constraints
3
+ * installed under the `llm-opencode-go` settings namespace on DSH 0.1.5/0.1.6.
4
+ * DSH 0.1.7 edits the `opencode-go` profile entry through live references.
5
+ * Both paths update field by field without a restart. Self-contained constraints
6
6
  * (URL shape, numeric bounds) fail at load for the composition layer and
7
7
  * refuse the write for the settings layer.
8
8
  *
@@ -15,6 +15,19 @@ export declare const DEFAULT_API_KEY_ENV = "OPENCODE_API_KEY";
15
15
  export declare const DEFAULT_REFRESH_MINUTES = 60;
16
16
  /** Default maximum idle interval while a stream read is outstanding. */
17
17
  export declare const DEFAULT_STREAM_IDLE_TIMEOUT_MS = 300000;
18
+ /**
19
+ * One model's configured capacities. Every field is optional so a deployment
20
+ * can override only the value it needs. Null explicitly selects the catalog
21
+ * value even when a lower profile/settings layer supplies an override.
22
+ */
23
+ export interface OpencodeGoModelLimit {
24
+ /** Context window in tokens, overriding what the catalog advertised. */
25
+ contextWindow?: number | null;
26
+ /** Output cap per request, overriding what the catalog advertised. */
27
+ maxTokens?: number | null;
28
+ }
29
+ /** Per-model capacities; a null entry selects both original catalog values. */
30
+ export type OpencodeGoModelLimits = Record<string, OpencodeGoModelLimit | null>;
18
31
  /** Runtime configuration for one plugin mount. */
19
32
  export interface OpencodeGoConfig {
20
33
  /**
@@ -39,9 +52,20 @@ export interface OpencodeGoConfig {
39
52
  requestImagePixelBudget: number;
40
53
  /** Raw encoded-byte target for one request image before base64 expansion. */
41
54
  requestImageMaxBytes: number;
55
+ /** Per-model capacity overrides; an absent field inherits the catalog value. */
56
+ modelLimits: OpencodeGoModelLimits;
42
57
  }
43
- /** Runtime schema for {@link OpencodeGoConfig}. */
44
- export declare const Config: z<OpencodeGoConfig>;
58
+ /** Plain values used by the adapter and by pre-0.1.7 settings documents. */
59
+ export declare const PlainConfig: z<OpencodeGoConfig>;
60
+ /** 0.1.7's Loader retains these references when profile fields change. */
61
+ export type LiveConfig = {
62
+ [K in keyof OpencodeGoConfig]: {
63
+ get(): OpencodeGoConfig[K];
64
+ };
65
+ };
66
+ export declare const Config: z<Partial<OpencodeGoConfig>, LiveConfig>;
67
+ /** Keep the Loader's references: reparsing them would detach live updates. */
68
+ export declare function readConfig(config: LiveConfig): OpencodeGoConfig;
45
69
  /**
46
70
  * Accept only an http(s) base without a query or fragment. Runs at load for
47
71
  * the composition layer and as the settings section's write validator, so a
@@ -8,9 +8,8 @@
8
8
  * cannot express: a mandatory per-conversation `x-opencode-session` routing
9
9
  * header and a model list that rotates faster than any shipped catalog.
10
10
  *
11
- * Configuration layers like every settings-backed plugin: a `cordis.yml`
12
- * entry supplies the composition base and the settings document overrides it
13
- * field by field.
11
+ * DSH 0.1.5/0.1.6 layer the settings document over the composition entry;
12
+ * 0.1.7 edits live configuration fields on the profile entry directly.
14
13
  *
15
14
  * ```yaml
16
15
  * - id: llm-opencode-go
@@ -32,11 +31,16 @@
32
31
  * @module dsh-opencode-go
33
32
  */
34
33
  import type { Context } from '@deepseek-ai/cordis';
35
- import type { OpencodeGoConfig } from './config.ts';
34
+ import type { LiveConfig, OpencodeGoConfig } from './config.ts';
35
+ declare module '@deepseek-ai/cordis' {
36
+ interface Events {
37
+ 'loader/volatile-update'(paths: readonly (readonly string[])[]): void;
38
+ }
39
+ }
36
40
  export { OpencodeGoAdapter } from './adapter.ts';
37
41
  export type { OpencodeGoAdapterOptions, OpencodeGoImageAccess } from './adapter.ts';
38
42
  export { DEFAULT_BASE_URL, DISPLAY_NAME, PROVIDER_ID, OpencodeGoCatalog, discoverCatalogModels, readLiveModelIds, } from './catalog.ts';
39
- export { Config, assertBaseURL } from './config.ts';
43
+ export { Config, PlainConfig, assertBaseURL } from './config.ts';
40
44
  export type { OpencodeGoConfig } from './config.ts';
41
45
  export declare const name = "llm-opencode-go";
42
46
  export declare const inject: string[];
@@ -48,4 +52,4 @@ export declare const NS = "llm-opencode-go";
48
52
  * replaced by the settings section's resolved value once the settings
49
53
  * provider attaches; the adapter re-reads it at every operation.
50
54
  */
51
- export declare function apply(ctx: Context, raw?: OpencodeGoConfig): void;
55
+ export declare function apply(ctx: Context, raw?: OpencodeGoConfig | LiveConfig): void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-opencode-go",
3
- "version": "0.1.6",
3
+ "version": "0.1.7",
4
4
  "description": "OpenCode Go model provider and settings UI for DeepSeek Harness",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -14,7 +14,7 @@
14
14
  },
15
15
  "engines": {
16
16
  "node": "^22.19.0 || >=24.0.0",
17
- "dsh": ">=0.1.5-rc.1 <0.1.6-0 || 0.1.6-alpha.1 || 0.1.6-alpha.2"
17
+ "dsh": ">=0.1.5-rc.1 <0.1.6-0 || 0.1.6-alpha.1 || 0.1.6-alpha.2 || 0.1.7-alpha.1"
18
18
  },
19
19
  "main": "./lib/index.js",
20
20
  "types": "./lib/types/index.d.ts",
@@ -60,30 +60,30 @@
60
60
  "verify:headless": "node scripts/headless-smoke.mjs"
61
61
  },
62
62
  "peerDependencies": {
63
- "@deepseek-ai/cordis": "4.0.2",
64
- "@deepseek-ai/dsh-api-gateway": ">=0.1.5-rc.1 <0.1.6 || 0.1.6-alpha.1 || 0.1.6-alpha.2",
65
- "@deepseek-ai/dsh-api-remotes": ">=0.1.5-rc.1 <0.1.6 || 0.1.6-alpha.1 || 0.1.6-alpha.2",
66
- "@deepseek-ai/dsh-api-settings-controller": ">=0.1.5-rc.1 <0.1.6 || 0.1.6-alpha.1 || 0.1.6-alpha.2",
67
- "@deepseek-ai/dsh-attachment": ">=0.1.5-rc.1 <0.1.6 || 0.1.6-alpha.1 || 0.1.6-alpha.2",
68
- "@deepseek-ai/dsh-client-locale": ">=0.1.5-rc.1 <0.1.6 || 0.1.6-alpha.1 || 0.1.6-alpha.2",
69
- "@deepseek-ai/dsh-client-store": ">=0.1.5-rc.1 <0.1.6 || 0.1.6-alpha.1 || 0.1.6-alpha.2",
70
- "@deepseek-ai/dsh-client-ui-conversation": ">=0.1.5-rc.1 <0.1.6 || 0.1.6-alpha.1 || 0.1.6-alpha.2",
71
- "@deepseek-ai/dsh-client-ui-model-selection": ">=0.1.5-rc.1 <0.1.6 || 0.1.6-alpha.1 || 0.1.6-alpha.2",
72
- "@deepseek-ai/dsh-client-ui-renderer": ">=0.1.5-rc.1 <0.1.6 || 0.1.6-alpha.1 || 0.1.6-alpha.2",
73
- "@deepseek-ai/dsh-client-ui-settings": ">=0.1.5-rc.1 <0.1.6 || 0.1.6-alpha.1 || 0.1.6-alpha.2",
74
- "@deepseek-ai/dsh-client-ui-slots": ">=0.1.5-rc.1 <0.1.6 || 0.1.6-alpha.1 || 0.1.6-alpha.2",
75
- "@deepseek-ai/dsh-credentials": ">=0.1.5-rc.1 <0.1.6 || 0.1.6-alpha.1 || 0.1.6-alpha.2",
76
- "@deepseek-ai/dsh-fs": ">=0.1.5-rc.1 <0.1.6 || 0.1.6-alpha.1 || 0.1.6-alpha.2",
77
- "@deepseek-ai/dsh-launch-environment": ">=0.1.5-rc.1 <0.1.6 || 0.1.6-alpha.1 || 0.1.6-alpha.2",
78
- "@deepseek-ai/dsh-llm": ">=0.1.5-rc.1 <0.1.6 || 0.1.6-alpha.1 || 0.1.6-alpha.2",
79
- "@deepseek-ai/dsh-settings": ">=0.1.5-rc.1 <0.1.6 || 0.1.6-alpha.1 || 0.1.6-alpha.2",
80
- "@deepseek-ai/dsh-timeout": ">=0.1.5-rc.1 <0.1.6 || 0.1.6-alpha.1 || 0.1.6-alpha.2",
81
- "@deepseek-ai/dsh-typert-protocol": ">=0.1.5-rc.1 <0.1.6 || 0.1.6-alpha.1 || 0.1.6-alpha.2",
82
- "@deepseek-ai/dsh-typert-registry": ">=0.1.5-rc.1 <0.1.6 || 0.1.6-alpha.1 || 0.1.6-alpha.2"
63
+ "@deepseek-ai/cordis": "4.0.2 || 4.0.3",
64
+ "@deepseek-ai/dsh-api-gateway": ">=0.1.5-rc.1 <0.1.6 || 0.1.6-alpha.1 || 0.1.6-alpha.2 || 0.1.7-alpha.1",
65
+ "@deepseek-ai/dsh-api-remotes": ">=0.1.5-rc.1 <0.1.6 || 0.1.6-alpha.1 || 0.1.6-alpha.2 || 0.1.7-alpha.1",
66
+ "@deepseek-ai/dsh-api-settings-controller": ">=0.1.5-rc.1 <0.1.6 || 0.1.6-alpha.1 || 0.1.6-alpha.2 || 0.1.7-alpha.1",
67
+ "@deepseek-ai/dsh-attachment": ">=0.1.5-rc.1 <0.1.6 || 0.1.6-alpha.1 || 0.1.6-alpha.2 || 0.1.7-alpha.1",
68
+ "@deepseek-ai/dsh-client-locale": ">=0.1.5-rc.1 <0.1.6 || 0.1.6-alpha.1 || 0.1.6-alpha.2 || 0.1.7-alpha.1",
69
+ "@deepseek-ai/dsh-client-store": ">=0.1.5-rc.1 <0.1.6 || 0.1.6-alpha.1 || 0.1.6-alpha.2 || 0.1.7-alpha.1",
70
+ "@deepseek-ai/dsh-client-ui-conversation": ">=0.1.5-rc.1 <0.1.6 || 0.1.6-alpha.1 || 0.1.6-alpha.2 || 0.1.7-alpha.1",
71
+ "@deepseek-ai/dsh-client-ui-model-selection": ">=0.1.5-rc.1 <0.1.6 || 0.1.6-alpha.1 || 0.1.6-alpha.2 || 0.1.7-alpha.1",
72
+ "@deepseek-ai/dsh-client-ui-renderer": ">=0.1.5-rc.1 <0.1.6 || 0.1.6-alpha.1 || 0.1.6-alpha.2 || 0.1.7-alpha.1",
73
+ "@deepseek-ai/dsh-client-ui-settings": ">=0.1.5-rc.1 <0.1.6 || 0.1.6-alpha.1 || 0.1.6-alpha.2 || 0.1.7-alpha.1",
74
+ "@deepseek-ai/dsh-client-ui-slots": ">=0.1.5-rc.1 <0.1.6 || 0.1.6-alpha.1 || 0.1.6-alpha.2 || 0.1.7-alpha.1",
75
+ "@deepseek-ai/dsh-credentials": ">=0.1.5-rc.1 <0.1.6 || 0.1.6-alpha.1 || 0.1.6-alpha.2 || 0.1.7-alpha.1",
76
+ "@deepseek-ai/dsh-fs": ">=0.1.5-rc.1 <0.1.6 || 0.1.6-alpha.1 || 0.1.6-alpha.2 || 0.1.7-alpha.1",
77
+ "@deepseek-ai/dsh-launch-environment": ">=0.1.5-rc.1 <0.1.6 || 0.1.6-alpha.1 || 0.1.6-alpha.2 || 0.1.7-alpha.1",
78
+ "@deepseek-ai/dsh-llm": ">=0.1.5-rc.1 <0.1.6 || 0.1.6-alpha.1 || 0.1.6-alpha.2 || 0.1.7-alpha.1",
79
+ "@deepseek-ai/dsh-settings": ">=0.1.5-rc.1 <0.1.6 || 0.1.6-alpha.1 || 0.1.6-alpha.2 || 0.1.7-alpha.1",
80
+ "@deepseek-ai/dsh-timeout": ">=0.1.5-rc.1 <0.1.6 || 0.1.6-alpha.1 || 0.1.6-alpha.2 || 0.1.7-alpha.1",
81
+ "@deepseek-ai/dsh-typert-protocol": ">=0.1.5-rc.1 <0.1.6 || 0.1.6-alpha.1 || 0.1.6-alpha.2 || 0.1.7-alpha.1",
82
+ "@deepseek-ai/dsh-typert-registry": ">=0.1.5-rc.1 <0.1.6 || 0.1.6-alpha.1 || 0.1.6-alpha.2 || 0.1.7-alpha.1"
83
83
  },
84
84
  "dependencies": {
85
85
  "@deepseek-ai/dsh-brand": "0.1.6-alpha.1",
86
- "@deepseek-ai/schemastery": "3.18.2",
86
+ "@deepseek-ai/schemastery": "3.18.3",
87
87
  "@earendil-works/pi-ai": "0.85.1"
88
88
  },
89
89
  "devDependencies": {
@@ -116,6 +116,7 @@
116
116
  "@deepseek-ai/dsh-typert-protocol": "0.1.6-alpha.1",
117
117
  "@deepseek-ai/dsh-typert-registry": "0.1.6-alpha.1",
118
118
  "@shikijs/langs": "^4.3.1",
119
+ "@testing-library/dom": "^10.4.2",
119
120
  "@testing-library/react": "^16.3.2",
120
121
  "@types/mdast": "^4.0.4",
121
122
  "@types/node": "^22.20.0",
@@ -204,5 +205,8 @@
204
205
  "opencode-go",
205
206
  "llm",
206
207
  "cordis"
208
+ ],
209
+ "workspaces": [
210
+ "tests/hosts/*"
207
211
  ]
208
212
  }