@awiki/dsh-plugin 0.3.10 → 0.3.11-rc.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/README.md +4 -3
- package/README.zh.md +4 -3
- package/lib/client.js +1351 -158
- package/lib/client.js.map +1 -1
- package/lib/index.js +172 -93
- package/lib/model-proxy-contract.js +8 -8
- package/lib/typert.host.js +56 -56
- package/lib/typert.remote-client.js +56 -56
- package/lib/types/client/AwikiIdentityAccess.d.ts +6 -4
- package/lib/types/client/AwikiIdentityAccess.d.ts.map +1 -1
- package/lib/types/client/AwikiIdentityAccess.js +111 -43
- package/lib/types/client/AwikiIdentityAccess.js.map +1 -1
- package/lib/types/client/AwikiOverlay.js +1 -1
- package/lib/types/client/AwikiOverlay.js.map +1 -1
- package/lib/types/client/AwikiRecoveryForm.d.ts +1 -0
- package/lib/types/client/AwikiRecoveryForm.d.ts.map +1 -1
- package/lib/types/client/AwikiRecoveryForm.js +3 -2
- package/lib/types/client/AwikiRecoveryForm.js.map +1 -1
- package/lib/types/client/AwikiSettingsSection.d.ts +1 -1
- package/lib/types/client/AwikiSettingsSection.d.ts.map +1 -1
- package/lib/types/client/awiki-client-bridge.d.ts +1 -1
- package/lib/types/client/awiki-client-bridge.d.ts.map +1 -1
- package/lib/types/client/awiki-client-bridge.js +1 -1
- package/lib/types/client/awiki-client-bridge.js.map +1 -1
- package/lib/types/client/controller.d.ts +8 -0
- package/lib/types/client/controller.d.ts.map +1 -1
- package/lib/types/client/controller.js +274 -53
- package/lib/types/client/controller.js.map +1 -1
- package/lib/types/client/index.d.ts +1 -1
- package/lib/types/client/index.d.ts.map +1 -1
- package/lib/types/client/index.js +2 -1
- package/lib/types/client/index.js.map +1 -1
- package/lib/types/client/otp-cooldown.d.ts +1 -0
- package/lib/types/client/otp-cooldown.d.ts.map +1 -1
- package/lib/types/client/otp-cooldown.js +12 -1
- package/lib/types/client/otp-cooldown.js.map +1 -1
- package/lib/types/client/settings-controller.d.ts +4 -2
- package/lib/types/client/settings-controller.d.ts.map +1 -1
- package/lib/types/client/settings-controller.js +24 -8
- package/lib/types/client/settings-controller.js.map +1 -1
- package/lib/types/client/slots.d.ts +1 -0
- package/lib/types/client/slots.d.ts.map +1 -1
- package/lib/types/client/store.d.ts +1 -1
- package/lib/types/client/store.d.ts.map +1 -1
- package/lib/types/client/store.js +1 -1
- package/lib/types/client/store.js.map +1 -1
- package/lib/types/index.d.ts +1 -0
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/index.js +35 -9
- package/lib/types/index.js.map +1 -1
- package/lib/types/listener.d.ts.map +1 -1
- package/lib/types/listener.js +2 -1
- package/lib/types/listener.js.map +1 -1
- package/lib/types/model-proxy-contract.d.ts +8 -8
- package/lib/types/model-proxy-contract.d.ts.map +1 -1
- package/lib/types/model-proxy-contract.js +8 -8
- package/lib/types/model-proxy-contract.js.map +1 -1
- package/lib/types/package-version.generated.d.ts +2 -2
- package/lib/types/package-version.generated.d.ts.map +1 -1
- package/lib/types/package-version.generated.js +2 -2
- package/lib/types/package-version.generated.js.map +1 -1
- package/lib/types/registration-policy.d.ts +7 -0
- package/lib/types/registration-policy.d.ts.map +1 -0
- package/lib/types/registration-policy.js +21 -0
- package/lib/types/registration-policy.js.map +1 -0
- package/lib/types/settings-rpc-contract.d.ts +14 -14
- package/lib/types/settings-rpc-contract.d.ts.map +1 -1
- package/lib/types/settings-rpc-contract.js +14 -14
- package/lib/types/settings-rpc-contract.js.map +1 -1
- package/lib/types/settings-rpc.d.ts.map +1 -1
- package/lib/types/settings-rpc.js +2 -2
- package/lib/types/settings-rpc.js.map +1 -1
- package/lib/types/settings-transport.d.ts +7 -0
- package/lib/types/settings-transport.d.ts.map +1 -0
- package/lib/types/settings-transport.js +52 -0
- package/lib/types/settings-transport.js.map +1 -0
- package/lib/types/types.d.ts +1 -1
- package/lib/types/types.d.ts.map +1 -1
- package/lib/types/update-policy.d.ts +2 -2
- package/lib/types/update-policy.d.ts.map +1 -1
- package/package.json +82 -73
package/lib/index.js
CHANGED
|
@@ -5,15 +5,151 @@ import { homedir } from "node:os";
|
|
|
5
5
|
import { basename, dirname, isAbsolute, join, resolve } from "node:path";
|
|
6
6
|
import z from "@deepseek-ai/schemastery";
|
|
7
7
|
import { Remote, TypertRemoteService } from "@deepseek-ai/dsh-typert-protocol";
|
|
8
|
-
import { SettingsConflictError
|
|
8
|
+
import { SettingsConflictError } from "@deepseek-ai/dsh-settings";
|
|
9
9
|
import { chmod, lstat, mkdir, readFile, readdir, rename, rm, unlink, utimes, writeFile } from "node:fs/promises";
|
|
10
10
|
import { defineTool } from "@deepseek-ai/dsh-tools";
|
|
11
|
+
import { SessionId, SessionLogOffset } from "@deepseek-ai/dsh-session";
|
|
11
12
|
import { installModelSelection } from "@deepseek-ai/dsh-agent";
|
|
12
13
|
import { createUserMessage } from "@deepseek-ai/dsh-llm";
|
|
13
|
-
import { SessionId } from "@deepseek-ai/dsh-session";
|
|
14
14
|
import { fileURLToPath } from "node:url";
|
|
15
15
|
import { copyFileSync, existsSync, mkdirSync, readFileSync, readdirSync, renameSync, rmSync, statSync, writeFileSync } from "node:fs";
|
|
16
16
|
import { satisfies } from "semver";
|
|
17
|
+
//#region lib/types/builtin-tenant-config.js
|
|
18
|
+
/** Build-injected two-slot tenant catalog with a source-tree default for tests. */
|
|
19
|
+
function record(value) {
|
|
20
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
21
|
+
}
|
|
22
|
+
function definition(value) {
|
|
23
|
+
if (!record(value) || !record(value.display_name) || typeof value.display_name["zh-CN"] !== "string" || value.display_name["zh-CN"].trim() === "" || typeof value.display_name.en !== "string" || value.display_name.en.trim() === "" || typeof value.backend_origin !== "string" || typeof value.did_host !== "string") throw new Error("awiki: invalid built-in tenant definition");
|
|
24
|
+
const origin = new URL(value.backend_origin);
|
|
25
|
+
const loopback = origin.protocol === "http:" && [
|
|
26
|
+
"localhost",
|
|
27
|
+
"127.0.0.1",
|
|
28
|
+
"[::1]"
|
|
29
|
+
].includes(origin.hostname);
|
|
30
|
+
if (origin.protocol !== "https:" && !loopback || origin.username !== "" || origin.password !== "" || origin.pathname !== "/" || origin.search !== "" || origin.hash !== "" || !loopback && origin.port !== "") throw new Error("awiki: built-in tenant origin must be an HTTPS origin");
|
|
31
|
+
const didHost = value.did_host.trim().toLowerCase().replace(/\.$/u, "");
|
|
32
|
+
if (origin.hostname !== didHost) throw new Error("awiki: built-in tenant DID host must match its origin");
|
|
33
|
+
return {
|
|
34
|
+
displayName: {
|
|
35
|
+
"zh-CN": value.display_name["zh-CN"].trim(),
|
|
36
|
+
en: value.display_name.en.trim()
|
|
37
|
+
},
|
|
38
|
+
backendOrigin: origin.origin,
|
|
39
|
+
didHost
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
function decodeBuiltinTenantConfig(value) {
|
|
43
|
+
if (!record(value) || value.schema_version !== 1 || value.default_slot !== "primary" && value.default_slot !== "secondary" || !record(value.tenants) || Object.keys(value.tenants).sort().join(",") !== "primary,secondary") throw new Error("awiki: invalid built-in tenant config");
|
|
44
|
+
const primary = definition(value.tenants.primary);
|
|
45
|
+
const secondary = definition(value.tenants.secondary);
|
|
46
|
+
if (primary.backendOrigin === secondary.backendOrigin || primary.didHost === secondary.didHost) throw new Error("awiki: built-in tenant slots must use distinct endpoints");
|
|
47
|
+
return {
|
|
48
|
+
schemaVersion: 1,
|
|
49
|
+
defaultSlot: value.default_slot,
|
|
50
|
+
tenants: {
|
|
51
|
+
primary,
|
|
52
|
+
secondary
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
function rawConfig() {
|
|
57
|
+
return JSON.parse("{\n \"schema_version\": 1,\n \"default_slot\": \"primary\",\n \"tenants\": {\n \"primary\": {\n \"display_name\": {\n \"zh-CN\": \"AWiki 中国(上海)\",\n \"en\": \"AWiki China (Shanghai)\"\n },\n \"backend_origin\": \"https://awiki.me\",\n \"did_host\": \"awiki.me\"\n },\n \"secondary\": {\n \"display_name\": {\n \"zh-CN\": \"AWiki 全球(硅谷)\",\n \"en\": \"AWiki Global (Silicon Valley)\"\n },\n \"backend_origin\": \"https://awiki.ai\",\n \"did_host\": \"awiki.ai\"\n }\n }\n}\n");
|
|
58
|
+
}
|
|
59
|
+
const AWIKI_BUILTIN_TENANT_CONFIG = decodeBuiltinTenantConfig(rawConfig());
|
|
60
|
+
const AWIKI_DEFAULT_BUILTIN_TENANT = AWIKI_BUILTIN_TENANT_CONFIG.tenants[AWIKI_BUILTIN_TENANT_CONFIG.defaultSlot];
|
|
61
|
+
//#endregion
|
|
62
|
+
//#region lib/types/domain.js
|
|
63
|
+
/** Client-safe AWiki Handle provider domain constants and validation. */
|
|
64
|
+
/** Default Handle provider domain for new AWiki deployments. */
|
|
65
|
+
const DEFAULT_AWIKI_DOMAIN = AWIKI_DEFAULT_BUILTIN_TENANT.didHost;
|
|
66
|
+
/** Field carrying the Handle provider domain in the AWiki settings namespace. */
|
|
67
|
+
const AWIKI_DOMAIN_FIELD = "domain";
|
|
68
|
+
/** Settings namespace owned by the AWiki plugin. */
|
|
69
|
+
const AWIKI_SETTINGS_NAMESPACE = "awiki";
|
|
70
|
+
/** Normalize and validate one DNS provider domain. */
|
|
71
|
+
function normalizeAwikiDomain(raw, field = "domain") {
|
|
72
|
+
const value = raw.trim().toLowerCase();
|
|
73
|
+
const valid = /^(?=.{1,253}$)(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/u.test(value);
|
|
74
|
+
if (value.length > 253 || !valid) throw new TypeError(`awiki: ${field} must contain a valid DNS domain`);
|
|
75
|
+
return value;
|
|
76
|
+
}
|
|
77
|
+
//#endregion
|
|
78
|
+
//#region lib/types/settings-rpc-contract.js
|
|
79
|
+
/** Shared Connection carrier with plugin-owned exact loopback routes. */
|
|
80
|
+
const AWIKI_SETTINGS_RPC_CHANNEL = "/api";
|
|
81
|
+
/** Supported channel-relative operations. */
|
|
82
|
+
const AWIKI_SETTINGS_RPC_ENDPOINTS = {
|
|
83
|
+
describe: "awiki-settings/describe",
|
|
84
|
+
setDomain: "awiki-settings/set-domain",
|
|
85
|
+
resetDomain: "awiki-settings/reset-domain",
|
|
86
|
+
describeTenants: "awiki-settings/describe-tenants",
|
|
87
|
+
createTenant: "awiki-settings/create-tenant",
|
|
88
|
+
renameTenant: "awiki-settings/rename-tenant",
|
|
89
|
+
switchTenant: "awiki-settings/switch-tenant",
|
|
90
|
+
archiveTenant: "awiki-settings/archive-tenant",
|
|
91
|
+
describeUpdatePolicy: "awiki-settings/describe-update-policy",
|
|
92
|
+
refreshUpdatePolicy: "awiki-settings/refresh-update-policy",
|
|
93
|
+
describeDesktopUpdate: "awiki-settings/describe-desktop-update",
|
|
94
|
+
refreshDesktopUpdate: "awiki-settings/refresh-desktop-update"
|
|
95
|
+
};
|
|
96
|
+
//#endregion
|
|
97
|
+
//#region lib/types/settings-transport.js
|
|
98
|
+
/** Register exact buffered routes; Connection applies authentication before dispatch. */
|
|
99
|
+
function registerAwikiSettingsTransport(connection, handler) {
|
|
100
|
+
registerAwikiLoopbackRpc(connection, AWIKI_SETTINGS_RPC_CHANNEL, Object.values(AWIKI_SETTINGS_RPC_ENDPOINTS), handler);
|
|
101
|
+
}
|
|
102
|
+
/** Shared carrier for the AWiki and Model Proxy plugin-owned local operations. */
|
|
103
|
+
function registerAwikiLoopbackRpc(connection, channel, endpoints, handler) {
|
|
104
|
+
for (const endpoint of endpoints) connection.fetch.register({
|
|
105
|
+
path: `${channel}/${endpoint}`,
|
|
106
|
+
methods: ["POST"],
|
|
107
|
+
requestBody: "buffered",
|
|
108
|
+
async fetch(request) {
|
|
109
|
+
const authority = request.headers.get("host") ?? "";
|
|
110
|
+
if (!/^(?:localhost|127\.0\.0\.1|\[::1\])(?::[0-9]{1,5})?$/iu.test(authority)) return new Response("forbidden", { status: 403 });
|
|
111
|
+
if (request.headers.get("content-type")?.split(";", 1)[0]?.trim().toLowerCase() !== "application/json") return new Response("unsupported content type", { status: 415 });
|
|
112
|
+
let body;
|
|
113
|
+
try {
|
|
114
|
+
body = await request.json();
|
|
115
|
+
} catch {
|
|
116
|
+
return new Response("invalid request", { status: 400 });
|
|
117
|
+
}
|
|
118
|
+
if (typeof body !== "object" || body === null || Array.isArray(body)) return new Response("invalid request", { status: 400 });
|
|
119
|
+
const envelope = body;
|
|
120
|
+
if (Object.keys(envelope).sort().join(",") !== "method,payload,rpcId,type" || envelope.type !== "client-request" || envelope.method !== endpoint || typeof envelope.rpcId !== "string" || envelope.rpcId.length === 0 || envelope.rpcId.length > 256) return new Response("invalid request", { status: 400 });
|
|
121
|
+
try {
|
|
122
|
+
const result = await handler(endpoint, envelope.payload, request.signal);
|
|
123
|
+
return Response.json({
|
|
124
|
+
type: "server-response",
|
|
125
|
+
rpcId: envelope.rpcId,
|
|
126
|
+
result
|
|
127
|
+
});
|
|
128
|
+
} catch {
|
|
129
|
+
return new Response("AWiki settings unavailable", { status: 500 });
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
//#endregion
|
|
135
|
+
//#region lib/types/registration-policy.js
|
|
136
|
+
const HANDLE_LOCAL_PART = /^(?!-)(?!.*--)[a-z0-9-]{1,63}(?<!-)$/u;
|
|
137
|
+
/** Return the canonical local part when the input has valid WNS local-part syntax. */
|
|
138
|
+
function registrationHandleLocalPart(value) {
|
|
139
|
+
let normalized = value.trim().toLowerCase();
|
|
140
|
+
if (normalized.startsWith("wba://")) normalized = normalized.slice(6);
|
|
141
|
+
const dot = normalized.indexOf(".");
|
|
142
|
+
const localPart = (dot < 0 ? normalized : normalized.slice(0, dot)).trim();
|
|
143
|
+
return HANDLE_LOCAL_PART.test(localPart) ? localPart : void 0;
|
|
144
|
+
}
|
|
145
|
+
/** One- through four-character Handle registrations require the unavailable invitation flow. */
|
|
146
|
+
function shortHandleInviteRequired(value) {
|
|
147
|
+
const localPart = registrationHandleLocalPart(value);
|
|
148
|
+
if (localPart === void 0) return false;
|
|
149
|
+
const length = Array.from(localPart).length;
|
|
150
|
+
return length >= 1 && length <= 4;
|
|
151
|
+
}
|
|
152
|
+
//#endregion
|
|
17
153
|
//#region lib/types/version.js
|
|
18
154
|
/** Shared strict version comparison for update presentation and Host gates. */
|
|
19
155
|
function assertVersion(value) {
|
|
@@ -1151,67 +1287,6 @@ function mailSendRequest(request) {
|
|
|
1151
1287
|
};
|
|
1152
1288
|
}
|
|
1153
1289
|
//#endregion
|
|
1154
|
-
//#region lib/types/builtin-tenant-config.js
|
|
1155
|
-
/** Build-injected two-slot tenant catalog with a source-tree default for tests. */
|
|
1156
|
-
function record(value) {
|
|
1157
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1158
|
-
}
|
|
1159
|
-
function definition(value) {
|
|
1160
|
-
if (!record(value) || !record(value.display_name) || typeof value.display_name["zh-CN"] !== "string" || value.display_name["zh-CN"].trim() === "" || typeof value.display_name.en !== "string" || value.display_name.en.trim() === "" || typeof value.backend_origin !== "string" || typeof value.did_host !== "string") throw new Error("awiki: invalid built-in tenant definition");
|
|
1161
|
-
const origin = new URL(value.backend_origin);
|
|
1162
|
-
const loopback = origin.protocol === "http:" && [
|
|
1163
|
-
"localhost",
|
|
1164
|
-
"127.0.0.1",
|
|
1165
|
-
"[::1]"
|
|
1166
|
-
].includes(origin.hostname);
|
|
1167
|
-
if (origin.protocol !== "https:" && !loopback || origin.username !== "" || origin.password !== "" || origin.pathname !== "/" || origin.search !== "" || origin.hash !== "" || !loopback && origin.port !== "") throw new Error("awiki: built-in tenant origin must be an HTTPS origin");
|
|
1168
|
-
const didHost = value.did_host.trim().toLowerCase().replace(/\.$/u, "");
|
|
1169
|
-
if (origin.hostname !== didHost) throw new Error("awiki: built-in tenant DID host must match its origin");
|
|
1170
|
-
return {
|
|
1171
|
-
displayName: {
|
|
1172
|
-
"zh-CN": value.display_name["zh-CN"].trim(),
|
|
1173
|
-
en: value.display_name.en.trim()
|
|
1174
|
-
},
|
|
1175
|
-
backendOrigin: origin.origin,
|
|
1176
|
-
didHost
|
|
1177
|
-
};
|
|
1178
|
-
}
|
|
1179
|
-
function decodeBuiltinTenantConfig(value) {
|
|
1180
|
-
if (!record(value) || value.schema_version !== 1 || value.default_slot !== "primary" && value.default_slot !== "secondary" || !record(value.tenants) || Object.keys(value.tenants).sort().join(",") !== "primary,secondary") throw new Error("awiki: invalid built-in tenant config");
|
|
1181
|
-
const primary = definition(value.tenants.primary);
|
|
1182
|
-
const secondary = definition(value.tenants.secondary);
|
|
1183
|
-
if (primary.backendOrigin === secondary.backendOrigin || primary.didHost === secondary.didHost) throw new Error("awiki: built-in tenant slots must use distinct endpoints");
|
|
1184
|
-
return {
|
|
1185
|
-
schemaVersion: 1,
|
|
1186
|
-
defaultSlot: value.default_slot,
|
|
1187
|
-
tenants: {
|
|
1188
|
-
primary,
|
|
1189
|
-
secondary
|
|
1190
|
-
}
|
|
1191
|
-
};
|
|
1192
|
-
}
|
|
1193
|
-
function rawConfig() {
|
|
1194
|
-
return JSON.parse("{\n \"schema_version\": 1,\n \"default_slot\": \"primary\",\n \"tenants\": {\n \"primary\": {\n \"display_name\": {\n \"zh-CN\": \"AWiki 中国(上海)\",\n \"en\": \"AWiki China (Shanghai)\"\n },\n \"backend_origin\": \"https://awiki.me\",\n \"did_host\": \"awiki.me\"\n },\n \"secondary\": {\n \"display_name\": {\n \"zh-CN\": \"AWiki 全球(硅谷)\",\n \"en\": \"AWiki Global (Silicon Valley)\"\n },\n \"backend_origin\": \"https://awiki.ai\",\n \"did_host\": \"awiki.ai\"\n }\n }\n}\n");
|
|
1195
|
-
}
|
|
1196
|
-
const AWIKI_BUILTIN_TENANT_CONFIG = decodeBuiltinTenantConfig(rawConfig());
|
|
1197
|
-
const AWIKI_DEFAULT_BUILTIN_TENANT = AWIKI_BUILTIN_TENANT_CONFIG.tenants[AWIKI_BUILTIN_TENANT_CONFIG.defaultSlot];
|
|
1198
|
-
//#endregion
|
|
1199
|
-
//#region lib/types/domain.js
|
|
1200
|
-
/** Client-safe AWiki Handle provider domain constants and validation. */
|
|
1201
|
-
/** Default Handle provider domain for new AWiki deployments. */
|
|
1202
|
-
const DEFAULT_AWIKI_DOMAIN = AWIKI_DEFAULT_BUILTIN_TENANT.didHost;
|
|
1203
|
-
/** Field carrying the Handle provider domain in the AWiki settings namespace. */
|
|
1204
|
-
const AWIKI_DOMAIN_FIELD = "domain";
|
|
1205
|
-
/** Settings namespace owned by the AWiki plugin. */
|
|
1206
|
-
const AWIKI_SETTINGS_NAMESPACE = "awiki";
|
|
1207
|
-
/** Normalize and validate one DNS provider domain. */
|
|
1208
|
-
function normalizeAwikiDomain(raw, field = "domain") {
|
|
1209
|
-
const value = raw.trim().toLowerCase();
|
|
1210
|
-
const valid = /^(?=.{1,253}$)(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/u.test(value);
|
|
1211
|
-
if (value.length > 253 || !valid) throw new TypeError(`awiki: ${field} must contain a valid DNS domain`);
|
|
1212
|
-
return value;
|
|
1213
|
-
}
|
|
1214
|
-
//#endregion
|
|
1215
1290
|
//#region lib/types/settings.js
|
|
1216
1291
|
/** Durable AWiki settings shared by the Host service and browser settings page. */
|
|
1217
1292
|
/** Durable AWiki schema exposed through the DSH settings service. */
|
|
@@ -1221,25 +1296,6 @@ function validateAwikiSettings(value) {
|
|
|
1221
1296
|
if (normalizeAwikiDomain(value.domain) !== value.domain) throw new TypeError("awiki: domain must be lowercase and must not contain surrounding whitespace");
|
|
1222
1297
|
}
|
|
1223
1298
|
//#endregion
|
|
1224
|
-
//#region lib/types/settings-rpc-contract.js
|
|
1225
|
-
/** Dedicated Connection channel; the Host registers it with loopback authority. */
|
|
1226
|
-
const AWIKI_SETTINGS_RPC_CHANNEL = "/awiki-settings";
|
|
1227
|
-
/** Supported channel-relative operations. */
|
|
1228
|
-
const AWIKI_SETTINGS_RPC_ENDPOINTS = {
|
|
1229
|
-
describe: "describe",
|
|
1230
|
-
setDomain: "set-domain",
|
|
1231
|
-
resetDomain: "reset-domain",
|
|
1232
|
-
describeTenants: "describe-tenants",
|
|
1233
|
-
createTenant: "create-tenant",
|
|
1234
|
-
renameTenant: "rename-tenant",
|
|
1235
|
-
switchTenant: "switch-tenant",
|
|
1236
|
-
archiveTenant: "archive-tenant",
|
|
1237
|
-
describeUpdatePolicy: "describe-update-policy",
|
|
1238
|
-
refreshUpdatePolicy: "refresh-update-policy",
|
|
1239
|
-
describeDesktopUpdate: "describe-desktop-update",
|
|
1240
|
-
refreshDesktopUpdate: "refresh-desktop-update"
|
|
1241
|
-
};
|
|
1242
|
-
//#endregion
|
|
1243
1299
|
//#region lib/types/settings-rpc.js
|
|
1244
1300
|
/** Loopback-only Host transport for AWiki's durable plugin settings. */
|
|
1245
1301
|
function isRecord$4(value) {
|
|
@@ -1464,7 +1520,7 @@ function createAwikiSettingsRpcHandler(getProvider, tenantManagement) {
|
|
|
1464
1520
|
};
|
|
1465
1521
|
else return badRequest();
|
|
1466
1522
|
try {
|
|
1467
|
-
await provider.mutate(
|
|
1523
|
+
await provider.mutate(AWIKI_SETTINGS_NAMESPACE, [operation], revision);
|
|
1468
1524
|
const current = view(provider);
|
|
1469
1525
|
return current === void 0 ? unavailable() : {
|
|
1470
1526
|
ok: true,
|
|
@@ -2256,7 +2312,7 @@ var DshAwikiListenerAgentRuntime = class {
|
|
|
2256
2312
|
agent.followup(message);
|
|
2257
2313
|
await agent.whenIdle();
|
|
2258
2314
|
await this.ctx.sessions.flush(agent.session);
|
|
2259
|
-
const output = finalAssistantText(agent.session.
|
|
2315
|
+
const output = finalAssistantText(agent.session.snapshotEvents(SessionLogOffset(firstSeq)), message.id);
|
|
2260
2316
|
if (output === void 0) throw new Error("awiki listener: Agent produced no completed text response");
|
|
2261
2317
|
return output;
|
|
2262
2318
|
}
|
|
@@ -3173,8 +3229,8 @@ function legacyDocument(seed, usePreRegistryDefault) {
|
|
|
3173
3229
|
//#endregion
|
|
3174
3230
|
//#region lib/types/package-version.generated.js
|
|
3175
3231
|
/** Generated from package.json by scripts/sync-package-versions.mjs. */
|
|
3176
|
-
const DSH_AWIKI_PACKAGE_VERSION = "0.3.
|
|
3177
|
-
const DSH_AWIKI_MODEL_PROXY_PACKAGE_VERSION = "0.1.
|
|
3232
|
+
const DSH_AWIKI_PACKAGE_VERSION = "0.3.11-rc.1";
|
|
3233
|
+
const DSH_AWIKI_MODEL_PROXY_PACKAGE_VERSION = "0.1.7-rc.1";
|
|
3178
3234
|
//#endregion
|
|
3179
3235
|
//#region lib/types/update-policy.js
|
|
3180
3236
|
/** Tenant-scoped DSH AWiki plugin update policy and verified cache. */
|
|
@@ -3591,6 +3647,7 @@ const FAILURE_CODES = /* @__PURE__ */ new Set([
|
|
|
3591
3647
|
"invalid-otp",
|
|
3592
3648
|
"challenge-expired",
|
|
3593
3649
|
"handle-unavailable",
|
|
3650
|
+
"short-handle-invite-required",
|
|
3594
3651
|
"not-found",
|
|
3595
3652
|
"forbidden",
|
|
3596
3653
|
"device-rejoin-required",
|
|
@@ -3628,6 +3685,7 @@ const FAILURE_MESSAGES = {
|
|
|
3628
3685
|
"invalid-otp": "The AWiki verification code is invalid.",
|
|
3629
3686
|
"challenge-expired": "The AWiki verification challenge expired.",
|
|
3630
3687
|
"handle-unavailable": "The requested AWiki handle is unavailable.",
|
|
3688
|
+
"short-handle-invite-required": "A new one- through four-character AWiki handle requires an invitation.",
|
|
3631
3689
|
"not-found": "The requested AWiki resource was not found.",
|
|
3632
3690
|
"forbidden": "The AWiki operation is not permitted.",
|
|
3633
3691
|
"device-rejoin-required": "This device credential was revoked and must join the Handle again.",
|
|
@@ -3910,7 +3968,12 @@ function normalizeRecoveryPrepareRequest(request) {
|
|
|
3910
3968
|
};
|
|
3911
3969
|
}
|
|
3912
3970
|
const IDENTITY_ACCESS_RESPONSE_MAX_BYTES = 65536;
|
|
3971
|
+
const DID_URI = /^did:[a-z0-9]+:(?:[A-Za-z0-9._-]|%[0-9A-Fa-f]{2})+(?::(?:[A-Za-z0-9._-]|%[0-9A-Fa-f]{2})+)*$/u;
|
|
3972
|
+
const DID_URI_MAX_CHARACTERS = 2048;
|
|
3913
3973
|
const SERVER_INFO_RESPONSE_MAX_BYTES = 65536;
|
|
3974
|
+
function isBoundedDidUri(value) {
|
|
3975
|
+
return typeof value === "string" && value.length <= DID_URI_MAX_CHARACTERS && DID_URI.test(value);
|
|
3976
|
+
}
|
|
3914
3977
|
/** Read one untrusted discovery response without buffering beyond the fixed Host limit. */
|
|
3915
3978
|
async function readBoundedResponseText(response, maxBytes) {
|
|
3916
3979
|
const declaredLength = response.headers.get("content-length");
|
|
@@ -3953,7 +4016,7 @@ function identityAccessTarget(request, configuredDomain) {
|
|
|
3953
4016
|
const dot = handle.indexOf(".");
|
|
3954
4017
|
const localPart = (dot < 0 ? handle : handle.slice(0, dot)).trim();
|
|
3955
4018
|
const domain = (dot < 0 ? configuredDomain : handle.slice(dot + 1)).trim().replace(/\.$/u, "");
|
|
3956
|
-
if (localPart
|
|
4019
|
+
if (registrationHandleLocalPart(localPart) !== localPart || domain !== configuredDomain) return void 0;
|
|
3957
4020
|
return {
|
|
3958
4021
|
localPart,
|
|
3959
4022
|
fullHandle: `${localPart}.${configuredDomain}`
|
|
@@ -4976,7 +5039,7 @@ let AwikiService = (() => {
|
|
|
4976
5039
|
this.startupUserServiceDomain = this.resolved.userServiceDomain;
|
|
4977
5040
|
ctx.inject(["settings"], (settingsCtx) => {
|
|
4978
5041
|
const provider = settingsCtx.settings;
|
|
4979
|
-
const settingsScope = settingsCtx.settings.register(
|
|
5042
|
+
const settingsScope = settingsCtx.settings.register(AWIKI_SETTINGS_NAMESPACE, AwikiSettingsSchema, {
|
|
4980
5043
|
base: { domain: this.resolved.userServiceDomain },
|
|
4981
5044
|
applies: "restart",
|
|
4982
5045
|
validate: validateAwikiSettings
|
|
@@ -4991,7 +5054,7 @@ let AwikiService = (() => {
|
|
|
4991
5054
|
}, "awiki: release settings namespace");
|
|
4992
5055
|
});
|
|
4993
5056
|
ctx.inject(["connection"], (connectionCtx) => {
|
|
4994
|
-
connectionCtx.connection
|
|
5057
|
+
registerAwikiSettingsTransport(connectionCtx.connection, createAwikiSettingsRpcHandler(() => this.settingsProvider, {
|
|
4995
5058
|
describe: () => this.getTenantRegistryView(),
|
|
4996
5059
|
create: (displayName, domain) => this.createCustomTenant(displayName, domain),
|
|
4997
5060
|
rename: (tenantId, displayName) => this.renameCustomTenant(tenantId, displayName),
|
|
@@ -5001,7 +5064,7 @@ let AwikiService = (() => {
|
|
|
5001
5064
|
refreshUpdate: () => this.refreshUpdatePolicy(),
|
|
5002
5065
|
describeDesktopUpdate: () => this.getDesktopUpdate(),
|
|
5003
5066
|
refreshDesktopUpdate: () => this.refreshDesktopUpdate()
|
|
5004
|
-
})
|
|
5067
|
+
}));
|
|
5005
5068
|
});
|
|
5006
5069
|
ctx.inject(["workspaceRegistry"], (workspaceCtx) => {
|
|
5007
5070
|
this.workspaceContext = workspaceCtx;
|
|
@@ -5627,7 +5690,7 @@ let AwikiService = (() => {
|
|
|
5627
5690
|
fullHandle: target.fullHandle
|
|
5628
5691
|
}
|
|
5629
5692
|
};
|
|
5630
|
-
if (!response.ok) return {
|
|
5693
|
+
if (!response.ok && response.status !== 410) return {
|
|
5631
5694
|
ok: false,
|
|
5632
5695
|
error: failure("remote")
|
|
5633
5696
|
};
|
|
@@ -5643,7 +5706,7 @@ let AwikiService = (() => {
|
|
|
5643
5706
|
error: failure("remote")
|
|
5644
5707
|
};
|
|
5645
5708
|
const binding = value;
|
|
5646
|
-
if (binding.handle !== target.fullHandle ||
|
|
5709
|
+
if (binding.handle !== target.fullHandle || !isBoundedDidUri(binding.did) || typeof binding.status !== "string" || binding.status.length === 0 || response.status === 410 && binding.status !== "revoked") return {
|
|
5647
5710
|
ok: false,
|
|
5648
5711
|
error: failure("remote")
|
|
5649
5712
|
};
|
|
@@ -5662,6 +5725,14 @@ let AwikiService = (() => {
|
|
|
5662
5725
|
}
|
|
5663
5726
|
}
|
|
5664
5727
|
async sendRegistrationOtp(request) {
|
|
5728
|
+
if (shortHandleInviteRequired(request.handle)) {
|
|
5729
|
+
const inspection = await this.inspectIdentityAccess({ handle: request.handle });
|
|
5730
|
+
if (!inspection.ok) return inspection;
|
|
5731
|
+
if (inspection.value.status === "available") return {
|
|
5732
|
+
ok: false,
|
|
5733
|
+
error: failure("short-handle-invite-required")
|
|
5734
|
+
};
|
|
5735
|
+
}
|
|
5665
5736
|
this.pendingDeviceJoin = void 0;
|
|
5666
5737
|
return this.run(async (client) => {
|
|
5667
5738
|
if (await this.selectDeviceJoinSession(client) !== null) throw Object.assign(/* @__PURE__ */ new Error("join already exists"), {
|
|
@@ -5677,6 +5748,14 @@ let AwikiService = (() => {
|
|
|
5677
5748
|
* @returns The new public identity or a closed failure.
|
|
5678
5749
|
*/
|
|
5679
5750
|
async registerIdentity(request) {
|
|
5751
|
+
if (shortHandleInviteRequired(request.handle)) {
|
|
5752
|
+
const inspection = await this.inspectIdentityAccess({ handle: request.handle });
|
|
5753
|
+
if (!inspection.ok) return inspection;
|
|
5754
|
+
if (inspection.value.status === "available") return {
|
|
5755
|
+
ok: false,
|
|
5756
|
+
error: failure("short-handle-invite-required")
|
|
5757
|
+
};
|
|
5758
|
+
}
|
|
5680
5759
|
this.pendingDeviceJoin = void 0;
|
|
5681
5760
|
const result = await this.run(async (client) => {
|
|
5682
5761
|
if (await this.selectDeviceJoinSession(client) !== null) throw Object.assign(/* @__PURE__ */ new Error("join already exists"), {
|
|
@@ -7107,4 +7186,4 @@ function containsUnexpectedBinary(value, seen) {
|
|
|
7107
7186
|
return false;
|
|
7108
7187
|
}
|
|
7109
7188
|
//#endregion
|
|
7110
|
-
export { AWIKI_CHINA_TENANT_ID, AWIKI_CLEAR_LOCAL_DATA_CONFIRMATION, AWIKI_DOMAIN_FIELD, AWIKI_EXTERNAL_HTTP_MAX_BODY_BYTES, AWIKI_GLOBAL_TENANT_ID, AWIKI_HISTORY_TOOL, AWIKI_IDENTITY_STATUS_TOOL, AWIKI_LIST_CONVERSATIONS_TOOL, AWIKI_LOGOUT_CONFIRMATION, AWIKI_MAIL_ACCOUNT_TOOL, AWIKI_MAIL_INBOX_TOOL, AWIKI_MAIL_MARK_READ_TOOL, AWIKI_MAIL_READ_TOOL, AWIKI_MAIL_SEND_TOOL, AWIKI_OFFICIAL_CATALOG_VERSION, AWIKI_SEND_ATTACHMENT_TOOL, AWIKI_SEND_MESSAGE_TOOL, AWIKI_SETTINGS_NAMESPACE, AWIKI_TENANT_REGISTRY_SCHEMA_VERSION, AwikiExternalHttpAuthError, AwikiService, AwikiService as default, AwikiSettingsSchema, Config, DEFAULT_ATTACHMENT_MAX_BYTES, DEFAULT_AWIKI_DOMAIN, DEFAULT_AWIKI_MESSAGE_SERVICE_DID, DEFAULT_AWIKI_SERVICE_URL, DEFAULT_IMAGE_ATTACHMENT_CACHE_MAX_BYTES, DEFAULT_POLL_INTERVAL_MS, DEFAULT_SUMMARY_MAX_INPUT_BYTES, DSH_AWIKI_MODEL_PROXY_VERSION, DSH_AWIKI_VERSION, MAX_SUMMARY_MESSAGES, compareVersions as compareAwikiPluginVersions, normalizeAwikiDomain, validateAwikiSettings };
|
|
7189
|
+
export { AWIKI_CHINA_TENANT_ID, AWIKI_CLEAR_LOCAL_DATA_CONFIRMATION, AWIKI_DOMAIN_FIELD, AWIKI_EXTERNAL_HTTP_MAX_BODY_BYTES, AWIKI_GLOBAL_TENANT_ID, AWIKI_HISTORY_TOOL, AWIKI_IDENTITY_STATUS_TOOL, AWIKI_LIST_CONVERSATIONS_TOOL, AWIKI_LOGOUT_CONFIRMATION, AWIKI_MAIL_ACCOUNT_TOOL, AWIKI_MAIL_INBOX_TOOL, AWIKI_MAIL_MARK_READ_TOOL, AWIKI_MAIL_READ_TOOL, AWIKI_MAIL_SEND_TOOL, AWIKI_OFFICIAL_CATALOG_VERSION, AWIKI_SEND_ATTACHMENT_TOOL, AWIKI_SEND_MESSAGE_TOOL, AWIKI_SETTINGS_NAMESPACE, AWIKI_TENANT_REGISTRY_SCHEMA_VERSION, AwikiExternalHttpAuthError, AwikiService, AwikiService as default, AwikiSettingsSchema, Config, DEFAULT_ATTACHMENT_MAX_BYTES, DEFAULT_AWIKI_DOMAIN, DEFAULT_AWIKI_MESSAGE_SERVICE_DID, DEFAULT_AWIKI_SERVICE_URL, DEFAULT_IMAGE_ATTACHMENT_CACHE_MAX_BYTES, DEFAULT_POLL_INTERVAL_MS, DEFAULT_SUMMARY_MAX_INPUT_BYTES, DSH_AWIKI_MODEL_PROXY_VERSION, DSH_AWIKI_VERSION, MAX_SUMMARY_MESSAGES, compareVersions as compareAwikiPluginVersions, normalizeAwikiDomain, registerAwikiLoopbackRpc, validateAwikiSettings };
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
//#region lib/types/model-proxy-contract.js
|
|
2
2
|
/** Browser-safe contracts for the loopback AWiki-hosted DeepSeek proxy channel. */
|
|
3
|
-
const AWIKI_MODEL_PROXY_RPC_CHANNEL = "/
|
|
3
|
+
const AWIKI_MODEL_PROXY_RPC_CHANNEL = "/api";
|
|
4
4
|
const AWIKI_MODEL_PROXY_RPC_ENDPOINTS = {
|
|
5
|
-
capability: "capability",
|
|
6
|
-
status: "status",
|
|
7
|
-
usage: "usage",
|
|
8
|
-
setEnabled: "set-enabled",
|
|
9
|
-
createRecharge: "create-recharge",
|
|
10
|
-
rechargeStatus: "recharge-status",
|
|
11
|
-
closeRecharge: "close-recharge"
|
|
5
|
+
capability: "awiki-model-proxy/capability",
|
|
6
|
+
status: "awiki-model-proxy/status",
|
|
7
|
+
usage: "awiki-model-proxy/usage",
|
|
8
|
+
setEnabled: "awiki-model-proxy/set-enabled",
|
|
9
|
+
createRecharge: "awiki-model-proxy/create-recharge",
|
|
10
|
+
rechargeStatus: "awiki-model-proxy/recharge-status",
|
|
11
|
+
closeRecharge: "awiki-model-proxy/close-recharge"
|
|
12
12
|
};
|
|
13
13
|
function decodeModelProxyCapability(value) {
|
|
14
14
|
return isRecord(value) && value.available === true && value.protocol === 1 ? {
|