dsh-opencode-go 0.1.20 → 0.1.22

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.
Files changed (56) hide show
  1. package/README.en.md +133 -127
  2. package/README.md +131 -127
  3. package/THIRD_PARTY_NOTICES.md +3 -1
  4. package/docs/development.md +60 -8
  5. package/docs/fork-review-2026-09-25.md +191 -0
  6. package/docs/independent-package.md +2 -2
  7. package/docs/verification.md +241 -0
  8. package/lib/build-info.json +8 -1
  9. package/lib/client.js +1576 -234
  10. package/lib/index.js +7001 -338
  11. package/lib/types/account-manager.d.ts +23 -0
  12. package/lib/types/account-operations.d.ts +31 -0
  13. package/lib/types/account-policy.d.ts +16 -0
  14. package/lib/types/account-recovery.d.ts +2 -0
  15. package/lib/types/account-selection.d.ts +30 -0
  16. package/lib/types/account-service.d.ts +12 -0
  17. package/lib/types/accounts-contract.d.ts +38 -0
  18. package/lib/types/accounts.d.ts +31 -0
  19. package/lib/types/adapter.d.ts +43 -9
  20. package/lib/types/call-trace.d.ts +54 -0
  21. package/lib/types/catalog-manager.d.ts +20 -0
  22. package/lib/types/catalog.d.ts +6 -3
  23. package/lib/types/client/AccountsCard.d.ts +19 -0
  24. package/lib/types/client/Section.d.ts +3 -6
  25. package/lib/types/client/UsagePill.d.ts +4 -2
  26. package/lib/types/client/accounts-controller.d.ts +69 -0
  27. package/lib/types/client/host-compat.d.ts +7 -0
  28. package/lib/types/client/locales.d.ts +55 -1
  29. package/lib/types/client/section-controller.d.ts +17 -41
  30. package/lib/types/client/staged-form.d.ts +1 -3
  31. package/lib/types/client/usage.d.ts +1 -1
  32. package/lib/types/config-contract.d.ts +69 -0
  33. package/lib/types/config.d.ts +12 -47
  34. package/lib/types/conversion/context.d.ts +5 -1
  35. package/lib/types/conversion/image-pool.d.ts +24 -0
  36. package/lib/types/conversion/replay.d.ts +1 -1
  37. package/lib/types/conversion/stream.d.ts +1 -1
  38. package/lib/types/gateway-diagnostics.d.ts +22 -0
  39. package/lib/types/gateway-error.d.ts +2 -0
  40. package/lib/types/host-settings.d.ts +11 -0
  41. package/lib/types/index.d.ts +2 -1
  42. package/lib/types/json-response.d.ts +1 -1
  43. package/lib/types/model-metadata.d.ts +3 -1
  44. package/lib/types/models-contract.d.ts +7 -0
  45. package/lib/types/protocol-contract.d.ts +5 -0
  46. package/lib/types/protocol-policy.d.ts +4 -0
  47. package/lib/types/proxy-url.d.ts +2 -0
  48. package/lib/types/proxy.d.ts +11 -0
  49. package/lib/types/reasoning.d.ts +36 -6
  50. package/lib/types/request-control.d.ts +2 -0
  51. package/lib/types/sdk-types.d.ts +1568 -0
  52. package/lib/types/settings-bridge.d.ts +22 -0
  53. package/lib/types/usage-contract.d.ts +5 -0
  54. package/lib/types/usage.d.ts +14 -2
  55. package/lib/vendor-licenses.txt +103 -0
  56. package/package.json +8 -2
@@ -4,52 +4,21 @@
4
4
  *
5
5
  * The key is the one control that does not live in the section: its literal
6
6
  * never rides a response, so the page learns only whether one is configured
7
- * and writes it through the credentials domain, addressed by the reference the
8
- * section names. It is still staged with the rest of the form, so one save
7
+ * and writes it through the host account service, pinned to the account where
8
+ * the draft began. It is still staged with the rest of the form, so one save
9
9
  * covers everything the page shows.
10
10
  */
11
11
  import type { Context as ClientContext } from '@deepseek-ai/cordis';
12
12
  import type { RemoteResult } from '@deepseek-ai/dsh-typert-protocol';
13
13
  import type { GoModel, GoModelCatalog } from '../models-contract.ts';
14
- import { type UsageDisplayMode } from '../usage-display.ts';
15
14
  import type { SnapshotStore } from '@deepseek-ai/dsh-client-store';
