dsh-opencode-go 0.1.21 → 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 (48) hide show
  1. package/README.en.md +128 -167
  2. package/README.md +126 -158
  3. package/THIRD_PARTY_NOTICES.md +3 -1
  4. package/docs/development.md +56 -6
  5. package/docs/fork-review-2026-09-25.md +191 -0
  6. package/docs/independent-package.md +2 -2
  7. package/docs/verification.md +154 -0
  8. package/lib/build-info.json +8 -1
  9. package/lib/client.js +412 -262
  10. package/lib/index.js +6763 -428
  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 +5 -0
  19. package/lib/types/adapter.d.ts +30 -10
  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 +5 -3
  23. package/lib/types/client/accounts-controller.d.ts +6 -17
  24. package/lib/types/client/host-compat.d.ts +7 -0
  25. package/lib/types/client/locales.d.ts +9 -0
  26. package/lib/types/client/section-controller.d.ts +11 -46
  27. package/lib/types/client/staged-form.d.ts +1 -3
  28. package/lib/types/client/usage.d.ts +1 -1
  29. package/lib/types/config-contract.d.ts +69 -0
  30. package/lib/types/config.d.ts +12 -53
  31. package/lib/types/conversion/context.d.ts +5 -1
  32. package/lib/types/conversion/image-pool.d.ts +24 -0
  33. package/lib/types/conversion/replay.d.ts +1 -1
  34. package/lib/types/conversion/stream.d.ts +1 -1
  35. package/lib/types/gateway-diagnostics.d.ts +22 -0
  36. package/lib/types/gateway-error.d.ts +2 -0
  37. package/lib/types/host-settings.d.ts +11 -0
  38. package/lib/types/index.d.ts +1 -1
  39. package/lib/types/model-metadata.d.ts +3 -1
  40. package/lib/types/models-contract.d.ts +7 -0
  41. package/lib/types/protocol-contract.d.ts +5 -0
  42. package/lib/types/protocol-policy.d.ts +4 -0
  43. package/lib/types/reasoning.d.ts +36 -6
  44. package/lib/types/request-control.d.ts +2 -0
  45. package/lib/types/sdk-types.d.ts +1568 -0
  46. package/lib/types/settings-bridge.d.ts +22 -0
  47. package/lib/vendor-licenses.txt +103 -0
  48. package/package.json +6 -2
