dsh-llm-ustc 0.2.0 → 0.3.0
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.md +17 -8
- package/lib/adapter.js +28 -24
- package/lib/adapter.js.map +1 -1
- package/lib/client.js +256 -125
- package/lib/config.js +7 -4
- package/lib/config.js.map +1 -1
- package/lib/constants.js +3 -2
- package/lib/constants.js.map +1 -1
- package/lib/index.js +25 -17
- package/lib/index.js.map +1 -1
- package/lib/model-catalog.js +5 -9
- package/lib/model-catalog.js.map +1 -1
- package/lib/state.js +9 -9
- package/lib/state.js.map +1 -1
- package/lib/tokenworks.js +379 -0
- package/lib/tokenworks.js.map +1 -0
- package/lib/types/adapter.d.ts +3 -1
- package/lib/types/adapter.d.ts.map +1 -1
- package/lib/types/client/index.d.ts +24 -6
- package/lib/types/client/index.d.ts.map +1 -1
- package/lib/types/config.d.ts +16 -3
- package/lib/types/config.d.ts.map +1 -1
- package/lib/types/constants.d.ts +3 -2
- package/lib/types/constants.d.ts.map +1 -1
- package/lib/types/index.d.ts +1 -1
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/model-catalog.d.ts +2 -3
- package/lib/types/model-catalog.d.ts.map +1 -1
- package/lib/types/state.d.ts +1 -1
- package/lib/types/state.d.ts.map +1 -1
- package/lib/types/tokenworks.d.ts +44 -0
- package/lib/types/tokenworks.d.ts.map +1 -0
- package/lib/types/web.d.ts +23 -1
- package/lib/types/web.d.ts.map +1 -1
- package/lib/web.js +80 -51
- package/lib/web.js.map +1 -1
- package/locale/en.json +6 -0
- package/locale/zh.json +6 -0
- package/package.json +63 -43
package/lib/index.js
CHANGED
|
@@ -1,42 +1,50 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { credentialRef } from '@deepseek-ai/dsh-credentials';
|
|
2
|
+
import { assertUsableApiKey, LlmError } from '@deepseek-ai/dsh-llm';
|
|
2
3
|
import { UstcAdapter } from "./adapter.js";
|
|
3
4
|
import { Config, resolveConfig } from "./config.js";
|
|
4
|
-
import { PROVIDER, PROVIDER_NAME, SETTINGS_NS } from "./constants.js";
|
|
5
|
+
import { API_KEY_REF, PROVIDER, PROVIDER_NAME, SETTINGS_NS } from "./constants.js";
|
|
5
6
|
import { HelperManager } from "./helper.js";
|
|
6
7
|
import { ModelCatalog } from "./model-catalog.js";
|
|
7
8
|
import { StateStore } from "./state.js";
|
|
9
|
+
import { TokenworksAuth } from "./tokenworks.js";
|
|
8
10
|
import { installWeb, UstcWebBackend } from "./web.js";
|
|
9
11
|
export const name = 'dsh-llm-ustc';
|
|
10
12
|
export const inject = ['llm', 'credentials', 'settings'];
|
|
11
13
|
export { Config };
|
|
12
|
-
export async function apply(ctx, config
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
applies: 'live',
|
|
16
|
-
validate: resolveConfig,
|
|
17
|
-
});
|
|
14
|
+
export async function apply(ctx, config) {
|
|
15
|
+
ctx.inject(['settings'], child => { child.effect(() => child.settings.configure({ auto: false }, ctx.fiber)); });
|
|
16
|
+
const settingsId = ctx.fiber.entry?.options.id ?? SETTINGS_NS;
|
|
18
17
|
const store = new StateStore();
|
|
19
18
|
await store.load();
|
|
20
|
-
const helper = new HelperManager(ctx, resolveConfig(
|
|
21
|
-
const
|
|
22
|
-
const
|
|
19
|
+
const helper = new HelperManager(ctx, resolveConfig(config));
|
|
20
|
+
const tokenworks = new TokenworksAuth(ctx);
|
|
21
|
+
const resolveApiKey = async () => {
|
|
22
|
+
if (config.keySource.get() === 'tokenworks')
|
|
23
|
+
return tokenworks.apiKey();
|
|
24
|
+
const hit = await ctx.credentials.resolve(credentialRef(API_KEY_REF));
|
|
25
|
+
if (hit === undefined)
|
|
26
|
+
throw new LlmError(`USTC LLM credential ${API_KEY_REF} is not configured`, 'MISSING_CREDENTIAL');
|
|
27
|
+
return assertUsableApiKey(hit.value, name, API_KEY_REF);
|
|
28
|
+
};
|
|
29
|
+
const catalog = new ModelCatalog(resolveApiKey, helper, store);
|
|
30
|
+
const adapter = new UstcAdapter(ctx, helper, catalog, resolveApiKey);
|
|
23
31
|
const registration = ctx.llm.registerAdapter([PROVIDER], adapter);
|
|
24
32
|
const directory = ctx.llm.registerConfigurableProviders([{
|
|
25
33
|
provider: PROVIDER,
|
|
26
34
|
displayName: PROVIDER_NAME,
|
|
27
|
-
settingsNs:
|
|
35
|
+
settingsNs: settingsId,
|
|
28
36
|
settingsPath: [],
|
|
29
37
|
declared: false,
|
|
30
38
|
}]);
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
39
|
+
ctx.on('settings/document-updated', ns => {
|
|
40
|
+
if (ns === settingsId)
|
|
41
|
+
helper.reconfigure(resolveConfig(config));
|
|
34
42
|
});
|
|
35
|
-
installWeb(ctx, new UstcWebBackend(ctx, helper, catalog, store));
|
|
43
|
+
installWeb(ctx, new UstcWebBackend(ctx, helper, catalog, store, undefined, settingsId, config, tokenworks));
|
|
36
44
|
return async () => {
|
|
37
|
-
watch();
|
|
38
45
|
directory();
|
|
39
46
|
registration();
|
|
47
|
+
tokenworks.dispose();
|
|
40
48
|
await helper.dispose();
|
|
41
49
|
};
|
|
42
50
|
}
|
package/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/lib/model-catalog.js
CHANGED
|
@@ -1,12 +1,10 @@
|
|
|
1
|
-
import { credentialRef } from '@deepseek-ai/dsh-credentials';
|
|
2
|
-
import { API_KEY_REF } from "./constants.js";
|
|
3
1
|
import { normalizeModels } from "./state.js";
|
|
4
2
|
export class ModelCatalog {
|
|
5
|
-
|
|
3
|
+
resolveApiKey;
|
|
6
4
|
helper;
|
|
7
5
|
store;
|
|
8
|
-
constructor(
|
|
9
|
-
this.
|
|
6
|
+
constructor(resolveApiKey, helper, store) {
|
|
7
|
+
this.resolveApiKey = resolveApiKey;
|
|
10
8
|
this.helper = helper;
|
|
11
9
|
this.store = store;
|
|
12
10
|
this.helper.onDirectRecovered(async () => { await this.refresh(); });
|
|
@@ -15,15 +13,13 @@ export class ModelCatalog {
|
|
|
15
13
|
return this.store.models();
|
|
16
14
|
}
|
|
17
15
|
async refresh(signal) {
|
|
18
|
-
const
|
|
19
|
-
if (credential === undefined)
|
|
20
|
-
throw new Error(`${API_KEY_REF} is not configured`);
|
|
16
|
+
const key = await this.resolveApiKey();
|
|
21
17
|
const timeout = AbortSignal.timeout(20_000);
|
|
22
18
|
const response = await this.helper.fetch('/v1/models', {
|
|
23
19
|
signal: signal === undefined ? timeout : AbortSignal.any([signal, timeout]),
|
|
24
20
|
headers: {
|
|
25
21
|
accept: 'application/json',
|
|
26
|
-
authorization: `Bearer ${
|
|
22
|
+
authorization: `Bearer ${key}`,
|
|
27
23
|
},
|
|
28
24
|
});
|
|
29
25
|
if (!response.ok)
|
package/lib/model-catalog.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model-catalog.js","sourceRoot":"","sources":["../src/model-catalog.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"model-catalog.js","sourceRoot":"","sources":["../src/model-catalog.ts"],"names":[],"mappings":"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"}
|
package/lib/state.js
CHANGED
|
@@ -1,20 +1,16 @@
|
|
|
1
1
|
import { mkdir, readFile, rename, writeFile } from 'node:fs/promises';
|
|
2
|
-
import { dirname
|
|
3
|
-
import {
|
|
2
|
+
import { dirname } from 'node:path';
|
|
3
|
+
import { dshCachePath, resolveDshHome } from '@deepseek-ai/dsh-home-paths';
|
|
4
4
|
import { DEFAULT_MODEL } from "./constants.js";
|
|
5
5
|
const FALLBACK = {
|
|
6
6
|
models: [{ id: DEFAULT_MODEL, name: DEFAULT_MODEL }],
|
|
7
7
|
};
|
|
8
|
-
export function resolveDshHome() {
|
|
9
|
-
const configured = process.env.DSH_HOME?.trim();
|
|
10
|
-
return configured === undefined || configured.length === 0 ? join(homedir(), '.dsh') : configured;
|
|
11
|
-
}
|
|
12
8
|
export class StateStore {
|
|
13
9
|
filename;
|
|
14
10
|
current = structuredClone(FALLBACK);
|
|
15
11
|
writes = Promise.resolve();
|
|
16
12
|
constructor(dshHome = resolveDshHome()) {
|
|
17
|
-
this.filename =
|
|
13
|
+
this.filename = dshCachePath({ dshHome }, 'dsh-llm-ustc', 'models.json');
|
|
18
14
|
}
|
|
19
15
|
async load() {
|
|
20
16
|
try {
|
|
@@ -43,6 +39,10 @@ export class StateStore {
|
|
|
43
39
|
};
|
|
44
40
|
await this.persist();
|
|
45
41
|
}
|
|
42
|
+
async removeModel(id) {
|
|
43
|
+
this.current = { ...this.current, models: this.current.models.filter(model => model.id !== id) };
|
|
44
|
+
await this.persist();
|
|
45
|
+
}
|
|
46
46
|
async persist() {
|
|
47
47
|
const snapshot = `${JSON.stringify(this.current, null, 2)}\n`;
|
|
48
48
|
this.writes = this.writes.then(async () => {
|
|
@@ -58,7 +58,7 @@ export function normalizeModels(models) {
|
|
|
58
58
|
const unique = new Map();
|
|
59
59
|
for (const model of models) {
|
|
60
60
|
const id = model.id.trim();
|
|
61
|
-
if (id.length === 0 || id.length > 256 || /^claude/iu.test(id) || unique.has(id))
|
|
61
|
+
if (id.length === 0 || id.length > 256 || /^(?:claude|smart)/iu.test(id) || id.toLowerCase() === 'unlimited-ocr' || unique.has(id))
|
|
62
62
|
continue;
|
|
63
63
|
const name = model.name.trim();
|
|
64
64
|
unique.set(id, { id, name: name.length === 0 ? id : name });
|
|
@@ -78,7 +78,7 @@ function parseState(value) {
|
|
|
78
78
|
return structuredClone(FALLBACK);
|
|
79
79
|
let models;
|
|
80
80
|
try {
|
|
81
|
-
models = normalizeModels(value.models.filter(isCachedModel));
|
|
81
|
+
models = value.models.length === 0 ? [] : normalizeModels(value.models.filter(isCachedModel));
|
|
82
82
|
}
|
|
83
83
|
catch {
|
|
84
84
|
models = structuredClone(FALLBACK.models);
|
package/lib/state.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"state.js","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AACrE,OAAO,EAAE,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"state.js","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,379 @@
|
|
|
1
|
+
import { credentialRef } from '@deepseek-ai/dsh-credentials';
|
|
2
|
+
import { createHash, createPublicKey, randomBytes, verify } from 'node:crypto';
|
|
3
|
+
import { createServer } from 'node:http';
|
|
4
|
+
import { request as httpsRequest } from 'node:https';
|
|
5
|
+
import { TOKENWORKS_SESSION_REF } from "./constants.js";
|
|
6
|
+
const ISSUER = 'https://id.ustc.edu.cn/doc/oidc';
|
|
7
|
+
const CONTENT_ROOT = 'https://id.ustc.edu.cn/doc/claude/tokenworks-content';
|
|
8
|
+
const BOOTSTRAP_URL = 'https://id.ustc.edu.cn/doc/claude/bootstrap';
|
|
9
|
+
const PUBLISHER_KEY = '-----BEGIN PUBLIC KEY-----\nMCowBQYDK2VwAyEAQaBXGreNtCH3e1iRrPECbtZofjjB/OJefrBKgEpQ5lI=\n-----END PUBLIC KEY-----';
|
|
10
|
+
const LOGIN_TTL = 10 * 60_000;
|
|
11
|
+
/** Only obtains a gateway key; inference still uses the existing USTC helper. */
|
|
12
|
+
export class TokenworksAuth {
|
|
13
|
+
ctx;
|
|
14
|
+
request;
|
|
15
|
+
publisherKey;
|
|
16
|
+
pending;
|
|
17
|
+
config;
|
|
18
|
+
key;
|
|
19
|
+
fetching;
|
|
20
|
+
credentialWrites = Promise.resolve();
|
|
21
|
+
generation = 0;
|
|
22
|
+
error;
|
|
23
|
+
ref = credentialRef(TOKENWORKS_SESSION_REF);
|
|
24
|
+
constructor(ctx, request = requestDirect, publisherKey = PUBLISHER_KEY) {
|
|
25
|
+
this.ctx = ctx;
|
|
26
|
+
this.request = request;
|
|
27
|
+
this.publisherKey = publisherKey;
|
|
28
|
+
}
|
|
29
|
+
async snapshot() {
|
|
30
|
+
const [info, session] = await Promise.all([this.ctx.credentials.describe(this.ref), this.readSession()]);
|
|
31
|
+
return {
|
|
32
|
+
configured: session !== undefined,
|
|
33
|
+
writable: info.writable,
|
|
34
|
+
pending: this.pending !== undefined,
|
|
35
|
+
...(session === undefined ? {} : { name: session.name }),
|
|
36
|
+
...(this.error === undefined ? {} : { error: this.error }),
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
async begin() {
|
|
40
|
+
this.cancel();
|
|
41
|
+
this.error = undefined;
|
|
42
|
+
const generation = this.generation;
|
|
43
|
+
const config = await this.loginConfig();
|
|
44
|
+
if (generation !== this.generation)
|
|
45
|
+
throw new Error('Tokenworks sign-in was cancelled');
|
|
46
|
+
const state = randomBytes(24).toString('base64url');
|
|
47
|
+
const nonce = randomBytes(24).toString('base64url');
|
|
48
|
+
const verifier = randomBytes(48).toString('base64url');
|
|
49
|
+
const server = createServer((request, response) => {
|
|
50
|
+
response.setHeader('content-type', 'text/html; charset=utf-8');
|
|
51
|
+
response.setHeader('cache-control', 'no-store');
|
|
52
|
+
response.setHeader('content-security-policy', "default-src 'none'; frame-ancestors 'none'");
|
|
53
|
+
const pending = this.pending;
|
|
54
|
+
const url = new URL(request.url ?? '/', 'http://127.0.0.1');
|
|
55
|
+
if (request.method !== 'GET' || url.pathname !== '/callback') {
|
|
56
|
+
response.writeHead(404).end();
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
if (pending?.server !== server || pending.consumed || url.searchParams.get('state') !== pending.state) {
|
|
60
|
+
response.writeHead(400).end('登录状态无效,请重新开始登录。');
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
pending.consumed = true;
|
|
64
|
+
void this.complete(pending, url).then(() => {
|
|
65
|
+
response.end('词元工坊登录完成,可以关闭此页并返回 DSH。');
|
|
66
|
+
}, error => {
|
|
67
|
+
if (pending.generation === this.generation)
|
|
68
|
+
this.error = error instanceof Error ? error.message : 'Tokenworks sign-in failed';
|
|
69
|
+
response.writeHead(400).end('词元工坊登录失败,请返回 DSH 查看错误并重试。');
|
|
70
|
+
}).finally(() => { if (this.pending === pending)
|
|
71
|
+
this.closeLogin(); });
|
|
72
|
+
});
|
|
73
|
+
await new Promise((resolve, reject) => {
|
|
74
|
+
server.once('error', reject);
|
|
75
|
+
server.listen(0, '127.0.0.1', () => { server.removeListener('error', reject); resolve(); });
|
|
76
|
+
});
|
|
77
|
+
if (generation !== this.generation) {
|
|
78
|
+
server.close();
|
|
79
|
+
throw new Error('Tokenworks sign-in was cancelled');
|
|
80
|
+
}
|
|
81
|
+
const address = server.address();
|
|
82
|
+
const redirectUri = `http://127.0.0.1:${address.port}/callback`;
|
|
83
|
+
const timer = setTimeout(() => {
|
|
84
|
+
this.cancel();
|
|
85
|
+
this.error = 'Tokenworks sign-in expired; start again';
|
|
86
|
+
}, LOGIN_TTL);
|
|
87
|
+
timer.unref();
|
|
88
|
+
server.unref();
|
|
89
|
+
this.pending = { server, timer, state, nonce, verifier, redirectUri, config, generation, consumed: false };
|
|
90
|
+
const url = new URL(config.authorizationEndpoint);
|
|
91
|
+
url.search = new URLSearchParams({
|
|
92
|
+
client_id: config.clientId, response_type: 'code', redirect_uri: redirectUri,
|
|
93
|
+
scope: config.scopes.join(' '), state, nonce,
|
|
94
|
+
code_challenge: createHash('sha256').update(verifier).digest('base64url'),
|
|
95
|
+
code_challenge_method: 'S256',
|
|
96
|
+
}).toString();
|
|
97
|
+
return { authUrl: url.href };
|
|
98
|
+
}
|
|
99
|
+
cancel() {
|
|
100
|
+
++this.generation;
|
|
101
|
+
this.closeLogin();
|
|
102
|
+
this.fetching = undefined;
|
|
103
|
+
}
|
|
104
|
+
async logout() {
|
|
105
|
+
this.cancel();
|
|
106
|
+
this.key = undefined;
|
|
107
|
+
this.error = undefined;
|
|
108
|
+
await this.writeSession(undefined, this.generation);
|
|
109
|
+
}
|
|
110
|
+
dispose() {
|
|
111
|
+
this.cancel();
|
|
112
|
+
this.key = undefined;
|
|
113
|
+
}
|
|
114
|
+
async apiKey() {
|
|
115
|
+
if (this.key !== undefined && Date.now() < this.key.recheckAt && Date.now() < this.key.expiresAt)
|
|
116
|
+
return this.key.value;
|
|
117
|
+
if (this.fetching !== undefined)
|
|
118
|
+
return this.fetching;
|
|
119
|
+
const generation = this.generation;
|
|
120
|
+
const fetching = this.fetchKey(generation);
|
|
121
|
+
this.fetching = fetching;
|
|
122
|
+
try {
|
|
123
|
+
return await fetching;
|
|
124
|
+
}
|
|
125
|
+
finally {
|
|
126
|
+
if (this.fetching === fetching)
|
|
127
|
+
this.fetching = undefined;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
closeLogin() {
|
|
131
|
+
if (this.pending === undefined)
|
|
132
|
+
return;
|
|
133
|
+
clearTimeout(this.pending.timer);
|
|
134
|
+
this.pending.server.close();
|
|
135
|
+
this.pending = undefined;
|
|
136
|
+
}
|
|
137
|
+
async complete(pending, url) {
|
|
138
|
+
const issuer = url.searchParams.get('iss');
|
|
139
|
+
if ((pending.config.requiresIssuer || issuer !== null) && issuer !== ISSUER)
|
|
140
|
+
throw new Error('Tokenworks callback issuer does not match');
|
|
141
|
+
if (url.searchParams.has('error'))
|
|
142
|
+
throw new Error('Tokenworks sign-in was denied');
|
|
143
|
+
const code = url.searchParams.get('code');
|
|
144
|
+
if (!code)
|
|
145
|
+
throw new Error('Tokenworks callback has no authorization code');
|
|
146
|
+
const token = await this.exchange(pending.config, {
|
|
147
|
+
grant_type: 'authorization_code', code, redirect_uri: pending.redirectUri, code_verifier: pending.verifier,
|
|
148
|
+
});
|
|
149
|
+
const claims = await this.verifyIdToken(token.id_token, pending.config, pending.nonce);
|
|
150
|
+
const session = this.sessionFromToken(token, pending.config.clientId, claims);
|
|
151
|
+
const key = await this.bootstrap(session.accessToken);
|
|
152
|
+
if (pending.generation !== this.generation)
|
|
153
|
+
throw new Error('Tokenworks sign-in was cancelled');
|
|
154
|
+
await this.writeSession(session, pending.generation);
|
|
155
|
+
if (pending.generation !== this.generation)
|
|
156
|
+
throw new Error('Tokenworks sign-in was cancelled');
|
|
157
|
+
this.key = key;
|
|
158
|
+
this.error = undefined;
|
|
159
|
+
}
|
|
160
|
+
async fetchKey(generation) {
|
|
161
|
+
try {
|
|
162
|
+
let session = await this.readSession();
|
|
163
|
+
if (session === undefined)
|
|
164
|
+
throw new Error('Sign in to Tokenworks first');
|
|
165
|
+
if (Date.now() + 30_000 >= session.expiresAt) {
|
|
166
|
+
if (!session.refreshToken)
|
|
167
|
+
throw new LoginExpired();
|
|
168
|
+
const config = await this.loginConfig();
|
|
169
|
+
if (config.clientId !== session.clientId)
|
|
170
|
+
throw new LoginExpired();
|
|
171
|
+
const token = await this.exchange(config, { grant_type: 'refresh_token', refresh_token: session.refreshToken });
|
|
172
|
+
const claims = token.id_token === undefined ? { sub: session.subject, name: session.name } : await this.verifyIdToken(token.id_token, config);
|
|
173
|
+
if (claims.sub !== session.subject)
|
|
174
|
+
throw new Error('Tokenworks refreshed account does not match');
|
|
175
|
+
session = this.sessionFromToken(token, session.clientId, claims, session.refreshToken);
|
|
176
|
+
if (generation !== this.generation)
|
|
177
|
+
throw new Error('Tokenworks sign-in changed');
|
|
178
|
+
await this.writeSession(session, generation);
|
|
179
|
+
}
|
|
180
|
+
const key = await this.bootstrap(session.accessToken);
|
|
181
|
+
if (generation !== this.generation)
|
|
182
|
+
throw new Error('Tokenworks sign-in changed');
|
|
183
|
+
this.key = key;
|
|
184
|
+
return key.value;
|
|
185
|
+
}
|
|
186
|
+
catch (error) {
|
|
187
|
+
if (generation !== this.generation)
|
|
188
|
+
throw new Error('Tokenworks sign-in changed');
|
|
189
|
+
if (error instanceof LoginExpired) {
|
|
190
|
+
this.key = undefined;
|
|
191
|
+
await this.writeSession(undefined, generation);
|
|
192
|
+
}
|
|
193
|
+
else if (error instanceof AccessDenied) {
|
|
194
|
+
this.key = undefined;
|
|
195
|
+
}
|
|
196
|
+
else if (error instanceof NetworkError && this.key !== undefined && Date.now() < this.key.expiresAt) {
|
|
197
|
+
this.key.recheckAt = Math.min(this.key.expiresAt, Date.now() + 60_000);
|
|
198
|
+
return this.key.value;
|
|
199
|
+
}
|
|
200
|
+
throw error;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
async readSession() {
|
|
204
|
+
const hit = await this.ctx.credentials.resolve(this.ref);
|
|
205
|
+
return hit === undefined ? undefined : JSON.parse(hit.value);
|
|
206
|
+
}
|
|
207
|
+
// Serialize writes so a refresh completing during sign-out cannot restore the session.
|
|
208
|
+
writeSession(session, generation) {
|
|
209
|
+
this.credentialWrites = this.credentialWrites.catch(() => { }).then(async () => {
|
|
210
|
+
if (generation !== this.generation)
|
|
211
|
+
return;
|
|
212
|
+
if (session === undefined)
|
|
213
|
+
await this.ctx.credentials.unset(this.ref);
|
|
214
|
+
else
|
|
215
|
+
await this.ctx.credentials.set(this.ref, JSON.stringify(session));
|
|
216
|
+
});
|
|
217
|
+
return this.credentialWrites;
|
|
218
|
+
}
|
|
219
|
+
async exchange(config, fields) {
|
|
220
|
+
const response = await this.request(config.tokenEndpoint, {
|
|
221
|
+
method: 'POST', headers: { 'content-type': 'application/x-www-form-urlencoded' },
|
|
222
|
+
body: new URLSearchParams({ client_id: config.clientId, ...fields }).toString(),
|
|
223
|
+
});
|
|
224
|
+
const token = await readJson(response);
|
|
225
|
+
if (token.error === 'invalid_grant' || response.status === 401)
|
|
226
|
+
throw new LoginExpired();
|
|
227
|
+
if (!response.ok)
|
|
228
|
+
throw new Error(`Tokenworks token endpoint answered HTTP ${response.status}`);
|
|
229
|
+
if (typeof token.access_token !== 'string' || !token.access_token || typeof token.token_type !== 'string' || token.token_type.toLowerCase() !== 'bearer')
|
|
230
|
+
throw new Error('Tokenworks returned an invalid access token');
|
|
231
|
+
return token;
|
|
232
|
+
}
|
|
233
|
+
sessionFromToken(token, clientId, claims, previousRefresh) {
|
|
234
|
+
if (typeof token.expires_in !== 'number' || !Number.isFinite(token.expires_in) || token.expires_in <= 0)
|
|
235
|
+
throw new Error('Tokenworks returned an invalid token lifetime');
|
|
236
|
+
const refreshToken = typeof token.refresh_token === 'string' ? token.refresh_token : previousRefresh;
|
|
237
|
+
return {
|
|
238
|
+
accessToken: token.access_token,
|
|
239
|
+
...(refreshToken === undefined ? {} : { refreshToken }),
|
|
240
|
+
expiresAt: Date.now() + token.expires_in * 1_000, clientId, subject: claims.sub,
|
|
241
|
+
name: [claims.name, claims.preferred_username, claims.email, claims.sub].find(value => typeof value === 'string'),
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
async bootstrap(accessToken) {
|
|
245
|
+
const response = await this.request(BOOTSTRAP_URL, { headers: { authorization: `Bearer ${accessToken}` } });
|
|
246
|
+
if (response.status === 401)
|
|
247
|
+
throw new LoginExpired();
|
|
248
|
+
if (response.status === 403)
|
|
249
|
+
throw new AccessDenied();
|
|
250
|
+
if (response.status >= 500)
|
|
251
|
+
throw new NetworkError('Tokenworks gateway key service is temporarily unavailable');
|
|
252
|
+
if (!response.ok)
|
|
253
|
+
throw new Error(`Tokenworks bootstrap answered HTTP ${response.status}`);
|
|
254
|
+
const value = await readJson(response);
|
|
255
|
+
const upstream = new URL(String(value.inferenceGatewayBaseUrl));
|
|
256
|
+
if (upstream.origin !== 'https://api.llm.ustc.edu.cn' || upstream.username || upstream.password || upstream.search || upstream.hash) {
|
|
257
|
+
throw new Error('Tokenworks gateway is not the USTC API');
|
|
258
|
+
}
|
|
259
|
+
if (value.inferenceProvider !== 'gateway' || (value.inferenceCredentialKind ?? 'static') !== 'static' || (value.inferenceGatewayAuthScheme ?? 'bearer') !== 'bearer' || Object.keys(value.inferenceCustomHeaders ?? {}).length > 0) {
|
|
260
|
+
throw new Error('Tokenworks gateway authentication is unsupported');
|
|
261
|
+
}
|
|
262
|
+
if (typeof value.inferenceGatewayApiKey !== 'string' || !value.inferenceGatewayApiKey.trim())
|
|
263
|
+
throw new Error('Tokenworks bootstrap has no gateway key');
|
|
264
|
+
const expiresAt = typeof value.expiresAt === 'number' ? value.expiresAt * (value.expiresAt < 1e12 ? 1_000 : 1) : Infinity;
|
|
265
|
+
if (!(expiresAt > Date.now()))
|
|
266
|
+
throw new Error('Tokenworks gateway key has expired');
|
|
267
|
+
const minutes = typeof value.configRecheckIntervalMinutes === 'number' ? Math.max(2, Math.min(30, value.configRecheckIntervalMinutes)) : 10;
|
|
268
|
+
return { value: value.inferenceGatewayApiKey.trim(), expiresAt, recheckAt: Math.min(expiresAt, Date.now() + minutes * 60_000) };
|
|
269
|
+
}
|
|
270
|
+
loginConfig() {
|
|
271
|
+
this.config ??= this.loadLoginConfig().catch(error => { this.config = undefined; throw error; });
|
|
272
|
+
return this.config;
|
|
273
|
+
}
|
|
274
|
+
async loadLoginConfig() {
|
|
275
|
+
const envelope = await this.json(`${CONTENT_ROOT}/stable/latest.json`);
|
|
276
|
+
const bytes = Buffer.from(envelope.payload, 'base64url');
|
|
277
|
+
if (!verify(null, bytes, this.publisherKey, Buffer.from(envelope.signature, 'base64url')))
|
|
278
|
+
throw new Error('Tokenworks content signature does not match');
|
|
279
|
+
const manifest = JSON.parse(bytes.toString('utf8'));
|
|
280
|
+
if (manifest.publisher !== 'ustc-tokenworks' || manifest.channel !== 'stable' || !manifest.bundle.url.startsWith(`${CONTENT_ROOT}/bundles/`))
|
|
281
|
+
throw new Error('Tokenworks content publisher does not match');
|
|
282
|
+
const bundleResponse = await this.request(manifest.bundle.url);
|
|
283
|
+
if (!bundleResponse.ok)
|
|
284
|
+
throw new Error(`Tokenworks content answered HTTP ${bundleResponse.status}`);
|
|
285
|
+
const bundle = Buffer.from(await bundleResponse.arrayBuffer());
|
|
286
|
+
if (bundle.length !== manifest.bundle.bytes || createHash('sha256').update(bundle).digest('hex') !== manifest.bundle.sha256)
|
|
287
|
+
throw new Error('Tokenworks content checksum does not match');
|
|
288
|
+
const content = JSON.parse(bundle.toString('utf8'));
|
|
289
|
+
const oidc = content.configuration.organizations.find(org => org.id === 'ustc')?.oidc;
|
|
290
|
+
if (oidc?.issuer !== ISSUER || !oidc.clientId || !oidc.scopes.includes('openid'))
|
|
291
|
+
throw new Error('Tokenworks OIDC configuration is invalid');
|
|
292
|
+
const discovery = await this.json(`${ISSUER}/.well-known/openid-configuration`);
|
|
293
|
+
if (discovery.issuer !== ISSUER || !discovery.code_challenge_methods_supported?.includes('S256'))
|
|
294
|
+
throw new Error('Tokenworks OIDC issuer does not support PKCE');
|
|
295
|
+
const endpoint = (value) => {
|
|
296
|
+
const url = new URL(String(value));
|
|
297
|
+
if (url.origin !== new URL(ISSUER).origin || url.username || url.password)
|
|
298
|
+
throw new Error('Tokenworks OIDC endpoint has an unexpected origin');
|
|
299
|
+
return url.href;
|
|
300
|
+
};
|
|
301
|
+
return {
|
|
302
|
+
clientId: oidc.clientId, scopes: oidc.scopes,
|
|
303
|
+
authorizationEndpoint: endpoint(discovery.authorization_endpoint), tokenEndpoint: endpoint(discovery.token_endpoint),
|
|
304
|
+
jwksUri: endpoint(discovery.jwks_uri), requiresIssuer: discovery.authorization_response_iss_parameter_supported === true,
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
async verifyIdToken(token, config, nonce) {
|
|
308
|
+
if (typeof token !== 'string')
|
|
309
|
+
throw new Error('Tokenworks response has no ID token');
|
|
310
|
+
const [headerPart, payloadPart, signature, extra] = token.split('.');
|
|
311
|
+
if (!headerPart || !payloadPart || !signature || extra !== undefined)
|
|
312
|
+
throw new Error('Tokenworks ID token is invalid');
|
|
313
|
+
const header = JSON.parse(Buffer.from(headerPart, 'base64url').toString('utf8'));
|
|
314
|
+
if (header.alg !== 'RS256')
|
|
315
|
+
throw new Error('Tokenworks ID token algorithm is unsupported');
|
|
316
|
+
const jwks = await this.json(config.jwksUri);
|
|
317
|
+
const keys = jwks.keys.filter(key => key.kty === 'RSA' && key.kid === header.kid && (!key.use || key.use === 'sig') && (!key.alg || key.alg === 'RS256'));
|
|
318
|
+
if (keys.length !== 1 || !verify('RSA-SHA256', Buffer.from(`${headerPart}.${payloadPart}`), createPublicKey({ key: keys[0], format: 'jwk' }), Buffer.from(signature, 'base64url')))
|
|
319
|
+
throw new Error('Tokenworks ID token signature does not match');
|
|
320
|
+
const claims = JSON.parse(Buffer.from(payloadPart, 'base64url').toString('utf8'));
|
|
321
|
+
const aud = Array.isArray(claims.aud) ? claims.aud : [claims.aud];
|
|
322
|
+
const now = Date.now() / 1_000;
|
|
323
|
+
const validAudience = aud.includes(config.clientId) && (aud.length === 1 || claims.azp === config.clientId) && (claims.azp === undefined || claims.azp === config.clientId);
|
|
324
|
+
const validLifetime = typeof claims.exp === 'number' && claims.exp >= now - 60 && typeof claims.iat === 'number' && claims.iat <= now + 60;
|
|
325
|
+
if (claims.iss !== ISSUER || !validAudience || !validLifetime || typeof claims.sub !== 'string' || !claims.sub || (nonce !== undefined && claims.nonce !== nonce)) {
|
|
326
|
+
throw new Error('Tokenworks ID token claims do not match');
|
|
327
|
+
}
|
|
328
|
+
return claims;
|
|
329
|
+
}
|
|
330
|
+
async json(url) {
|
|
331
|
+
const response = await this.request(url);
|
|
332
|
+
if (!response.ok)
|
|
333
|
+
throw new Error(`Tokenworks identity service answered HTTP ${response.status}`);
|
|
334
|
+
return readJson(response);
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
class LoginExpired extends Error {
|
|
338
|
+
constructor() { super('Tokenworks sign-in expired; sign in again'); }
|
|
339
|
+
}
|
|
340
|
+
class AccessDenied extends Error {
|
|
341
|
+
constructor() { super('Tokenworks has not granted access to the USTC API'); }
|
|
342
|
+
}
|
|
343
|
+
class NetworkError extends Error {
|
|
344
|
+
}
|
|
345
|
+
async function readJson(response) {
|
|
346
|
+
try {
|
|
347
|
+
return await response.json();
|
|
348
|
+
}
|
|
349
|
+
catch {
|
|
350
|
+
throw new Error('Tokenworks returned invalid JSON');
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
// Direct HTTPS only: no global fetch/proxy agent, redirect following or helper tunnel.
|
|
354
|
+
function requestDirect(url, init = {}) {
|
|
355
|
+
return new Promise((resolve, reject) => {
|
|
356
|
+
const request = httpsRequest(url, { method: init.method ?? 'GET', headers: Object.fromEntries(new Headers(init.headers)), agent: false }, response => {
|
|
357
|
+
const chunks = [];
|
|
358
|
+
let size = 0;
|
|
359
|
+
response.on('data', (chunk) => {
|
|
360
|
+
size += chunk.length;
|
|
361
|
+
if (size > 4 * 1024 * 1024)
|
|
362
|
+
request.destroy(new Error('Tokenworks response is too large'));
|
|
363
|
+
else
|
|
364
|
+
chunks.push(chunk);
|
|
365
|
+
});
|
|
366
|
+
response.once('error', () => reject(new NetworkError('Tokenworks connection interrupted')));
|
|
367
|
+
response.once('end', () => {
|
|
368
|
+
const status = response.statusCode ?? 502;
|
|
369
|
+
const body = [204, 205, 304].includes(status) ? null : new Uint8Array(Buffer.concat(chunks));
|
|
370
|
+
resolve(new Response(body, { status }));
|
|
371
|
+
});
|
|
372
|
+
});
|
|
373
|
+
const timer = setTimeout(() => request.destroy(new Error('timeout')), 8_000);
|
|
374
|
+
request.once('close', () => clearTimeout(timer));
|
|
375
|
+
request.once('error', () => reject(new NetworkError('Tokenworks identity service connection failed')));
|
|
376
|
+
request.end(init.body);
|
|
377
|
+
});
|
|
378
|
+
}
|
|
379
|
+
//# sourceMappingURL=tokenworks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tokenworks.js","sourceRoot":"","sources":["../src/tokenworks.ts"],"names":[],"mappings":"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"}
|
package/lib/types/adapter.d.ts
CHANGED
|
@@ -6,8 +6,10 @@ export declare class UstcAdapter extends LlmAdapter {
|
|
|
6
6
|
private readonly ctx;
|
|
7
7
|
private readonly helper;
|
|
8
8
|
private readonly catalog;
|
|
9
|
+
private readonly resolveApiKey;
|
|
9
10
|
private delegate;
|
|
10
|
-
|
|
11
|
+
private readonly auth;
|
|
12
|
+
constructor(ctx: Context, helper: HelperManager, catalog: ModelCatalog, resolveApiKey: () => Promise<string>);
|
|
11
13
|
providerInfo(provider: string): {
|
|
12
14
|
id: string;
|
|
13
15
|
name: string;
|