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.
- package/README.en.md +133 -127
- package/README.md +131 -127
- package/THIRD_PARTY_NOTICES.md +3 -1
- package/docs/development.md +60 -8
- package/docs/fork-review-2026-09-25.md +191 -0
- package/docs/independent-package.md +2 -2
- package/docs/verification.md +241 -0
- package/lib/build-info.json +8 -1
- package/lib/client.js +1576 -234
- package/lib/index.js +7001 -338
- package/lib/types/account-manager.d.ts +23 -0
- package/lib/types/account-operations.d.ts +31 -0
- package/lib/types/account-policy.d.ts +16 -0
- package/lib/types/account-recovery.d.ts +2 -0
- package/lib/types/account-selection.d.ts +30 -0
- package/lib/types/account-service.d.ts +12 -0
- package/lib/types/accounts-contract.d.ts +38 -0
- package/lib/types/accounts.d.ts +31 -0
- package/lib/types/adapter.d.ts +43 -9
- package/lib/types/call-trace.d.ts +54 -0
- package/lib/types/catalog-manager.d.ts +20 -0
- package/lib/types/catalog.d.ts +6 -3
- package/lib/types/client/AccountsCard.d.ts +19 -0
- package/lib/types/client/Section.d.ts +3 -6
- package/lib/types/client/UsagePill.d.ts +4 -2
- package/lib/types/client/accounts-controller.d.ts +69 -0
- package/lib/types/client/host-compat.d.ts +7 -0
- package/lib/types/client/locales.d.ts +55 -1
- package/lib/types/client/section-controller.d.ts +17 -41
- package/lib/types/client/staged-form.d.ts +1 -3
- package/lib/types/client/usage.d.ts +1 -1
- package/lib/types/config-contract.d.ts +69 -0
- package/lib/types/config.d.ts +12 -47
- package/lib/types/conversion/context.d.ts +5 -1
- package/lib/types/conversion/image-pool.d.ts +24 -0
- package/lib/types/conversion/replay.d.ts +1 -1
- package/lib/types/conversion/stream.d.ts +1 -1
- package/lib/types/gateway-diagnostics.d.ts +22 -0
- package/lib/types/gateway-error.d.ts +2 -0
- package/lib/types/host-settings.d.ts +11 -0
- package/lib/types/index.d.ts +2 -1
- package/lib/types/json-response.d.ts +1 -1
- package/lib/types/model-metadata.d.ts +3 -1
- package/lib/types/models-contract.d.ts +7 -0
- package/lib/types/protocol-contract.d.ts +5 -0
- package/lib/types/protocol-policy.d.ts +4 -0
- package/lib/types/proxy-url.d.ts +2 -0
- package/lib/types/proxy.d.ts +11 -0
- package/lib/types/reasoning.d.ts +36 -6
- package/lib/types/request-control.d.ts +2 -0
- package/lib/types/sdk-types.d.ts +1568 -0
- package/lib/types/settings-bridge.d.ts +22 -0
- package/lib/types/usage-contract.d.ts +5 -0
- package/lib/types/usage.d.ts +14 -2
- package/lib/vendor-licenses.txt +103 -0
- package/package.json +8 -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,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;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/** Client-safe account metadata. Secrets stay in the host credential service. */
|
|
2
|
+
import type { GoAccountOperation } from './account-operations.ts';
|
|
3
|
+
export type GoAccount = {
|
|
4
|
+
id: string;
|
|
5
|
+
name: string;
|
|
6
|
+
apiKeyEnv: string;
|
|
7
|
+
};
|
|
8
|
+
export declare const MAX_ACCOUNTS = 20;
|
|
9
|
+
export declare const ACCOUNT_REF_PREFIX = "DSH_OPENCODE_GO_ACCOUNT_";
|
|
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;
|
|
13
|
+
export interface AccountSettings {
|
|
14
|
+
apiKeyEnv?: string;
|
|
15
|
+
/** Omission/null preserves legacy credentials; an explicit empty list removes all accounts. */
|
|
16
|
+
accounts?: readonly GoAccount[] | null;
|
|
17
|
+
autoSwitch?: boolean;
|
|
18
|
+
/** Recovery intentions owned by this exact settings/profile document. */
|
|
19
|
+
accountOperations?: readonly GoAccountOperation[];
|
|
20
|
+
}
|
|
21
|
+
export declare function accountRefOf(settings: AccountSettings): string;
|
|
22
|
+
/** Include an externally selected reference without rewriting existing configuration. */
|
|
23
|
+
export declare function accountsOf(settings: AccountSettings): readonly GoAccount[];
|
|
24
|
+
export declare function assertAccounts(accounts: readonly GoAccount[] | null | undefined, selectedRef?: string): void;
|
|
25
|
+
/** Safe UI notice for a successful request using a fallback account. */
|
|
26
|
+
export interface GoAccountSwitch {
|
|
27
|
+
fromRef: string;
|
|
28
|
+
toRef: string;
|
|
29
|
+
reason: 'quota' | 'credential';
|
|
30
|
+
at: number;
|
|
31
|
+
}
|
package/lib/types/adapter.d.ts
CHANGED
|
@@ -25,7 +25,11 @@ import { LlmAdapter } from '@deepseek-ai/dsh-llm';
|
|
|
25
25
|
import type { GenerateOptions, ImageAttachmentAccess, LlmModelInfo, LlmResolvedModelInfo, StreamChunk } from '@deepseek-ai/dsh-llm';
|
|
26
26
|
import type { AttachmentStore, ImageAttachmentRef } from '@deepseek-ai/dsh-attachment';
|
|
27
27
|
import { OpencodeGoCatalog } from './catalog.ts';
|
|
28
|
+
import { ProxyTransport } from './proxy.ts';
|
|
28
29
|
import type { OpencodeGoConfig } from './config.ts';
|
|
30
|
+
import { type GoAccountSwitch } from './accounts.ts';
|
|
31
|
+
import { type GoCallTrace } from './call-trace.ts';
|
|
32
|
+
export type { GoCallTrace } from './call-trace.ts';
|
|
29
33
|
/**
|
|
30
34
|
* The attachment-service bridges one image request reads. Construction-time
|
|
31
35
|
* (context-dependent); the config-dependent policy numbers are merged per
|
|
@@ -37,8 +41,22 @@ export interface OpencodeGoImageAccess {
|
|
|
37
41
|
/** Bridge one attachment reference into the current model-tool execution world. */
|
|
38
42
|
resolveImageAccess: (attachments: AttachmentStore, ref: ImageAttachmentRef) => ImageAttachmentAccess | undefined;
|
|
39
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
|
+
}
|
|
40
52
|
/** Constructor inputs for {@link OpencodeGoAdapter}. */
|
|
41
53
|
export interface OpencodeGoAdapterOptions {
|
|
54
|
+
/** Shared with Host usage reads for this plugin mount. */
|
|
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;
|
|
42
60
|
/**
|
|
43
61
|
* The current configuration, re-read at every operation: a settings write
|
|
44
62
|
* reaches the next request without a restart, and one operation never mixes
|
|
@@ -46,7 +64,9 @@ export interface OpencodeGoAdapterOptions {
|
|
|
46
64
|
*/
|
|
47
65
|
config: () => OpencodeGoConfig;
|
|
48
66
|
/** Resolve the credential reference captured with this call's endpoint; missing must fail loud. */
|
|
49
|
-
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;
|
|
50
70
|
/**
|
|
51
71
|
* Image input machinery; absent refuses image content, which is the posture
|
|
52
72
|
* for direct construction without a durable attachment service behind it.
|
|
@@ -60,10 +80,17 @@ export interface OpencodeGoAdapterOptions {
|
|
|
60
80
|
}) => void;
|
|
61
81
|
/** Observe live ids the curated table cannot route. */
|
|
62
82
|
onOmitted?: (ids: readonly string[]) => void;
|
|
83
|
+
onCatalogWarning?: (warning: string) => void;
|
|
63
84
|
/** Observe assistant history degrading to provider-neutral conversion. */
|
|
64
85
|
onReplayDegrade?: (reason: string) => void;
|
|
65
86
|
/** Re-read picker models after a background catalog refresh commits. */
|
|
66
87
|
onCatalogRefresh?: () => 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;
|
|
67
94
|
}
|
|
68
95
|
/**
|
|
69
96
|
* The single route's adapter. The catalog snapshot freezes at each operation,
|
|
@@ -72,14 +99,14 @@ export interface OpencodeGoAdapterOptions {
|
|
|
72
99
|
*/
|
|
73
100
|
export declare class OpencodeGoAdapter extends LlmAdapter {
|
|
74
101
|
private readonly options;
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
private catalogCache;
|
|
102
|
+
private readonly resolveCatalog;
|
|
103
|
+
private readonly transport;
|
|
104
|
+
/** Per-reference rejection deadlines, isolated by the gateway that rejected it. */
|
|
105
|
+
private readonly rejectedKeys;
|
|
106
|
+
/** Monotonic sequence of the latest request this adapter started. */
|
|
107
|
+
private callSeq;
|
|
82
108
|
constructor(options: OpencodeGoAdapterOptions);
|
|
109
|
+
dispose(): Promise<void>;
|
|
83
110
|
/**
|
|
84
111
|
* The catalog resolver for one configuration, rebuilding on the facts it
|
|
85
112
|
* owns. Public for the plugin's discovery registration, which resolves the
|
|
@@ -94,7 +121,7 @@ export declare class OpencodeGoAdapter extends LlmAdapter {
|
|
|
94
121
|
};
|
|
95
122
|
listModels(_provider: string): Promise<readonly LlmModelInfo[]>;
|
|
96
123
|
resolveModel(_provider: string, model: string, signal?: AbortSignal): Promise<LlmResolvedModelInfo>;
|
|
97
|
-
/**
|
|
124
|
+
/** Capture limits and protocol before discovery can yield to a settings update. */
|
|
98
125
|
private callSnapshot;
|
|
99
126
|
/** Keep capability resolution and eventual dispatch on the same configuration. */
|
|
100
127
|
prepareCall(_provider: string, model: string, signal?: AbortSignal): Promise<{
|
|
@@ -107,4 +134,11 @@ export declare class OpencodeGoAdapter extends LlmAdapter {
|
|
|
107
134
|
private resolveReasoningLevel;
|
|
108
135
|
stream(options: GenerateOptions): AsyncIterable<StreamChunk>;
|
|
109
136
|
private streamWithSnapshot;
|
|
137
|
+
private dispatch;
|
|
138
|
+
private streamAccounts;
|
|
139
|
+
private rememberRejectedKey;
|
|
140
|
+
/** A stored change to a reference outranks the gateway's last rejection of it. */
|
|
141
|
+
forgetRejectedKey(ref: string): void;
|
|
142
|
+
/** One account, one SDK attempt; host recovery still owns failures after output. */
|
|
143
|
+
private streamAttempt;
|
|
110
144
|
}
|
|
@@ -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
|
+
}
|
package/lib/types/catalog.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Api, Model, Provider } from '
|
|
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;
|
|
@@ -30,6 +31,8 @@ export declare class OpencodeGoCatalog {
|
|
|
30
31
|
/** Kept for API compatibility; now reports unconfigured ids rather than hiding them. */
|
|
31
32
|
private readonly onOmitted;
|
|
32
33
|
private readonly onRefresh;
|
|
34
|
+
private readonly fetcher?;
|
|
35
|
+
private readonly onWarning?;
|
|
33
36
|
private served;
|
|
34
37
|
private pending;
|
|
35
38
|
/** A cold runtime read can use disk metadata while the shared online refresh runs. */
|
|
@@ -48,7 +51,7 @@ export declare class OpencodeGoCatalog {
|
|
|
48
51
|
kept: number;
|
|
49
52
|
}) => void,
|
|
50
53
|
/** Kept for API compatibility; now reports unconfigured ids rather than hiding them. */
|
|
51
|
-
onOmitted: (ids: readonly string[]) => void, onRefresh?: () => void);
|
|
54
|
+
onOmitted: (ids: readonly string[]) => void, onRefresh?: () => void, fetcher?: typeof globalThis.fetch | undefined, onWarning?: ((warning: string) => void) | undefined);
|
|
52
55
|
snapshot(force?: boolean, signal?: AbortSignal): Promise<CatalogSnapshot>;
|
|
53
56
|
private restoreMetadata;
|
|
54
57
|
private readSnapshot;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { GoAccountsActions, GoAccountsState } from './accounts-controller.ts';
|
|
2
|
+
import type { en } from './locales.ts';
|
|
3
|
+
type Translate = (key: keyof typeof en, params?: Record<string, unknown>) => string;
|
|
4
|
+
/**
|
|
5
|
+
* The account card: a folded header that summarizes the set, and one row per
|
|
6
|
+
* account inside. Rows keep the identity, key state, rolling quota and its reset
|
|
7
|
+
* countdown; everything else opens under the row. The handle is the drag source —
|
|
8
|
+
* dragging it, or the arrow keys on it, reorders the list, and the first row is
|
|
9
|
+
* the preferred account. Every row is read in the same pass, so the one refresh
|
|
10
|
+
* stamp belongs to the card and sits in its header.
|
|
11
|
+
*/
|
|
12
|
+
export declare function AccountsCard({ state, actions, writable, t, locale }: {
|
|
13
|
+
state: GoAccountsState;
|
|
14
|
+
actions: GoAccountsActions;
|
|
15
|
+
writable: boolean;
|
|
16
|
+
t: Translate;
|
|
17
|
+
locale?: string;
|
|
18
|
+
}): import("react").JSX.Element;
|
|
19
|
+
export {};
|
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The OpenCode Go settings page
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* capacities, and the adapter tuning fields behind a collapsed disclosure at the
|
|
6
|
-
* foot. The credential reference, the endpoint, and the tuning knobs all live in
|
|
7
|
-
* the `llm-opencode-go` namespace, so every card writes the same document.
|
|
2
|
+
* The OpenCode Go settings page: provider activation, accounts and credentials,
|
|
3
|
+
* available models and capacities, then advanced tuning. Account operations
|
|
4
|
+
* apply immediately; tuning fields use the page's save/discard actions.
|
|
8
5
|
*/
|
|
9
6
|
import type { InjectFace } from '@deepseek-ai/dsh-client-ui-slots';
|
|
10
7
|
import type { OpencodeGoSectionFace } from './section-controller.ts';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { SnapshotStore } from '@deepseek-ai/dsh-client-store';
|
|
2
2
|
import type { ModelDirectoryState } from '@deepseek-ai/dsh-client-ui-model-selection/client';
|
|
3
|
-
import type
|
|
3
|
+
import { type GoUsage } from '../usage-contract.ts';
|
|
4
4
|
import type { SettingsScope } from './settings.ts';
|
|
5
5
|
import type { OpencodeGoSettings } from './section-controller.ts';
|
|
6
6
|
export interface UsagePillProps {
|
|
@@ -9,6 +9,8 @@ export interface UsagePillProps {
|
|
|
9
9
|
readUsage: () => Promise<GoUsage>;
|
|
10
10
|
t: (key: string) => string;
|
|
11
11
|
getLocale?: () => string;
|
|
12
|
+
credentialChanges?: SnapshotStore<number>;
|
|
13
|
+
selectAccount?: (ref: string) => Promise<boolean>;
|
|
12
14
|
}
|
|
13
15
|
/** Only a visible, enabled pill mounts the usage poller. */
|
|
14
|
-
export declare function UsagePill({ directory, settings, ...props }: UsagePillProps): import("react").JSX.Element | null;
|
|
16
|
+
export declare function UsagePill({ directory, settings, credentialChanges, ...props }: UsagePillProps): import("react").JSX.Element | null;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
2
|
+
import { type AccountSettings, type GoAccount } from '../accounts.ts';
|
|
3
|
+
import type { GoUsage } from '../usage-contract.ts';
|
|
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>;
|
|
8
|
+
export interface GoAccountView extends GoAccount {
|
|
9
|
+
configured?: boolean;
|
|
10
|
+
writable?: boolean;
|
|
11
|
+
usage?: GoUsage;
|
|
12
|
+
updatedAt?: number;
|
|
13
|
+
stale?: boolean;
|
|
14
|
+
loading?: boolean;
|
|
15
|
+
failed?: boolean;
|
|
16
|
+
/** Why the last quota read failed, safe to show: it carries no credential value. */
|
|
17
|
+
problem?: string;
|
|
18
|
+
}
|
|
19
|
+
export interface GoAccountsState {
|
|
20
|
+
entries: readonly GoAccountView[];
|
|
21
|
+
activeRef: string;
|
|
22
|
+
autoSwitch: boolean;
|
|
23
|
+
busy: boolean;
|
|
24
|
+
blocked: boolean;
|
|
25
|
+
refreshing: boolean;
|
|
26
|
+
failure?: 'write' | 'cleanup' | 'remove' | 'read';
|
|
27
|
+
}
|
|
28
|
+
export interface GoAccountsActions {
|
|
29
|
+
loadAccounts: () => void;
|
|
30
|
+
addAccount: (name: string, key: string) => Promise<boolean>;
|
|
31
|
+
renameAccount: (ref: string, name: string) => Promise<boolean>;
|
|
32
|
+
removeAccount: (ref: string) => Promise<boolean>;
|
|
33
|
+
selectAccount: (ref: string) => Promise<boolean>;
|
|
34
|
+
setAutoSwitch: (next: boolean) => Promise<boolean>;
|
|
35
|
+
replaceAccountKey: (ref: string, key: string) => Promise<boolean>;
|
|
36
|
+
/** Move one account to a new position; the first row becomes the preferred account. */
|
|
37
|
+
moveAccount: (ref: string, toIndex: number) => Promise<boolean>;
|
|
38
|
+
}
|
|
39
|
+
/** Immediate account operations, separate from the page's staged tuning form. */
|
|
40
|
+
export declare class GoAccountsController {
|
|
41
|
+
private readonly scope;
|
|
42
|
+
private readonly ctx;
|
|
43
|
+
private readonly readUsage;
|
|
44
|
+
private readonly publish;
|
|
45
|
+
private readonly blocked;
|
|
46
|
+
private readonly execute;
|
|
47
|
+
private rows;
|
|
48
|
+
private busy;
|
|
49
|
+
private refreshing;
|
|
50
|
+
private failure;
|
|
51
|
+
private epoch;
|
|
52
|
+
private identity;
|
|
53
|
+
private loaded;
|
|
54
|
+
private disposed;
|
|
55
|
+
private addition;
|
|
56
|
+
constructor(scope: SettingsScope<AccountSettings & {
|
|
57
|
+
baseURL?: string;
|
|
58
|
+
proxyURL?: string;
|
|
59
|
+
}>, ctx: Context, readUsage: (ref: string) => Promise<GoUsage>, publish: () => void, blocked: () => boolean, execute?: ExecuteAccountCommand);
|
|
60
|
+
snapshot(): GoAccountsState;
|
|
61
|
+
sync(): void;
|
|
62
|
+
dispose(): void;
|
|
63
|
+
invalidate(ref: string): void;
|
|
64
|
+
refresh(): Promise<void>;
|
|
65
|
+
/** Mark every account row as unreadable with the Host's own diagnostic. */
|
|
66
|
+
private markUnreadable;
|
|
67
|
+
actions(): GoAccountsActions;
|
|
68
|
+
private run;
|
|
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;
|
|
@@ -1,8 +1,49 @@
|
|
|
1
1
|
/** Copy dictionaries for the OpenCode Go settings page. English is the key-set source of truth. */
|
|
2
2
|
export declare const en: {
|
|
3
|
+
accountsTitle: string;
|
|
4
|
+
accountsRefresh: string;
|
|
5
|
+
accountsBlocked: string;
|
|
6
|
+
accountsEmpty: string;
|
|
7
|
+
accountsWriteFailed: string;
|
|
8
|
+
accountsReadFailed: string;
|
|
9
|
+
accountsCleanupFailed: string;
|
|
10
|
+
accountsRemoveKeyFailed: string;
|
|
11
|
+
accountsStatusUnknown: string;
|
|
12
|
+
accountDefault: string;
|
|
13
|
+
accountAdd: string;
|
|
14
|
+
accountRename: string;
|
|
15
|
+
accountReplaceKey: string;
|
|
16
|
+
accountRemove: string;
|
|
17
|
+
accountRemoveHint: string;
|
|
18
|
+
accountName: string;
|
|
19
|
+
accountKeyHint: string;
|
|
20
|
+
accountConfirm: string;
|
|
21
|
+
accountCancel: string;
|
|
22
|
+
accountAutoSwitch: string;
|
|
23
|
+
accountAutoSwitchHint: string;
|
|
24
|
+
accountPreferredTag: string;
|
|
25
|
+
accountSwitchAction: string;
|
|
26
|
+
accountSwitchTitle: string;
|
|
27
|
+
accountSwitchBack: string;
|
|
28
|
+
accountSwitchHint: string;
|
|
29
|
+
accountSwitchFailed: string;
|
|
30
|
+
accountFallbackQuota: string;
|
|
31
|
+
accountFallbackCredential: string;
|
|
32
|
+
accountsSummary: string;
|
|
33
|
+
accountsSummaryEmpty: string;
|
|
34
|
+
accountsAvailability: string;
|
|
35
|
+
accountsAvailabilityFailed: string;
|
|
36
|
+
accountsDetails: string;
|
|
37
|
+
accountsDetailsHide: string;
|
|
38
|
+
accountDragHandle: string;
|
|
39
|
+
accountConfigureHint: string;
|
|
40
|
+
usageResetMinutes: string;
|
|
41
|
+
usageResetHours: string;
|
|
42
|
+
usageResetDays: string;
|
|
43
|
+
usageResetDue: string;
|
|
44
|
+
usageResetUnknown: string;
|
|
3
45
|
usageTitle: string;
|
|
4
46
|
usageRollingShort: string;
|
|
5
|
-
usageHint: string;
|
|
6
47
|
usageWeekShort: string;
|
|
7
48
|
usage_rolling: string;
|
|
8
49
|
usage_weekly: string;
|
|
@@ -12,6 +53,7 @@ export declare const en: {
|
|
|
12
53
|
usageLoading: string;
|
|
13
54
|
usageUnavailable: string;
|
|
14
55
|
usageStaleShort: string;
|
|
56
|
+
usageFallbackShort: string;
|
|
15
57
|
usageStaleHint: string;
|
|
16
58
|
usageRefreshFailed: string;
|
|
17
59
|
usageLastUpdated: string;
|
|
@@ -54,6 +96,11 @@ export declare const en: {
|
|
|
54
96
|
limitsModel: string;
|
|
55
97
|
limitsContext: string;
|
|
56
98
|
limitsOutput: string;
|
|
99
|
+
thinkingBudgets: string;
|
|
100
|
+
thinkingBudgetsHint: string;
|
|
101
|
+
thinkingBudgetAddLabel: string;
|
|
102
|
+
thinkingBudgetAdd: string;
|
|
103
|
+
thinkingBudgetRemove: string;
|
|
57
104
|
capacityDefault: string;
|
|
58
105
|
capacityMissing: string;
|
|
59
106
|
modalityLabel: string;
|
|
@@ -97,10 +144,17 @@ export declare const en: {
|
|
|
97
144
|
usageDisplay_auto: string;
|
|
98
145
|
usageDisplay_always: string;
|
|
99
146
|
usageDisplay_off: string;
|
|
147
|
+
protocolOverridesLabel: string;
|
|
148
|
+
protocolOverridesHint: string;
|
|
149
|
+
protocolOverridesAuto: string;
|
|
150
|
+
protocolOverridesResponses: string;
|
|
100
151
|
apiKeyEnvLabel: string;
|
|
101
152
|
apiKeyEnvHint: string;
|
|
102
153
|
baseURLLabel: string;
|
|
103
154
|
baseURLHint: string;
|
|
155
|
+
proxyURLLabel: string;
|
|
156
|
+
proxyURLHint: string;
|
|
157
|
+
proxyURLInvalid: string;
|
|
104
158
|
refreshMinutesLabel: string;
|
|
105
159
|
refreshMinutesHint: string;
|
|
106
160
|
streamIdleTimeoutMsLabel: string;
|