@@ -0,0 +1,23 @@
1
+ import { type CredentialProvider } from '@deepseek-ai/dsh-credentials';
2
+ import { type AccountSettingsWriter, type SettingsWriteResult } from './settings-bridge.ts';
3
+ import { type AccountCommand } from './accounts-contract.ts';
4
+ export declare const ACCOUNT_RECOVERY_TIMEOUT_MS = 30000;
5
+ /** Serialize account commands and recover the same durable operations for one profile. */
6
+ export declare class GoAccountManager {
7
+ private readonly logger;
8
+ private connection;
9
+ private pending;
10
+ private again;
11
+ private queue;
12
+ constructor(logger: {
13
+ warn(message: string): void;
14
+ });
15
+ connect(settings: AccountSettingsWriter, credentials: Pick<CredentialProvider, 'describe' | 'unset'> & Partial<Pick<CredentialProvider, 'set'>>): () => void;
16
+ trigger(): void;
17
+ recover(): Promise<void>;
18
+ private row;
19
+ private run;
20
+ private complete;
21
+ private enqueue;
22
+ execute(raw: AccountCommand): Promise<SettingsWriteResult>;
23
+ }
@@ -0,0 +1,31 @@
1
+ /** Durable, client-safe intentions. Never put a credential value in this document. */
2
+ import { type AccountSettings, type GoAccount } from './accounts.ts';
3
+ export type GoAccountOperation = {
4
+ id: string;
5
+ kind: 'add';
6
+ account: GoAccount;
7
+ previousRef: string;
8
+ select: boolean;
9
+ } | {
10
+ id: string;
11
+ kind: 'remove';
12
+ account: GoAccount;
13
+ };
14
+ export declare function ownsAccountCredential(account: GoAccount): boolean;
15
+ export declare function assertAccountOperations(value: readonly GoAccountOperation[] | undefined): void;
16
+ /** Pending additions remain visible so a lost key write can be repaired or removed. */
17
+ export declare function visibleAccountsOf(settings: AccountSettings): readonly GoAccount[];
18
+ /** The same transition completes a foreground operation or a recovered intention. */
19
+ export declare function accountOperationPatch(settings: AccountSettings, operation: GoAccountOperation, dropLegacyRef?: string): ({
20
+ op: "set";
21
+ path: string[];
22
+ value: GoAccount[];
23
+ } | {
24
+ op: "set";
25
+ path: string[];
26
+ value: string;
27
+ } | {
28
+ op: "set";
29
+ path: string[];
30
+ value: GoAccountOperation[];
31
+ })[];
@@ -0,0 +1,16 @@
1
+ import type { GoAccountSwitch } from './accounts.ts';
2
+ export interface AttemptOutcome {
3
+ failure?: {
4
+ code: string;
5
+ };
6
+ emitted: boolean;
7
+ totalTokens: number;
8
+ aborted: boolean;
9
+ hasNext: boolean;
10
+ }
11
+ /** Switching accounts must never replay output or already charged work. */
12
+ export declare function accountFallback(outcome: AttemptOutcome): GoAccountSwitch['reason'] | undefined;
13
+ /** Missing local credentials and exhausted quota do not blacklist a gateway key. */
14
+ export declare function isGatewayKeyRejection(failure: {
15
+ code: string;
16
+ }): boolean;
@@ -0,0 +1,2 @@
1
+ /** Backward-compatible name for the host's shared foreground/recovery executor. */
2
+ export { GoAccountManager as GoAccountRecovery, ACCOUNT_RECOVERY_TIMEOUT_MS } from './account-manager.ts';
@@ -0,0 +1,30 @@
1
+ import type { GoAccountSettlement } from './adapter.ts';
2
+ import { type GoAccountSwitch } from './accounts.ts';
3
+ import type { OpencodeGoConfig } from './config.ts';
4
+ import { type AccountSettingsWriter } from './settings-bridge.ts';
5
+ export type { AccountSettingsWriter } from './settings-bridge.ts';
6
+ /** Owns both the fallback notice and its optional persisted account selection. */
7
+ export declare class GoAccountSelection {
8
+ private readonly config;
9
+ private readonly logger;
10
+ private settings;
11
+ private connection;
12
+ private credentials;
13
+ private version;
14
+ private signature;
15
+ private latestSeq;
16
+ private notice;
17
+ constructor(config: () => OpencodeGoConfig, logger: {
18
+ debug(message: string): void;
19
+ warn(message: string): void;
20
+ });
21
+ connect(settings: AccountSettingsWriter): () => void;
22
+ private row;
23
+ /** Reading the revision also catches A → C → A before async change watchers run. */
24
+ capture(): number;
25
+ credentialChanged(): void;
26
+ lastSwitch(): GoAccountSwitch | undefined;
27
+ /** One freshness decision governs both side effects of a request's outcome. */
28
+ settle(event: GoAccountSettlement): void;
29
+ private adopt;
30
+ }
@@ -0,0 +1,12 @@
1
+ import type { Context } from '@deepseek-ai/cordis';
2
+ import { TypertRemoteService } from '@deepseek-ai/dsh-typert-protocol';
3
+ import type { AccountCommand } from './accounts-contract.ts';
4
+ import type { GoAccountManager } from './account-manager.ts';
5
+ /** The browser sends commands; the host owns credentials, revisions and recovery. */
6
+ export declare class GoAccountsService extends TypertRemoteService {
7
+ private readonly options;
8
+ constructor(ctx: Context, options: {
9
+ manager: GoAccountManager;
10
+ });
11
+ execute(command: AccountCommand): Promise<import("./settings-bridge.ts").SettingsWriteResult>;
12
+ }
@@ -0,0 +1,38 @@
1
+ import type { RemoteResult, TypertRemoteContribution } from '@deepseek-ai/dsh-typert-protocol';
2
+ import type { SettingsWriteResult } from './settings-bridge.ts';
3
+ export type AccountCommand = {
4
+ kind: 'add';
5
+ id: string;
6
+ name: string;
7
+ key: string;
8
+ } | {
9
+ kind: 'remove';
10
+ ref: string;
11
+ } | {
12
+ kind: 'select';
13
+ ref: string;
14
+ } | {
15
+ kind: 'rename';
16
+ ref: string;
17
+ name: string;
18
+ } | {
19
+ kind: 'replace-key';
20
+ ref: string;
21
+ key: string;
22
+ } | {
23
+ kind: 'move';
24
+ ref: string;
25
+ toIndex: number;
26
+ } | {
27
+ kind: 'auto-switch';
28
+ value: boolean;
29
+ };
30
+ export declare function parseAccountCommand(value: unknown): AccountCommand;
31
+ declare module '@deepseek-ai/dsh-typert-protocol' {
32
+ interface TypertRemoteNamespaceMap {
33
+ opencodeGoAccounts: {
34
+ execute(command: AccountCommand): Promise<RemoteResult<SettingsWriteResult>>;
35
+ };
36
+ }
37
+ }
38
+ export declare const accountsRemote: TypertRemoteContribution;
@@ -1,4 +1,5 @@
1
1
  /** Client-safe account metadata. Secrets stay in the host credential service. */
