@eddyskywalker/dsh-chatgpt-subscription 0.10.0 → 0.10.5
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/CHANGELOG.md +58 -0
- package/README.md +39 -1
- package/lib/client.js +1675 -208
- package/lib/client.js.map +1 -1
- package/lib/index.js +5891 -1342
- package/lib/types/client/ProviderHubSection.d.ts.map +1 -1
- package/lib/types/client/index.d.ts +2 -0
- package/lib/types/client/index.d.ts.map +1 -1
- package/lib/types/client/minimax-code/MinimaxCodeComposerQuota.d.ts +27 -0
- package/lib/types/client/minimax-code/MinimaxCodeComposerQuota.d.ts.map +1 -0
- package/lib/types/client/minimax-code/MinimaxCodeSection.d.ts +49 -0
- package/lib/types/client/minimax-code/MinimaxCodeSection.d.ts.map +1 -0
- package/lib/types/client/minimax-code/api.d.ts +5 -0
- package/lib/types/client/minimax-code/api.d.ts.map +1 -0
- package/lib/types/client/minimax-code/locales.d.ts +377 -0
- package/lib/types/client/minimax-code/locales.d.ts.map +1 -0
- package/lib/types/client/minimax-code/styles.d.ts +12 -0
- package/lib/types/client/minimax-code/styles.d.ts.map +1 -0
- package/lib/types/client/styles.d.ts.map +1 -1
- package/lib/types/compat.d.ts +1 -0
- package/lib/types/compat.d.ts.map +1 -1
- package/lib/types/host/minimax-code/account-pool.d.ts +219 -0
- package/lib/types/host/minimax-code/account-pool.d.ts.map +1 -0
- package/lib/types/host/minimax-code/adapter.d.ts +168 -0
- package/lib/types/host/minimax-code/adapter.d.ts.map +1 -0
- package/lib/types/host/minimax-code/checkin-gateway.d.ts +109 -0
- package/lib/types/host/minimax-code/checkin-gateway.d.ts.map +1 -0
- package/lib/types/host/minimax-code/checkin.d.ts +150 -0
- package/lib/types/host/minimax-code/checkin.d.ts.map +1 -0
- package/lib/types/host/minimax-code/client.d.ts +184 -0
- package/lib/types/host/minimax-code/client.d.ts.map +1 -0
- package/lib/types/host/minimax-code/mapper.d.ts +172 -0
- package/lib/types/host/minimax-code/mapper.d.ts.map +1 -0
- package/lib/types/host/minimax-code/model-catalog.d.ts +146 -0
- package/lib/types/host/minimax-code/model-catalog.d.ts.map +1 -0
- package/lib/types/host/minimax-code/oauth.d.ts +204 -0
- package/lib/types/host/minimax-code/oauth.d.ts.map +1 -0
- package/lib/types/host/minimax-code/routes.d.ts +82 -0
- package/lib/types/host/minimax-code/routes.d.ts.map +1 -0
- package/lib/types/host/minimax-code/token-store.d.ts +253 -0
- package/lib/types/host/minimax-code/token-store.d.ts.map +1 -0
- package/lib/types/host/minimax-code/types.d.ts +222 -0
- package/lib/types/host/minimax-code/types.d.ts.map +1 -0
- package/lib/types/index.d.ts +11 -0
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/shared/minimax-code-contracts.d.ts +202 -0
- package/lib/types/shared/minimax-code-contracts.d.ts.map +1 -0
- package/package.json +31 -31
- package/lib/types/host/claude/__probe-assert.d.ts +0 -2
- package/lib/types/host/claude/__probe-assert.d.ts.map +0 -1
- package/lib/types/shared/__probe-claude-import.d.ts +0 -2
- package/lib/types/shared/__probe-claude-import.d.ts.map +0 -1
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MiniMax Code 号池:the account pool for the MiniMax Code (编程订阅) line.
|
|
3
|
+
*
|
|
4
|
+
* This is the second line in this package that pools a credential it does not
|
|
5
|
+
* own (WorkBuddy was the first), and that one fact decides every shape below:
|
|
6
|
+
*
|
|
7
|
+
* 1. MiniMax Code's normal credential is the desktop application's own
|
|
8
|
+
* \`~/.minimax/auth/<buildEnv>/<region>/mcode-public/auth.json\`. The plugin
|
|
9
|
+
* reads it so a user already signed in to the app never signs in twice, which
|
|
10
|
+
* is exactly the WorkBuddy precedent for the CodeBuddy client's \`*.info\`
|
|
11
|
+
* files.
|
|
12
|
+
* 2. ADOPTED MEANS NEVER DESTROYED. That file belongs to an application the
|
|
13
|
+
* user is running. The pool may read it, may adopt it into its own account
|
|
14
|
+
* list, and may write a rotated token back through the store's atomic
|
|
15
|
+
* replacement — but no path in this file may revoke it or delete it. A
|
|
16
|
+
* deleted \`auth.json\` signs the user out of MiniMax Code itself, so such an
|
|
17
|
+
* account is reported as \`removable: false\` and deletion is refused
|
|
18
|
+
* ({@link MinimaxCodeAccountPool.deleteAccount}), mirroring WorkBuddy's
|
|
19
|
+
* desktop accounts.
|
|
20
|
+
* 3. What the pool adds on top of the single-credential line is rotation: more
|
|
21
|
+
* than one sign-in can serve requests, a 429 cools one account down instead
|
|
22
|
+
* of taking the line offline, and the settings card can list, alias, promote
|
|
23
|
+
* and switch between them.
|
|
24
|
+
*
|
|
25
|
+
* The credential format stays the store's: this file never invents a field of
|
|
26
|
+
* its own inside a token record, so a write back into the app's document keeps
|
|
27
|
+
* the exact shape the app expects.
|
|
28
|
+
*/
|
|
29
|
+
import type { IncomingMessage, ServerResponse } from 'node:http';
|
|
30
|
+
import { AccountPoolCore, type PoolAccountShape, type PoolData } from '../common/account-pool.ts';
|
|
31
|
+
import type { CredentialStore } from '../token-store.ts';
|
|
32
|
+
import { MinimaxCodeCredentialStore, type MinimaxCodeCredentialSource, type MinimaxCodeCredentials } from './token-store.ts';
|
|
33
|
+
import type { MinimaxCodeRegion } from '../../shared/minimax-code-contracts.ts';
|
|
34
|
+
import type { AccountRotationStrategy, PoolAccountSummaryDto } from '../../shared/account-pool-contracts.ts';
|
|
35
|
+
/**
|
|
36
|
+
* One pooled MiniMax Code account.
|
|
37
|
+
*
|
|
38
|
+
* The credential travels whole (the pool persists it, and the store knows how to
|
|
39
|
+
* write it back to the file it came from); everything else here is a non-secret
|
|
40
|
+
* fact the settings card renders without a second round trip.
|
|
41
|
+
*/
|
|
42
|
+
export interface MinimaxCodePoolAccount extends PoolAccountShape<MinimaxCodeCredentials> {
|
|
43
|
+
/** Region the credential was issued in; decides every host this account uses. */
|
|
44
|
+
region: MinimaxCodeRegion;
|
|
45
|
+
/**
|
|
46
|
+
* Which store owns the credential.
|
|
47
|
+
*
|
|
48
|
+
* \`minimax-native\` is MiniMax Code's own \`auth.json\`: adopted and renewed,
|
|
49
|
+
* never deletable from here. \`file\` is the plugin's own store, written by a
|
|
50
|
+
* device-code sign-in started in this plugin.
|
|
51
|
+
*/
|
|
52
|
+
source: MinimaxCodeCredentialSource;
|
|
53
|
+
/** Display facts, when the credential's token claims carry them. */
|
|
54
|
+
email?: string;
|
|
55
|
+
planName?: string;
|
|
56
|
+
}
|
|
57
|
+
/** The pool slice the settings card renders, mirroring {@link AccountPoolStatusDto}. */
|
|
58
|
+
export interface MinimaxCodeAccountSummaryDto extends PoolAccountSummaryDto {
|
|
59
|
+
region?: MinimaxCodeRegion;
|
|
60
|
+
source?: MinimaxCodeCredentialSource;
|
|
61
|
+
/** Credential generation; diagnostics for two-sided refresh contention with the app. */
|
|
62
|
+
generation?: number;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Encrypted pool file this line owns.
|
|
66
|
+
*
|
|
67
|
+
* Separate from the credential file on purpose: the pool may hold several
|
|
68
|
+
* accounts, while \`~/.minimax/auth\` holds exactly one session per region and is
|
|
69
|
+
* the desktop app's to write.
|
|
70
|
+
*/
|
|
71
|
+
export declare function minimaxCodePoolPath(): string;
|
|
72
|
+
/**
|
|
73
|
+
* Identity two credentials share when they are the same account.
|
|
74
|
+
*
|
|
75
|
+
* Neither token can be used for this: the access token is replaced on every
|
|
76
|
+
* refresh and the refresh token rotates, so keying on either would make one
|
|
77
|
+
* account look new after every rotation. A hash of the refresh token would have
|
|
78
|
+
* the same defect and no compensating benefit, so it is not done.
|
|
79
|
+
*
|
|
80
|
+
* Two different identities are available, one per provenance:
|
|
81
|
+
*
|
|
82
|
+
* - A native credential names the desktop app's own record slot through
|
|
83
|
+
* \`recordKey\`. That key is a non-secret digest of the app's auth-home path, so
|
|
84
|
+
* it is stable across every rotation, and the app keeps exactly one session per
|
|
85
|
+
* slot: re-signing in there replaces the session, which for routing purposes is
|
|
86
|
+
* the same account, so updating the row in place is the correct outcome.
|
|
87
|
+
* - A plugin-owned credential has no record slot (the app's key is a hash this
|
|
88
|
+
* plugin cannot reproduce) and no account profile, so the sign-in that produced
|
|
89
|
+
* it — its \`loginEpoch\`, which survives every rotation — is the identity. A
|
|
90
|
+
* second device-code sign-in is genuinely a second session with its own refresh
|
|
91
|
+
* token chain, so it is its own account.
|
|
92
|
+
*
|
|
93
|
+
* When neither is present there is nothing stable to key on: the function returns
|
|
94
|
+
* undefined, the core mints \`acc_<random>\`, and the row is added rather than
|
|
95
|
+
* silently merged with an unrelated credential.
|
|
96
|
+
*/
|
|
97
|
+
export declare function minimaxCodePoolIdentity(credentials: MinimaxCodeCredentials): string | undefined;
|
|
98
|
+
/**
|
|
99
|
+
* Validate and normalize one whole pool document.
|
|
100
|
+
*
|
|
101
|
+
* The credential is re-parsed through the store's own validator, so a row can
|
|
102
|
+
* never hold a token shape the store would refuse to write back. \`source\`,
|
|
103
|
+
* \`recordKey\` and \`buildEnv\` have to be restored explicitly: the validator
|
|
104
|
+
* takes them from its fallback rather than from the payload, and a native account
|
|
105
|
+
* that lost them would be re-labelled as plugin-owned (so the card would offer a
|
|
106
|
+
* delete that must never happen, and a rotation would land in the plugin's file
|
|
107
|
+
* instead of the app's).
|
|
108
|
+
*/
|
|
109
|
+
export declare function parseMinimaxCodePoolData(value: unknown): PoolData<MinimaxCodePoolAccount>;
|
|
110
|
+
export interface MinimaxCodeAccountPoolOptions {
|
|
111
|
+
/**
|
|
112
|
+
* Credential store the pool reads the desktop app's sign-in through and mirrors
|
|
113
|
+
* its primary account into.
|
|
114
|
+
*/
|
|
115
|
+
store?: MinimaxCodeCredentialStore;
|
|
116
|
+
/** Test seam; production builds the platform backend from the pool path. */
|
|
117
|
+
backend?: CredentialStore<PoolData<MinimaxCodePoolAccount>>;
|
|
118
|
+
/** Accounts this pool accepts; defaults to the core's limit. */
|
|
119
|
+
maxAccounts?: number;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* MiniMax Code's account pool.
|
|
123
|
+
*
|
|
124
|
+
* It owns rotation and the write-back, exactly like the sibling lines, with one
|
|
125
|
+
* asymmetry the hooks below enforce: an account whose credential lives in the
|
|
126
|
+
* desktop app's file is adopted, never owned.
|
|
127
|
+
*/
|
|
128
|
+
export declare class MinimaxCodeAccountPool extends AccountPoolCore<MinimaxCodeCredentials, MinimaxCodePoolAccount, MinimaxCodeAccountSummaryDto> {
|
|
129
|
+
private readonly store;
|
|
130
|
+
constructor(options?: MinimaxCodeAccountPoolOptions);
|
|
131
|
+
/**
|
|
132
|
+
* Pick the account for the next request.
|
|
133
|
+
*
|
|
134
|
+
* The returned credential carries its own region and record key, so a caller
|
|
135
|
+
* must use those rather than any process-wide default. This is the method the
|
|
136
|
+
* adapter uses; {@link getEffectiveAccount} beneath it already refreshes a
|
|
137
|
+
* credential that is about to expire and writes the rotation back.
|
|
138
|
+
*/
|
|
139
|
+
getEffectiveCredential(excludeIds?: ReadonlySet<string>, fetchFn?: typeof fetch): Promise<{
|
|
140
|
+
account: MinimaxCodePoolAccount;
|
|
141
|
+
credentials: MinimaxCodeCredentials;
|
|
142
|
+
}>;
|
|
143
|
+
/**
|
|
144
|
+
* The desktop app's own current copy of one native account's credential.
|
|
145
|
+
*
|
|
146
|
+
* The app rotates its token on its own schedule, so the copy the pool adopted
|
|
147
|
+
* can be older than what is on disk. Only the same record slot counts: a
|
|
148
|
+
* different record key or region is a different account, and substituting it
|
|
149
|
+
* would present one account's token as another's. A file whose token is already
|
|
150
|
+
* stale is not newer authority either — the refresh path has just written the
|
|
151
|
+
* pair back, and reading the pre-refresh file would undo it.
|
|
152
|
+
*/
|
|
153
|
+
private liveNativeCredential;
|
|
154
|
+
/**
|
|
155
|
+
* Adopt the sign-in the desktop app currently holds into the pool.
|
|
156
|
+
*
|
|
157
|
+
* The pre-pool projection ({@link legacyAccount}) only surfaces when the pool is
|
|
158
|
+
* empty, so a user who already has a plugin-owned account needs an explicit way
|
|
159
|
+
* to bring the app's session in as well. Nothing is ever removed from the app;
|
|
160
|
+
* the account is added under its own record-slot identity, so adopting twice
|
|
161
|
+
* updates the same row.
|
|
162
|
+
*/
|
|
163
|
+
adoptNativeAccount(alias?: string): Promise<MinimaxCodePoolAccount>;
|
|
164
|
+
/**
|
|
165
|
+
* Delete one account.
|
|
166
|
+
*
|
|
167
|
+
* An account whose credential is the desktop app's own \`auth.json\` is refused:
|
|
168
|
+
* this plugin does not own that file, and removing the account would either
|
|
169
|
+
* strand the app's session or — if the deletion were ever allowed to reach the
|
|
170
|
+
* file — sign the user out of MiniMax Code itself. Signing out there is the
|
|
171
|
+
* supported way to end it, and the card is told so by \`removable: false\`.
|
|
172
|
+
*/
|
|
173
|
+
deleteAccount(accountId: string): Promise<void>;
|
|
174
|
+
/** The credential store this pool mirrors its primary account into. */
|
|
175
|
+
mirrorStore(): MinimaxCodeCredentialStore;
|
|
176
|
+
}
|
|
177
|
+
/** The pool slice of a status response; exactly the fields the card renders. */
|
|
178
|
+
export interface MinimaxCodePoolStatus {
|
|
179
|
+
accounts: MinimaxCodeAccountSummaryDto[];
|
|
180
|
+
activeAccountId?: string;
|
|
181
|
+
rotationStrategy: AccountRotationStrategy;
|
|
182
|
+
/** Whether this process installed a pool at all. */
|
|
183
|
+
poolInstalled: boolean;
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Read the pool slice of the status DTO.
|
|
187
|
+
*
|
|
188
|
+
* A pool that cannot be read must not fail the whole card: the connection
|
|
189
|
+
* section is still worth rendering, just with an empty account list.
|
|
190
|
+
*/
|
|
191
|
+
export declare function minimaxCodePoolStatus(pool: MinimaxCodeAccountPool | undefined): Promise<MinimaxCodePoolStatus>;
|
|
192
|
+
export interface MinimaxCodeAccountsRouteOptions {
|
|
193
|
+
/**
|
|
194
|
+
* Status the route answers a mutation with, so the card re-renders in one round
|
|
195
|
+
* trip. Defaults to the pool slice alone.
|
|
196
|
+
*/
|
|
197
|
+
readStatus?: () => Promise<unknown>;
|
|
198
|
+
/**
|
|
199
|
+
* Called after a mutation that can move which account serves a request, so the
|
|
200
|
+
* caller can drop per-account caches (quota, catalog) that belong to the account
|
|
201
|
+
* that just changed.
|
|
202
|
+
*/
|
|
203
|
+
onAccountsChanged?: () => void;
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* The \`/accounts\` route for this line, as a self-contained handler.
|
|
207
|
+
*
|
|
208
|
+
* It is a handler rather than a second \`webServer.register\` call because the
|
|
209
|
+
* parent route already owns the \`/minimax-code/api\` prefix: registering a nested
|
|
210
|
+
* prefix beside it would make which handler sees \`/accounts\` depend on the
|
|
211
|
+
* server's prefix-matching order. The parent dispatches on \`path === 'accounts'\`
|
|
212
|
+
* and calls this.
|
|
213
|
+
*
|
|
214
|
+
* Every POST goes through {@link isSameOriginMutation}, exactly like the sibling
|
|
215
|
+
* lines' account routes, and no response ever carries a credential: what leaves
|
|
216
|
+
* here is the summary DTO the card renders.
|
|
217
|
+
*/
|
|
218
|
+
export declare function createMinimaxCodeAccountsHandler(pool: MinimaxCodeAccountPool | undefined, options?: MinimaxCodeAccountsRouteOptions): (request: IncomingMessage, response: ServerResponse) => Promise<void>;
|
|
219
|
+
//# sourceMappingURL=account-pool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"account-pool.d.ts","sourceRoot":"","sources":["../../../../src/host/minimax-code/account-pool.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The DSH adapter for the MiniMax Code subscription.
|
|
3
|
+
*
|
|
4
|
+
* It follows the shape every other line in this package uses — claim the provider
|
|
5
|
+
* id, list the hardcoded directory, resolve one model, stream one request — with
|
|
6
|
+
* two differences that belong to this line alone:
|
|
7
|
+
*
|
|
8
|
+
* 1. the credential is the desktop app's own \`auth.json\`, read and renewed through
|
|
9
|
+
* ./oauth.ts under the read-only-first discipline; and
|
|
10
|
+
* 2. there is no account pool. Pooling exists to rotate several signed-in accounts
|
|
11
|
+
* against one subscription; here there is exactly one credential, shared with an
|
|
12
|
+
* application the user is also running, and inventing a second one would mean
|
|
13
|
+
* racing that application for a rotation neither of them needs.
|
|
14
|
+
*/
|
|
15
|
+
import { LlmAdapter, type GenerateOptions, type LlmModelInfo, type LlmProviderInfo, type LlmResolvedModelInfo, type PreparedAdapterCall, type ResolvedRetryPolicy, type StreamChunk } from '@deepseek-ai/dsh-llm';
|
|
16
|
+
import { PROVIDER_ID } from './types.ts';
|
|
17
|
+
import { MinimaxCodeCredentialStore, MinimaxCodeModelSettingsStore, type MinimaxCodePreferenceStore } from './token-store.ts';
|
|
18
|
+
import { clampOutputToContext, maxOutputTokensFor, type AttachmentImageReader } from './mapper.ts';
|
|
19
|
+
import type { MinimaxCodeAccountPool } from './account-pool.ts';
|
|
20
|
+
/**
|
|
21
|
+
* Transient-failure retry policy for the minimax-code route.
|
|
22
|
+
*
|
|
23
|
+
* The subscription fronts the model providers, so a call can fail with a 502/503
|
|
24
|
+
* while the subscription and the credential stay perfectly usable. The retryable
|
|
25
|
+
* set is therefore SERVER (any 5xx), RATE_LIMIT (genuine back-pressure), TRANSPORT
|
|
26
|
+
* (a connection that produced no response) and TIMEOUT (a stalled stream, handled
|
|
27
|
+
* by the idle watchdog).
|
|
28
|
+
*
|
|
29
|
+
* Deliberately outside the set: INVALID_CREDENTIAL (a rejected token fails
|
|
30
|
+
* identically every time), PROVIDER_ERROR (a 400 or a plan refusal), and ABORTED
|
|
31
|
+
* (the caller already cancelled).
|
|
32
|
+
*/
|
|
33
|
+
export declare const MINIMAX_CODE_RETRY_POLICY_CONFIG: {
|
|
34
|
+
mode: 'normal';
|
|
35
|
+
maxRetries: number;
|
|
36
|
+
retryableCodes: string[];
|
|
37
|
+
backoff: {
|
|
38
|
+
initialDelayMs: number;
|
|
39
|
+
maxDelayMs: number;
|
|
40
|
+
jitterRatio: number;
|
|
41
|
+
};
|
|
42
|
+
};
|
|
43
|
+
/** What one failed response means for the retry policy. */
|
|
44
|
+
export interface MinimaxFailureClassification {
|
|
45
|
+
/** DSH error code; decides whether the route retries. */
|
|
46
|
+
code: string;
|
|
47
|
+
/** Message shown to the user, with the service's own text appended. */
|
|
48
|
+
message: string;
|
|
49
|
+
/** True only when the failure is worth retrying. */
|
|
50
|
+
retryable: boolean;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Classify one non-2xx response for the retry policy.
|
|
54
|
+
*
|
|
55
|
+
* A 401 on this route is the one failure with an unambiguous remedy, and it is the
|
|
56
|
+
* one the credentials rule exists for: the service answers
|
|
57
|
+
* \`{"code":401,"message":"token is required"}\` both when no credential was sent
|
|
58
|
+
* and when the one that was sent is no longer accepted, so the message names the
|
|
59
|
+
* sign-in path instead of asking the user to guess.
|
|
60
|
+
*/
|
|
61
|
+
export declare function classifyMinimaxFailure(status: number, bodyText: string): MinimaxFailureClassification;
|
|
62
|
+
export interface MinimaxCodeAdapterOptions {
|
|
63
|
+
fetchFn?: typeof fetch;
|
|
64
|
+
/** Attachment seam: verified bytes for one durable image. */
|
|
65
|
+
attachments?: AttachmentImageReader;
|
|
66
|
+
/**
|
|
67
|
+
* The account pool, when this process installed one.
|
|
68
|
+
*
|
|
69
|
+
* With a pool the adapter rotates between accounts and lets a 429 cool one
|
|
70
|
+
* account down instead of taking the whole line offline; without one it keeps
|
|
71
|
+
* the single-credential behaviour it had before, reading and renewing the one
|
|
72
|
+
* stored credential. Both postures are supported because the pool is optional
|
|
73
|
+
* in a composition (a headless host, a test), and a missing pool must not make
|
|
74
|
+
* the route unusable.
|
|
75
|
+
*/
|
|
76
|
+
accountPool?: MinimaxCodeAccountPool;
|
|
77
|
+
}
|
|
78
|
+
export declare class MinimaxCodeAdapter extends LlmAdapter {
|
|
79
|
+
private readonly store;
|
|
80
|
+
/**
|
|
81
|
+
* The JSON file fallback for the model selection.
|
|
82
|
+
*
|
|
83
|
+
* Every sibling line has one, and it is not dead weight even where a settings
|
|
84
|
+
* service exists: it is what a later run on a harness that dropped the register
|
|
85
|
+
* seam reads back.
|
|
86
|
+
*/
|
|
87
|
+
private readonly modelSettings;
|
|
88
|
+
/**
|
|
89
|
+
* Registered model settings, when the harness still offers the register seam.
|
|
90
|
+
*
|
|
91
|
+
* Optional because the adapter is also constructed by tooling and tests that
|
|
92
|
+
* have no settings service; {@link settings} then reads the file directly, so
|
|
93
|
+
* both shapes answer the same three questions.
|
|
94
|
+
*/
|
|
95
|
+
private readonly preferences;
|
|
96
|
+
private readonly options;
|
|
97
|
+
constructor(store?: MinimaxCodeCredentialStore, options?: MinimaxCodeAdapterOptions, modelSettings?: MinimaxCodeModelSettingsStore, preferences?: MinimaxCodePreferenceStore);
|
|
98
|
+
/**
|
|
99
|
+
* The current model selection.
|
|
100
|
+
*
|
|
101
|
+
* Synchronous on the register seam (the scope reads from memory) and a single
|
|
102
|
+
* file read otherwise. The loop over models that consults it runs on every
|
|
103
|
+
* model-picker query, so this is deliberately not memoized: a cached snapshot
|
|
104
|
+
* would keep serving a model the user disabled in the card until the process
|
|
105
|
+
* restarted, which is the complaint this whole settings surface exists to fix.
|
|
106
|
+
*/
|
|
107
|
+
private settings;
|
|
108
|
+
/**
|
|
109
|
+
* The credential one request should present, and the pool account behind it.
|
|
110
|
+
*
|
|
111
|
+
* With a pool, the pool picks the account (rotation, cooldown, stickiness) and
|
|
112
|
+
* owns the refresh, so this must not read the single-credential file: that file
|
|
113
|
+
* mirrors one pooled account, and presenting it would silently pin every request
|
|
114
|
+
* to whichever account was mirrored last.
|
|
115
|
+
*
|
|
116
|
+
* Without a pool the previous behaviour is kept exactly, including the
|
|
117
|
+
* read-only-first refresh policy.
|
|
118
|
+
*/
|
|
119
|
+
private acquireCredential;
|
|
120
|
+
/**
|
|
121
|
+
* Renew the credential the service just refused.
|
|
122
|
+
*
|
|
123
|
+
* With a pool, the account that failed is the one renewed, so the rotation lands
|
|
124
|
+
* on that account's own record instead of the single-credential file; without a
|
|
125
|
+
* pool the store's own forced refresh is what ran before the pool existed.
|
|
126
|
+
*/
|
|
127
|
+
private renewCredential;
|
|
128
|
+
providerInfo(provider: string): LlmProviderInfo;
|
|
129
|
+
providerRetryPolicy(): ResolvedRetryPolicy;
|
|
130
|
+
imageRequestPricing(): undefined;
|
|
131
|
+
/**
|
|
132
|
+
* The hardcoded directory, narrowed to what the user enabled it to serve.
|
|
133
|
+
*
|
|
134
|
+
* Nothing is fetched: the listing route is unavailable on this endpoint, so a
|
|
135
|
+
* "live catalog" would be a request that can only ever fail.
|
|
136
|
+
*
|
|
137
|
+
* The line-wide switch is honoured before the selection is even resolved, so
|
|
138
|
+
* turning the card's switch off exposes no model at all — including the ones
|
|
139
|
+
* the user left ticked, which is what "off" has to mean if it is to mean
|
|
140
|
+
* anything.
|
|
141
|
+
*/
|
|
142
|
+
listModels(provider?: string): Promise<readonly LlmModelInfo[]>;
|
|
143
|
+
/**
|
|
144
|
+
* One model's resolved metadata, read through the current selection.
|
|
145
|
+
*
|
|
146
|
+
* The effective context window is the override when one is saved, and the
|
|
147
|
+
* output cap is sized against that same number — a window the card shows and a
|
|
148
|
+
* cap the request path computes from a different one is precisely the drift
|
|
149
|
+
* this single resolver exists to prevent.
|
|
150
|
+
*/
|
|
151
|
+
resolveModel(provider: string, modelId: string, signal?: AbortSignal): Promise<LlmResolvedModelInfo>;
|
|
152
|
+
prepareCall(provider: string, model: string, signal?: AbortSignal): Promise<PreparedAdapterCall>;
|
|
153
|
+
/**
|
|
154
|
+
* One request, with the line's default reasoning effort materialized.
|
|
155
|
+
*
|
|
156
|
+
* A caller that states an effort is passed through untouched: DSH materializes
|
|
157
|
+
* {@link resolveModel}'s default into the options for a picker-driven turn, so
|
|
158
|
+
* a value arriving here is a deliberate choice and must not be replaced. Only
|
|
159
|
+
* an unstated one is filled in, and only when the user actually configured a
|
|
160
|
+
* global level — the shipped default is "say nothing", because the model has
|
|
161
|
+
* its own and restating it in every body is a chance to disagree with it.
|
|
162
|
+
*/
|
|
163
|
+
stream(options: GenerateOptions): AsyncIterable<StreamChunk>;
|
|
164
|
+
private requestStream;
|
|
165
|
+
}
|
|
166
|
+
export { PROVIDER_ID, MinimaxCodeCredentialStore };
|
|
167
|
+
export { maxOutputTokensFor, clampOutputToContext };
|
|
168
|
+
//# sourceMappingURL=adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../../../src/host/minimax-code/adapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wire half of the MiniMax Code daily check-in.
|
|
3
|
+
*
|
|
4
|
+
* Everything in this file is measured against, or ported from, the official
|
|
5
|
+
* client's own open source (`MiniMax-AI/minimax-code`, MIT):
|
|
6
|
+
* `packages/tui/src/checkin/http-gateway.ts` does the two check-in calls and
|
|
7
|
+
* `packages/tui/src/runtime/public-gateway.ts` builds the request. The wire
|
|
8
|
+
* shape was additionally verified live against the CN deployment with this
|
|
9
|
+
* machine's own credential (see the 0.2.0-rc.1-era probe notes in the
|
|
10
|
+
* changelog): `GET signin/status` and `POST signin/claim` answer exactly the
|
|
11
|
+
* shapes validated below, and a duplicate claim answers
|
|
12
|
+
* `claim_result: 2` (AlreadyClaimed) rather than an error.
|
|
13
|
+
*
|
|
14
|
+
* The `yy` / `x-timestamp` / `x-signature` headers are the same first-party
|
|
15
|
+
* attribution literals this package's `types.ts` product-token note discusses.
|
|
16
|
+
* The official source's own comment calls them wire-protocol constants that
|
|
17
|
+
* are "not credentials or a security boundary" — authorization is the Bearer
|
|
18
|
+
* token. Unlike the quota read (where they are optional and stay off by
|
|
19
|
+
* default), the check-in gateway refuses requests without them, so this
|
|
20
|
+
* feature cannot exist without sending them; that trade is recorded in the
|
|
21
|
+
* changelog and was made explicitly, not by default. The User-Agent stays the
|
|
22
|
+
* plugin's own honest one — it is NOT part of the signed surface.
|
|
23
|
+
*/
|
|
24
|
+
import type { MinimaxCodeRegion } from '../../shared/minimax-code-contracts.ts';
|
|
25
|
+
/** Activity status surface; answers whether today is claimable or claimed. */
|
|
26
|
+
export declare const SIGNIN_STATUS_PATH = "/minimax-cloud/api/v1/signin/status";
|
|
27
|
+
/** Check-in surface; credits are granted by posting here once a day. */
|
|
28
|
+
export declare const SIGNIN_CLAIM_PATH = "/minimax-cloud/api/v1/signin/claim";
|
|
29
|
+
/** Account identity surface; resolves the realUserID the query string needs. */
|
|
30
|
+
export declare const USER_INFO_PATH = "/v1/api/user/info";
|
|
31
|
+
/** Day status values the panel reports. Mirrors the official SigninDayStatus. */
|
|
32
|
+
export declare const SIGNIN_DAY_UPCOMING = 1;
|
|
33
|
+
export declare const SIGNIN_DAY_CLAIMABLE = 2;
|
|
34
|
+
export declare const SIGNIN_DAY_CLAIMED = 3;
|
|
35
|
+
export declare const SIGNIN_DAY_DISABLED = 4;
|
|
36
|
+
/** Claim outcomes the service reports. Mirrors the official SigninClaimResult. */
|
|
37
|
+
export declare const SIGNIN_CLAIM_FRESH = 1;
|
|
38
|
+
export declare const SIGNIN_CLAIM_ALREADY = 2;
|
|
39
|
+
export declare const CHECKIN_TIMEOUT_MS = 30000;
|
|
40
|
+
/** Origin the official client uses for this surface, per region. */
|
|
41
|
+
export declare function checkinGatewayOrigin(region: MinimaxCodeRegion): string;
|
|
42
|
+
export interface SigninDayItem {
|
|
43
|
+
day_no: number;
|
|
44
|
+
points: number;
|
|
45
|
+
bonus_points?: number;
|
|
46
|
+
status: number;
|
|
47
|
+
is_today: boolean;
|
|
48
|
+
}
|
|
49
|
+
export interface SigninPanel {
|
|
50
|
+
scene: number;
|
|
51
|
+
days: SigninDayItem[];
|
|
52
|
+
}
|
|
53
|
+
export interface ClaimSigninData {
|
|
54
|
+
claim_id: string;
|
|
55
|
+
claim_result: number;
|
|
56
|
+
day_no: number;
|
|
57
|
+
points: number;
|
|
58
|
+
expire_at_ms: number;
|
|
59
|
+
panel: SigninPanel;
|
|
60
|
+
}
|
|
61
|
+
/** Identity the check-in needs beyond the access token. */
|
|
62
|
+
export interface MinimaxCodeAccountIdentity {
|
|
63
|
+
realUserID: string;
|
|
64
|
+
userName?: string;
|
|
65
|
+
subUserName?: string;
|
|
66
|
+
userEmail?: string;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Validate one panel response. Ported from the official
|
|
70
|
+
* `validateSigninPanel`: exactly seven days, day numbers 1..7 without
|
|
71
|
+
* repeats, at most one claimable and at most one "today". A panel that fails
|
|
72
|
+
* this is a wire surprise, and treating it as "nothing to do" would silently
|
|
73
|
+
* skip the day, so validation throws.
|
|
74
|
+
*/
|
|
75
|
+
export declare function validateSigninPanel(value: unknown): SigninPanel;
|
|
76
|
+
/** Validate one claim response. Ported from the official `validateClaimSigninData`. */
|
|
77
|
+
export declare function validateClaimSigninData(value: unknown): ClaimSigninData;
|
|
78
|
+
/**
|
|
79
|
+
* The consecutive-claimed count ending today, from one panel.
|
|
80
|
+
*
|
|
81
|
+
* Ported from the official `getCurrentSigninStreak`: when today is claimed it
|
|
82
|
+
* counts; when today is still claimable the streak up to yesterday is what a
|
|
83
|
+
* claim would extend, so that is what the card shows.
|
|
84
|
+
*/
|
|
85
|
+
export declare function currentSigninStreak(days: readonly SigninDayItem[]): number;
|
|
86
|
+
export interface CheckinHttpOptions {
|
|
87
|
+
fetchFn?: typeof fetch;
|
|
88
|
+
/** Clock injection for tests. */
|
|
89
|
+
nowMs?: () => number;
|
|
90
|
+
/** `desktop_version` the request reports; the plugin version in production. */
|
|
91
|
+
appVersion?: string;
|
|
92
|
+
signal?: AbortSignal;
|
|
93
|
+
}
|
|
94
|
+
export declare class MinimaxCodeCheckinHttpError extends Error {
|
|
95
|
+
readonly status: number | null;
|
|
96
|
+
constructor(message: string, status: number | null);
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Resolve the account's realUserID (and display fields) through the identity
|
|
100
|
+
* surface. The check-in query string needs realUserID and the OAuth document
|
|
101
|
+
* does not carry it, so it is resolved once per scheduler pass and cached in
|
|
102
|
+
* the check-in state afterwards.
|
|
103
|
+
*/
|
|
104
|
+
export declare function fetchAccountIdentity(accessToken: string, region: MinimaxCodeRegion, options?: CheckinHttpOptions): Promise<MinimaxCodeAccountIdentity>;
|
|
105
|
+
/** Read the seven-day panel; throws on transport, HTTP, or shape failures. */
|
|
106
|
+
export declare function fetchSigninPanel(accessToken: string, realUserID: string, region: MinimaxCodeRegion, options?: CheckinHttpOptions): Promise<SigninPanel>;
|
|
107
|
+
/** Claim today's credit; the response carries the fresh panel. */
|
|
108
|
+
export declare function claimSignin(accessToken: string, realUserID: string, region: MinimaxCodeRegion, options?: CheckinHttpOptions): Promise<ClaimSigninData>;
|
|
109
|
+
//# sourceMappingURL=checkin-gateway.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checkin-gateway.d.ts","sourceRoot":"","sources":["../../../../src/host/minimax-code/checkin-gateway.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Daily check-in scheduler for the MiniMax Code line.
|
|
3
|
+
*
|
|
4
|
+
* Modeled on the sibling WorkBuddy scheduler and kept semantically identical
|
|
5
|
+
* where the two services face the same problem; the wire half lives in
|
|
6
|
+
* ./checkin-gateway.ts (official-client recipe, verified live).
|
|
7
|
+
*
|
|
8
|
+
* - **Both regions.** The official client's public gateway has an origin per
|
|
9
|
+
* region, so an account signs in against its own region's origin. There is
|
|
10
|
+
* no CN-only carve-out like WorkBuddy's: the CLI ships the same surface
|
|
11
|
+
* worldwide.
|
|
12
|
+
* - **Idempotent.** The panel is read first; an account whose today is already
|
|
13
|
+
* claimed (by anyone) is only recorded. A duplicate claim answers
|
|
14
|
+
* `claim_result: 2` (AlreadyClaimed), which is a success, never a retry.
|
|
15
|
+
* - **Patient with the day.** A today that is neither claimable nor claimed
|
|
16
|
+
* (upcoming/disabled) is parked and re-checked on an hourly cadence rather
|
|
17
|
+
* than abandoned: the activity flips on its own schedule, and the host
|
|
18
|
+
* usually boots before it does.
|
|
19
|
+
* - **Bounded.** A failing account is retried at most {@link CHECKIN_ATTEMPT_CAP}
|
|
20
|
+
* times a day, so a broken account cannot turn the ten-minute tick into a
|
|
21
|
+
* request loop. A manual run ignores the cap and the toggle, like the
|
|
22
|
+
* workbuddy card's "check in now", and is queued behind an in-flight run.
|
|
23
|
+
*
|
|
24
|
+
* Credentials stay host-side: the only write beyond the state file is the
|
|
25
|
+
* account pool's own refresh write-back, reused here unchanged through
|
|
26
|
+
* `getFreshCredential` / `renewCredential`.
|
|
27
|
+
*/
|
|
28
|
+
import type { MinimaxCodeCheckinSummary } from '../../shared/minimax-code-contracts.ts';
|
|
29
|
+
import type { MinimaxCodeAccountPool } from './account-pool.ts';
|
|
30
|
+
/**
|
|
31
|
+
* Scheduler cadence. The first tick at host startup is the daily run; the
|
|
32
|
+
* interval keeps a long-lived process signing in on later days without a
|
|
33
|
+
* restart. Idle ticks cost no requests — the day state short-circuits them.
|
|
34
|
+
*/
|
|
35
|
+
export declare const CHECKIN_TICK_MS: number;
|
|
36
|
+
/** Daily retry ceiling for one account after a failed attempt. */
|
|
37
|
+
export declare const CHECKIN_ATTEMPT_CAP = 3;
|
|
38
|
+
/**
|
|
39
|
+
* How long a not-yet-claimable today waits before the panel is polled again.
|
|
40
|
+
* Same reasoning as the workbuddy scheduler: the activity opens on its own
|
|
41
|
+
* schedule, and the first answer of the day is frequently "not open yet".
|
|
42
|
+
*/
|
|
43
|
+
export declare const CHECKIN_INACTIVE_RECHECK_MS: number;
|
|
44
|
+
/** State document the scheduler keeps beside the other plugin stores. */
|
|
45
|
+
export declare function checkinStatePath(): string;
|
|
46
|
+
/** Local calendar day an instant belongs to; state entries are keyed by it. */
|
|
47
|
+
export declare function localDateString(nowMs: number): string;
|
|
48
|
+
/** The slice of the account pool the scheduler uses. */
|
|
49
|
+
export type MinimaxCodeCheckinPool = Pick<MinimaxCodeAccountPool, 'listAccounts' | 'getFreshCredential' | 'renewCredential'>;
|
|
50
|
+
export interface MinimaxCodeCheckinServiceOptions {
|
|
51
|
+
fetchFn?: typeof fetch;
|
|
52
|
+
/** State document path; tests redirect it, production uses {@link checkinStatePath}. */
|
|
53
|
+
statePath?: string;
|
|
54
|
+
/** Live preference, re-read on every tick so the toggle applies at once. */
|
|
55
|
+
settings: () => {
|
|
56
|
+
enabled: boolean;
|
|
57
|
+
};
|
|
58
|
+
/**
|
|
59
|
+
* Resolves once the preference store has read its stored document, so the
|
|
60
|
+
* startup pass cannot act on a default the stored document is about to
|
|
61
|
+
* overwrite. Optional for callers whose settings are already in memory.
|
|
62
|
+
*/
|
|
63
|
+
ready?: () => Promise<void>;
|
|
64
|
+
/** Clock injection for tests. */
|
|
65
|
+
now?: () => number;
|
|
66
|
+
/** `desktop_version` the wire request reports; the plugin version in production. */
|
|
67
|
+
appVersion?: string;
|
|
68
|
+
logger?: {
|
|
69
|
+
info(message: string): void;
|
|
70
|
+
warn(message: string): void;
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* The check-in scheduler. One instance per plugin load; the host owns the
|
|
75
|
+
* interval and clears it from the same `ctx.effect` that created it.
|
|
76
|
+
*/
|
|
77
|
+
export declare class MinimaxCodeCheckinService {
|
|
78
|
+
private readonly pool;
|
|
79
|
+
private readonly options;
|
|
80
|
+
private readonly fetchFn;
|
|
81
|
+
private readonly statePath;
|
|
82
|
+
private readonly now;
|
|
83
|
+
private readonly logger;
|
|
84
|
+
private readonly appVersion;
|
|
85
|
+
private state;
|
|
86
|
+
private identities;
|
|
87
|
+
private loaded;
|
|
88
|
+
/** Passes waiting to run, in order; `true` marks a manual pass. */
|
|
89
|
+
private readonly queue;
|
|
90
|
+
/** The drain loop currently working the queue, if any. */
|
|
91
|
+
private draining;
|
|
92
|
+
private lastRunAt;
|
|
93
|
+
/** Memoized preference warmup, so it is awaited once however many passes run. */
|
|
94
|
+
private readyWait;
|
|
95
|
+
constructor(pool: MinimaxCodeCheckinPool, options: MinimaxCodeCheckinServiceOptions);
|
|
96
|
+
/**
|
|
97
|
+
* One scheduler pass. Automatic passes honour the toggle and the retry cap;
|
|
98
|
+
* a manual pass (`manual: true`, the card's "check in now") ignores both
|
|
99
|
+
* but still respects an account already signed in today.
|
|
100
|
+
*
|
|
101
|
+
* A manual pass that lands while a run is already in flight is *queued*, not
|
|
102
|
+
* absorbed: joining the running pass would silently discard the one thing the
|
|
103
|
+
* button promises, that the retry cap and the toggle are bypassed now.
|
|
104
|
+
*/
|
|
105
|
+
tick(manual?: boolean): Promise<void>;
|
|
106
|
+
private drain;
|
|
107
|
+
private runQueue;
|
|
108
|
+
private run;
|
|
109
|
+
/** Wait for the preference store's warmup read, once. */
|
|
110
|
+
private ready;
|
|
111
|
+
/**
|
|
112
|
+
* Resolve the account's realUserID, cached across days.
|
|
113
|
+
*
|
|
114
|
+
* The OAuth document does not carry it and the check-in query string needs
|
|
115
|
+
* it, so it is fetched from the identity surface once and kept in the state
|
|
116
|
+
* document. The region is cached alongside because the identity call's
|
|
117
|
+
* origin depends on it.
|
|
118
|
+
*/
|
|
119
|
+
private identityFor;
|
|
120
|
+
/** Check one account in, recording the outcome in its today's entry. */
|
|
121
|
+
private checkinOne;
|
|
122
|
+
/**
|
|
123
|
+
* One full try for one account: identity, panel, and — when today is
|
|
124
|
+
* claimable — the claim. Settles the entry on every outcome; throws for the
|
|
125
|
+
* caller's renew-and-retry or attempt bookkeeping.
|
|
126
|
+
*/
|
|
127
|
+
private attemptOnce;
|
|
128
|
+
/** The status call, against the current credential. */
|
|
129
|
+
private panel;
|
|
130
|
+
/** The claim call, against the current credential. */
|
|
131
|
+
private claim;
|
|
132
|
+
/**
|
|
133
|
+
* Fold one panel into the day's entry.
|
|
134
|
+
*
|
|
135
|
+
* Returns true when the entry is settled for the day (claimed already, or
|
|
136
|
+
* parked inactive): the caller then skips the claim. Today claimable is the
|
|
137
|
+
* one answer that returns false.
|
|
138
|
+
*/
|
|
139
|
+
private recordPanelOutcome;
|
|
140
|
+
/** Record a confirmed sign-in, clearing the transient failure bookkeeping. */
|
|
141
|
+
private markSignedIn;
|
|
142
|
+
/**
|
|
143
|
+
* The aggregate the settings card renders. Reads only local state and the
|
|
144
|
+
* account list; it never spends a network request.
|
|
145
|
+
*/
|
|
146
|
+
summary(): Promise<MinimaxCodeCheckinSummary>;
|
|
147
|
+
private load;
|
|
148
|
+
private save;
|
|
149
|
+
}
|
|
150
|
+
//# sourceMappingURL=checkin.d.ts.map
|