dsh-plugin-subscription-oauth 0.5.0 → 0.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/auth/deepseek-balance.d.ts +58 -0
- package/lib/auth/deepseek-balance.js +63 -0
- package/lib/auth/rpc.d.ts +25 -2
- package/lib/auth/rpc.js +45 -23
- package/lib/client/UsageChip.d.ts +13 -23
- package/lib/client/UsageChip.js +27 -28
- package/lib/client/index.js +0 -14
- package/lib/client/subscriptions-rpc.d.ts +21 -20
- package/lib/client/subscriptions-rpc.js +16 -14
- package/lib/client.js +34 -38
- package/lib/client.js.map +1 -1
- package/lib/index.d.ts +12 -0
- package/lib/index.js +33 -1
- package/lib/protocol.d.ts +33 -3
- package/lib/protocol.js +1 -0
- package/lib/providers/kimi.d.ts +8 -0
- package/lib/providers/kimi.js +27 -1
- package/lib/translate/moonshot-schema.d.ts +54 -0
- package/lib/translate/moonshot-schema.js +142 -0
- package/package.json +1 -1
package/lib/index.d.ts
CHANGED
|
@@ -44,6 +44,18 @@ export interface Config {
|
|
|
44
44
|
* the other routes. Defaults to true.
|
|
45
45
|
*/
|
|
46
46
|
auto?: boolean;
|
|
47
|
+
/**
|
|
48
|
+
* The credential reference a non-subscription provider's balance query uses, by
|
|
49
|
+
* provider id.
|
|
50
|
+
*
|
|
51
|
+
* A provider that is not a subscription this plugin serves has no usage windows to
|
|
52
|
+
* meter, so the chip shows its balance instead — read by cc-switch's query, which needs
|
|
53
|
+
* the provider's API key. The provider's profile names that key by reference
|
|
54
|
+
* (`apiKeyEnv`), and the host's credential service resolves the name; this map is the
|
|
55
|
+
* one place a provider id is tied to that reference. A provider with no entry, or
|
|
56
|
+
* whose key does not resolve, gets no balance and the chip stays silent.
|
|
57
|
+
*/
|
|
58
|
+
balanceCredentialRefs?: Record<string, string>;
|
|
47
59
|
}
|
|
48
60
|
/** Configuration schema, with the config file's own defaults applied. */
|
|
49
61
|
export declare const Config: z<Config>;
|
package/lib/index.js
CHANGED
|
@@ -188,7 +188,39 @@ export function apply(ctx, config = {}) {
|
|
|
188
188
|
handles.set(route.id, handle);
|
|
189
189
|
ctx.effect(() => () => handle(), `${name}: ${route.id} provider route`);
|
|
190
190
|
}
|
|
191
|
-
|
|
191
|
+
// A non-subscription provider's balance is read by cc-switch's query, which needs the
|
|
192
|
+
// provider's API key. The provider's profile names that key by reference (`apiKeyEnv`),
|
|
193
|
+
// and the configured map ties a provider id to that reference; the host's credential
|
|
194
|
+
// service resolves it. The map lives in server config because that is where the rest
|
|
195
|
+
// of the plugin's wiring is, and the client learns a provider's balance by id, never
|
|
196
|
+
// by its credential reference.
|
|
197
|
+
const credentialRefs = config.balanceCredentialRefs ?? {};
|
|
198
|
+
// The DeepSeek account's balance is read on the node half through the host's
|
|
199
|
+
// `deepseekAccount` service; the browser reaches it through the plugin's own RPC, the
|
|
200
|
+
// same channel as the rest of the chip's data. The service is read lazily, per request
|
|
201
|
+
// (not once in apply), because it may register after this plugin applies; a composition
|
|
202
|
+
// without it still serves every other endpoint, and the balance endpoint answers nothing.
|
|
203
|
+
const balanceContext = {
|
|
204
|
+
credentialRefs,
|
|
205
|
+
resolveDeepSeekAccount: () => {
|
|
206
|
+
try {
|
|
207
|
+
return ctx.get('deepseekAccount');
|
|
208
|
+
}
|
|
209
|
+
catch {
|
|
210
|
+
return undefined;
|
|
211
|
+
}
|
|
212
|
+
},
|
|
213
|
+
resolveCredential: async (ref) => {
|
|
214
|
+
try {
|
|
215
|
+
const credentials = ctx.get('credentials');
|
|
216
|
+
return (await credentials?.resolve?.(ref))?.value;
|
|
217
|
+
}
|
|
218
|
+
catch {
|
|
219
|
+
return undefined;
|
|
220
|
+
}
|
|
221
|
+
},
|
|
222
|
+
};
|
|
223
|
+
registerSubscriptionRpc(ctx, registry, balanceContext);
|
|
192
224
|
// Warm each route's live catalog for an install that is already signed in.
|
|
193
225
|
for (const id of registry.ids()) {
|
|
194
226
|
void registry.discover(id, false).catch((error) => {
|
package/lib/protocol.d.ts
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
/** Prefix of every RPC method this plugin serves. */
|
|
13
13
|
export declare const RPC_PREFIX = "subscription-oauth.";
|
|
14
14
|
/** Endpoints the Settings page may call. */
|
|
15
|
-
export declare const RPC_ENDPOINTS: readonly ["status", "login", "cancel", "logout", "setDefault", "refresh", "discover", "setModelVisible", "setModelOrder", "addModel", "removeModel", "usage", "reload", "ccswitch-balance"];
|
|
15
|
+
export declare const RPC_ENDPOINTS: readonly ["status", "login", "cancel", "logout", "setDefault", "refresh", "discover", "setModelVisible", "setModelOrder", "addModel", "removeModel", "usage", "reload", "deepseek-balance", "ccswitch-balance"];
|
|
16
16
|
/** One endpoint name. */
|
|
17
17
|
export type RpcEndpoint = typeof RPC_ENDPOINTS[number];
|
|
18
18
|
/** Client → host envelope. */
|
|
@@ -313,6 +313,10 @@ export interface RpcMap {
|
|
|
313
313
|
payload: undefined;
|
|
314
314
|
value: SubscriptionStatus;
|
|
315
315
|
};
|
|
316
|
+
'deepseek-balance': {
|
|
317
|
+
payload: DeepSeekBalanceRequest;
|
|
318
|
+
value: DeepSeekBalanceResult;
|
|
319
|
+
};
|
|
316
320
|
'ccswitch-balance': {
|
|
317
321
|
payload: CcSwitchBalanceRequest;
|
|
318
322
|
value: CcSwitchBalanceResult;
|
|
@@ -343,10 +347,36 @@ export type BalanceResult =
|
|
|
343
347
|
| {
|
|
344
348
|
ok: false;
|
|
345
349
|
};
|
|
350
|
+
/** Payload of `deepseek-balance`. */
|
|
351
|
+
export interface DeepSeekBalanceRequest {
|
|
352
|
+
/** Client metadata the host's account service expects. */
|
|
353
|
+
version?: string;
|
|
354
|
+
locale?: string;
|
|
355
|
+
timezoneOffsetSeconds?: number;
|
|
356
|
+
}
|
|
357
|
+
/** One currency's wallet, as the host's account service reports it. */
|
|
358
|
+
export interface DeepSeekWallet {
|
|
359
|
+
/** ISO currency the balance is denominated in. */
|
|
360
|
+
currency: string;
|
|
361
|
+
/** Remaining balance, as a decimal string. */
|
|
362
|
+
balance: string;
|
|
363
|
+
}
|
|
364
|
+
/**
|
|
365
|
+
* Result of `deepseek-balance`.
|
|
366
|
+
*
|
|
367
|
+
* `undefined` means the account is signed out or the read failed, so a chip stays
|
|
368
|
+
* silent rather than showing a wrong figure.
|
|
369
|
+
*/
|
|
370
|
+
export type DeepSeekBalanceResult = {
|
|
371
|
+
/** Normal (topped-up) wallets, one per currency. */
|
|
372
|
+
wallets: readonly DeepSeekWallet[];
|
|
373
|
+
/** Bonus / promotional wallets, one per currency. */
|
|
374
|
+
bonusWallets: readonly DeepSeekWallet[];
|
|
375
|
+
} | undefined;
|
|
346
376
|
/** Payload of `ccswitch-balance`. */
|
|
347
377
|
export interface CcSwitchBalanceRequest {
|
|
348
|
-
/** The
|
|
349
|
-
|
|
378
|
+
/** The provider whose balance to read; the server maps it to its credential reference. */
|
|
379
|
+
provider: string;
|
|
350
380
|
}
|
|
351
381
|
/**
|
|
352
382
|
* Result of `ccswitch-balance`.
|
package/lib/protocol.js
CHANGED
package/lib/providers/kimi.d.ts
CHANGED
|
@@ -95,7 +95,15 @@ export declare class KimiAdapter extends LlmAdapter {
|
|
|
95
95
|
private discovered;
|
|
96
96
|
/** Ids the user added by hand, cached so the sync catalog can name them. */
|
|
97
97
|
private userAddedIds;
|
|
98
|
+
/** Tools already reported as flattened, so each is stated once. */
|
|
99
|
+
private readonly flattenedTools;
|
|
98
100
|
constructor(options: KimiAdapterOptions);
|
|
101
|
+
/**
|
|
102
|
+
* Tool schemas in the shape Moonshot accepts: no `$ref`, and under its size
|
|
103
|
+
* ceiling. A declaration too large to send keeps its arguments, and that is
|
|
104
|
+
* reported once per tool rather than on every turn.
|
|
105
|
+
*/
|
|
106
|
+
private moonshotTools;
|
|
99
107
|
providerInfo(provider: string): LlmProviderInfo;
|
|
100
108
|
providerRetryPolicy(): undefined;
|
|
101
109
|
listModels(_provider: string): Promise<readonly LlmModelInfo[]>;
|
package/lib/providers/kimi.js
CHANGED
|
@@ -14,6 +14,7 @@ import { idleWatchdog, httpLlmError, isMissingOrInvalidCredential, mapFetchFailu
|
|
|
14
14
|
import { streamProviderResponses } from './responses-stream.js';
|
|
15
15
|
import { fallbackEntry, findEntry, resolveCatalog } from './catalog.js';
|
|
16
16
|
import { streamResponses, toResponsesInput, toResponsesTools } from '../translate/responses.js';
|
|
17
|
+
import { prepareMoonshotTool } from '../translate/moonshot-schema.js';
|
|
17
18
|
/**
|
|
18
19
|
* Coerce one decoded credential entry into a Kimi session.
|
|
19
20
|
* @param value - decoded JSON value for one account.
|
|
@@ -130,10 +131,31 @@ export class KimiAdapter extends LlmAdapter {
|
|
|
130
131
|
discovered;
|
|
131
132
|
/** Ids the user added by hand, cached so the sync catalog can name them. */
|
|
132
133
|
userAddedIds = [];
|
|
134
|
+
/** Tools already reported as flattened, so each is stated once. */
|
|
135
|
+
flattenedTools = new Set();
|
|
133
136
|
constructor(options) {
|
|
134
137
|
super();
|
|
135
138
|
this.options = options;
|
|
136
139
|
}
|
|
140
|
+
/**
|
|
141
|
+
* Tool schemas in the shape Moonshot accepts: no `$ref`, and under its size
|
|
142
|
+
* ceiling. A declaration too large to send keeps its arguments, and that is
|
|
143
|
+
* reported once per tool rather than on every turn.
|
|
144
|
+
*/
|
|
145
|
+
moonshotTools(tools) {
|
|
146
|
+
return tools.map((tool) => {
|
|
147
|
+
const prepared = prepareMoonshotTool(tool.parameters);
|
|
148
|
+
if (prepared.preparedAs !== 'as-declared' && !this.flattenedTools.has(tool.name)) {
|
|
149
|
+
this.flattenedTools.add(tool.name);
|
|
150
|
+
this.options.onWarn?.(prepared.preparedAs === 'flattened'
|
|
151
|
+
? `kimi: ${tool.name} declares an argument schema larger than the endpoint accepts; `
|
|
152
|
+
+ 'its arguments are described without their nested structure'
|
|
153
|
+
: `kimi: ${tool.name} declares an argument schema larger than the endpoint accepts; `
|
|
154
|
+
+ 'it is offered as an unrestricted object');
|
|
155
|
+
}
|
|
156
|
+
return { ...tool, parameters: prepared.parameters };
|
|
157
|
+
});
|
|
158
|
+
}
|
|
137
159
|
providerInfo(provider) {
|
|
138
160
|
return { id: provider, name: KIMI_PROVIDER_NAME };
|
|
139
161
|
}
|
|
@@ -310,7 +332,11 @@ export class KimiAdapter extends LlmAdapter {
|
|
|
310
332
|
input: resolved.input,
|
|
311
333
|
...options.tools === undefined || options.tools.length === 0
|
|
312
334
|
? {}
|
|
313
|
-
: {
|
|
335
|
+
: {
|
|
336
|
+
tools: toResponsesTools(this.moonshotTools(options.tools)),
|
|
337
|
+
tool_choice: 'auto',
|
|
338
|
+
parallel_tool_calls: true,
|
|
339
|
+
},
|
|
314
340
|
...options.maxTokens === undefined ? {} : { max_output_tokens: options.maxTokens },
|
|
315
341
|
...options.reasoningEffort === undefined
|
|
316
342
|
? {}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool-schema preparation for the Moonshot wire (Kimi Code).
|
|
3
|
+
*
|
|
4
|
+
* Moonshot validates `tools[].function.parameters` with its own reader, and
|
|
5
|
+
* that reader expands every `$ref` before it measures or checks the schema. The
|
|
6
|
+
* harness forwards each tool's schema exactly as its owner declared it, and
|
|
7
|
+
* every MCP tool REA registers holds its shapes in a `$defs` block that its
|
|
8
|
+
* properties reference, so Kimi refused the whole request with
|
|
9
|
+
* `tools.function.parameters is not a valid moonshot flavored json schema`.
|
|
10
|
+
*
|
|
11
|
+
* Live probes against `api.kimi.com` measured both edges of that reader:
|
|
12
|
+
*
|
|
13
|
+
* - a `$ref` whose target itself holds `$ref`s is refused as
|
|
14
|
+
* `detected infinite recursion without termination condition` — the failing
|
|
15
|
+
* tool reported the node `properties.actions` and, once that node was
|
|
16
|
+
* inlined so its reference stood alone, the deeper `properties.actions.items`.
|
|
17
|
+
* A one-level reference is accepted; a chain is not.
|
|
18
|
+
* - the expanded schema has a size ceiling between 80,081 B (accepted) and
|
|
19
|
+
* 124,389 B (refused). `compare_web_captures` declares 57,175 B of shared
|
|
20
|
+
* definitions but expands past 153,000 B, so it was refused even as declared.
|
|
21
|
+
*
|
|
22
|
+
* So this module sends no references at all — every local pointer is replaced
|
|
23
|
+
* by the definition it names, and the document keywords that only existed to
|
|
24
|
+
* hold them (`$defs`, `$schema`, `$id`, `definitions`) are dropped. A pointer
|
|
25
|
+
* that re-enters itself cannot be inlined, and there the referencing node keeps
|
|
26
|
+
* its own keywords instead of recursing. A tool whose expanded schema still
|
|
27
|
+
* exceeds the ceiling is flattened in steps — the arguments with their prose,
|
|
28
|
+
* then the arguments alone, then an unrestricted object — so that one oversized
|
|
29
|
+
* tool costs its own detail rather than the whole request.
|
|
30
|
+
*
|
|
31
|
+
* @module dsh-plugin-subscription-oauth/translate/moonshot-schema
|
|
32
|
+
*/
|
|
33
|
+
/** How much of a declaration a schema too large to send had to give up. */
|
|
34
|
+
export type MoonshotPreparation =
|
|
35
|
+
/** Sent as declared, with its references inlined. */
|
|
36
|
+
'as-declared'
|
|
37
|
+
/** Only the arguments: names, types, choices, `required`, and prose while it fits. */
|
|
38
|
+
| 'flattened'
|
|
39
|
+
/** An unrestricted object, because even the arguments did not fit. */
|
|
40
|
+
| 'permissive';
|
|
41
|
+
/** One prepared tool schema together with what had to be done to it. */
|
|
42
|
+
export interface MoonshotToolSchema {
|
|
43
|
+
/** The schema to send. */
|
|
44
|
+
parameters: Record<string, unknown>;
|
|
45
|
+
/** What the declaration had to give up to fit. */
|
|
46
|
+
preparedAs: MoonshotPreparation;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Prepare one tool's parameters for Moonshot.
|
|
50
|
+
*
|
|
51
|
+
* @param parameters - the tool's declared argument schema.
|
|
52
|
+
* @returns the schema to send and what it had to give up to fit the endpoint.
|
|
53
|
+
*/
|
|
54
|
+
export declare function prepareMoonshotTool(parameters: Record<string, unknown>): MoonshotToolSchema;
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool-schema preparation for the Moonshot wire (Kimi Code).
|
|
3
|
+
*
|
|
4
|
+
* Moonshot validates `tools[].function.parameters` with its own reader, and
|
|
5
|
+
* that reader expands every `$ref` before it measures or checks the schema. The
|
|
6
|
+
* harness forwards each tool's schema exactly as its owner declared it, and
|
|
7
|
+
* every MCP tool REA registers holds its shapes in a `$defs` block that its
|
|
8
|
+
* properties reference, so Kimi refused the whole request with
|
|
9
|
+
* `tools.function.parameters is not a valid moonshot flavored json schema`.
|
|
10
|
+
*
|
|
11
|
+
* Live probes against `api.kimi.com` measured both edges of that reader:
|
|
12
|
+
*
|
|
13
|
+
* - a `$ref` whose target itself holds `$ref`s is refused as
|
|
14
|
+
* `detected infinite recursion without termination condition` — the failing
|
|
15
|
+
* tool reported the node `properties.actions` and, once that node was
|
|
16
|
+
* inlined so its reference stood alone, the deeper `properties.actions.items`.
|
|
17
|
+
* A one-level reference is accepted; a chain is not.
|
|
18
|
+
* - the expanded schema has a size ceiling between 80,081 B (accepted) and
|
|
19
|
+
* 124,389 B (refused). `compare_web_captures` declares 57,175 B of shared
|
|
20
|
+
* definitions but expands past 153,000 B, so it was refused even as declared.
|
|
21
|
+
*
|
|
22
|
+
* So this module sends no references at all — every local pointer is replaced
|
|
23
|
+
* by the definition it names, and the document keywords that only existed to
|
|
24
|
+
* hold them (`$defs`, `$schema`, `$id`, `definitions`) are dropped. A pointer
|
|
25
|
+
* that re-enters itself cannot be inlined, and there the referencing node keeps
|
|
26
|
+
* its own keywords instead of recursing. A tool whose expanded schema still
|
|
27
|
+
* exceeds the ceiling is flattened in steps — the arguments with their prose,
|
|
28
|
+
* then the arguments alone, then an unrestricted object — so that one oversized
|
|
29
|
+
* tool costs its own detail rather than the whole request.
|
|
30
|
+
*
|
|
31
|
+
* @module dsh-plugin-subscription-oauth/translate/moonshot-schema
|
|
32
|
+
*/
|
|
33
|
+
/** Keywords that describe the schema document rather than the values it accepts. */
|
|
34
|
+
const DOCUMENT_KEYS = new Set(['$schema', '$id', '$defs', 'definitions']);
|
|
35
|
+
/** Root keywords a flattened schema keeps. */
|
|
36
|
+
const ROOT_KEYS = ['type', 'description', 'required', 'additionalProperties', 'minProperties', 'maxProperties'];
|
|
37
|
+
/**
|
|
38
|
+
* Largest expanded schema the endpoint is asked to take, in bytes.
|
|
39
|
+
*
|
|
40
|
+
* Measured rather than assumed: 80,081 B was accepted and 124,389 B was refused
|
|
41
|
+
* with `At path 'root': schema exceeds maximum allowed size`. This sits below
|
|
42
|
+
* both so a schema this plugin sends has room to spare.
|
|
43
|
+
*/
|
|
44
|
+
const SIZE_BUDGET = 64 * 1024;
|
|
45
|
+
/** True for a plain object usable as a schema node. */
|
|
46
|
+
function object(value) {
|
|
47
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
48
|
+
}
|
|
49
|
+
/** Follow one local JSON pointer, or undefined when it does not resolve. */
|
|
50
|
+
function pointed(root, ref) {
|
|
51
|
+
if (!ref.startsWith('#/'))
|
|
52
|
+
return undefined;
|
|
53
|
+
let node = root;
|
|
54
|
+
for (const segment of ref.slice(2).split('/')) {
|
|
55
|
+
const key = segment.replaceAll('~1', '/').replaceAll('~0', '~');
|
|
56
|
+
if (Array.isArray(node))
|
|
57
|
+
node = node[Number(key)];
|
|
58
|
+
else if (object(node) && Object.hasOwn(node, key))
|
|
59
|
+
node = node[key];
|
|
60
|
+
else
|
|
61
|
+
return undefined;
|
|
62
|
+
}
|
|
63
|
+
return node;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Replace every reference reachable from one node with what it names.
|
|
67
|
+
*
|
|
68
|
+
* @param node - the node to rewrite.
|
|
69
|
+
* @param root - the tool's root schema, which local pointers resolve against.
|
|
70
|
+
* @param refs - pointers already being resolved on the path to this node.
|
|
71
|
+
* @returns the rewritten node.
|
|
72
|
+
*/
|
|
73
|
+
function inline(node, root, refs) {
|
|
74
|
+
if (Array.isArray(node))
|
|
75
|
+
return node.map((item) => inline(item, root, refs));
|
|
76
|
+
if (!object(node))
|
|
77
|
+
return node;
|
|
78
|
+
const { $ref, ...siblings } = node;
|
|
79
|
+
if (typeof $ref === 'string') {
|
|
80
|
+
// A repeated pointer, or one that names nothing local, cannot be inlined:
|
|
81
|
+
// the node's own keywords are all that is left.
|
|
82
|
+
const target = refs.has($ref) ? undefined : pointed(root, $ref);
|
|
83
|
+
return object(target)
|
|
84
|
+
? inline({ ...target, ...siblings }, root, new Set([...refs, $ref]))
|
|
85
|
+
: inline(siblings, root, refs);
|
|
86
|
+
}
|
|
87
|
+
return Object.fromEntries(Object.entries(node)
|
|
88
|
+
.filter(([key]) => !DOCUMENT_KEYS.has(key))
|
|
89
|
+
.map(([key, value]) => [key, inline(value, root, refs)]));
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Keep only what a model needs to call the tool: the root's own keywords, and
|
|
93
|
+
* each argument's name, type, value choices and — while the budget allows —
|
|
94
|
+
* its description.
|
|
95
|
+
*
|
|
96
|
+
* @param schema - an already inlined schema.
|
|
97
|
+
* @param prose - whether descriptions are worth their bytes.
|
|
98
|
+
* @returns the flattened schema.
|
|
99
|
+
*/
|
|
100
|
+
function flatten(schema, prose) {
|
|
101
|
+
const out = {};
|
|
102
|
+
for (const key of ROOT_KEYS) {
|
|
103
|
+
if (Object.hasOwn(schema, key) && (prose || key !== 'description'))
|
|
104
|
+
out[key] = schema[key];
|
|
105
|
+
}
|
|
106
|
+
if (!object(schema.properties))
|
|
107
|
+
return out;
|
|
108
|
+
out.properties = Object.fromEntries(Object.entries(schema.properties).map(([name, property]) => {
|
|
109
|
+
const node = object(property) ? property : {};
|
|
110
|
+
const reduced = {};
|
|
111
|
+
if (typeof node.type === 'string')
|
|
112
|
+
reduced.type = node.type;
|
|
113
|
+
if (Array.isArray(node.enum))
|
|
114
|
+
reduced.enum = node.enum;
|
|
115
|
+
if (prose && typeof node.description === 'string')
|
|
116
|
+
reduced.description = node.description;
|
|
117
|
+
return [name, reduced];
|
|
118
|
+
}));
|
|
119
|
+
return out;
|
|
120
|
+
}
|
|
121
|
+
/** Bytes the endpoint measures once it has expanded every reference. */
|
|
122
|
+
function expandedBytes(schema) {
|
|
123
|
+
return Buffer.byteLength(JSON.stringify(schema));
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Prepare one tool's parameters for Moonshot.
|
|
127
|
+
*
|
|
128
|
+
* @param parameters - the tool's declared argument schema.
|
|
129
|
+
* @returns the schema to send and what it had to give up to fit the endpoint.
|
|
130
|
+
*/
|
|
131
|
+
export function prepareMoonshotTool(parameters) {
|
|
132
|
+
const inlined = inline(parameters, parameters, new Set());
|
|
133
|
+
if (expandedBytes(inlined) <= SIZE_BUDGET)
|
|
134
|
+
return { parameters: inlined, preparedAs: 'as-declared' };
|
|
135
|
+
const documented = flatten(inlined, true);
|
|
136
|
+
if (expandedBytes(documented) <= SIZE_BUDGET)
|
|
137
|
+
return { parameters: documented, preparedAs: 'flattened' };
|
|
138
|
+
const bare = flatten(inlined, false);
|
|
139
|
+
if (expandedBytes(bare) <= SIZE_BUDGET)
|
|
140
|
+
return { parameters: bare, preparedAs: 'flattened' };
|
|
141
|
+
return { parameters: { type: 'object', additionalProperties: true }, preparedAs: 'permissive' };
|
|
142
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-plugin-subscription-oauth",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.1",
|
|
4
4
|
"description": "Use subscription accounts as DeepSeek Harness LLM providers — Kimi Code (OAuth device flow), Grok / X Premium (OIDC + PKCE), Google Antigravity (Google OAuth + Cloud Code Assist) and GLM / BigModel (ZCode's browser sign-in) — with per-model visibility, drag-to-reorder Auto fallback and plan quotas from the web Settings page",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "EricFL1998",
|