2
+ import type { GoAccountOperation } from './account-operations.ts';
2
3
  export type GoAccount = {
3
4
  id: string;
4
5
  name: string;
@@ -7,11 +8,15 @@ export type GoAccount = {
7
8
  export declare const MAX_ACCOUNTS = 20;
8
9
  export declare const ACCOUNT_REF_PREFIX = "DSH_OPENCODE_GO_ACCOUNT_";
9
10
  export declare const DEFAULT_ACCOUNT_REF = "OPENCODE_API_KEY";
11
+ /** A credential reference is a bare environment variable name, never empty or decorated. */
12
+ export declare const ACCOUNT_REF_PATTERN: RegExp;
10
13
  export interface AccountSettings {
11
14
  apiKeyEnv?: string;
12
15
  /** Omission/null preserves legacy credentials; an explicit empty list removes all accounts. */
13
16
  accounts?: readonly GoAccount[] | null;
14
17
  autoSwitch?: boolean;
18
+ /** Recovery intentions owned by this exact settings/profile document. */
19
+ accountOperations?: readonly GoAccountOperation[];
15
20
  }
16
21
  export declare function accountRefOf(settings: AccountSettings): string;
17
22
  /** Include an externally selected reference without rewriting existing configuration. */
@@ -28,6 +28,8 @@ import { OpencodeGoCatalog } from './catalog.ts';
28
28
  import { ProxyTransport } from './proxy.ts';
29
29
  import type { OpencodeGoConfig } from './config.ts';
30
30
  import { type GoAccountSwitch } from './accounts.ts';
31
+ import { type GoCallTrace } from './call-trace.ts';
32
+ export type { GoCallTrace } from './call-trace.ts';
31
33
  /**
32
34
  * The attachment-service bridges one image request reads. Construction-time
33
35
  * (context-dependent); the config-dependent policy numbers are merged per
@@ -39,10 +41,22 @@ export interface OpencodeGoImageAccess {
39
41
  /** Bridge one attachment reference into the current model-tool execution world. */
40
42
  resolveImageAccess: (attachments: AttachmentStore, ref: ImageAttachmentRef) => ImageAttachmentAccess | undefined;
41
43
  }
44
+ /** One request's serving account, with the identity captured before discovery. */
45
+ export interface GoAccountSettlement {
46
+ seq: number;
47
+ generation: number;
48
+ config: OpencodeGoConfig;
49
+ ref: string;
50
+ notice?: GoAccountSwitch;
51
+ }
42
52
  /** Constructor inputs for {@link OpencodeGoAdapter}. */
43
53
  export interface OpencodeGoAdapterOptions {
44
54
  /** Shared with Host usage reads for this plugin mount. */
45
55
  transport?: ProxyTransport;
56
+ /** Mount-owned discovery; direct construction supplies its own manager. */
57
+ catalog?: (config: OpencodeGoConfig) => OpencodeGoCatalog;
58
+ /** Optional directory for bounded HTTP error evidence; request contents are omitted. */
59
+ debugDirectory?: () => string | undefined;
46
60
  /**
47
61
  * The current configuration, re-read at every operation: a settings write
48
62
  * reaches the next request without a restart, and one operation never mixes
@@ -50,7 +64,9 @@ export interface OpencodeGoAdapterOptions {
50
64
  */
51
65
  config: () => OpencodeGoConfig;
52
66
  /** Resolve the credential reference captured with this call's endpoint; missing must fail loud. */
53
- resolveApiKey: (config: OpencodeGoConfig) => Promise<string | undefined>;
67
+ resolveApiKey: (config: OpencodeGoConfig, signal?: AbortSignal) => Promise<string | undefined>;
68
+ /** Observe one bounded, content-free summary for every dispatched call. */
69
+ onCallTrace?: (trace: GoCallTrace) => void;
54
70
  /**
55
71
  * Image input machinery; absent refuses image content, which is the posture
56
72
  * for direct construction without a durable attachment service behind it.
@@ -64,11 +80,17 @@ export interface OpencodeGoAdapterOptions {
64
80
  }) => void;
65
81
  /** Observe live ids the curated table cannot route. */
66
82
  onOmitted?: (ids: readonly string[]) => void;
83
+ onCatalogWarning?: (warning: string) => void;
67
84
  /** Observe assistant history degrading to provider-neutral conversion. */
68
85
  onReplayDegrade?: (reason: string) => void;
69
86
  /** Re-read picker models after a background catalog refresh commits. */
70
87
  onCatalogRefresh?: () => void;
71
- onAccountSwitch?: (notice: GoAccountSwitch | undefined, config: OpencodeGoConfig) => void;
88
+ /** Host account-state version, captured before asynchronous model discovery. */
89
+ accountGeneration?: () => number;
90
+ /** One outcome for both the displayed notice and the persisted selection. */
91
+ onAccountSettled?: (event: GoAccountSettlement) => void;
92
+ /** Legacy notice observer. Hosts that persist selection should use onAccountSettled. */
93
+ onAccountSwitch?: (notice: GoAccountSwitch | undefined, config: OpencodeGoConfig, seq: number) => void;
72
94
  }
73
95
  /**
74
96
  * The single route's adapter. The catalog snapshot freezes at each operation,
@@ -77,16 +99,12 @@ export interface OpencodeGoAdapterOptions {
77
99
  */
78
100
  export declare class OpencodeGoAdapter extends LlmAdapter {
79
101
  private readonly options;
80
- /**
81
- * One catalog instance per endpoint/refresh pair. A settings write that
82
- * changes either gets a fresh resolver (and a fresh live-listing fetch) on
83
- * the next operation; an unchanged configuration keeps its cached snapshot
84
- * for the whole refresh interval.
85
- */
86
- private catalogCache;
102
+ private readonly resolveCatalog;
87
103
  private readonly transport;
88
104
  /** Per-reference rejection deadlines, isolated by the gateway that rejected it. */
89
105
  private readonly rejectedKeys;
106
+ /** Monotonic sequence of the latest request this adapter started. */
107
+ private callSeq;
90
108
  constructor(options: OpencodeGoAdapterOptions);
91
109
  dispose(): Promise<void>;
92
110
  /**
@@ -103,7 +121,7 @@ export declare class OpencodeGoAdapter extends LlmAdapter {
103
121
  };
104
122
  listModels(_provider: string): Promise<readonly LlmModelInfo[]>;
105
123
  resolveModel(_provider: string, model: string, signal?: AbortSignal): Promise<LlmResolvedModelInfo>;
106
- /** Copy nested limits before discovery can yield to a settings update. */
124
+ /** Capture limits and protocol before discovery can yield to a settings update. */
107
125
  private callSnapshot;
108
126
  /** Keep capability resolution and eventual dispatch on the same configuration. */
109
127
  prepareCall(_provider: string, model: string, signal?: AbortSignal): Promise<{
@@ -116,6 +134,8 @@ export declare class OpencodeGoAdapter extends LlmAdapter {
116
134
  private resolveReasoningLevel;
117
135
  stream(options: GenerateOptions): AsyncIterable<StreamChunk>;
118
136
  private streamWithSnapshot;
137
+ private dispatch;
138
+ private streamAccounts;
119
139
  private rememberRejectedKey;
120
140
  /** A stored change to a reference outranks the gateway's last rejection of it. */
121
141
  forgetRejectedKey(ref: string): void;
@@ -0,0 +1,54 @@
1
+ import type { ImagePoolObservation } from './conversion/image-pool.ts';
2
+ type Outcome = 'completed' | 'failed' | 'aborted' | 'consumer-stopped';
3
+ type Stages = Partial<Record<'discovery' | 'credential' | 'images' | 'stream', number>>;
4
+ export interface GoAttemptTrace {
5
+ attempt: number;
6
+ elapsedMs: number;
7
+ stages: Stages;
8
+ outcome: Outcome;
9
+ code?: string;
10
+ httpStatus?: number;
11
+ requestId?: string;
12
+ /** First text, reasoning or tool argument delta, measured from attempt start. */
13
+ firstOutputMs?: number;
14
+ imagePool?: {
15
+ queueWaitMs: number;
16
+ maxActive: number;
17
+ maxQueued: number;
18
+ maxRetainedBytes: number;
19
+ rejected: boolean;
20
+ };
21
+ }
22
+ /** Safe per-call diagnostics: no transcript, credential, URL or raw session id. */
23
+ export interface GoCallTrace {
24
+ callId: string;
25
+ model: string;
26
+ elapsedMs: number;
27
+ stages: Stages;
28
+ attempts: number;
29
+ attemptDetails: readonly GoAttemptTrace[];
30
+ outcome: Outcome;
31
+ code?: string;
32
+ }
33
+ export declare class CallTrace {
34
+ private readonly model;
35
+ private readonly observer?;
36
+ private readonly started;
37
+ readonly callId: `${string}-${string}-${string}-${string}-${string}`;
38
+ readonly stages: GoCallTrace['stages'];
39
+ attempts: number;
40
+ outcome: GoCallTrace['outcome'];
41
+ code: string | undefined;
42
+ private readonly details;
43
+ private current;
44
+ private finished;
45
+ constructor(model: string, observer?: ((trace: GoCallTrace) => void) | undefined);
46
+ startAttempt(): void;
47
+ response(status: number, requestId?: string): void;
48
+ firstOutput(): void;
49
+ imagePool: (value: ImagePoolObservation) => void;
50
+ endAttempt(outcome?: Outcome, code?: string): void;
51
+ measure<T>(stage: keyof GoCallTrace['stages'], work: () => Promise<T>): Promise<T>;
52
+ finish(): void;
53
+ }
54
+ export {};
@@ -0,0 +1,20 @@
1
+ import { OpencodeGoCatalog } from './catalog.ts';
2
+ import type { OpencodeGoConfig } from './config-contract.ts';
3
+ import type { ProxyTransport } from './proxy.ts';
4
+ /** One mount owns discovery; inference, settings and pickers share its snapshots. */
5
+ export declare class GoCatalogManager {
6
+ private readonly options;
7
+ private current;
8
+ constructor(options: {
9
+ transport: ProxyTransport;
10
+ onFallback?: (detail: {
11
+ url: string;
12
+ error: unknown;
13
+ kept: number;
14
+ }) => void;
15
+ onOmitted?: (ids: readonly string[]) => void;
16
+ onRefresh?: () => void;
17
+ onWarning?: (warning: string) => void;
18
+ });
19
+ forConfig(config: OpencodeGoConfig): OpencodeGoCatalog;
20
+ }
@@ -1,4 +1,4 @@
1
- import type { Api, Model, Provider } from 'opencode-go-pi-ai';
1
+ import type { Api, Model, Provider } from './sdk-types.ts';
2
2
  import type { LlmDiscoveredModel } from '@deepseek-ai/dsh-llm';
3
3
  import { type GoModelCatalog } from './models-contract.ts';
4
4
  import type { ModelMetadata } from './model-metadata.ts';
@@ -14,6 +14,7 @@ export interface CatalogSnapshot {
14
14
  readonly metadataLive: boolean;
15
15
  /** Retained for explicit discovery; runtime callers may still use the last catalog. */
16
16
  readonly listingFailure?: unknown;
17
+ readonly listingWarning?: string;
17
18
  readonly metadataFailure?: unknown;
18
19
  /** Last successful fetch or revalidation, not the time of a failed attempt. */
19
20
  readonly listingUpdatedAtMs?: number;
@@ -21,7 +22,7 @@ export interface CatalogSnapshot {
21
22
  readonly fetchedAtMs: number;
22
23
  }
23
24
  /** A valid empty listing means the gateway serves nothing; malformed replies are failures. */
24
- export declare function readLiveModelIds(body: unknown): readonly string[];
25
+ export declare function readLiveModelIds(body: unknown, onInvalidRows?: (warning: string) => void): readonly string[];
25
26
  /** Runtime requests reuse a snapshot; discovery revalidates it. Concurrent reads coalesce. */
26
27
  export declare class OpencodeGoCatalog {
27
28
  private readonly baseURL;
@@ -31,6 +32,7 @@ export declare class OpencodeGoCatalog {
31
32
  private readonly onOmitted;
32
33
  private readonly onRefresh;
33
34
  private readonly fetcher?;
35
+ private readonly onWarning?;
34
36
  private served;
35
37
  private pending;
36
38
  /** A cold runtime read can use disk metadata while the shared online refresh runs. */
@@ -49,7 +51,7 @@ export declare class OpencodeGoCatalog {
49
51
  kept: number;
50
52
  }) => void,
51
53
  /** Kept for API compatibility; now reports unconfigured ids rather than hiding them. */
52
- onOmitted: (ids: readonly string[]) => void, onRefresh?: () => void, fetcher?: typeof globalThis.fetch | undefined);
54
+ onOmitted: (ids: readonly string[]) => void, onRefresh?: () => void, fetcher?: typeof globalThis.fetch | undefined, onWarning?: ((warning: string) => void) | undefined);
53
55
  snapshot(force?: boolean, signal?: AbortSignal): Promise<CatalogSnapshot>;
54
56
  private restoreMetadata;
55
57
  private readSnapshot;
@@ -2,6 +2,9 @@ import type { Context } from '@deepseek-ai/cordis';
2
2
  import { type AccountSettings, type GoAccount } from '../accounts.ts';
3
3
  import type { GoUsage } from '../usage-contract.ts';
4
4
  import type { SettingsScope } from './settings.ts';
5
+ import type { AccountCommand } from '../accounts-contract.ts';
6
+ import type { SettingsWriteResult } from '../settings-bridge.ts';
7
+ export type ExecuteAccountCommand = (command: AccountCommand) => Promise<SettingsWriteResult>;
5
8
  export interface GoAccountView extends GoAccount {
6
9
  configured?: boolean;
7
10
  writable?: boolean;
@@ -40,6 +43,7 @@ export declare class GoAccountsController {
40
43
  private readonly readUsage;
41
44
  private readonly publish;
42
45
  private readonly blocked;
46
+ private readonly execute;
43
47
  private rows;
44
48
  private busy;
45
49
  private refreshing;
@@ -48,10 +52,11 @@ export declare class GoAccountsController {
48
52
  private identity;
49
53
  private loaded;
50
54
  private disposed;
55
+ private addition;
51
56
  constructor(scope: SettingsScope<AccountSettings & {
52
57
  baseURL?: string;
53
58
  proxyURL?: string;
54
- }>, ctx: Context, readUsage: (ref: string) => Promise<GoUsage>, publish: () => void, blocked: () => boolean);
59
+ }>, ctx: Context, readUsage: (ref: string) => Promise<GoUsage>, publish: () => void, blocked: () => boolean, execute?: ExecuteAccountCommand);
55
60
  snapshot(): GoAccountsState;
56
61
  sync(): void;
57
62
  dispose(): void;
@@ -60,21 +65,5 @@ export declare class GoAccountsController {
60
65
  /** Mark every account row as unreadable with the Host's own diagnostic. */
61
66
  private markUnreadable;
62
67
  actions(): GoAccountsActions;
63
- /**
64
- * Reorder the visible accounts and keep the preferred reference on the first row.
65
- * The adapter tries the preferred reference first and the rest in array order, so
66
- * one write is what makes top-to-bottom the real call order. A placeholder row the
67
- * settings never stored is materialized here, which its `legacy:` id admits.
68
- */
69
- private move;
70
- private account;
71
- private mutate;
72
- private add;
73
- /** Loaded rows answer from cache; anything they do not know is described on
74
- * the spot, so a placeholder decision never races the page's first describe. */
75
- private configuredOf;
76
- private rename;
77
- private select;
78
- private remove;
79
68
  private run;
80
69
  }
@@ -0,0 +1,7 @@
1
+ import type { Context } from '@deepseek-ai/cordis';
2
+ import { type OpencodeGoSettings } from '../config-contract.ts';
3
+ import type { SettingsScope } from './settings.ts';
4
+ import type { ExecuteAccountCommand } from './accounts-controller.ts';
5
+ /** Only the boundary knows whether the host exposes profile forms or legacy scopes. */
6
+ export declare function mountSettingsScopes(ctx: Context, mount: (ctx: Context, scope: SettingsScope<OpencodeGoSettings>) => void): void;
7
+ export declare function accountCommands(ctx: Context): ExecuteAccountCommand;
@@ -96,6 +96,11 @@ export declare const en: {
96
96
  limitsModel: string;
97
97
  limitsContext: string;
98
98
  limitsOutput: string;
99
+ thinkingBudgets: string;
100
+ thinkingBudgetsHint: string;
101
+ thinkingBudgetAddLabel: string;
102
+ thinkingBudgetAdd: string;
103
+ thinkingBudgetRemove: string;
99
104
  capacityDefault: string;
100
105
  capacityMissing: string;
101
106
  modalityLabel: string;
@@ -139,6 +144,10 @@ export declare const en: {
139
144
  usageDisplay_auto: string;
140
145
  usageDisplay_always: string;
141
146
  usageDisplay_off: string;
147
+ protocolOverridesLabel: string;
148
+ protocolOverridesHint: string;
149
+ protocolOverridesAuto: string;
150
+ protocolOverridesResponses: string;
142
151
  apiKeyEnvLabel: string;
143
152
  apiKeyEnvHint: string;
144
153
  baseURLLabel: string;
@@ -4,58 +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';
17
- import type { GoAccount } from '../accounts.ts';
18
- import { type GoAccountsState, type GoAccountsActions } from './accounts-controller.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';
19
19
  import { type FieldState, type FormActions, type FormShell } from './staged-form.ts';
20
- /** 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. */
21
21
  export declare const OPENCODE_GO_NS = "llm-opencode-go";
22
- /** The adapter fields this page edits. */
23
- export interface OpencodeGoSettings {
24
- /** Whether the adapter serves its route; false withdraws it from every picker. */
25
- enabled?: boolean;
26
- /** Usage pill visibility, independent of the selected model in always mode. */
27
- usageDisplay?: UsageDisplayMode;
28
- /** Per-model switches; normal models default on, deprecated models default off. */
29
- modelVisibility?: Record<string, boolean>;
30
- /** Credential reference naming the environment key. */
31
- apiKeyEnv?: string;
32
- accounts?: GoAccount[] | null;
33
- autoSwitch?: boolean;
34
- /** The gateway endpoint; also the live listing base. */
35
- baseURL?: string;
36
- /** Optional network proxy used by the Host. */
37
- proxyURL?: string;
38
- /** Live catalog re-resolution interval, in minutes. */
39
- refreshMinutes?: number;
40
- /** Largest idle gap between stream events, in milliseconds. */
41
- streamIdleTimeoutMs?: number;
42
- /** Optional retained image occurrence cap per request. */
43
- maxImages?: number | null;
44
- /** Accumulated base64 image payload bound for one request. */
45
- maxRequestImageBytes?: number;
46
- /** Total-pixel budget for one request image. */
47
- requestImagePixelBudget?: number;
48
- /** Raw encoded-byte target for one request image. */
49
- requestImageMaxBytes?: number;
50
- /** Per-model capacity overrides, keyed by the gateway model id. */
51
- modelLimits?: OpencodeGoModelLimits;
52
- }
53
- /** The two capacity values the settings table can override. */
54
- export interface OpencodeGoModelLimit {
55
- contextWindow?: number | null;
56
- maxTokens?: number | null;
57
- }
58
- export type OpencodeGoModelLimits = Record<string, OpencodeGoModelLimit | null>;
59
22
  /** The gateway's model listing as the page reports it. */
60
23
  export type OpencodeGoModels =
61
24
  /** Not asked for yet; the page asks once it mounts. */
@@ -96,6 +59,7 @@ export interface OpencodeGoSectionState extends FormShell {
96
59
  */
97
60
  enabled: boolean;
98
61
  usageDisplay: FieldState;
62
+ protocolOverrides: FieldState;
99
63
  modelVisibility: Readonly<Record<string, boolean>>;
100
64
  pickerSaving: boolean;
101
65
  pickerFailed: boolean;
@@ -149,6 +113,7 @@ export declare class OpencodeGoSectionController {
149
113
  private readonly scope;
150
114
  private readonly ctx;
151
115
  private readonly readModels;
116
+ private readonly executeAccountCommand;
152
117
  private readonly form;
153
118
  private readonly store;
154
119
  private credential;
@@ -166,7 +131,7 @@ export declare class OpencodeGoSectionController {
166
131
  * @param ctx - the page plugin's context, whose `remote.credentials` namespace
167
132
  * answers for the credential the section references.
168
133
  */
169
- constructor(scope: SettingsScope<OpencodeGoSettings>, ctx: ClientContext, readModels?: () => Promise<RemoteResult<GoModelCatalog>>, readUsage?: (ref: string) => Promise<import('../usage-contract.ts').GoUsage>);
134
+ constructor(scope: SettingsScope<OpencodeGoSettings>, ctx: ClientContext, readModels?: () => Promise<RemoteResult<GoModelCatalog>>, readUsage?: (ref: string) => Promise<import('../usage-contract.ts').GoUsage>, executeAccountCommand?: ExecuteAccountCommand);
170
135
  /** Release subscriptions without disposing the host's shared form. */
171
136
  dispose(): void;
172
137
  private projection;
@@ -231,9 +196,9 @@ export declare class OpencodeGoSectionController {
231
196
  */
232
197
  inject(): OpencodeGoSectionFace;
233
198
  /**
234
- * 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.
235
200
  * @param value - the staged credential literal.
236
- * @returns whether the Host reports a configured credential afterwards.
201
+ * @returns whether the Host confirmed the write.
237
202
  */
238
203
  private writeKey;
239
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;