16
15
  import type { SettingsScope } from './settings.ts';
16
+ import type { OpencodeGoSettings, OpencodeGoModelLimits } from '../config-contract.ts';
17
+ export type { OpencodeGoSettings, OpencodeGoModelLimit, OpencodeGoModelLimits } from '../config-contract.ts';
18
+ import { type GoAccountsState, type GoAccountsActions, type ExecuteAccountCommand } from './accounts-controller.ts';
17
19
  import { type FieldState, type FormActions, type FormShell } from './staged-form.ts';
18
- /** Namespace of the OpenCode Go adapter. Spelled here rather than imported: a client package must not depend on a Host package. */
20
+ /** Namespace shared with the host through the browser-safe configuration contract. */
19
21
  export declare const OPENCODE_GO_NS = "llm-opencode-go";
20
- /** The adapter fields this page edits. */
21
- export interface OpencodeGoSettings {
22
- /** Whether the adapter serves its route; false withdraws it from every picker. */
23
- enabled?: boolean;
24
- /** Usage pill visibility, independent of the selected model in always mode. */
25
- usageDisplay?: UsageDisplayMode;
26
- /** Per-model switches; normal models default on, deprecated models default off. */
27
- modelVisibility?: Record<string, boolean>;
28
- /** Credential reference naming the environment key. */
29
- apiKeyEnv?: string;
30
- /** The gateway endpoint; also the live listing base. */
31
- baseURL?: string;
32
- /** Live catalog re-resolution interval, in minutes. */
33
- refreshMinutes?: number;
34
- /** Largest idle gap between stream events, in milliseconds. */
35
- streamIdleTimeoutMs?: number;
36
- /** Optional retained image occurrence cap per request. */
37
- maxImages?: number | null;
38
- /** Accumulated base64 image payload bound for one request. */
39
- maxRequestImageBytes?: number;
40
- /** Total-pixel budget for one request image. */
41
- requestImagePixelBudget?: number;
42
- /** Raw encoded-byte target for one request image. */
43
- requestImageMaxBytes?: number;
44
- /** Per-model capacity overrides, keyed by the gateway model id. */
45
- modelLimits?: OpencodeGoModelLimits;
46
- }
47
- /** The two capacity values the settings table can override. */
48
- export interface OpencodeGoModelLimit {
49
- contextWindow?: number | null;
50
- maxTokens?: number | null;
51
- }
52
- export type OpencodeGoModelLimits = Record<string, OpencodeGoModelLimit | null>;
53
22
  /** The gateway's model listing as the page reports it. */
54
23
  export type OpencodeGoModels =
55
24
  /** Not asked for yet; the page asks once it mounts. */
@@ -82,6 +51,7 @@ export type OpencodeGoModels =
82
51
  };
83
52
  /** What the settings page renders. */
