@klarkxy/dsh-web-search-manager 0.1.11 → 0.2.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 +31 -10
- package/cordis.patch.yml +1 -8
- package/docs/README.zh-CN.md +31 -10
- package/lib/client.inner.cjs +649 -104
- package/lib/client.inner.cjs.map +1 -1
- package/lib/client.js +650 -266
- package/lib/contracts.d.ts +15 -20
- package/lib/contracts.js +13 -1
- package/lib/contracts.js.map +1 -1
- package/lib/index.d.ts +19 -3
- package/lib/index.js +506 -389
- package/lib/index.js.map +1 -1
- package/package.json +23 -22
package/lib/contracts.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { WebFetchProvider, WebSearchProvider } from "@deepseek-ai/dsh-web";
|
|
2
|
+
import { DshWebManagementDescriptor } from "@klarkxy/dsh-plugin-kit/contracts";
|
|
2
3
|
//#region src/contracts.d.ts
|
|
3
4
|
declare const WEB_SEARCH_RPC_CHANNEL = "/web-search-manager";
|
|
4
5
|
type RpcResult<T = unknown> = {
|
|
@@ -13,25 +14,16 @@ type RpcResult<T = unknown> = {
|
|
|
13
14
|
};
|
|
14
15
|
};
|
|
15
16
|
type ProviderKind = 'search' | 'fetch';
|
|
16
|
-
/** Management metadata only.
|
|
17
|
-
interface ProviderDescriptor {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
readonly
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
readonly
|
|
25
|
-
|
|
26
|
-
readonly credentialHint?: string;
|
|
27
|
-
readonly billing: 'request' | 'model-and-tools' | 'none';
|
|
28
|
-
/** Optional provider-supplied billing summary. */
|
|
29
|
-
readonly pricing?: string;
|
|
30
|
-
/** Public HTTPS page explaining provider charges. */
|
|
31
|
-
readonly pricingUrl?: string;
|
|
32
|
-
/** Public HTTPS page where the user can create an API key. */
|
|
33
|
-
readonly signupUrl?: string;
|
|
34
|
-
}
|
|
17
|
+
/** Management metadata only. Field contract lives in plugin-kit; execution stays with ctx.web. */
|
|
18
|
+
interface ProviderDescriptor extends DshWebManagementDescriptor {}
|
|
19
|
+
declare const WEB_MANAGER_OWNER = "@klarkxy/dsh-web-search-manager";
|
|
20
|
+
/** Optional display metadata on a provider registered directly with ctx.web. */
|
|
21
|
+
type DiscoverableSearchProvider = WebSearchProvider & {
|
|
22
|
+
readonly dshWebManagement?: ProviderDescriptor;
|
|
23
|
+
};
|
|
24
|
+
type DiscoverableFetchProvider = WebFetchProvider & {
|
|
25
|
+
readonly dshWebManagement?: ProviderDescriptor;
|
|
26
|
+
};
|
|
35
27
|
interface ProviderOptions {
|
|
36
28
|
readonly apiKey?: string;
|
|
37
29
|
readonly baseURL?: string;
|
|
@@ -67,6 +59,8 @@ declare function pickActiveSearch(order: readonly string[], configured: (id: str
|
|
|
67
59
|
interface ProviderView extends ProviderDescriptor {
|
|
68
60
|
kind: ProviderKind;
|
|
69
61
|
configured: boolean;
|
|
62
|
+
/** True only for configuration explicitly owned by this manager bundle. */
|
|
63
|
+
configurationOwned?: boolean;
|
|
70
64
|
baseURL?: string;
|
|
71
65
|
calls: number;
|
|
72
66
|
failures: number;
|
|
@@ -79,7 +73,8 @@ interface WebStatus {
|
|
|
79
73
|
storageFailed: boolean;
|
|
80
74
|
}
|
|
81
75
|
declare function providerKey(kind: ProviderKind, id: string): string;
|
|
76
|
+
declare function safeConfigurationUrl(value: unknown): string | undefined;
|
|
82
77
|
declare function validateBaseURL(value: string): string;
|
|
83
78
|
//#endregion
|
|
84
|
-
export { DEFAULT_SEARCH_ORDER, FetchProviderFactory, ProviderDescriptor, ProviderKind, ProviderOptions, ProviderView, RpcResult, SearchProviderFactory, WEB_SEARCH_RPC_CHANNEL, WebSettings, WebStatus, defaultSearchOrder, defaultSettings, migrateSearchOrder, pickActiveSearch, providerKey, resolveSearchOrder, validateBaseURL };
|
|
79
|
+
export { DEFAULT_SEARCH_ORDER, DiscoverableFetchProvider, DiscoverableSearchProvider, FetchProviderFactory, ProviderDescriptor, ProviderKind, ProviderOptions, ProviderView, RpcResult, SearchProviderFactory, WEB_MANAGER_OWNER, WEB_SEARCH_RPC_CHANNEL, WebSettings, WebStatus, defaultSearchOrder, defaultSettings, migrateSearchOrder, pickActiveSearch, providerKey, resolveSearchOrder, safeConfigurationUrl, validateBaseURL };
|
|
85
80
|
//# sourceMappingURL=contracts.d.ts.map
|
package/lib/contracts.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
//#region src/contracts.ts
|
|
2
2
|
const WEB_SEARCH_RPC_CHANNEL = "/web-search-manager";
|
|
3
|
+
const WEB_MANAGER_OWNER = "@klarkxy/dsh-web-search-manager";
|
|
3
4
|
const DEFAULT_SEARCH_ORDER = ["ddg"];
|
|
4
5
|
const defaultSettings = () => ({
|
|
5
6
|
revision: 0,
|
|
@@ -30,12 +31,23 @@ function pickActiveSearch(order, configured) {
|
|
|
30
31
|
function providerKey(kind, id) {
|
|
31
32
|
return `${kind}:${id}`;
|
|
32
33
|
}
|
|
34
|
+
function safeConfigurationUrl(value) {
|
|
35
|
+
if (typeof value !== "string" || !value || /[\u0000-\u0020\\]/.test(value)) return;
|
|
36
|
+
try {
|
|
37
|
+
const url = new URL(value, "https://dsh.invalid");
|
|
38
|
+
if (url.username || url.password) return;
|
|
39
|
+
if (value.startsWith("/") && !value.startsWith("//") || value.startsWith("#")) return url.origin === "https://dsh.invalid" ? value : void 0;
|
|
40
|
+
return /^https:\/\//i.test(value) && url.protocol === "https:" ? value : void 0;
|
|
41
|
+
} catch {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
33
45
|
function validateBaseURL(value) {
|
|
34
46
|
const url = new URL(value);
|
|
35
47
|
if (url.protocol !== "https:" || url.username || url.password || url.search || url.hash) throw new Error("供应商地址必须是 HTTPS,且不能包含用户名、密码、查询参数或片段。");
|
|
36
48
|
return url.href.replace(/\/+$/, "");
|
|
37
49
|
}
|
|
38
50
|
//#endregion
|
|
39
|
-
export { DEFAULT_SEARCH_ORDER, WEB_SEARCH_RPC_CHANNEL, defaultSearchOrder, defaultSettings, migrateSearchOrder, pickActiveSearch, providerKey, resolveSearchOrder, validateBaseURL };
|
|
51
|
+
export { DEFAULT_SEARCH_ORDER, WEB_MANAGER_OWNER, WEB_SEARCH_RPC_CHANNEL, defaultSearchOrder, defaultSettings, migrateSearchOrder, pickActiveSearch, providerKey, resolveSearchOrder, safeConfigurationUrl, validateBaseURL };
|
|
40
52
|
|
|
41
53
|
//# sourceMappingURL=contracts.js.map
|
package/lib/contracts.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"contracts.js","names":[],"sources":["../src/contracts.ts"],"sourcesContent":["import type { WebFetchProvider, WebSearchProvider } from '@deepseek-ai/dsh-web'\n\nexport const WEB_SEARCH_RPC_CHANNEL = '/web-search-manager'\nexport type RpcResult<T = unknown> = { ok: true; value: T } | {\n ok: false; error: { code: string; message: string; details: Record<string, unknown> }\n}\nexport type ProviderKind = 'search' | 'fetch'\n/** Management metadata only.
|
|
1
|
+
{"version":3,"file":"contracts.js","names":[],"sources":["../src/contracts.ts"],"sourcesContent":["import type { WebFetchProvider, WebSearchProvider } from '@deepseek-ai/dsh-web'\nimport type { DshWebManagementDescriptor } from '@klarkxy/dsh-plugin-kit/contracts'\n\nexport const WEB_SEARCH_RPC_CHANNEL = '/web-search-manager'\nexport type RpcResult<T = unknown> = { ok: true; value: T } | {\n ok: false; error: { code: string; message: string; details: Record<string, unknown> }\n}\nexport type ProviderKind = 'search' | 'fetch'\n/** Management metadata only. Field contract lives in plugin-kit; execution stays with ctx.web. */\nexport interface ProviderDescriptor extends DshWebManagementDescriptor {}\nexport const WEB_MANAGER_OWNER = '@klarkxy/dsh-web-search-manager'\n/** Optional display metadata on a provider registered directly with ctx.web. */\nexport type DiscoverableSearchProvider = WebSearchProvider & { readonly dshWebManagement?: ProviderDescriptor }\nexport type DiscoverableFetchProvider = WebFetchProvider & { readonly dshWebManagement?: ProviderDescriptor }\nexport interface ProviderOptions {\n readonly apiKey?: string\n readonly baseURL?: string\n readonly timeoutMs: number\n readonly maxFetchChars: number\n}\nexport type SearchProviderFactory = (options: ProviderOptions) => WebSearchProvider\nexport type FetchProviderFactory = (options: ProviderOptions) => WebFetchProvider\n/** Never store credential values here. Keys are resolved by reference per call. */\nexport interface WebSettings {\n revision: number\n searchEnabled: boolean\n fetchEnabled: boolean\n searchProvider: string\n fetchProvider: string\n searchOrder: string[]\n maxResults: number\n maxQueries: number\n timeoutMs: number\n maxFetchChars: number\n endpoints: Record<string, string>\n}\nexport const DEFAULT_SEARCH_ORDER = ['ddg'] as const\n\nexport const defaultSettings = (): WebSettings => ({\n revision: 0, searchEnabled: true, fetchEnabled: true,\n searchProvider: 'ddg', fetchProvider: 'http', searchOrder: [...DEFAULT_SEARCH_ORDER],\n maxResults: 5, maxQueries: 1,\n timeoutMs: 30_000, maxFetchChars: 100_000, endpoints: {},\n})\n\n/** Keyed backends first, keyless last — same idea as OpenClaw auto-detect. */\nexport function defaultSearchOrder(ids: readonly string[], keyed: (id: string) => boolean): string[] {\n return [...ids.filter(keyed), ...ids.filter(id => !keyed(id))]\n}\n\nexport function migrateSearchOrder(settings: { searchOrder?: string[]; searchProvider?: string }): string[] {\n return settings.searchOrder ?? (settings.searchProvider ? [settings.searchProvider] : [...DEFAULT_SEARCH_ORDER])\n}\n\nexport function resolveSearchOrder(\n knownIds: readonly string[],\n settings: Pick<WebSettings, 'searchOrder' | 'searchProvider'>,\n _keyed: (id: string) => boolean,\n): string[] {\n return [...new Set(settings.searchOrder.filter(id => knownIds.includes(id)))]\n}\n\nexport function pickActiveSearch(order: readonly string[], configured: (id: string) => boolean): string {\n return order.find(configured) ?? ''\n}\nexport interface ProviderView extends ProviderDescriptor {\n kind: ProviderKind\n configured: boolean\n /** True only for configuration explicitly owned by this manager bundle. */\n configurationOwned?: boolean\n baseURL?: string\n calls: number\n failures: number\n}\nexport interface WebStatus {\n settings: WebSettings\n providers: ProviderView[]\n searchActive: boolean\n fetchActive: boolean\n storageFailed: boolean\n}\nexport function providerKey(kind: ProviderKind, id: string): string { return `${kind}:${id}` }\nexport function safeConfigurationUrl(value: unknown): string | undefined {\n if (typeof value !== 'string' || !value || /[\\u0000-\\u0020\\\\]/.test(value)) return\n try {\n const url = new URL(value, 'https://dsh.invalid')\n if (url.username || url.password) return\n if ((value.startsWith('/') && !value.startsWith('//')) || value.startsWith('#')) {\n return url.origin === 'https://dsh.invalid' ? value : undefined\n }\n return /^https:\\/\\//i.test(value) && url.protocol === 'https:' ? value : undefined\n } catch { return }\n}\nexport function validateBaseURL(value: string): string {\n const url = new URL(value)\n if (url.protocol !== 'https:' || url.username || url.password || url.search || url.hash) {\n throw new Error('供应商地址必须是 HTTPS,且不能包含用户名、密码、查询参数或片段。')\n }\n return url.href.replace(/\\/+$/, '')\n}\n"],"mappings":";AAGA,MAAa,yBAAyB;AAOtC,MAAa,oBAAoB;AA0BjC,MAAa,uBAAuB,CAAC,KAAK;AAE1C,MAAa,yBAAsC;CACjD,UAAU;CAAG,eAAe;CAAM,cAAc;CAChD,gBAAgB;CAAO,eAAe;CAAQ,aAAa,CAAC,GAAG,oBAAoB;CACnF,YAAY;CAAG,YAAY;CAC3B,WAAW;CAAQ,eAAe;CAAS,WAAW,CAAC;AACzD;;AAGA,SAAgB,mBAAmB,KAAwB,OAA0C;CACnG,OAAO,CAAC,GAAG,IAAI,OAAO,KAAK,GAAG,GAAG,IAAI,QAAO,OAAM,CAAC,MAAM,EAAE,CAAC,CAAC;AAC/D;AAEA,SAAgB,mBAAmB,UAAyE;CAC1G,OAAO,SAAS,gBAAgB,SAAS,iBAAiB,CAAC,SAAS,cAAc,IAAI,CAAC,GAAG,oBAAoB;AAChH;AAEA,SAAgB,mBACd,UACA,UACA,QACU;CACV,OAAO,CAAC,GAAG,IAAI,IAAI,SAAS,YAAY,QAAO,OAAM,SAAS,SAAS,EAAE,CAAC,CAAC,CAAC;AAC9E;AAEA,SAAgB,iBAAiB,OAA0B,YAA6C;CACtG,OAAO,MAAM,KAAK,UAAU,KAAK;AACnC;AAiBA,SAAgB,YAAY,MAAoB,IAAoB;CAAE,OAAO,GAAG,KAAK,GAAG;AAAK;AAC7F,SAAgB,qBAAqB,OAAoC;CACvE,IAAI,OAAO,UAAU,YAAY,CAAC,SAAS,oBAAoB,KAAK,KAAK,GAAG;CAC5E,IAAI;EACF,MAAM,MAAM,IAAI,IAAI,OAAO,qBAAqB;EAChD,IAAI,IAAI,YAAY,IAAI,UAAU;EAClC,IAAK,MAAM,WAAW,GAAG,KAAK,CAAC,MAAM,WAAW,IAAI,KAAM,MAAM,WAAW,GAAG,GAC5E,OAAO,IAAI,WAAW,wBAAwB,QAAQ,KAAA;EAExD,OAAO,eAAe,KAAK,KAAK,KAAK,IAAI,aAAa,WAAW,QAAQ,KAAA;CAC3E,QAAQ;EAAE;CAAO;AACnB;AACA,SAAgB,gBAAgB,OAAuB;CACrD,MAAM,MAAM,IAAI,IAAI,KAAK;CACzB,IAAI,IAAI,aAAa,YAAY,IAAI,YAAY,IAAI,YAAY,IAAI,UAAU,IAAI,MACjF,MAAM,IAAI,MAAM,qCAAqC;CAEvD,OAAO,IAAI,KAAK,QAAQ,QAAQ,EAAE;AACpC"}
|
package/lib/index.d.ts
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import { FetchProviderFactory, ProviderDescriptor, ProviderOptions, SearchProviderFactory, WebSettings, WebStatus } from "./contracts.js";
|
|
2
2
|
import { WebFetchProvider, WebSearchProvider } from "@deepseek-ai/dsh-web";
|
|
3
|
+
import { WEB_PROVIDER_AVAILABILITY_EVENT } from "@klarkxy/dsh-plugin-kit/contracts";
|
|
3
4
|
import { Context } from "@deepseek-ai/cordis";
|
|
4
|
-
//#region src/
|
|
5
|
+
//#region src/web-registry.d.ts
|
|
5
6
|
interface WebRegistry {
|
|
6
7
|
registerSearchProvider(provider: WebSearchProvider): () => void;
|
|
7
8
|
registerFetchProvider(provider: WebFetchProvider): () => void;
|
|
8
9
|
}
|
|
10
|
+
//#endregion
|
|
11
|
+
//#region src/manager.d.ts
|
|
9
12
|
interface ManagerOptions {
|
|
10
13
|
web: WebRegistry;
|
|
11
14
|
initial?: Omit<WebSettings, 'searchOrder'> & {
|
|
@@ -25,22 +28,29 @@ declare class WebSearchManager {
|
|
|
25
28
|
private suspended;
|
|
26
29
|
private disposed;
|
|
27
30
|
private storageFailed;
|
|
31
|
+
private refreshRevision;
|
|
32
|
+
private detach;
|
|
33
|
+
private legacyRegistrations;
|
|
28
34
|
constructor(options: ManagerOptions);
|
|
29
35
|
subscribe(listener: () => void): () => void;
|
|
30
36
|
private notify;
|
|
31
37
|
private knownSearchIds;
|
|
32
38
|
private keyed;
|
|
33
39
|
private configured;
|
|
40
|
+
private ready;
|
|
34
41
|
private searchOrder;
|
|
35
42
|
private activeSearchId;
|
|
36
43
|
private selected;
|
|
37
44
|
status(): WebStatus;
|
|
38
45
|
refresh(): Promise<WebStatus>;
|
|
39
46
|
private abort;
|
|
40
|
-
private
|
|
41
|
-
|
|
47
|
+
private discover;
|
|
48
|
+
/** @deprecated Provider plugins should register directly with ctx.web. */
|
|
42
49
|
registerSearchProvider(descriptor: ProviderDescriptor, factory: SearchProviderFactory): () => void;
|
|
50
|
+
/** @deprecated Provider plugins should register directly with ctx.web. */
|
|
43
51
|
registerFetchProvider(descriptor: ProviderDescriptor, factory: FetchProviderFactory): () => void;
|
|
52
|
+
private providerConfiguration;
|
|
53
|
+
private legacyRegistration;
|
|
44
54
|
private execute;
|
|
45
55
|
update(next: Omit<WebSettings, 'revision'>, expectedRevision: number): Promise<WebStatus>;
|
|
46
56
|
dispose(): Promise<void>;
|
|
@@ -55,6 +65,12 @@ declare module '@deepseek-ai/cordis' {
|
|
|
55
65
|
}
|
|
56
66
|
}
|
|
57
67
|
declare function apply(ctx: Context): Promise<void>;
|
|
68
|
+
declare module '@deepseek-ai/cordis' {
|
|
69
|
+
interface Events {
|
|
70
|
+
/** Repository extension: native providers announce a local availability change. */
|
|
71
|
+
[WEB_PROVIDER_AVAILABILITY_EVENT](kind: 'search' | 'fetch', id: string): void;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
58
74
|
//#endregion
|
|
59
75
|
export { type FetchProviderFactory, type ProviderDescriptor, type ProviderOptions, type SearchProviderFactory, WebSearchManager, apply, inject, name };
|
|
60
76
|
//# sourceMappingURL=index.d.ts.map
|