dsh-plugin-subscription-oauth 0.6.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/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,7 +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 {
|
|
17
|
+
import { prepareMoonshotTool } from '../translate/moonshot-schema.js';
|
|
18
18
|
/**
|
|
19
19
|
* Coerce one decoded credential entry into a Kimi session.
|
|
20
20
|
* @param value - decoded JSON value for one account.
|
|
@@ -131,10 +131,31 @@ export class KimiAdapter extends LlmAdapter {
|
|
|
131
131
|
discovered;
|
|
132
132
|
/** Ids the user added by hand, cached so the sync catalog can name them. */
|
|
133
133
|
userAddedIds = [];
|
|
134
|
+
/** Tools already reported as flattened, so each is stated once. */
|
|
135
|
+
flattenedTools = new Set();
|
|
134
136
|
constructor(options) {
|
|
135
137
|
super();
|
|
136
138
|
this.options = options;
|
|
137
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
|
+
}
|
|
138
159
|
providerInfo(provider) {
|
|
139
160
|
return { id: provider, name: KIMI_PROVIDER_NAME };
|
|
140
161
|
}
|
|
@@ -311,7 +332,11 @@ export class KimiAdapter extends LlmAdapter {
|
|
|
311
332
|
input: resolved.input,
|
|
312
333
|
...options.tools === undefined || options.tools.length === 0
|
|
313
334
|
? {}
|
|
314
|
-
: {
|
|
335
|
+
: {
|
|
336
|
+
tools: toResponsesTools(this.moonshotTools(options.tools)),
|
|
337
|
+
tool_choice: 'auto',
|
|
338
|
+
parallel_tool_calls: true,
|
|
339
|
+
},
|
|
315
340
|
...options.maxTokens === undefined ? {} : { max_output_tokens: options.maxTokens },
|
|
316
341
|
...options.reasoningEffort === undefined
|
|
317
342
|
? {}
|
|
@@ -1,31 +1,54 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Tool-schema preparation for the Moonshot wire (Kimi Code).
|
|
3
3
|
*
|
|
4
|
-
* Moonshot validates `tools[].function.parameters` with its own
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* tools REA registers use that shape heavily —
|
|
11
|
-
* `{"$ref": "#/$defs/__schema12", "description": "..."}` — 153 of 170 tools
|
|
12
|
-
* carried at least one such node, and the first one Moonshot reached killed
|
|
13
|
-
* every Kimi request that included a tool.
|
|
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`.
|
|
14
10
|
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
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.
|
|
22
30
|
*
|
|
23
31
|
* @module dsh-plugin-subscription-oauth/translate/moonshot-schema
|
|
24
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
|
+
}
|
|
25
48
|
/**
|
|
26
49
|
* Prepare one tool's parameters for Moonshot.
|
|
27
50
|
*
|
|
28
51
|
* @param parameters - the tool's declared argument schema.
|
|
29
|
-
* @returns
|
|
52
|
+
* @returns the schema to send and what it had to give up to fit the endpoint.
|
|
30
53
|
*/
|
|
31
|
-
export declare function
|
|
54
|
+
export declare function prepareMoonshotTool(parameters: Record<string, unknown>): MoonshotToolSchema;
|
|
@@ -1,27 +1,47 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Tool-schema preparation for the Moonshot wire (Kimi Code).
|
|
3
3
|
*
|
|
4
|
-
* Moonshot validates `tools[].function.parameters` with its own
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* tools REA registers use that shape heavily —
|
|
11
|
-
* `{"$ref": "#/$defs/__schema12", "description": "..."}` — 153 of 170 tools
|
|
12
|
-
* carried at least one such node, and the first one Moonshot reached killed
|
|
13
|
-
* every Kimi request that included a tool.
|
|
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`.
|
|
14
10
|
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
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.
|
|
22
30
|
*
|
|
23
31
|
* @module dsh-plugin-subscription-oauth/translate/moonshot-schema
|
|
24
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;
|
|
25
45
|
/** True for a plain object usable as a schema node. */
|
|
26
46
|
function object(value) {
|
|
27
47
|
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
@@ -43,7 +63,7 @@ function pointed(root, ref) {
|
|
|
43
63
|
return node;
|
|
44
64
|
}
|
|
45
65
|
/**
|
|
46
|
-
*
|
|
66
|
+
* Replace every reference reachable from one node with what it names.
|
|
47
67
|
*
|
|
48
68
|
* @param node - the node to rewrite.
|
|
49
69
|
* @param root - the tool's root schema, which local pointers resolve against.
|
|
@@ -56,26 +76,67 @@ function inline(node, root, refs) {
|
|
|
56
76
|
if (!object(node))
|
|
57
77
|
return node;
|
|
58
78
|
const { $ref, ...siblings } = node;
|
|
59
|
-
if (typeof $ref
|
|
60
|
-
|
|
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);
|
|
61
86
|
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
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));
|
|
72
124
|
}
|
|
73
125
|
/**
|
|
74
126
|
* Prepare one tool's parameters for Moonshot.
|
|
75
127
|
*
|
|
76
128
|
* @param parameters - the tool's declared argument schema.
|
|
77
|
-
* @returns
|
|
129
|
+
* @returns the schema to send and what it had to give up to fit the endpoint.
|
|
78
130
|
*/
|
|
79
|
-
export function
|
|
80
|
-
|
|
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' };
|
|
81
142
|
}
|
|
@@ -53,11 +53,9 @@ export declare function toResponsesInput(messages: readonly RequestMessage[], sy
|
|
|
53
53
|
* than letting the endpoint normalize every schema into strict mode.
|
|
54
54
|
*
|
|
55
55
|
* @param tools - the request's tool schemas.
|
|
56
|
-
* @param prepare - an endpoint-specific rewrite of one parameters schema, for
|
|
57
|
-
* a route whose JSON-Schema reader refuses the schema as declared.
|
|
58
56
|
* @returns `tools` array entries.
|
|
59
57
|
*/
|
|
60
|
-
export declare function toResponsesTools(tools: readonly ToolSchema[]
|
|
58
|
+
export declare function toResponsesTools(tools: readonly ToolSchema[]): Record<string, unknown>[];
|
|
61
59
|
/** The `usage` object of a completed response. */
|
|
62
60
|
export interface ResponsesUsage {
|
|
63
61
|
input_tokens?: number;
|
|
@@ -124,16 +124,14 @@ export async function toResponsesInput(messages, system, resolveImage) {
|
|
|
124
124
|
* than letting the endpoint normalize every schema into strict mode.
|
|
125
125
|
*
|
|
126
126
|
* @param tools - the request's tool schemas.
|
|
127
|
-
* @param prepare - an endpoint-specific rewrite of one parameters schema, for
|
|
128
|
-
* a route whose JSON-Schema reader refuses the schema as declared.
|
|
129
127
|
* @returns `tools` array entries.
|
|
130
128
|
*/
|
|
131
|
-
export function toResponsesTools(tools
|
|
129
|
+
export function toResponsesTools(tools) {
|
|
132
130
|
return tools.map((tool) => ({
|
|
133
131
|
type: 'function',
|
|
134
132
|
name: tool.name,
|
|
135
133
|
description: tool.description,
|
|
136
|
-
parameters:
|
|
134
|
+
parameters: tool.parameters,
|
|
137
135
|
strict: false,
|
|
138
136
|
}));
|
|
139
137
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-plugin-subscription-oauth",
|
|
3
|
-
"version": "0.6.
|
|
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",
|