84
53
  export interface OpencodeGoSectionState extends FormShell {
54
+ accounts?: GoAccountsState;
85
55
  /**
86
56
  * Whether the adapter currently serves its route. Resolved from the section
87
57
  * rather than staged: the switch writes on the click that flips it, because
@@ -89,6 +59,7 @@ export interface OpencodeGoSectionState extends FormShell {
89
59
  */
90
60
  enabled: boolean;
91
61
  usageDisplay: FieldState;
62
+ protocolOverrides: FieldState;
92
63
  modelVisibility: Readonly<Record<string, boolean>>;
93
64
  pickerSaving: boolean;
94
65
  pickerFailed: boolean;
@@ -96,6 +67,7 @@ export interface OpencodeGoSectionState extends FormShell {
96
67
  apiKeyEnv: FieldState;
97
68
  /** The gateway endpoint. */
98
69
  baseURL: FieldState;
70
+ proxyURL: FieldState;
99
71
  /** Live catalog re-resolution interval, in minutes. */
100
72
  refreshMinutes: FieldState;
101
73
  /** Largest idle gap between stream events, in milliseconds. */
@@ -122,7 +94,7 @@ export interface OpencodeGoSectionState extends FormShell {
122
94
  modelLimitDraft: OpencodeGoModelLimits;
123
95
  }
124
96
  /** The registration-side face the page's slot entry injects. */
125
- export interface OpencodeGoSectionFace extends FormActions {
97
+ export interface OpencodeGoSectionFace extends FormActions, GoAccountsActions {
126
98
  hooks: {
127
99
  /** Page snapshot bound by the UI renderer as useOpencodeGo. */
128
100
  opencodeGo: SnapshotStore<OpencodeGoSectionState>;
@@ -141,6 +113,7 @@ export declare class OpencodeGoSectionController {
141
113
  private readonly scope;
142
114
  private readonly ctx;
143
115
  private readonly readModels;
116
+ private readonly executeAccountCommand;
144
117
  private readonly form;
145
118
  private readonly store;
146
119
  private credential;
@@ -150,12 +123,15 @@ export declare class OpencodeGoSectionController {
150
123
  private pickerFailed;
151
124
  private face;
152
125
  private readonly unsubscribe;
126
+ private accounts;
127
+ private credentialRequest;
128
+ private keyDraftRef;
153
129
  /**
154
130
  * @param scope - the bound settings scope for the `llm-opencode-go` namespace.
155
131
  * @param ctx - the page plugin's context, whose `remote.credentials` namespace
156
132
  * answers for the credential the section references.
157
133
  */
158
- constructor(scope: SettingsScope<OpencodeGoSettings>, ctx: ClientContext, readModels?: () => Promise<RemoteResult<GoModelCatalog>>);
134
+ constructor(scope: SettingsScope<OpencodeGoSettings>, ctx: ClientContext, readModels?: () => Promise<RemoteResult<GoModelCatalog>>, readUsage?: (ref: string) => Promise<import('../usage-contract.ts').GoUsage>, executeAccountCommand?: ExecuteAccountCommand);
159
135
  /** Release subscriptions without disposing the host's shared form. */
160
136
  dispose(): void;
161
137
  private projection;
@@ -220,9 +196,9 @@ export declare class OpencodeGoSectionController {
220
196
  */
221
197
  inject(): OpencodeGoSectionFace;
222
198
  /**
223
- * Write the staged key, then re-read whether the Host now holds one.
199
+ * Ask the account service to write the staged key, then refresh its display.
224
200
  * @param value - the staged credential literal.
225
- * @returns whether the Host reports a configured credential afterwards.
201
+ * @returns whether the Host confirmed the write.
226
202
  */
227
203
  private writeKey;
228
204
  }
@@ -2,7 +2,7 @@
2
2
  * The staged form behind the OpenCode Go settings page.
3
3
  *
4
4
  * The page stages what the user types and writes it only when they save. Each
5
- * settings write is a durable, revision-fenced document mutation, so a control
5
+ * settings batch is a durable, revision-fenced document mutation, so a control
6
6
  * that committed as it settled turned one edit into a write the user never
7
7
  * asked for and could not preview; staged text makes what is on screen exactly
8
8
  * what a save would store.
@@ -182,8 +182,6 @@ export declare class StagedForm {
182
182
  * @returns the planned writes, in the order the fields were staged.
183
183
  */
184
184
  private plan;
185
- private clear;
186
- private store;
187
185
  private stage;
188
186
  private spec;
189
187
  private snapshotOf;
@@ -1,4 +1,4 @@
1
1
  import type { Context } from '@deepseek-ai/cordis';
2
2
  import type { SettingsScope } from './settings.ts';
3
3
  import type { OpencodeGoSettings } from './section-controller.ts';
4
- export declare function registerUsagePill(ctx: Context, settings: SettingsScope<OpencodeGoSettings>): void;
4
+ export declare function registerUsagePill(ctx: Context, settings: SettingsScope<OpencodeGoSettings>, selectAccount?: (ref: string) => Promise<boolean>): void;
@@ -0,0 +1,69 @@
1
+ /** Browser-safe configuration vocabulary shared by both plugin faces. */
2
+ import type { GoAccount } from './accounts.ts';
3
+ import type { GoAccountOperation } from './account-operations.ts';
4
+ import type { UsageDisplayMode } from './usage-display.ts';
5
+ import type { GoProtocolOverrides } from './protocol-contract.ts';
6
+ export declare const SETTINGS_NAMESPACE = "llm-opencode-go";
7
+ export declare const PROFILE_ENTRY_ID = "opencode-go";
8
+ /**
9
+ * One model's configured capacities. Every field is optional so a deployment
10
+ * can override only the value it needs. Null explicitly selects the catalog
11
+ * value even when a lower profile/settings layer supplies an override.
12
+ */
13
+ export interface OpencodeGoModelLimit {
14
+ /** Context window in tokens, overriding what the catalog advertised. */
15
+ contextWindow?: number | null;
16
+ /** Output cap per request, overriding what the catalog advertised. */
17
+ maxTokens?: number | null;
18
+ /** Additional selectable thinking budgets, in tokens; null keeps the standard presets. */
19
+ thinkingBudgets?: number[] | null;
20
+ }
21
+ /** Per-model capacities; a null entry selects both original catalog values. */
22
+ export type OpencodeGoModelLimits = Record<string, OpencodeGoModelLimit | null>;
23
+ /** Runtime configuration for one plugin mount. */
24
+ export interface OpencodeGoConfig {
25
+ /**
26
+ * Whether this adapter serves its route at all. False withdraws the
27
+ * `dsh-opencode-go` route and its models from every picker without unloading the
28
+ * plugin, so the settings page that owns this switch stays reachable to turn
29
+ * it back on. Independent of the credential: a key present while this is
30
+ * false registers nothing.
31
+ */
32
+ enabled: boolean;
33
+ /** Usage pill visibility; auto follows this plugin's selected provider. */
34
+ usageDisplay: UsageDisplayMode;
35
+ /** Per-model picker switches; absent entries default to enabled unless deprecated. */
36
+ modelVisibility?: Record<string, boolean>;
37
+ /** Experimental opt-in routing; omitted/null entries follow the catalog. */
38
+ protocolOverrides?: GoProtocolOverrides;
39
+ /** Credential reference: the environment variable the key resolves from. */
40
+ apiKeyEnv: string;
41
+ accounts?: GoAccount[] | null;
42
+ accountOperations?: GoAccountOperation[];
43
+ /** Try other saved accounts on quota/credential rejection before any content is emitted. */
44
+ autoSwitch?: boolean;
45
+ /** The gateway endpoint; also the base of the live model listing. */
46
+ baseURL: string;
47
+ /** Optional HTTP(S) or SOCKS5 proxy; blank uses the default network transport. */
48
+ proxyURL: string;
49
+ /** Request/picker cache lifetime in minutes; explicit discovery bypasses it. */
50
+ refreshMinutes: number;
51
+ /** Largest idle gap between stream events before the request fails. */
52
+ streamIdleTimeoutMs: number;
53
+ /** Bound discovery and each attempt's credential/image preparation. */
54
+ requestPreparationTimeoutMs?: number;
55
+ /** Whole dispatch deadline, including discovery and account fallback. */
56
+ requestTimeoutMs?: number;
57
+ /** Optional retained image occurrence cap per request; omission or null leaves the count unlimited. */
58
+ maxImages?: number | null;
59
+ /** Request-level bound on base64-encoded image payload, in bytes. */
60
+ maxRequestImageBytes: number;
61
+ /** Total-pixel budget for one request image. */
62
+ requestImagePixelBudget: number;
63
+ /** Raw encoded-byte target for one request image before base64 expansion. */
64
+ requestImageMaxBytes: number;
65
+ /** Per-model capacity overrides; an absent field inherits the catalog value. */
66
+ modelLimits: OpencodeGoModelLimits;
67
+ }
68
+ /** Settings snapshots may omit fields inherited from their base layer. */
69
+ export type OpencodeGoSettings = Partial<OpencodeGoConfig>;
@@ -9,59 +9,16 @@
9
9
  * @module dsh-llm-opencode-go/config
10
10
  */
11
11
  import z from '@deepseek-ai/schemastery';
12
- import { type UsageDisplayMode } from './usage-display.ts';
12
+ import type { OpencodeGoConfig } from './config-contract.ts';
13
+ export type { OpencodeGoConfig, OpencodeGoModelLimit, OpencodeGoModelLimits } from './config-contract.ts';
13
14
  /** Environment variable resolving the OpenCode API key. */
14
15
  export declare const DEFAULT_API_KEY_ENV = "OPENCODE_API_KEY";
15
16
  /** Successful refresh lifetime; failed refreshes retry sooner and explicit discovery revalidates immediately. */
16
17
  export declare const DEFAULT_REFRESH_MINUTES = 60;
17
18
  /** Default maximum idle interval while a stream read is outstanding. */
18
19
  export declare const DEFAULT_STREAM_IDLE_TIMEOUT_MS = 300000;
19
- /**
20
- * One model's configured capacities. Every field is optional so a deployment
21
- * can override only the value it needs. Null explicitly selects the catalog
22
- * value even when a lower profile/settings layer supplies an override.
23
- */
24
- export interface OpencodeGoModelLimit {
25
- /** Context window in tokens, overriding what the catalog advertised. */
26
- contextWindow?: number | null;
27
- /** Output cap per request, overriding what the catalog advertised. */
28
- maxTokens?: number | null;
29
- }
30
- /** Per-model capacities; a null entry selects both original catalog values. */
31
- export type OpencodeGoModelLimits = Record<string, OpencodeGoModelLimit | null>;
32
- /** Runtime configuration for one plugin mount. */
33
- export interface OpencodeGoConfig {
34
- /**
35
- * Whether this adapter serves its route at all. False withdraws the
36
- * `dsh-opencode-go` route and its models from every picker without unloading the
37
- * plugin, so the settings page that owns this switch stays reachable to turn
38
- * it back on. Independent of the credential: a key present while this is
39
- * false registers nothing.
40
- */
41
- enabled: boolean;
42
- /** Usage pill visibility; auto follows this plugin's selected provider. */
43
- usageDisplay: UsageDisplayMode;
44
- /** Per-model picker switches; absent entries default to enabled unless deprecated. */
45
- modelVisibility?: Record<string, boolean>;
46
- /** Credential reference: the environment variable the key resolves from. */
47
- apiKeyEnv: string;
48
- /** The gateway endpoint; also the base of the live model listing. */
49
- baseURL: string;
50
- /** Request/picker cache lifetime in minutes; explicit discovery bypasses it. */
51
- refreshMinutes: number;
52
- /** Largest idle gap between stream events before the request fails. */
53
- streamIdleTimeoutMs: number;
54
- /** Optional retained image occurrence cap per request; omission or null leaves the count unlimited. */
55
- maxImages?: number | null;
56
- /** Request-level bound on base64-encoded image payload, in bytes. */
57
- maxRequestImageBytes: number;
58
- /** Total-pixel budget for one request image. */
59
- requestImagePixelBudget: number;
60
- /** Raw encoded-byte target for one request image before base64 expansion. */
61
- requestImageMaxBytes: number;
62
- /** Per-model capacity overrides; an absent field inherits the catalog value. */
63
- modelLimits: OpencodeGoModelLimits;
64
- }
20
+ export declare const DEFAULT_REQUEST_PREPARATION_TIMEOUT_MS = 60000;
21
+ export declare const DEFAULT_REQUEST_TIMEOUT_MS: number;
65
22
  /** Plain values used by the adapter and by pre-0.1.7 settings documents. */
66
23
  export declare const PlainConfig: z<OpencodeGoConfig>;
67
24
  /** 0.1.7's Loader retains these references when profile fields change. */
@@ -81,3 +38,11 @@ export declare function readConfig(config: LiveConfig): OpencodeGoConfig;
81
38
  * @returns the normalized base URL without trailing slashes.
82
39
  */
83
40
  export declare function assertBaseURL(raw: string): string;
41
+ /**
42
+ * Reject a selected credential reference that is not a bare environment
43
+ * variable name. The schema pattern above fails the composition layer and the
44
+ * settings write; this assert gives the load and validate paths a message that
45
+ * names the field, instead of schemastery's generic regexp complaint.
46
+ * @param raw - the configured credential reference.
47
+ */
48
+ export declare function assertApiKeyEnv(raw: string): void;
@@ -5,7 +5,8 @@
5
5
  */
6
6
  import type { GenerateOptions, ImageAttachmentAccessResolver } from '@deepseek-ai/dsh-llm';
7
7
  import type { AttachmentStore } from '@deepseek-ai/dsh-attachment';
8
- import type { Context as PiContext } from 'opencode-go-pi-ai';
8
+ import type { Context as PiContext } from '../sdk-types.ts';
9
+ import { ImagePayloadLease, type ImagePoolObserver } from './image-pool.ts';
9
10
  /** Inputs that bind deterministic request images to one current tool execution world. */
10
11
  export interface PiImageRequestContext {
11
12
  /** Durable provider that resolves request-image bytes and provider-owned host objects. */
@@ -18,6 +19,9 @@ export interface PiImageRequestContext {
18
19
  maxRequestImageBytes?: number;
19
20
  /** Route pixel and raw encoded-byte budgets. */
20
21
  requestImagePolicy?: PiImageRequestBudget;
22
+ /** Adapter-owned lease retains its charge through provider streaming. */
23
+ payloadLease?: ImagePayloadLease;
24
+ onImagePool?: ImagePoolObserver;
21
25
  }
22
26
  /** Per-route budgets from which each request image's target is derived. */
23
27
  export interface PiImageRequestBudget {
@@ -0,0 +1,24 @@
1
+ /** Shared across requests so concurrent conversations cannot multiply image work. */
2
+ export declare const IMAGE_PREPARATION_CONCURRENCY = 4;
3
+ export declare const IMAGE_PREPARATION_QUEUE_LIMIT = 32;
4
+ /** Raw prepared bytes plus base64 payloads, not a bound on native decoder RSS. */
5
+ export declare const IMAGE_PAYLOAD_BUDGET_BYTES: number;
6
+ export interface ImagePoolObservation {
7
+ queueWaitMs: number;
8
+ active: number;
9
+ queued: number;
10
+ retainedBytes: number;
11
+ rejected?: boolean;
12
+ }
13
+ export type ImagePoolObserver = (observation: ImagePoolObservation) => void;
14
+ /** Held by the adapter until an attempt ends, including streaming and fallback. */
15
+ export declare class ImagePayloadLease {
16
+ private readonly observer?;
17
+ private bytes;
18
+ private closed;
19
+ constructor(observer?: ImagePoolObserver | undefined);
20
+ reserve(bytes: number): void;
21
+ [Symbol.dispose](): void;
22
+ }
23
+ /** Keep the permit until real work settles, even if its caller stops waiting. */
24
+ export declare function withImagePermit<T>(work: () => Promise<T>, signal?: AbortSignal, observer?: ImagePoolObserver): Promise<T>;
@@ -8,7 +8,7 @@
8
8
  * @module dsh-opencode-go/conversion/replay
9
9
  */
10
10
  import type { Message, ReplayEnvelope } from '@deepseek-ai/dsh-llm';
11
- import type { Api, AssistantMessage } from 'opencode-go-pi-ai';
11
+ import type { Api, AssistantMessage } from '../sdk-types.ts';
12
12
  /** Per-block half of the pi-ai replay envelope, one entry per content block. */
13
13
  export type PiAiReplayBlock = {
14
14
  type: 'text';
@@ -8,7 +8,7 @@
8
8
  * @module dsh-opencode-go/conversion/stream
9
9
  */
10
10
  import type { FinishReason, StreamChunk, TokenUsage } from '@deepseek-ai/dsh-llm';
11
- import type { AssistantMessage, AssistantMessageEvent, Usage as PiUsage } from 'opencode-go-pi-ai';
11
+ import type { AssistantMessage, AssistantMessageEvent, Usage as PiUsage } from '../sdk-types.ts';
12
12
  /**
13
13
  * Map pi-ai usage (reasoning folded into output by pi-ai).
14
14
  * @param usage - cumulative usage from the terminal pi-ai event.
@@ -0,0 +1,22 @@
1
+ /** One SDK attempt owns its capture; simultaneous requests cannot share evidence. */
2
+ export declare class GatewayDiagnostics {
3
+ private readonly options;
4
+ private evidence;
5
+ private code;
6
+ private readonly secrets;
7
+ constructor(options: {
8
+ provider: string;
9
+ model: string;
10
+ apiKey: string;
11
+ proxyURL?: string;
12
+ fetch?: typeof globalThis.fetch;
13
+ directory?: string;
14
+ callId?: string;
15
+ attempt?: number;
16
+ onResponse?: (status: number, requestId?: string) => void;
17
+ });
18
+ private redact;
19
+ readonly fetch: typeof globalThis.fetch;
20
+ failureCode(fallback: string): Promise<string>;
21
+ failureMessage(original: string): Promise<string>;
22
+ }
@@ -0,0 +1,2 @@
1
+ /** Gateway status codes cover several domains; a 401 alone cannot reject a key. */
2
+ export declare function classifyGatewayError(status: number, body: string, fallback: string): string;
@@ -0,0 +1,11 @@
1
+ import type { Context } from '@deepseek-ai/cordis';
2
+ import type { OpencodeGoConfig } from './config-contract.ts';
3
+ import type { AccountSettingsWriter } from './settings-bridge.ts';
4
+ export declare function validateGoConfig(value: OpencodeGoConfig): void;
5
+ /** Version-specific settings attachment and validation stay at the host boundary. */
6
+ export declare function installHostSettings(ctx: Context, entry: OpencodeGoConfig, options: {
7
+ connect: (settings: AccountSettingsWriter) => () => void;
8
+ setSource: (source: () => OpencodeGoConfig) => void;
9
+ onChange: () => void;
10
+ recover: () => void;
11
+ }): void;
@@ -38,9 +38,10 @@ declare module '@deepseek-ai/cordis' {
38
38
  }
39
39
  }
40
40
  export { OpencodeGoAdapter } from './adapter.ts';
41
- export type { OpencodeGoAdapterOptions, OpencodeGoImageAccess } from './adapter.ts';
41
+ export type { OpencodeGoAdapterOptions, OpencodeGoImageAccess, GoAccountSettlement, GoCallTrace } from './adapter.ts';
42
42
  export { DEFAULT_BASE_URL, DISPLAY_NAME, PROVIDER_ID, OpencodeGoCatalog, discoverCatalogModels, readLiveModelIds, } from './catalog.ts';
43
43
  export { Config, PlainConfig, assertBaseURL } from './config.ts';
44
+ export { assertProxyURL } from './proxy-url.ts';
44
45
  export type { OpencodeGoConfig } from './config.ts';
45
46
  export declare const name = "llm-opencode-go";
46
47
  export declare const inject: string[];
@@ -3,7 +3,7 @@ export declare function transportFailure(error: unknown): string;
3
3
  /** Keep the endpoint useful in diagnostics without user information or query secrets. */
4
4
  export declare function diagnosticURL(raw: string): string;
5
5
  /** The caller's signal covers both attempts, the retry delay, and all response reads. */
6
- export declare function fetchJsonResponse(url: string, init: RequestInit, maxBytes: number, encoding?: 'identity' | 'gzip'): Promise<{
6
+ export declare function fetchJsonResponse(url: string, init: RequestInit, maxBytes: number, encoding?: 'identity' | 'gzip', fetcher?: typeof globalThis.fetch): Promise<{
7
7
  response: Response;
8
8
  body: unknown;
9
9
  }>;
@@ -1,5 +1,5 @@
1
1
  /** Convert OpenCode's online models.dev metadata into the SDK's three wire protocols. */
2
- import type { Api, Model } from 'opencode-go-pi-ai';
2
+ import type { Api, Model } from './sdk-types.ts';
3
3
  import { type GoModel } from './models-contract.ts';
4
4
  export declare const MODEL_METADATA_URL = "https://models.dev/api.json";
5
5
  /** Lifecycle and capability data the online catalog adds to a gateway listing. */
@@ -11,6 +11,8 @@ export interface ModelMetadata {
11
11
  }
12
12
  /** Anthropic's SDK appends /v1/messages; the OpenAI SDKs append paths below /v1. */
13
13
  export declare function modelBaseURL(api: Api, baseURL: string): string;
14
+ /** Shared Responses defaults for declared models and explicit protocol overrides. */
15
+ export declare function responsesCompatibility(): NonNullable<Model<'openai-responses'>['compat']>;
14
16
  /**
15
17
  * Only read the opencode-go record. Online endpoints, headers and credentials
16
18
  * are deliberately ignored: model traffic always stays on the configured gateway.
@@ -5,6 +5,8 @@ export interface GoModel {
5
5
  name?: string;
6
6
  contextWindow?: number;
7
7
  maxTokens?: number;
8
+ /** Token budget controls available to this model, including their catalog bounds. */
9
+ reasoningBudget?: ThinkingBudgetRange;
8
10
  deprecated?: boolean;
9
11
  releaseDate?: string;
10
12
  /** Input modalities models.dev declares, in {@link INPUT_MODALITIES} order. */
@@ -12,6 +14,10 @@ export interface GoModel {
12
14
  /** Advertised by the gateway but lacking a usable protocol and capability configuration. */
13
15
  configurationMissing?: boolean;
14
16
  }
17
+ export interface ThinkingBudgetRange {
18
+ min: number;
19
+ max: number;
20
+ }
15
21
  /**
16
22
  * Input modalities this page can name. models.dev uses these same five tokens, so
17
23
  * an unknown token is dropped rather than rendered as an untranslatable chip.
@@ -29,6 +35,7 @@ export declare function normalizeInputModalities(value: unknown): readonly Input
29
35
  export interface GoCatalogSourceStatus {
30
36
  readonly updatedAt?: number;
31
37
  readonly error?: string;
38
+ readonly warning?: string;
32
39
  }
33
40
  /** A failed refresh retains the Host's usable data with an explicit diagnostic. */
34
41
  export interface GoModelCatalog {
@@ -0,0 +1,5 @@
1
+ /** The supported experimental override surface, shared with the settings UI. */
2
+ export declare const RESPONSES_OVERRIDE_MODEL = "deepseek-v4.1-flash";
3
+ export type GoProtocolOverrides = Partial<Record<typeof RESPONSES_OVERRIDE_MODEL, 'openai-responses' | null>>;
4
+ /** Null selects catalog routing even when a lower settings layer overrides it. */
5
+ export declare function assertProtocolOverrides(value: unknown): asserts value is GoProtocolOverrides | undefined;
@@ -0,0 +1,4 @@
1
+ import type { Api, Model } from './sdk-types.ts';
2
+ import type { OpencodeGoConfig } from './config-contract.ts';
3
+ /** Resolve a request's wire model without mutating the shared metadata catalog. */
4
+ export declare function withProtocolOverride(model: Model<Api>, config: OpencodeGoConfig): Model<Api>;
@@ -0,0 +1,2 @@
1
+ /** Shared by Host validation and the browser form; never echo proxy credentials. */
2
+ export declare function assertProxyURL(raw: string | undefined): string;
@@ -0,0 +1,11 @@
1
+ /** Per-mount transport. Fetch closures retain their address across settings changes. */
2
+ export declare class ProxyTransport {
3
+ private current;
4
+ private readonly retired;
5
+ private disposed;
6
+ forProxy(raw?: string): typeof globalThis.fetch | undefined;
7
+ /** Close replaced pools after their in-flight response bodies have finished. */
8
+ private retire;
9
+ /** Unloading the mount cancels remaining requests and releases every pool. */
10
+ dispose(): Promise<void>;
11
+ }
@@ -1,10 +1,40 @@
1
- /** Gateway reasoning controls shared by live metadata, fallbacks and requests. */
2
- import type { Api, Model, ModelThinkingLevel, ThinkingLevelMap } from 'opencode-go-pi-ai';
1
+ import type { Api, Model, ModelThinkingLevel, ThinkingBudgets, ThinkingLevelMap } from './sdk-types.ts';
2
+ import type { ThinkingBudgetRange } from './models-contract.ts';
3
3
  export declare const THINKING_LEVELS: readonly ModelThinkingLevel[];
4
- /** Formats that explicitly disable thinking when no SDK effort is supplied. */
4
+ /** Protocol formats whose switch/budget is understood by pi-ai. */
5
5
  export declare const NATIVE_THINKING_FLAGS: ReadonlySet<string>;
6
+ /** Expose budgets only when the SDK knows where to serialize a numeric limit. */
7
+ export declare function supportsThinkingBudget(api: Api, compat: Model<Api>['compat']): boolean;
8
+ export declare function reasoningBudgetRange(model: Model<Api>): ThinkingBudgetRange | undefined;
6
9
  export declare function unsupportedThinkingLevels(): ThinkingLevelMap;
7
- /** Exact model/protocol rules verified against OpenCode Go, never inherited by a family. */
10
+ /** Exact model/protocol controls verified against OpenCode Go. */
8
11
  export declare function withGatewayReasoning(model: Model<Api>): Model<Api>;
9
- /** An unset OpenAI effort preserves the provider default; explicit Off retains its wire value. */
10
- export declare function withRequestReasoning(model: Model<Api>, level: ModelThinkingLevel | undefined): Model<Api>;
12
+ export declare function reasoningChoices(model: Model<Api>): readonly {
13
+ id: string;
14
+ name: string;
15
+ }[];
16
+ export type ReasoningIntent = {
17
+ kind: 'default';
18
+ } | {
19
+ kind: 'off';
20
+ } | {
21
+ kind: 'on';
22
+ } | {
23
+ kind: 'effort';
24
+ level: Exclude<ModelThinkingLevel, 'off'>;
25
+ } | {
26
+ kind: 'budget';
27
+ tokens: number;
28
+ min: number;
29
+ };
30
+ /** Called after validation against the model's choices. */
31
+ export declare function reasoningIntent(model: Model<Api>, level: string | undefined): ReasoningIntent;
32
+ /**
33
+ * The SDK serializes explicit choices. Default must leave all thinking controls
34
+ * to the service; a switch's On must not acquire an invented effort spelling.
35
+ */
36
+ export declare function reasoningRequest(intent: ReasoningIntent): {
37
+ reasoning?: Exclude<ModelThinkingLevel, 'off'>;
38
+ thinkingBudgets?: ThinkingBudgets;
39
+ onPayload: (payload: unknown) => unknown;
40
+ };
@@ -0,0 +1,2 @@
1
+ /** Cancel a wait even when an external service does not observe its signal. */
2
+ export declare function waitWithSignal<T>(work: () => PromiseLike<T>, signal?: AbortSignal): Promise<T>;