@omnicross/contracts 0.1.10 → 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/dist/health-logging-types.d.cts +7 -0
- package/dist/health-logging-types.d.ts +7 -0
- package/dist/image-generation-types.cjs +63 -0
- package/dist/image-generation-types.d.cts +193 -0
- package/dist/image-generation-types.d.ts +193 -0
- package/dist/image-generation-types.js +37 -0
- package/dist/index.cjs +222 -2
- package/dist/index.d.cts +3 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +209 -1
- package/dist/search-compat.cjs +130 -0
- package/dist/search-compat.d.cts +93 -0
- package/dist/search-compat.d.ts +93 -0
- package/dist/search-compat.js +100 -0
- package/dist/search-types.cjs +102 -0
- package/dist/search-types.d.cts +420 -0
- package/dist/search-types.d.ts +420 -0
- package/dist/search-types.js +74 -0
- package/dist/usage-types.d.cts +2 -0
- package/dist/usage-types.d.ts +2 -0
- package/dist/websearch-types.d.cts +20 -2
- package/dist/websearch-types.d.ts +20 -2
- package/package.json +172 -156
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/search-compat.ts
|
|
21
|
+
var search_compat_exports = {};
|
|
22
|
+
__export(search_compat_exports, {
|
|
23
|
+
LEGACY_UNKNOWN_PROVIDER_ID: () => LEGACY_UNKNOWN_PROVIDER_ID,
|
|
24
|
+
fromLegacyWebSearchResponse: () => fromLegacyWebSearchResponse,
|
|
25
|
+
legacyErrorStringToSearchErrorCode: () => legacyErrorStringToSearchErrorCode,
|
|
26
|
+
legacyProviderIdToSearchProviderId: () => legacyProviderIdToSearchProviderId,
|
|
27
|
+
searchErrorToLegacyWebSearchResponse: () => searchErrorToLegacyWebSearchResponse,
|
|
28
|
+
toLegacyWebSearchResponse: () => toLegacyWebSearchResponse
|
|
29
|
+
});
|
|
30
|
+
module.exports = __toCommonJS(search_compat_exports);
|
|
31
|
+
var LEGACY_UNKNOWN_PROVIDER_ID = "legacy:unknown";
|
|
32
|
+
var DEFAULT_LEGACY_ERROR_CODE = "upstream_unavailable";
|
|
33
|
+
function legacyProviderIdToSearchProviderId(id) {
|
|
34
|
+
return id;
|
|
35
|
+
}
|
|
36
|
+
var LEGACY_ERROR_RULES = [
|
|
37
|
+
// Runtime facts first.
|
|
38
|
+
{ pattern: /abort|cancell?ed|cancell?ing/i, code: "cancelled" },
|
|
39
|
+
{ pattern: /timed ?out|timeout/i, code: "timeout" },
|
|
40
|
+
// WebSearchService.search()
|
|
41
|
+
{ pattern: /not configured/i, code: "config_missing" },
|
|
42
|
+
{ pattern: /is disabled/i, code: "policy_denied" },
|
|
43
|
+
{ pattern: /not implemented/i, code: "upstream_unavailable" },
|
|
44
|
+
// HttpOnlyWebSearchService / WebSearchOrchestrator transport availability
|
|
45
|
+
{ pattern: /unavailable in this host/i, code: "upstream_unavailable" },
|
|
46
|
+
{ pattern: /HTTP search transport is unavailable/i, code: "upstream_unavailable" },
|
|
47
|
+
// Exhausted-candidate summaries (both fallback implementations)
|
|
48
|
+
{ pattern: /No eligible web search provider returned usable results/i, code: "upstream_unavailable" },
|
|
49
|
+
{ pattern: /No keyless HTTP search provider returned usable results/i, code: "upstream_unavailable" },
|
|
50
|
+
// Anti-bot / anti-decoy refusals — the page came back, it just cannot be trusted.
|
|
51
|
+
{ pattern: /bot-challenge/i, code: "upstream_unavailable" },
|
|
52
|
+
{
|
|
53
|
+
pattern: /returned an untrusted search result page|refusing to return possible bot-decoy content/i,
|
|
54
|
+
code: "upstream_unavailable"
|
|
55
|
+
},
|
|
56
|
+
{ pattern: /JavaScript-only search shell without result entries/i, code: "upstream_unavailable" },
|
|
57
|
+
// Response the provider did return, but which could not be turned into results.
|
|
58
|
+
{ pattern: /response contained no result entries/i, code: "parse_failed" },
|
|
59
|
+
{ pattern: /returned an invalid response/i, code: "parse_failed" },
|
|
60
|
+
{ pattern: /returned an invalid result list/i, code: "parse_failed" },
|
|
61
|
+
{ pattern: /returned only duplicate results/i, code: "parse_failed" },
|
|
62
|
+
{ pattern: /returned no usable direct results/i, code: "parse_failed" },
|
|
63
|
+
{ pattern: /returned no results/i, code: "parse_failed" }
|
|
64
|
+
];
|
|
65
|
+
function legacyErrorStringToSearchErrorCode(message) {
|
|
66
|
+
for (const rule of LEGACY_ERROR_RULES) {
|
|
67
|
+
if (rule.pattern.test(message)) return rule.code;
|
|
68
|
+
}
|
|
69
|
+
return DEFAULT_LEGACY_ERROR_CODE;
|
|
70
|
+
}
|
|
71
|
+
function providerIdFromLegacyErrorString(message) {
|
|
72
|
+
const match = /^Provider\s+(?!is\b|returned\b|request\b)(\S+)\s+(?:is|not)\b/i.exec(message);
|
|
73
|
+
return match?.[1];
|
|
74
|
+
}
|
|
75
|
+
function toSearchResult(result) {
|
|
76
|
+
return { title: result.title, url: result.url, content: result.content };
|
|
77
|
+
}
|
|
78
|
+
function fromLegacyWebSearchResponse(resp) {
|
|
79
|
+
if (resp.success) {
|
|
80
|
+
return {
|
|
81
|
+
ok: true,
|
|
82
|
+
response: {
|
|
83
|
+
query: resp.query,
|
|
84
|
+
providerId: resp.provider ?? LEGACY_UNKNOWN_PROVIDER_ID,
|
|
85
|
+
results: resp.results.map(toSearchResult)
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
const message = resp.error ?? "Unknown error";
|
|
90
|
+
const error = {
|
|
91
|
+
code: legacyErrorStringToSearchErrorCode(message),
|
|
92
|
+
message
|
|
93
|
+
};
|
|
94
|
+
const providerId = resp.provider ?? providerIdFromLegacyErrorString(message);
|
|
95
|
+
if (providerId !== void 0) error.providerId = providerId;
|
|
96
|
+
return { ok: false, error };
|
|
97
|
+
}
|
|
98
|
+
function toLegacyWebSearchResponse(response) {
|
|
99
|
+
return {
|
|
100
|
+
success: true,
|
|
101
|
+
query: response.query,
|
|
102
|
+
results: response.results.map((result) => ({
|
|
103
|
+
title: result.title,
|
|
104
|
+
content: result.content,
|
|
105
|
+
url: result.url
|
|
106
|
+
})),
|
|
107
|
+
provider: response.providerId
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
function searchErrorToLegacyWebSearchResponse(query, error) {
|
|
111
|
+
const response = {
|
|
112
|
+
success: false,
|
|
113
|
+
query,
|
|
114
|
+
results: [],
|
|
115
|
+
error: error.message.trim().length > 0 ? error.message : error.code
|
|
116
|
+
};
|
|
117
|
+
if (error.providerId !== void 0) {
|
|
118
|
+
response.provider = error.providerId;
|
|
119
|
+
}
|
|
120
|
+
return response;
|
|
121
|
+
}
|
|
122
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
123
|
+
0 && (module.exports = {
|
|
124
|
+
LEGACY_UNKNOWN_PROVIDER_ID,
|
|
125
|
+
fromLegacyWebSearchResponse,
|
|
126
|
+
legacyErrorStringToSearchErrorCode,
|
|
127
|
+
legacyProviderIdToSearchProviderId,
|
|
128
|
+
searchErrorToLegacyWebSearchResponse,
|
|
129
|
+
toLegacyWebSearchResponse
|
|
130
|
+
});
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { SearchProviderId, SearchResponse, SearchErrorShape, SearchErrorCode } from './search-types.cjs';
|
|
2
|
+
import { WebSearchResponse, WebSearchProviderId } from './websearch-types.cjs';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Legacy ↔ target search conversions — a Phase-1 compat layer.
|
|
6
|
+
*
|
|
7
|
+
* **This module is temporary.** It exists so consumers can migrate from the
|
|
8
|
+
* legacy `WebSearch*` vocabulary in `./websearch-types` to the target
|
|
9
|
+
* `Search*` vocabulary in `./search-types` one at a time, instead of in one
|
|
10
|
+
* flag day. It is scheduled for deletion in Phase 2 (阶段8), once no consumer
|
|
11
|
+
* speaks the legacy shapes; every import of it is migration debt and is meant
|
|
12
|
+
* to be grep-able as such.
|
|
13
|
+
*
|
|
14
|
+
* Nothing here classifies a provider from its id's spelling. The one place a
|
|
15
|
+
* string is interpreted is {@link legacyErrorStringToSearchErrorCode}, which
|
|
16
|
+
* translates the *frozen* legacy error literals (recorded in
|
|
17
|
+
* `docs/design/search-baseline/elftia-search-baseline.md` §6.2) into the stable
|
|
18
|
+
* taxonomy — a single, tested mapping so the five Phase-1 stages do not each
|
|
19
|
+
* re-derive one.
|
|
20
|
+
*
|
|
21
|
+
* Pure module: no Node, Electron, HTTP, or SDK imports.
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Provider id used when a legacy response carries results but no `provider`.
|
|
26
|
+
*
|
|
27
|
+
* Namespaced so it can never collide with a real provider id, and deliberately
|
|
28
|
+
* not a member of `KnownSearchProviderId` — it marks "the legacy payload did
|
|
29
|
+
* not say", not a provider.
|
|
30
|
+
*/
|
|
31
|
+
declare const LEGACY_UNKNOWN_PROVIDER_ID: SearchProviderId;
|
|
32
|
+
/**
|
|
33
|
+
* Widen a legacy provider id into the open id space.
|
|
34
|
+
*
|
|
35
|
+
* Identity at runtime; the value is a re-typing, not a translation. Every
|
|
36
|
+
* member of the closed legacy union is a valid {@link SearchProviderId}.
|
|
37
|
+
*/
|
|
38
|
+
declare function legacyProviderIdToSearchProviderId(id: WebSearchProviderId): SearchProviderId;
|
|
39
|
+
/**
|
|
40
|
+
* Translate a legacy error string into a stable {@link SearchErrorCode}.
|
|
41
|
+
*
|
|
42
|
+
* Total and deterministic: every input returns a code, and the same input
|
|
43
|
+
* always returns the same one. Unrecognized strings — including a provider's
|
|
44
|
+
* own transport error text — map to the documented default
|
|
45
|
+
* `upstream_unavailable`, which is the safe assumption for a fallback policy
|
|
46
|
+
* (retry a different provider) as opposed to `cancelled` or `policy_denied`,
|
|
47
|
+
* which stop the loop.
|
|
48
|
+
*
|
|
49
|
+
* The recognized strings are the frozen legacy literals from baseline §6.2;
|
|
50
|
+
* they are asserted verbatim in this module's tests, so a future baseline
|
|
51
|
+
* drift fails loudly instead of silently re-coding a failure.
|
|
52
|
+
*/
|
|
53
|
+
declare function legacyErrorStringToSearchErrorCode(message: string): SearchErrorCode;
|
|
54
|
+
/**
|
|
55
|
+
* Convert a legacy provider response into the target vocabulary.
|
|
56
|
+
*
|
|
57
|
+
* A legacy `success: false` becomes a taxonomy-coded {@link SearchErrorShape}
|
|
58
|
+
* (the original string is preserved verbatim in `message`, so the baseline's
|
|
59
|
+
* comparison oracles still work); a `success: true` becomes a
|
|
60
|
+
* {@link SearchResponse}, falling back to {@link LEGACY_UNKNOWN_PROVIDER_ID}
|
|
61
|
+
* when the legacy payload named no provider.
|
|
62
|
+
*/
|
|
63
|
+
declare function fromLegacyWebSearchResponse(resp: WebSearchResponse): {
|
|
64
|
+
ok: true;
|
|
65
|
+
response: SearchResponse;
|
|
66
|
+
} | {
|
|
67
|
+
ok: false;
|
|
68
|
+
error: SearchErrorShape;
|
|
69
|
+
};
|
|
70
|
+
/**
|
|
71
|
+
* Convert a target response back into the legacy shape for a consumer that
|
|
72
|
+
* still speaks it.
|
|
73
|
+
*
|
|
74
|
+
* The legacy `provider` field is typed as the closed `WebSearchProviderId`
|
|
75
|
+
* union, which cannot express the ids Omnicross ships for HTTP providers
|
|
76
|
+
* (`http-bing`, `http-duckduckgo` — Elftia widened its own copy to
|
|
77
|
+
* `WebSearchExecutionProviderId` for exactly this reason). The id is preserved
|
|
78
|
+
* verbatim through a cast rather than dropped: losing which provider produced
|
|
79
|
+
* a result set is worse than a union the legacy type cannot name, and this
|
|
80
|
+
* mismatch is one of the reasons the compat layer is temporary.
|
|
81
|
+
*/
|
|
82
|
+
declare function toLegacyWebSearchResponse(response: SearchResponse): WebSearchResponse;
|
|
83
|
+
/**
|
|
84
|
+
* Render a target error as a legacy failure response.
|
|
85
|
+
*
|
|
86
|
+
* The message is passed through unchanged — no code prefix — because legacy
|
|
87
|
+
* consumers and the baseline oracles compare these strings literally. An empty
|
|
88
|
+
* message falls back to the taxonomy code so the legacy `error` field is never
|
|
89
|
+
* blank.
|
|
90
|
+
*/
|
|
91
|
+
declare function searchErrorToLegacyWebSearchResponse(query: string, error: SearchErrorShape): WebSearchResponse;
|
|
92
|
+
|
|
93
|
+
export { LEGACY_UNKNOWN_PROVIDER_ID, fromLegacyWebSearchResponse, legacyErrorStringToSearchErrorCode, legacyProviderIdToSearchProviderId, searchErrorToLegacyWebSearchResponse, toLegacyWebSearchResponse };
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { SearchProviderId, SearchResponse, SearchErrorShape, SearchErrorCode } from './search-types.js';
|
|
2
|
+
import { WebSearchResponse, WebSearchProviderId } from './websearch-types.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Legacy ↔ target search conversions — a Phase-1 compat layer.
|
|
6
|
+
*
|
|
7
|
+
* **This module is temporary.** It exists so consumers can migrate from the
|
|
8
|
+
* legacy `WebSearch*` vocabulary in `./websearch-types` to the target
|
|
9
|
+
* `Search*` vocabulary in `./search-types` one at a time, instead of in one
|
|
10
|
+
* flag day. It is scheduled for deletion in Phase 2 (阶段8), once no consumer
|
|
11
|
+
* speaks the legacy shapes; every import of it is migration debt and is meant
|
|
12
|
+
* to be grep-able as such.
|
|
13
|
+
*
|
|
14
|
+
* Nothing here classifies a provider from its id's spelling. The one place a
|
|
15
|
+
* string is interpreted is {@link legacyErrorStringToSearchErrorCode}, which
|
|
16
|
+
* translates the *frozen* legacy error literals (recorded in
|
|
17
|
+
* `docs/design/search-baseline/elftia-search-baseline.md` §6.2) into the stable
|
|
18
|
+
* taxonomy — a single, tested mapping so the five Phase-1 stages do not each
|
|
19
|
+
* re-derive one.
|
|
20
|
+
*
|
|
21
|
+
* Pure module: no Node, Electron, HTTP, or SDK imports.
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Provider id used when a legacy response carries results but no `provider`.
|
|
26
|
+
*
|
|
27
|
+
* Namespaced so it can never collide with a real provider id, and deliberately
|
|
28
|
+
* not a member of `KnownSearchProviderId` — it marks "the legacy payload did
|
|
29
|
+
* not say", not a provider.
|
|
30
|
+
*/
|
|
31
|
+
declare const LEGACY_UNKNOWN_PROVIDER_ID: SearchProviderId;
|
|
32
|
+
/**
|
|
33
|
+
* Widen a legacy provider id into the open id space.
|
|
34
|
+
*
|
|
35
|
+
* Identity at runtime; the value is a re-typing, not a translation. Every
|
|
36
|
+
* member of the closed legacy union is a valid {@link SearchProviderId}.
|
|
37
|
+
*/
|
|
38
|
+
declare function legacyProviderIdToSearchProviderId(id: WebSearchProviderId): SearchProviderId;
|
|
39
|
+
/**
|
|
40
|
+
* Translate a legacy error string into a stable {@link SearchErrorCode}.
|
|
41
|
+
*
|
|
42
|
+
* Total and deterministic: every input returns a code, and the same input
|
|
43
|
+
* always returns the same one. Unrecognized strings — including a provider's
|
|
44
|
+
* own transport error text — map to the documented default
|
|
45
|
+
* `upstream_unavailable`, which is the safe assumption for a fallback policy
|
|
46
|
+
* (retry a different provider) as opposed to `cancelled` or `policy_denied`,
|
|
47
|
+
* which stop the loop.
|
|
48
|
+
*
|
|
49
|
+
* The recognized strings are the frozen legacy literals from baseline §6.2;
|
|
50
|
+
* they are asserted verbatim in this module's tests, so a future baseline
|
|
51
|
+
* drift fails loudly instead of silently re-coding a failure.
|
|
52
|
+
*/
|
|
53
|
+
declare function legacyErrorStringToSearchErrorCode(message: string): SearchErrorCode;
|
|
54
|
+
/**
|
|
55
|
+
* Convert a legacy provider response into the target vocabulary.
|
|
56
|
+
*
|
|
57
|
+
* A legacy `success: false` becomes a taxonomy-coded {@link SearchErrorShape}
|
|
58
|
+
* (the original string is preserved verbatim in `message`, so the baseline's
|
|
59
|
+
* comparison oracles still work); a `success: true` becomes a
|
|
60
|
+
* {@link SearchResponse}, falling back to {@link LEGACY_UNKNOWN_PROVIDER_ID}
|
|
61
|
+
* when the legacy payload named no provider.
|
|
62
|
+
*/
|
|
63
|
+
declare function fromLegacyWebSearchResponse(resp: WebSearchResponse): {
|
|
64
|
+
ok: true;
|
|
65
|
+
response: SearchResponse;
|
|
66
|
+
} | {
|
|
67
|
+
ok: false;
|
|
68
|
+
error: SearchErrorShape;
|
|
69
|
+
};
|
|
70
|
+
/**
|
|
71
|
+
* Convert a target response back into the legacy shape for a consumer that
|
|
72
|
+
* still speaks it.
|
|
73
|
+
*
|
|
74
|
+
* The legacy `provider` field is typed as the closed `WebSearchProviderId`
|
|
75
|
+
* union, which cannot express the ids Omnicross ships for HTTP providers
|
|
76
|
+
* (`http-bing`, `http-duckduckgo` — Elftia widened its own copy to
|
|
77
|
+
* `WebSearchExecutionProviderId` for exactly this reason). The id is preserved
|
|
78
|
+
* verbatim through a cast rather than dropped: losing which provider produced
|
|
79
|
+
* a result set is worse than a union the legacy type cannot name, and this
|
|
80
|
+
* mismatch is one of the reasons the compat layer is temporary.
|
|
81
|
+
*/
|
|
82
|
+
declare function toLegacyWebSearchResponse(response: SearchResponse): WebSearchResponse;
|
|
83
|
+
/**
|
|
84
|
+
* Render a target error as a legacy failure response.
|
|
85
|
+
*
|
|
86
|
+
* The message is passed through unchanged — no code prefix — because legacy
|
|
87
|
+
* consumers and the baseline oracles compare these strings literally. An empty
|
|
88
|
+
* message falls back to the taxonomy code so the legacy `error` field is never
|
|
89
|
+
* blank.
|
|
90
|
+
*/
|
|
91
|
+
declare function searchErrorToLegacyWebSearchResponse(query: string, error: SearchErrorShape): WebSearchResponse;
|
|
92
|
+
|
|
93
|
+
export { LEGACY_UNKNOWN_PROVIDER_ID, fromLegacyWebSearchResponse, legacyErrorStringToSearchErrorCode, legacyProviderIdToSearchProviderId, searchErrorToLegacyWebSearchResponse, toLegacyWebSearchResponse };
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
// src/search-compat.ts
|
|
2
|
+
var LEGACY_UNKNOWN_PROVIDER_ID = "legacy:unknown";
|
|
3
|
+
var DEFAULT_LEGACY_ERROR_CODE = "upstream_unavailable";
|
|
4
|
+
function legacyProviderIdToSearchProviderId(id) {
|
|
5
|
+
return id;
|
|
6
|
+
}
|
|
7
|
+
var LEGACY_ERROR_RULES = [
|
|
8
|
+
// Runtime facts first.
|
|
9
|
+
{ pattern: /abort|cancell?ed|cancell?ing/i, code: "cancelled" },
|
|
10
|
+
{ pattern: /timed ?out|timeout/i, code: "timeout" },
|
|
11
|
+
// WebSearchService.search()
|
|
12
|
+
{ pattern: /not configured/i, code: "config_missing" },
|
|
13
|
+
{ pattern: /is disabled/i, code: "policy_denied" },
|
|
14
|
+
{ pattern: /not implemented/i, code: "upstream_unavailable" },
|
|
15
|
+
// HttpOnlyWebSearchService / WebSearchOrchestrator transport availability
|
|
16
|
+
{ pattern: /unavailable in this host/i, code: "upstream_unavailable" },
|
|
17
|
+
{ pattern: /HTTP search transport is unavailable/i, code: "upstream_unavailable" },
|
|
18
|
+
// Exhausted-candidate summaries (both fallback implementations)
|
|
19
|
+
{ pattern: /No eligible web search provider returned usable results/i, code: "upstream_unavailable" },
|
|
20
|
+
{ pattern: /No keyless HTTP search provider returned usable results/i, code: "upstream_unavailable" },
|
|
21
|
+
// Anti-bot / anti-decoy refusals — the page came back, it just cannot be trusted.
|
|
22
|
+
{ pattern: /bot-challenge/i, code: "upstream_unavailable" },
|
|
23
|
+
{
|
|
24
|
+
pattern: /returned an untrusted search result page|refusing to return possible bot-decoy content/i,
|
|
25
|
+
code: "upstream_unavailable"
|
|
26
|
+
},
|
|
27
|
+
{ pattern: /JavaScript-only search shell without result entries/i, code: "upstream_unavailable" },
|
|
28
|
+
// Response the provider did return, but which could not be turned into results.
|
|
29
|
+
{ pattern: /response contained no result entries/i, code: "parse_failed" },
|
|
30
|
+
{ pattern: /returned an invalid response/i, code: "parse_failed" },
|
|
31
|
+
{ pattern: /returned an invalid result list/i, code: "parse_failed" },
|
|
32
|
+
{ pattern: /returned only duplicate results/i, code: "parse_failed" },
|
|
33
|
+
{ pattern: /returned no usable direct results/i, code: "parse_failed" },
|
|
34
|
+
{ pattern: /returned no results/i, code: "parse_failed" }
|
|
35
|
+
];
|
|
36
|
+
function legacyErrorStringToSearchErrorCode(message) {
|
|
37
|
+
for (const rule of LEGACY_ERROR_RULES) {
|
|
38
|
+
if (rule.pattern.test(message)) return rule.code;
|
|
39
|
+
}
|
|
40
|
+
return DEFAULT_LEGACY_ERROR_CODE;
|
|
41
|
+
}
|
|
42
|
+
function providerIdFromLegacyErrorString(message) {
|
|
43
|
+
const match = /^Provider\s+(?!is\b|returned\b|request\b)(\S+)\s+(?:is|not)\b/i.exec(message);
|
|
44
|
+
return match?.[1];
|
|
45
|
+
}
|
|
46
|
+
function toSearchResult(result) {
|
|
47
|
+
return { title: result.title, url: result.url, content: result.content };
|
|
48
|
+
}
|
|
49
|
+
function fromLegacyWebSearchResponse(resp) {
|
|
50
|
+
if (resp.success) {
|
|
51
|
+
return {
|
|
52
|
+
ok: true,
|
|
53
|
+
response: {
|
|
54
|
+
query: resp.query,
|
|
55
|
+
providerId: resp.provider ?? LEGACY_UNKNOWN_PROVIDER_ID,
|
|
56
|
+
results: resp.results.map(toSearchResult)
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
const message = resp.error ?? "Unknown error";
|
|
61
|
+
const error = {
|
|
62
|
+
code: legacyErrorStringToSearchErrorCode(message),
|
|
63
|
+
message
|
|
64
|
+
};
|
|
65
|
+
const providerId = resp.provider ?? providerIdFromLegacyErrorString(message);
|
|
66
|
+
if (providerId !== void 0) error.providerId = providerId;
|
|
67
|
+
return { ok: false, error };
|
|
68
|
+
}
|
|
69
|
+
function toLegacyWebSearchResponse(response) {
|
|
70
|
+
return {
|
|
71
|
+
success: true,
|
|
72
|
+
query: response.query,
|
|
73
|
+
results: response.results.map((result) => ({
|
|
74
|
+
title: result.title,
|
|
75
|
+
content: result.content,
|
|
76
|
+
url: result.url
|
|
77
|
+
})),
|
|
78
|
+
provider: response.providerId
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
function searchErrorToLegacyWebSearchResponse(query, error) {
|
|
82
|
+
const response = {
|
|
83
|
+
success: false,
|
|
84
|
+
query,
|
|
85
|
+
results: [],
|
|
86
|
+
error: error.message.trim().length > 0 ? error.message : error.code
|
|
87
|
+
};
|
|
88
|
+
if (error.providerId !== void 0) {
|
|
89
|
+
response.provider = error.providerId;
|
|
90
|
+
}
|
|
91
|
+
return response;
|
|
92
|
+
}
|
|
93
|
+
export {
|
|
94
|
+
LEGACY_UNKNOWN_PROVIDER_ID,
|
|
95
|
+
fromLegacyWebSearchResponse,
|
|
96
|
+
legacyErrorStringToSearchErrorCode,
|
|
97
|
+
legacyProviderIdToSearchProviderId,
|
|
98
|
+
searchErrorToLegacyWebSearchResponse,
|
|
99
|
+
toLegacyWebSearchResponse
|
|
100
|
+
};
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/search-types.ts
|
|
21
|
+
var search_types_exports = {};
|
|
22
|
+
__export(search_types_exports, {
|
|
23
|
+
SearchProviderError: () => SearchProviderError,
|
|
24
|
+
isKnownSearchProviderId: () => isKnownSearchProviderId,
|
|
25
|
+
isSearchProviderError: () => isSearchProviderError,
|
|
26
|
+
toSearchErrorShape: () => toSearchErrorShape
|
|
27
|
+
});
|
|
28
|
+
module.exports = __toCommonJS(search_types_exports);
|
|
29
|
+
var KNOWN_SEARCH_PROVIDER_IDS = /* @__PURE__ */ new Set([
|
|
30
|
+
"http-bing",
|
|
31
|
+
"http-duckduckgo",
|
|
32
|
+
"tavily",
|
|
33
|
+
"jina",
|
|
34
|
+
"searxng",
|
|
35
|
+
"zhipu",
|
|
36
|
+
"z.ai"
|
|
37
|
+
]);
|
|
38
|
+
function isKnownSearchProviderId(id) {
|
|
39
|
+
return KNOWN_SEARCH_PROVIDER_IDS.has(id);
|
|
40
|
+
}
|
|
41
|
+
var SEARCH_ERROR_CODES = /* @__PURE__ */ new Set([
|
|
42
|
+
"config_missing",
|
|
43
|
+
"auth_failed",
|
|
44
|
+
"rate_limited",
|
|
45
|
+
"timeout",
|
|
46
|
+
"upstream_unavailable",
|
|
47
|
+
"parse_failed",
|
|
48
|
+
"cancelled",
|
|
49
|
+
"policy_denied"
|
|
50
|
+
]);
|
|
51
|
+
var DEFAULT_SEARCH_ERROR_CODE = "upstream_unavailable";
|
|
52
|
+
var SearchProviderError = class _SearchProviderError extends Error {
|
|
53
|
+
/** Stable taxonomy code. */
|
|
54
|
+
code;
|
|
55
|
+
/** The provider that failed, when known. */
|
|
56
|
+
providerId;
|
|
57
|
+
/** Whether retrying the same provider could plausibly succeed. */
|
|
58
|
+
retryable;
|
|
59
|
+
/** Pre-sanitized string-valued context. */
|
|
60
|
+
details;
|
|
61
|
+
constructor(code, message, init = {}) {
|
|
62
|
+
super(message, init.cause === void 0 ? void 0 : { cause: init.cause });
|
|
63
|
+
this.name = "SearchProviderError";
|
|
64
|
+
this.code = code;
|
|
65
|
+
this.providerId = init.providerId;
|
|
66
|
+
this.retryable = init.retryable;
|
|
67
|
+
this.details = init.details;
|
|
68
|
+
Object.setPrototypeOf(this, _SearchProviderError.prototype);
|
|
69
|
+
}
|
|
70
|
+
/** This error as its serializable {@link SearchErrorShape}. */
|
|
71
|
+
toShape() {
|
|
72
|
+
return toSearchErrorShape(this);
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
function isSearchProviderError(value) {
|
|
76
|
+
if (value instanceof SearchProviderError) return true;
|
|
77
|
+
if (!(value instanceof Error)) return false;
|
|
78
|
+
const code = value.code;
|
|
79
|
+
return typeof code === "string" && SEARCH_ERROR_CODES.has(code);
|
|
80
|
+
}
|
|
81
|
+
function toSearchErrorShape(value) {
|
|
82
|
+
if (isSearchProviderError(value)) {
|
|
83
|
+
const shape = { code: value.code, message: value.message };
|
|
84
|
+
if (value.providerId !== void 0) shape.providerId = value.providerId;
|
|
85
|
+
if (value.retryable !== void 0) shape.retryable = value.retryable;
|
|
86
|
+
if (value.details !== void 0) shape.details = value.details;
|
|
87
|
+
return shape;
|
|
88
|
+
}
|
|
89
|
+
return { code: DEFAULT_SEARCH_ERROR_CODE, message: describeUnknownError(value) };
|
|
90
|
+
}
|
|
91
|
+
function describeUnknownError(value) {
|
|
92
|
+
if (typeof value === "string") return value;
|
|
93
|
+
if (value instanceof Error && value.message) return value.message;
|
|
94
|
+
return "Unknown error";
|
|
95
|
+
}
|
|
96
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
97
|
+
0 && (module.exports = {
|
|
98
|
+
SearchProviderError,
|
|
99
|
+
isKnownSearchProviderId,
|
|
100
|
+
isSearchProviderError,
|
|
101
|
+
toSearchErrorShape
|
|
102
|
+
});
|