harness-mcp-v2 3.2.4 → 3.2.6
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 +62 -3
- package/build/config.d.ts +22 -3
- package/build/config.d.ts.map +1 -1
- package/build/config.js +10 -0
- package/build/config.js.map +1 -1
- package/build/data/examples/index.d.ts +2 -0
- package/build/data/examples/index.d.ts.map +1 -1
- package/build/data/examples/index.js +4 -0
- package/build/data/examples/index.js.map +1 -1
- package/build/data/schemas/v0/pipeline.d.ts.map +1 -1
- package/build/data/schemas/v0/pipeline.js +209 -10
- package/build/data/schemas/v0/pipeline.js.map +1 -1
- package/build/data/schemas/v0/template.d.ts.map +1 -1
- package/build/data/schemas/v0/template.js +388 -105
- package/build/data/schemas/v0/template.js.map +1 -1
- package/build/data/schemas/v1/pipeline.d.ts.map +1 -1
- package/build/data/schemas/v1/pipeline.js +11 -0
- package/build/data/schemas/v1/pipeline.js.map +1 -1
- package/build/data/schemas/v1/template.d.ts.map +1 -1
- package/build/data/schemas/v1/template.js +11 -0
- package/build/data/schemas/v1/template.js.map +1 -1
- package/build/index.js +67 -11
- package/build/index.js.map +1 -1
- package/build/prompts/create-agent.d.ts.map +1 -1
- package/build/prompts/create-agent.js +21 -1
- package/build/prompts/create-agent.js.map +1 -1
- package/build/registry/extractors.d.ts +10 -3
- package/build/registry/extractors.d.ts.map +1 -1
- package/build/registry/extractors.js +27 -9
- package/build/registry/extractors.js.map +1 -1
- package/build/registry/toolsets/chaos-descriptions.d.ts +23 -19
- package/build/registry/toolsets/chaos-descriptions.d.ts.map +1 -1
- package/build/registry/toolsets/chaos-descriptions.js +134 -48
- package/build/registry/toolsets/chaos-descriptions.js.map +1 -1
- package/build/registry/toolsets/chaos.d.ts.map +1 -1
- package/build/registry/toolsets/chaos.js +323 -56
- package/build/registry/toolsets/chaos.js.map +1 -1
- package/build/registry/toolsets/dbops.js +2 -2
- package/build/registry/toolsets/dbops.js.map +1 -1
- package/build/registry/toolsets/idp.d.ts.map +1 -1
- package/build/registry/toolsets/idp.js +0 -6
- package/build/registry/toolsets/idp.js.map +1 -1
- package/build/registry/toolsets/pipelines.d.ts.map +1 -1
- package/build/registry/toolsets/pipelines.js +6 -4
- package/build/registry/toolsets/pipelines.js.map +1 -1
- package/build/registry/toolsets/pull-requests.d.ts.map +1 -1
- package/build/registry/toolsets/pull-requests.js +47 -2
- package/build/registry/toolsets/pull-requests.js.map +1 -1
- package/build/registry/toolsets/scs.d.ts.map +1 -1
- package/build/registry/toolsets/scs.js +4 -14
- package/build/registry/toolsets/scs.js.map +1 -1
- package/build/search/embedding-content.d.ts +5 -0
- package/build/search/embedding-content.d.ts.map +1 -0
- package/build/search/embedding-content.js +31 -0
- package/build/search/embedding-content.js.map +1 -0
- package/build/search/index.d.ts +8 -0
- package/build/search/index.d.ts.map +1 -0
- package/build/search/index.js +6 -0
- package/build/search/index.js.map +1 -0
- package/build/search/local-provider.d.ts +37 -0
- package/build/search/local-provider.d.ts.map +1 -0
- package/build/search/local-provider.js +269 -0
- package/build/search/local-provider.js.map +1 -0
- package/build/search/manager.d.ts +39 -0
- package/build/search/manager.d.ts.map +1 -0
- package/build/search/manager.js +287 -0
- package/build/search/manager.js.map +1 -0
- package/build/search/null-provider.d.ts +9 -0
- package/build/search/null-provider.d.ts.map +1 -0
- package/build/search/null-provider.js +8 -0
- package/build/search/null-provider.js.map +1 -0
- package/build/search/remote-provider.d.ts +28 -0
- package/build/search/remote-provider.d.ts.map +1 -0
- package/build/search/remote-provider.js +148 -0
- package/build/search/remote-provider.js.map +1 -0
- package/build/search/routing-eval.d.ts +49 -0
- package/build/search/routing-eval.d.ts.map +1 -0
- package/build/search/routing-eval.js +80 -0
- package/build/search/routing-eval.js.map +1 -0
- package/build/search/types.d.ts +58 -0
- package/build/search/types.d.ts.map +1 -0
- package/build/search/types.js +7 -0
- package/build/search/types.js.map +1 -0
- package/build/tools/harness-execute.d.ts.map +1 -1
- package/build/tools/harness-execute.js +19 -7
- package/build/tools/harness-execute.js.map +1 -1
- package/build/tools/harness-get.d.ts +2 -1
- package/build/tools/harness-get.d.ts.map +1 -1
- package/build/tools/harness-get.js +21 -1
- package/build/tools/harness-get.js.map +1 -1
- package/build/tools/harness-list.d.ts +2 -1
- package/build/tools/harness-list.d.ts.map +1 -1
- package/build/tools/harness-list.js +22 -1
- package/build/tools/harness-list.js.map +1 -1
- package/build/tools/harness-search.d.ts +20 -1
- package/build/tools/harness-search.d.ts.map +1 -1
- package/build/tools/harness-search.js +124 -14
- package/build/tools/harness-search.js.map +1 -1
- package/build/tools/index.d.ts +2 -1
- package/build/tools/index.d.ts.map +1 -1
- package/build/tools/index.js +4 -4
- package/build/tools/index.js.map +1 -1
- package/build/utils/http-health.d.ts +11 -0
- package/build/utils/http-health.d.ts.map +1 -0
- package/build/utils/http-health.js +11 -0
- package/build/utils/http-health.js.map +1 -0
- package/build/utils/http-sessions.d.ts +8 -0
- package/build/utils/http-sessions.d.ts.map +1 -0
- package/build/utils/http-sessions.js +12 -0
- package/build/utils/http-sessions.js.map +1 -0
- package/package.json +5 -1
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { Config } from "../config.js";
|
|
2
|
+
import type { Registry } from "../registry/index.js";
|
|
3
|
+
import type { HarnessClient } from "../client/harness-client.js";
|
|
4
|
+
import type { SearchCorpus, SearchProvider, SearchReadiness, IndexableItem } from "./types.js";
|
|
5
|
+
import "../data/examples/load-all.js";
|
|
6
|
+
export declare class SearchManager {
|
|
7
|
+
private provider;
|
|
8
|
+
private readonly mcpMode;
|
|
9
|
+
private readonly configuredProvider;
|
|
10
|
+
private readiness;
|
|
11
|
+
private loggedResourcesCorpusDisabled;
|
|
12
|
+
constructor(config: Config);
|
|
13
|
+
/**
|
|
14
|
+
* Whether live customer data may be indexed into the given corpus.
|
|
15
|
+
* In multi-user mode the local in-process store must not hold per-account entity data
|
|
16
|
+
* (no isolation between accounts). The remote provider handles this correctly via tenant_id.
|
|
17
|
+
*/
|
|
18
|
+
canIndexCorpus(corpus: SearchCorpus): boolean;
|
|
19
|
+
/**
|
|
20
|
+
* Index a single item, enforcing corpus/mode policy before delegating to the provider.
|
|
21
|
+
*/
|
|
22
|
+
indexItem(item: IndexableItem): Promise<void>;
|
|
23
|
+
getProvider(): SearchProvider;
|
|
24
|
+
getReadiness(): SearchReadiness;
|
|
25
|
+
initialize(): Promise<void>;
|
|
26
|
+
/**
|
|
27
|
+
* Index all static, account-agnostic content into mcp_resources corpus.
|
|
28
|
+
* Safe to call in any mode — no account context needed.
|
|
29
|
+
* Items are permanent (ttlMs=0) since they're bundled with the server.
|
|
30
|
+
*/
|
|
31
|
+
indexStaticContent(registry: Registry): Promise<void>;
|
|
32
|
+
/**
|
|
33
|
+
* Pre-index tier-1 Harness resources for a specific account.
|
|
34
|
+
* Only call in stdio (single-user) mode where client.account is known.
|
|
35
|
+
*/
|
|
36
|
+
initializeIndex(registry: Registry, client: HarnessClient): Promise<void>;
|
|
37
|
+
private loadProvider;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/search/manager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AACjE,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAsB,eAAe,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAKnH,OAAO,8BAA8B,CAAC;AAUtC,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAiB;IACjC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA6B;IACrD,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAqB;IACxD,OAAO,CAAC,SAAS,CAAkB;IACnC,OAAO,CAAC,6BAA6B,CAAS;gBAElC,MAAM,EAAE,MAAM;IAS1B;;;;OAIG;IACH,cAAc,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO;IAO7C;;OAEG;IACG,SAAS,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAYnD,WAAW,IAAI,cAAc;IAI7B,YAAY,IAAI,eAAe;IAIzB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAkCjC;;;;OAIG;IACG,kBAAkB,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IA8G3D;;;OAGG;IACG,eAAe,CAAC,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAsC/E,OAAO,CAAC,YAAY;CAoBrB"}
|
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
import { NullSearchProvider } from "./null-provider.js";
|
|
2
|
+
import { LocalSearchProvider } from "./local-provider.js";
|
|
3
|
+
import { RemoteSearchProvider } from "./remote-provider.js";
|
|
4
|
+
import { createLogger } from "../utils/logger.js";
|
|
5
|
+
import "../data/examples/load-all.js";
|
|
6
|
+
import { getAllExamples } from "../data/examples/index.js";
|
|
7
|
+
import { SCHEMAS } from "../data/schemas/index.js";
|
|
8
|
+
import { ENTITY_BUNDLED_SCHEMAS } from "../data/schemas/entities/index.js";
|
|
9
|
+
import { buildResourceIndexContent } from "./embedding-content.js";
|
|
10
|
+
const log = createLogger("search-manager");
|
|
11
|
+
const TIER1_TYPES = ["pipeline", "service", "environment", "connector"];
|
|
12
|
+
export class SearchManager {
|
|
13
|
+
provider;
|
|
14
|
+
mcpMode;
|
|
15
|
+
configuredProvider;
|
|
16
|
+
readiness;
|
|
17
|
+
loggedResourcesCorpusDisabled = false;
|
|
18
|
+
constructor(config) {
|
|
19
|
+
this.mcpMode = config.HARNESS_MCP_MODE;
|
|
20
|
+
this.configuredProvider = resolveConfiguredProvider(config);
|
|
21
|
+
this.provider = this.loadProvider(config);
|
|
22
|
+
this.readiness = this.configuredProvider === "none"
|
|
23
|
+
? { state: "disabled", configured: "none" }
|
|
24
|
+
: { state: "initializing", configured: this.configuredProvider };
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Whether live customer data may be indexed into the given corpus.
|
|
28
|
+
* In multi-user mode the local in-process store must not hold per-account entity data
|
|
29
|
+
* (no isolation between accounts). The remote provider handles this correctly via tenant_id.
|
|
30
|
+
*/
|
|
31
|
+
canIndexCorpus(corpus) {
|
|
32
|
+
if (corpus === "entities" && this.mcpMode === "multi-user" && this.configuredProvider === "local") {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Index a single item, enforcing corpus/mode policy before delegating to the provider.
|
|
39
|
+
*/
|
|
40
|
+
async indexItem(item) {
|
|
41
|
+
if (!this.provider.isAvailable())
|
|
42
|
+
return;
|
|
43
|
+
if (!this.canIndexCorpus(item.corpus)) {
|
|
44
|
+
if (!this.loggedResourcesCorpusDisabled) {
|
|
45
|
+
this.loggedResourcesCorpusDisabled = true;
|
|
46
|
+
log.warn("resources corpus disabled in multi-user mode — requires HarnessSearchProvider");
|
|
47
|
+
}
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
await this.provider.index(item);
|
|
51
|
+
}
|
|
52
|
+
getProvider() {
|
|
53
|
+
return this.provider;
|
|
54
|
+
}
|
|
55
|
+
getReadiness() {
|
|
56
|
+
return this.readiness;
|
|
57
|
+
}
|
|
58
|
+
async initialize() {
|
|
59
|
+
if (this.configuredProvider === "none") {
|
|
60
|
+
this.readiness = { state: "disabled", configured: "none" };
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
this.readiness = { state: "initializing", configured: this.configuredProvider };
|
|
64
|
+
try {
|
|
65
|
+
await this.provider.initialize();
|
|
66
|
+
if (this.provider.isAvailable()) {
|
|
67
|
+
this.readiness = {
|
|
68
|
+
state: "ready",
|
|
69
|
+
configured: this.configuredProvider,
|
|
70
|
+
provider: this.provider.constructor.name,
|
|
71
|
+
};
|
|
72
|
+
log.info(`Search provider initialized: ${this.provider.constructor.name}, available=true`);
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
const error = getProviderInitError(this.provider) ?? "provider unavailable after initialization";
|
|
76
|
+
this.readiness = { state: "failed", configured: this.configuredProvider, error };
|
|
77
|
+
log.error("Semantic search unavailable — configured provider failed to initialize", {
|
|
78
|
+
configured: this.configuredProvider,
|
|
79
|
+
provider: this.provider.constructor.name,
|
|
80
|
+
error,
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
catch (err) {
|
|
84
|
+
const error = String(err);
|
|
85
|
+
log.error("Search provider initialization failed — falling back to null provider", { error });
|
|
86
|
+
this.provider = new NullSearchProvider();
|
|
87
|
+
this.readiness = { state: "failed", configured: this.configuredProvider, error };
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Index all static, account-agnostic content into mcp_resources corpus.
|
|
92
|
+
* Safe to call in any mode — no account context needed.
|
|
93
|
+
* Items are permanent (ttlMs=0) since they're bundled with the server.
|
|
94
|
+
*/
|
|
95
|
+
async indexStaticContent(registry) {
|
|
96
|
+
if (!this.provider.isAvailable())
|
|
97
|
+
return;
|
|
98
|
+
// 1. Resource type definitions from registry
|
|
99
|
+
const resourceTypes = registry.getAllResourceTypes();
|
|
100
|
+
await Promise.all(resourceTypes.map(rt => {
|
|
101
|
+
try {
|
|
102
|
+
const def = registry.getResource(rt);
|
|
103
|
+
const ops = Object.keys(def.operations ?? {}).join(", ");
|
|
104
|
+
return this.provider.index({
|
|
105
|
+
id: `resource-def:${rt}`,
|
|
106
|
+
content: [rt.replace(/_/g, " "), def.displayName, def.description, ops].filter(Boolean).join(" "),
|
|
107
|
+
corpus: "knowledge",
|
|
108
|
+
ttlMs: 0,
|
|
109
|
+
metadata: {
|
|
110
|
+
type: "resource_definition",
|
|
111
|
+
resource_type: rt,
|
|
112
|
+
display_name: def.displayName ?? rt,
|
|
113
|
+
operations: ops,
|
|
114
|
+
scope: def.scope ?? "",
|
|
115
|
+
},
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
catch {
|
|
119
|
+
return Promise.resolve();
|
|
120
|
+
}
|
|
121
|
+
}));
|
|
122
|
+
log.info(`Indexed ${resourceTypes.length} resource definitions`);
|
|
123
|
+
// 2. Examples (YAML templates)
|
|
124
|
+
const examples = getAllExamples();
|
|
125
|
+
await Promise.all(examples.map(ex => this.provider.index({
|
|
126
|
+
id: `example:${ex.name}`,
|
|
127
|
+
content: [ex.resourceType.replace(/_/g, " "), ex.name.replace(/-/g, " "), ex.description, ex.tags.join(" ")].join(" "),
|
|
128
|
+
corpus: "knowledge",
|
|
129
|
+
ttlMs: 0,
|
|
130
|
+
metadata: {
|
|
131
|
+
type: "example",
|
|
132
|
+
resource_type: ex.resourceType,
|
|
133
|
+
name: ex.name,
|
|
134
|
+
description: ex.description,
|
|
135
|
+
tags: ex.tags.join(","),
|
|
136
|
+
},
|
|
137
|
+
})));
|
|
138
|
+
log.info(`Indexed ${examples.length} examples`);
|
|
139
|
+
// 3. Bundled pipeline/template/trigger schemas
|
|
140
|
+
// Display-only mapping: comma-separated resource types for schemas that span multiple types.
|
|
141
|
+
// NOT used for routing (comma values won't match any single type in extractRoutingTypes).
|
|
142
|
+
const SCHEMA_RESOURCE_TYPES = {
|
|
143
|
+
"pipeline": "pipeline",
|
|
144
|
+
"pipeline_v1": "pipeline_v1",
|
|
145
|
+
"template": "template,pipeline,template_v1",
|
|
146
|
+
"template_v1": "template_v1,template",
|
|
147
|
+
"trigger": "trigger,pipeline",
|
|
148
|
+
"inputSet_v1": "input_set",
|
|
149
|
+
"overlayInputSet_v1": "input_set",
|
|
150
|
+
"agent-pipeline": "pipeline,pipeline_v1",
|
|
151
|
+
};
|
|
152
|
+
const schemaEntries = Object.entries(SCHEMAS);
|
|
153
|
+
await Promise.all(schemaEntries.map(([name, schema]) => {
|
|
154
|
+
const resourceType = SCHEMA_RESOURCE_TYPES[name] ?? name;
|
|
155
|
+
return this.provider.index({
|
|
156
|
+
id: `schema:${name}`,
|
|
157
|
+
content: [
|
|
158
|
+
name.replace(/_/g, " ").replace(/-/g, " "),
|
|
159
|
+
"schema",
|
|
160
|
+
"yaml structure",
|
|
161
|
+
schema?.title ?? "",
|
|
162
|
+
schema?.description ?? "",
|
|
163
|
+
].filter(Boolean).join(" "),
|
|
164
|
+
corpus: "knowledge",
|
|
165
|
+
ttlMs: 0,
|
|
166
|
+
metadata: {
|
|
167
|
+
type: "schema",
|
|
168
|
+
resource_type: resourceType,
|
|
169
|
+
schema_name: name,
|
|
170
|
+
uri: `schema:///${name}`,
|
|
171
|
+
action: `call harness_schema with resource_type="${name.replace("_v1", "").replace("-", "_")}"`,
|
|
172
|
+
},
|
|
173
|
+
});
|
|
174
|
+
}));
|
|
175
|
+
// 4. Entity schemas (connector, environment, service, secret, infrastructure)
|
|
176
|
+
const entityEntries = Object.entries(ENTITY_BUNDLED_SCHEMAS);
|
|
177
|
+
await Promise.all(entityEntries.map(([name, schema]) => this.provider.index({
|
|
178
|
+
id: `entity-schema:${name}`,
|
|
179
|
+
content: [
|
|
180
|
+
name.replace(/[._]/g, " "),
|
|
181
|
+
"schema",
|
|
182
|
+
"yaml structure",
|
|
183
|
+
schema?.title ?? "",
|
|
184
|
+
schema?.description ?? "",
|
|
185
|
+
].filter(Boolean).join(" "),
|
|
186
|
+
corpus: "knowledge",
|
|
187
|
+
ttlMs: 0,
|
|
188
|
+
metadata: {
|
|
189
|
+
type: "entity_schema",
|
|
190
|
+
schema_name: name,
|
|
191
|
+
resource_type: name.split(".")[0] ?? name,
|
|
192
|
+
scope: name.split(".")[1] ?? "",
|
|
193
|
+
action: `call harness_schema with resource_type="${name.split(".")[0] ?? name}"`,
|
|
194
|
+
},
|
|
195
|
+
})));
|
|
196
|
+
log.info(`Indexed ${schemaEntries.length} bundled schemas, ${entityEntries.length} entity schemas`);
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Pre-index tier-1 Harness resources for a specific account.
|
|
200
|
+
* Only call in stdio (single-user) mode where client.account is known.
|
|
201
|
+
*/
|
|
202
|
+
async initializeIndex(registry, client) {
|
|
203
|
+
if (!this.provider.isAvailable())
|
|
204
|
+
return;
|
|
205
|
+
if (!this.canIndexCorpus("entities")) {
|
|
206
|
+
if (!this.loggedResourcesCorpusDisabled) {
|
|
207
|
+
this.loggedResourcesCorpusDisabled = true;
|
|
208
|
+
log.warn("resources corpus disabled in multi-user mode — requires HarnessSearchProvider");
|
|
209
|
+
}
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
const accountId = client.account;
|
|
213
|
+
const types = TIER1_TYPES.filter(t => registry.supportsOperation(t, "list"));
|
|
214
|
+
for (const resourceType of types) {
|
|
215
|
+
try {
|
|
216
|
+
const result = await registry.dispatch(client, resourceType, "list", {
|
|
217
|
+
size: 50, limit: 50, page: 0,
|
|
218
|
+
}, { tool: "search-init" });
|
|
219
|
+
const items = result?.items ?? [];
|
|
220
|
+
await Promise.all(items.filter(item => item["identifier"] ?? item["id"]).map(item => this.indexItem({
|
|
221
|
+
id: `${resourceType}:${String(item["identifier"] ?? item["id"] ?? "")}`,
|
|
222
|
+
content: buildResourceIndexContent(resourceType, item),
|
|
223
|
+
corpus: "entities",
|
|
224
|
+
accountId,
|
|
225
|
+
metadata: {
|
|
226
|
+
resource_type: resourceType,
|
|
227
|
+
identifier: String(item["identifier"] ?? item["id"] ?? ""),
|
|
228
|
+
name: String(item["name"] ?? ""),
|
|
229
|
+
},
|
|
230
|
+
})));
|
|
231
|
+
log.info(`Pre-indexed ${items.length} ${resourceType} items`);
|
|
232
|
+
}
|
|
233
|
+
catch (err) {
|
|
234
|
+
log.warn(`Failed to pre-index ${resourceType}`, { error: String(err) });
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
loadProvider(config) {
|
|
239
|
+
if (this.configuredProvider === "local") {
|
|
240
|
+
return new LocalSearchProvider({
|
|
241
|
+
cacheDir: config.HARNESS_HF_CACHE_DIR,
|
|
242
|
+
model: process.env.HARNESS_SEARCH_MODEL,
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
if (this.configuredProvider === "remote") {
|
|
246
|
+
if (!config.HARNESS_SEARCH_SERVICE_URL) {
|
|
247
|
+
log.error("HARNESS_SEARCH_PROVIDER=remote requires HARNESS_SEARCH_SERVICE_URL to be set");
|
|
248
|
+
return new NullSearchProvider();
|
|
249
|
+
}
|
|
250
|
+
return new RemoteSearchProvider({
|
|
251
|
+
baseUrl: config.HARNESS_SEARCH_SERVICE_URL,
|
|
252
|
+
headers: parseSearchServiceHeaders(config.HARNESS_SEARCH_SERVICE_HEADERS),
|
|
253
|
+
timeoutMs: config.HARNESS_API_TIMEOUT_MS,
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
return new NullSearchProvider();
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
function resolveConfiguredProvider(config) {
|
|
260
|
+
return config.HARNESS_SEARCH_PROVIDER ?? "none";
|
|
261
|
+
}
|
|
262
|
+
function parseSearchServiceHeaders(raw) {
|
|
263
|
+
if (!raw)
|
|
264
|
+
return undefined;
|
|
265
|
+
try {
|
|
266
|
+
const parsed = JSON.parse(raw);
|
|
267
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
268
|
+
const dropped = Object.entries(parsed).filter(([, v]) => typeof v !== "string").map(([k]) => k);
|
|
269
|
+
if (dropped.length > 0) {
|
|
270
|
+
log.warn("HARNESS_SEARCH_SERVICE_HEADERS: non-string values ignored", { keys: dropped });
|
|
271
|
+
}
|
|
272
|
+
return Object.fromEntries(Object.entries(parsed).filter(([, v]) => typeof v === "string"));
|
|
273
|
+
}
|
|
274
|
+
log.warn("HARNESS_SEARCH_SERVICE_HEADERS is not a JSON object — ignoring");
|
|
275
|
+
}
|
|
276
|
+
catch {
|
|
277
|
+
log.warn("HARNESS_SEARCH_SERVICE_HEADERS is not valid JSON — ignoring");
|
|
278
|
+
}
|
|
279
|
+
return undefined;
|
|
280
|
+
}
|
|
281
|
+
function getProviderInitError(provider) {
|
|
282
|
+
if ("getInitError" in provider && typeof provider.getInitError === "function") {
|
|
283
|
+
return provider.getInitError();
|
|
284
|
+
}
|
|
285
|
+
return undefined;
|
|
286
|
+
}
|
|
287
|
+
//# sourceMappingURL=manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manager.js","sourceRoot":"","sources":["../../src/search/manager.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,8BAA8B,CAAC;AACtC,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAC;AACnD,OAAO,EAAE,sBAAsB,EAAE,MAAM,mCAAmC,CAAC;AAC3E,OAAO,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAC;AAEnE,MAAM,GAAG,GAAG,YAAY,CAAC,gBAAgB,CAAC,CAAC;AAE3C,MAAM,WAAW,GAAG,CAAC,UAAU,EAAE,SAAS,EAAE,aAAa,EAAE,WAAW,CAAU,CAAC;AAEjF,MAAM,OAAO,aAAa;IAChB,QAAQ,CAAiB;IAChB,OAAO,CAA6B;IACpC,kBAAkB,CAAqB;IAChD,SAAS,CAAkB;IAC3B,6BAA6B,GAAG,KAAK,CAAC;IAE9C,YAAY,MAAc;QACxB,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC,gBAAgB,CAAC;QACvC,IAAI,CAAC,kBAAkB,GAAG,yBAAyB,CAAC,MAAM,CAAC,CAAC;QAC5D,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;QAC1C,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,kBAAkB,KAAK,MAAM;YACjD,CAAC,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,EAAE;YAC3C,CAAC,CAAC,EAAE,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,IAAI,CAAC,kBAAkB,EAAE,CAAC;IACrE,CAAC;IAED;;;;OAIG;IACH,cAAc,CAAC,MAAoB;QACjC,IAAI,MAAM,KAAK,UAAU,IAAI,IAAI,CAAC,OAAO,KAAK,YAAY,IAAI,IAAI,CAAC,kBAAkB,KAAK,OAAO,EAAE,CAAC;YAClG,OAAO,KAAK,CAAC;QACf,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,SAAS,CAAC,IAAmB;QACjC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE;YAAE,OAAO;QACzC,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;YACtC,IAAI,CAAC,IAAI,CAAC,6BAA6B,EAAE,CAAC;gBACxC,IAAI,CAAC,6BAA6B,GAAG,IAAI,CAAC;gBAC1C,GAAG,CAAC,IAAI,CAAC,+EAA+E,CAAC,CAAC;YAC5F,CAAC;YACD,OAAO;QACT,CAAC;QACD,MAAM,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAClC,CAAC;IAED,WAAW;QACT,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;IAED,YAAY;QACV,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;IAED,KAAK,CAAC,UAAU;QACd,IAAI,IAAI,CAAC,kBAAkB,KAAK,MAAM,EAAE,CAAC;YACvC,IAAI,CAAC,SAAS,GAAG,EAAE,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC;YAC3D,OAAO;QACT,CAAC;QAED,IAAI,CAAC,SAAS,GAAG,EAAE,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAChF,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,QAAQ,CAAC,UAAU,EAAE,CAAC;YACjC,IAAI,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE,EAAE,CAAC;gBAChC,IAAI,CAAC,SAAS,GAAG;oBACf,KAAK,EAAE,OAAO;oBACd,UAAU,EAAE,IAAI,CAAC,kBAAkB;oBACnC,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI;iBACzC,CAAC;gBACF,GAAG,CAAC,IAAI,CAAC,gCAAgC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,kBAAkB,CAAC,CAAC;gBAC3F,OAAO;YACT,CAAC;YAED,MAAM,KAAK,GAAG,oBAAoB,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,2CAA2C,CAAC;YACjG,IAAI,CAAC,SAAS,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,IAAI,CAAC,kBAAkB,EAAE,KAAK,EAAE,CAAC;YACjF,GAAG,CAAC,KAAK,CAAC,wEAAwE,EAAE;gBAClF,UAAU,EAAE,IAAI,CAAC,kBAAkB;gBACnC,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI;gBACxC,KAAK;aACN,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;YAC1B,GAAG,CAAC,KAAK,CAAC,uEAAuE,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;YAC9F,IAAI,CAAC,QAAQ,GAAG,IAAI,kBAAkB,EAAE,CAAC;YACzC,IAAI,CAAC,SAAS,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,IAAI,CAAC,kBAAkB,EAAE,KAAK,EAAE,CAAC;QACnF,CAAC;IACH,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,kBAAkB,CAAC,QAAkB;QACzC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE;YAAE,OAAO;QAEzC,6CAA6C;QAC7C,MAAM,aAAa,GAAG,QAAQ,CAAC,mBAAmB,EAAE,CAAC;QACrD,MAAM,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE;YACvC,IAAI,CAAC;gBACH,MAAM,GAAG,GAAG,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;gBACrC,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACzD,OAAO,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;oBACzB,EAAE,EAAE,gBAAgB,EAAE,EAAE;oBACxB,OAAO,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,GAAG,CAAC,WAAW,EAAE,GAAG,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;oBACjG,MAAM,EAAE,WAAW;oBACnB,KAAK,EAAE,CAAC;oBACR,QAAQ,EAAE;wBACR,IAAI,EAAE,qBAAqB;wBAC3B,aAAa,EAAE,EAAE;wBACjB,YAAY,EAAE,GAAG,CAAC,WAAW,IAAI,EAAE;wBACnC,UAAU,EAAE,GAAG;wBACf,KAAK,EAAE,GAAG,CAAC,KAAK,IAAI,EAAE;qBACvB;iBACF,CAAC,CAAC;YACL,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;YAC3B,CAAC;QACH,CAAC,CAAC,CAAC,CAAC;QACJ,GAAG,CAAC,IAAI,CAAC,WAAW,aAAa,CAAC,MAAM,uBAAuB,CAAC,CAAC;QAEjE,+BAA+B;QAC/B,MAAM,QAAQ,GAAG,cAAc,EAAE,CAAC;QAClC,MAAM,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAClC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;YAClB,EAAE,EAAE,WAAW,EAAE,CAAC,IAAI,EAAE;YACxB,OAAO,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;YACtH,MAAM,EAAE,WAAW;YACnB,KAAK,EAAE,CAAC;YACR,QAAQ,EAAE;gBACR,IAAI,EAAE,SAAS;gBACf,aAAa,EAAE,EAAE,CAAC,YAAY;gBAC9B,IAAI,EAAE,EAAE,CAAC,IAAI;gBACb,WAAW,EAAE,EAAE,CAAC,WAAW;gBAC3B,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;aACxB;SACF,CAAC,CACH,CAAC,CAAC;QACH,GAAG,CAAC,IAAI,CAAC,WAAW,QAAQ,CAAC,MAAM,WAAW,CAAC,CAAC;QAEhD,+CAA+C;QAC/C,6FAA6F;QAC7F,0FAA0F;QAC1F,MAAM,qBAAqB,GAA2B;YACpD,UAAU,EAAE,UAAU;YACtB,aAAa,EAAE,aAAa;YAC5B,UAAU,EAAE,+BAA+B;YAC3C,aAAa,EAAE,sBAAsB;YACrC,SAAS,EAAE,kBAAkB;YAC7B,aAAa,EAAE,WAAW;YAC1B,oBAAoB,EAAE,WAAW;YACjC,gBAAgB,EAAE,sBAAsB;SACzC,CAAC;QACF,MAAM,aAAa,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAC9C,MAAM,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,EAAE;YACrD,MAAM,YAAY,GAAG,qBAAqB,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC;YACzD,OAAO,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;gBACzB,EAAE,EAAE,UAAU,IAAI,EAAE;gBACpB,OAAO,EAAE;oBACP,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC;oBAC1C,QAAQ;oBACR,gBAAgB;oBAChB,MAAM,EAAE,KAAK,IAAI,EAAE;oBACnB,MAAM,EAAE,WAAW,IAAI,EAAE;iBAC1B,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;gBAC3B,MAAM,EAAE,WAAW;gBACnB,KAAK,EAAE,CAAC;gBACR,QAAQ,EAAE;oBACR,IAAI,EAAE,QAAQ;oBACd,aAAa,EAAE,YAAY;oBAC3B,WAAW,EAAE,IAAI;oBACjB,GAAG,EAAE,aAAa,IAAI,EAAE;oBACxB,MAAM,EAAE,2CAA2C,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG;iBAChG;aACF,CAAC,CAAC;QACL,CAAC,CAAC,CAAC,CAAC;QAEJ,8EAA8E;QAC9E,MAAM,aAAa,GAAG,MAAM,CAAC,OAAO,CAAC,sBAAsB,CAAC,CAAC;QAC7D,MAAM,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,EAAE,CACrD,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;YAClB,EAAE,EAAE,iBAAiB,IAAI,EAAE;YAC3B,OAAO,EAAE;gBACP,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC;gBAC1B,QAAQ;gBACR,gBAAgB;gBAChB,MAAM,EAAE,KAAK,IAAI,EAAE;gBACnB,MAAM,EAAE,WAAW,IAAI,EAAE;aAC1B,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;YAC3B,MAAM,EAAE,WAAW;YACnB,KAAK,EAAE,CAAC;YACR,QAAQ,EAAE;gBACR,IAAI,EAAE,eAAe;gBACrB,WAAW,EAAE,IAAI;gBACjB,aAAa,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI;gBACzC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE;gBAC/B,MAAM,EAAE,2CAA2C,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,GAAG;aACjF;SACF,CAAC,CACH,CAAC,CAAC;QACH,GAAG,CAAC,IAAI,CAAC,WAAW,aAAa,CAAC,MAAM,qBAAqB,aAAa,CAAC,MAAM,iBAAiB,CAAC,CAAC;IACtG,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,eAAe,CAAC,QAAkB,EAAE,MAAqB;QAC7D,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE;YAAE,OAAO;QACzC,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC,EAAE,CAAC;YACrC,IAAI,CAAC,IAAI,CAAC,6BAA6B,EAAE,CAAC;gBACxC,IAAI,CAAC,6BAA6B,GAAG,IAAI,CAAC;gBAC1C,GAAG,CAAC,IAAI,CAAC,+EAA+E,CAAC,CAAC;YAC5F,CAAC;YACD,OAAO;QACT,CAAC;QACD,MAAM,SAAS,GAAG,MAAM,CAAC,OAAO,CAAC;QACjC,MAAM,KAAK,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;QAE7E,KAAK,MAAM,YAAY,IAAI,KAAK,EAAE,CAAC;YACjC,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,QAAQ,CAAC,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE;oBACnE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;iBAC7B,EAAE,EAAE,IAAI,EAAE,aAAa,EAAE,CAA+C,CAAC;gBAC1E,MAAM,KAAK,GAAG,MAAM,EAAE,KAAK,IAAI,EAAE,CAAC;gBAClC,MAAM,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAClF,IAAI,CAAC,SAAS,CAAC;oBACb,EAAE,EAAE,GAAG,YAAY,IAAI,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,EAAE;oBACvE,OAAO,EAAE,yBAAyB,CAAC,YAAY,EAAE,IAAI,CAAC;oBACtD,MAAM,EAAE,UAAU;oBAClB,SAAS;oBACT,QAAQ,EAAE;wBACR,aAAa,EAAE,YAAY;wBAC3B,UAAU,EAAE,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;wBAC1D,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;qBACjC;iBACF,CAAC,CACH,CAAC,CAAC;gBACH,GAAG,CAAC,IAAI,CAAC,eAAe,KAAK,CAAC,MAAM,IAAI,YAAY,QAAQ,CAAC,CAAC;YAChE,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,GAAG,CAAC,IAAI,CAAC,uBAAuB,YAAY,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAC1E,CAAC;QACH,CAAC;IACH,CAAC;IAEO,YAAY,CAAC,MAAc;QACjC,IAAI,IAAI,CAAC,kBAAkB,KAAK,OAAO,EAAE,CAAC;YACxC,OAAO,IAAI,mBAAmB,CAAC;gBAC7B,QAAQ,EAAE,MAAM,CAAC,oBAAoB;gBACrC,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,oBAAoB;aACxC,CAAC,CAAC;QACL,CAAC;QACD,IAAI,IAAI,CAAC,kBAAkB,KAAK,QAAQ,EAAE,CAAC;YACzC,IAAI,CAAC,MAAM,CAAC,0BAA0B,EAAE,CAAC;gBACvC,GAAG,CAAC,KAAK,CAAC,8EAA8E,CAAC,CAAC;gBAC1F,OAAO,IAAI,kBAAkB,EAAE,CAAC;YAClC,CAAC;YACD,OAAO,IAAI,oBAAoB,CAAC;gBAC9B,OAAO,EAAE,MAAM,CAAC,0BAA0B;gBAC1C,OAAO,EAAE,yBAAyB,CAAC,MAAM,CAAC,8BAA8B,CAAC;gBACzE,SAAS,EAAE,MAAM,CAAC,sBAAsB;aACzC,CAAC,CAAC;QACL,CAAC;QACD,OAAO,IAAI,kBAAkB,EAAE,CAAC;IAClC,CAAC;CACF;AAED,SAAS,yBAAyB,CAAC,MAAc;IAC/C,OAAO,MAAM,CAAC,uBAAuB,IAAI,MAAM,CAAC;AAClD,CAAC;AAED,SAAS,yBAAyB,CAAC,GAAuB;IACxD,IAAI,CAAC,GAAG;QAAE,OAAO,SAAS,CAAC;IAC3B,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC/B,IAAI,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YACnE,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;YAChG,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACvB,GAAG,CAAC,IAAI,CAAC,2DAA2D,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;YAC3F,CAAC;YACD,OAAO,MAAM,CAAC,WAAW,CACvB,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CACtC,CAAC;QAC9B,CAAC;QACD,GAAG,CAAC,IAAI,CAAC,gEAAgE,CAAC,CAAC;IAC7E,CAAC;IAAC,MAAM,CAAC;QACP,GAAG,CAAC,IAAI,CAAC,6DAA6D,CAAC,CAAC;IAC1E,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,oBAAoB,CAAC,QAAwB;IACpD,IAAI,cAAc,IAAI,QAAQ,IAAI,OAAO,QAAQ,CAAC,YAAY,KAAK,UAAU,EAAE,CAAC;QAC9E,OAAO,QAAQ,CAAC,YAAY,EAAE,CAAC;IACjC,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { SearchProvider, SearchResult, SearchOptions, IndexableItem } from "./types.js";
|
|
2
|
+
export declare class NullSearchProvider implements SearchProvider {
|
|
3
|
+
initialize(): Promise<void>;
|
|
4
|
+
isAvailable(): boolean;
|
|
5
|
+
search(_query: string, _options?: SearchOptions): Promise<SearchResult[]>;
|
|
6
|
+
index(_item: IndexableItem): Promise<void>;
|
|
7
|
+
evictExpired(): void;
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=null-provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"null-provider.d.ts","sourceRoot":"","sources":["../../src/search/null-provider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE7F,qBAAa,kBAAmB,YAAW,cAAc;IACjD,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IACjC,WAAW,IAAI,OAAO;IAChB,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IACzE,KAAK,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAChD,YAAY,IAAI,IAAI;CACrB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"null-provider.js","sourceRoot":"","sources":["../../src/search/null-provider.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,kBAAkB;IAC7B,KAAK,CAAC,UAAU,KAAmB,CAAC;IACpC,WAAW,KAAc,OAAO,KAAK,CAAC,CAAC,CAAC;IACxC,KAAK,CAAC,MAAM,CAAC,MAAc,EAAE,QAAwB,IAA6B,OAAO,EAAE,CAAC,CAAC,CAAC;IAC9F,KAAK,CAAC,KAAK,CAAC,KAAoB,IAAkB,CAAC;IACnD,YAAY,KAAU,CAAC;CACxB"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { SearchProvider, SearchResult, SearchOptions, IndexableItem } from "./types.js";
|
|
2
|
+
export interface RemoteSearchProviderOptions {
|
|
3
|
+
baseUrl: string;
|
|
4
|
+
/**
|
|
5
|
+
* Extra headers sent with every request. Supports any auth scheme:
|
|
6
|
+
* { "Authorization": "Bearer <token>" } — standard bearer
|
|
7
|
+
* { "x-api-key": "key" } — API key header
|
|
8
|
+
* { "x-harness-token": "svc", "x-tenant": "..." } — internal service mesh
|
|
9
|
+
*/
|
|
10
|
+
headers?: Record<string, string>;
|
|
11
|
+
timeoutMs?: number;
|
|
12
|
+
}
|
|
13
|
+
export declare class RemoteSearchProvider implements SearchProvider {
|
|
14
|
+
private available;
|
|
15
|
+
private initError;
|
|
16
|
+
private readonly baseUrl;
|
|
17
|
+
private readonly extraHeaders;
|
|
18
|
+
private readonly timeoutMs;
|
|
19
|
+
constructor(options: RemoteSearchProviderOptions);
|
|
20
|
+
initialize(): Promise<void>;
|
|
21
|
+
getInitError(): string | undefined;
|
|
22
|
+
isAvailable(): boolean;
|
|
23
|
+
evictExpired(): void;
|
|
24
|
+
search(query: string, options?: SearchOptions): Promise<SearchResult[]>;
|
|
25
|
+
index(item: IndexableItem): Promise<void>;
|
|
26
|
+
private doFetch;
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=remote-provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remote-provider.d.ts","sourceRoot":"","sources":["../../src/search/remote-provider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,aAAa,EAAE,aAAa,EAAgB,MAAM,YAAY,CAAC;AAoB3G,MAAM,WAAW,2BAA2B;IAC1C,OAAO,EAAE,MAAM,CAAC;IAChB;;;;;OAKG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAuBD,qBAAa,oBAAqB,YAAW,cAAc;IACzD,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,SAAS,CAAqB;IACtC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAyB;IACtD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;gBAEvB,OAAO,EAAE,2BAA2B;IAM1C,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAgBjC,YAAY,IAAI,MAAM,GAAG,SAAS;IAIlC,WAAW,IAAI,OAAO;IAItB,YAAY,IAAI,IAAI;IAId,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAwD3E,KAAK,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAgC/C,OAAO,CAAC,OAAO;CAWhB"}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { createLogger } from "../utils/logger.js";
|
|
2
|
+
const log = createLogger("remote-search-provider");
|
|
3
|
+
const CORPORA = ["entities", "docs", "knowledge"];
|
|
4
|
+
/**
|
|
5
|
+
* Each corpus maps to its own collection in the search service.
|
|
6
|
+
* Static corpora (docs, knowledge) are shared across all tenants — no tenant_id filter needed.
|
|
7
|
+
* Entity corpus is per-account — tenant_id scopes results to the requesting account.
|
|
8
|
+
*/
|
|
9
|
+
const STATIC_CORPORA = new Set(["docs", "knowledge"]);
|
|
10
|
+
/** Collection name in the search service for each corpus. */
|
|
11
|
+
const CORPUS_COLLECTION = {
|
|
12
|
+
knowledge: "mcp_knowledge",
|
|
13
|
+
docs: "mcp_docs",
|
|
14
|
+
entities: "mcp_entities",
|
|
15
|
+
};
|
|
16
|
+
export class RemoteSearchProvider {
|
|
17
|
+
available = false;
|
|
18
|
+
initError;
|
|
19
|
+
baseUrl;
|
|
20
|
+
extraHeaders;
|
|
21
|
+
timeoutMs;
|
|
22
|
+
constructor(options) {
|
|
23
|
+
this.baseUrl = options.baseUrl.replace(/\/$/, "");
|
|
24
|
+
this.extraHeaders = options.headers ?? {};
|
|
25
|
+
this.timeoutMs = options.timeoutMs ?? 10_000;
|
|
26
|
+
}
|
|
27
|
+
async initialize() {
|
|
28
|
+
try {
|
|
29
|
+
const res = await this.doFetch("/v1/health");
|
|
30
|
+
if (res.ok) {
|
|
31
|
+
this.available = true;
|
|
32
|
+
log.info("RemoteSearchProvider initialized", { baseUrl: this.baseUrl });
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
this.initError = `Health check returned HTTP ${res.status}`;
|
|
36
|
+
log.error("RemoteSearchProvider health check failed", { status: res.status });
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
catch (err) {
|
|
40
|
+
this.initError = String(err);
|
|
41
|
+
log.error("RemoteSearchProvider initialization failed", { error: this.initError });
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
getInitError() {
|
|
45
|
+
return this.initError;
|
|
46
|
+
}
|
|
47
|
+
isAvailable() {
|
|
48
|
+
return this.available;
|
|
49
|
+
}
|
|
50
|
+
evictExpired() {
|
|
51
|
+
// The search service owns TTL — nothing to do locally
|
|
52
|
+
}
|
|
53
|
+
async search(query, options = {}) {
|
|
54
|
+
if (!this.available)
|
|
55
|
+
return [];
|
|
56
|
+
try {
|
|
57
|
+
const { corpus = "all", accountId, k = 10 } = options;
|
|
58
|
+
const corpora = corpus === "all" ? CORPORA : [corpus];
|
|
59
|
+
// One request per corpus — each targets its own collection.
|
|
60
|
+
// Use hybrid search (vector + BM25); the service gracefully degrades to
|
|
61
|
+
// vector-only when the collection is not hybrid-capable.
|
|
62
|
+
// Static corpora omit tenant_id (whole collection is shared).
|
|
63
|
+
// Entities corpus passes accountId as tenant_id for per-account scoping.
|
|
64
|
+
const { filters } = options;
|
|
65
|
+
const allResults = await Promise.all(corpora.map(async (c) => {
|
|
66
|
+
const params = new URLSearchParams({
|
|
67
|
+
q: query,
|
|
68
|
+
k: String(k),
|
|
69
|
+
collection_name: CORPUS_COLLECTION[c],
|
|
70
|
+
});
|
|
71
|
+
if (!STATIC_CORPORA.has(c) && accountId) {
|
|
72
|
+
params.set("tenant_id", accountId);
|
|
73
|
+
}
|
|
74
|
+
if (filters) {
|
|
75
|
+
for (const [key, value] of Object.entries(filters)) {
|
|
76
|
+
params.set(key, value);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
const res = await this.doFetch(`/v1/hybrid?${params}`);
|
|
80
|
+
if (!res.ok) {
|
|
81
|
+
log.warn("Remote search request failed", { status: res.status, corpus: c });
|
|
82
|
+
await res.text().catch(() => undefined);
|
|
83
|
+
return [];
|
|
84
|
+
}
|
|
85
|
+
const body = await res.json();
|
|
86
|
+
const results = body?.results ?? [];
|
|
87
|
+
return results.map(r => ({
|
|
88
|
+
id: r.id,
|
|
89
|
+
content: r.content,
|
|
90
|
+
score: r.score,
|
|
91
|
+
corpus: c,
|
|
92
|
+
metadata: r.metadata,
|
|
93
|
+
}));
|
|
94
|
+
}));
|
|
95
|
+
return allResults
|
|
96
|
+
.flat()
|
|
97
|
+
.sort((a, b) => b.score - a.score)
|
|
98
|
+
.slice(0, k);
|
|
99
|
+
}
|
|
100
|
+
catch (err) {
|
|
101
|
+
log.error("RemoteSearchProvider search failed", { error: String(err) });
|
|
102
|
+
return [];
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
async index(item) {
|
|
106
|
+
if (!this.available)
|
|
107
|
+
return;
|
|
108
|
+
try {
|
|
109
|
+
const body = {
|
|
110
|
+
content: item.content,
|
|
111
|
+
metadata: {
|
|
112
|
+
...item.metadata,
|
|
113
|
+
...(item.ttlMs !== undefined ? { ttl_ms: String(item.ttlMs) } : {}),
|
|
114
|
+
},
|
|
115
|
+
collection_name: CORPUS_COLLECTION[item.corpus],
|
|
116
|
+
document_id: item.id,
|
|
117
|
+
// Entities are per-account; static corpora have no tenant scoping.
|
|
118
|
+
...(!STATIC_CORPORA.has(item.corpus) && item.accountId
|
|
119
|
+
? { tenant_id: item.accountId }
|
|
120
|
+
: {}),
|
|
121
|
+
};
|
|
122
|
+
const res = await this.doFetch("/v1/ingest", {
|
|
123
|
+
method: "POST",
|
|
124
|
+
headers: { "Content-Type": "application/json" },
|
|
125
|
+
body: JSON.stringify(body),
|
|
126
|
+
});
|
|
127
|
+
if (!res.ok) {
|
|
128
|
+
log.warn("Remote index request failed", { id: item.id, status: res.status });
|
|
129
|
+
await res.text().catch(() => undefined);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
catch (err) {
|
|
133
|
+
log.error("RemoteSearchProvider index failed", { id: item.id, error: String(err) });
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
doFetch(pathOrUrl, init) {
|
|
137
|
+
const url = pathOrUrl.startsWith("http") ? pathOrUrl : `${this.baseUrl}${pathOrUrl}`;
|
|
138
|
+
const headers = {
|
|
139
|
+
...this.extraHeaders,
|
|
140
|
+
...(init?.headers ?? {}),
|
|
141
|
+
};
|
|
142
|
+
const controller = new AbortController();
|
|
143
|
+
const timer = setTimeout(() => controller.abort(), this.timeoutMs);
|
|
144
|
+
return fetch(url, { ...init, headers, signal: controller.signal })
|
|
145
|
+
.finally(() => clearTimeout(timer));
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
//# sourceMappingURL=remote-provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remote-provider.js","sourceRoot":"","sources":["../../src/search/remote-provider.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
export type SearchRoutingMode = "specific" | "cross_domain" | "ambiguous";
|
|
2
|
+
export interface SearchRoutingGoldenCase {
|
|
3
|
+
id: string;
|
|
4
|
+
query: string;
|
|
5
|
+
mode: SearchRoutingMode;
|
|
6
|
+
expectedTypes: string[];
|
|
7
|
+
acceptableTypes?: string[];
|
|
8
|
+
description?: string;
|
|
9
|
+
}
|
|
10
|
+
export interface SearchRoutingObservation {
|
|
11
|
+
id: string;
|
|
12
|
+
query: string;
|
|
13
|
+
mode: SearchRoutingMode;
|
|
14
|
+
expectedTypes: string[];
|
|
15
|
+
acceptableTypes: string[];
|
|
16
|
+
routedTypes: string[];
|
|
17
|
+
semanticRouted: boolean;
|
|
18
|
+
searchedTypes: number;
|
|
19
|
+
candidateTypes: number;
|
|
20
|
+
topScore: number;
|
|
21
|
+
latencyMs: number;
|
|
22
|
+
}
|
|
23
|
+
export interface SearchRoutingCaseResult extends SearchRoutingObservation {
|
|
24
|
+
matchedExpectedTypes: string[];
|
|
25
|
+
missingExpectedTypes: string[];
|
|
26
|
+
extraRoutedTypes: string[];
|
|
27
|
+
expectedRecall: number;
|
|
28
|
+
passed: boolean;
|
|
29
|
+
}
|
|
30
|
+
export interface SearchRoutingSummary {
|
|
31
|
+
totalCases: number;
|
|
32
|
+
passedCases: number;
|
|
33
|
+
failedCases: number;
|
|
34
|
+
expectedTypeRecall: number;
|
|
35
|
+
falseNegativeCount: number;
|
|
36
|
+
averageRoutedTypes: number;
|
|
37
|
+
averageSearchedTypes: number;
|
|
38
|
+
averageLatencyMs: number;
|
|
39
|
+
averageTopScore: number;
|
|
40
|
+
}
|
|
41
|
+
export interface SearchRoutingEvaluation {
|
|
42
|
+
cases: SearchRoutingCaseResult[];
|
|
43
|
+
summary: SearchRoutingSummary;
|
|
44
|
+
}
|
|
45
|
+
export declare function validateGoldenCases(cases: readonly SearchRoutingGoldenCase[], knownResourceTypes: readonly string[]): string[];
|
|
46
|
+
export declare function evaluateRoutingCase(observation: SearchRoutingObservation): SearchRoutingCaseResult;
|
|
47
|
+
export declare function summarizeRoutingEvaluation(cases: readonly SearchRoutingCaseResult[]): SearchRoutingSummary;
|
|
48
|
+
export declare function evaluateRouting(observations: readonly SearchRoutingObservation[]): SearchRoutingEvaluation;
|
|
49
|
+
//# sourceMappingURL=routing-eval.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"routing-eval.d.ts","sourceRoot":"","sources":["../../src/search/routing-eval.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,iBAAiB,GAAG,UAAU,GAAG,cAAc,GAAG,WAAW,CAAC;AAE1E,MAAM,WAAW,uBAAuB;IACtC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,iBAAiB,CAAC;IACxB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,wBAAwB;IACvC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,iBAAiB,CAAC;IACxB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,cAAc,EAAE,OAAO,CAAC;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,uBAAwB,SAAQ,wBAAwB;IACvE,oBAAoB,EAAE,MAAM,EAAE,CAAC;IAC/B,oBAAoB,EAAE,MAAM,EAAE,CAAC;IAC/B,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,oBAAoB;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,gBAAgB,EAAE,MAAM,CAAC;IACzB,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,uBAAuB;IACtC,KAAK,EAAE,uBAAuB,EAAE,CAAC;IACjC,OAAO,EAAE,oBAAoB,CAAC;CAC/B;AAMD,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,SAAS,uBAAuB,EAAE,EACzC,kBAAkB,EAAE,SAAS,MAAM,EAAE,GACpC,MAAM,EAAE,CAsBV;AAED,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,wBAAwB,GAAG,uBAAuB,CA4BlG;AAED,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,SAAS,uBAAuB,EAAE,GACxC,oBAAoB,CAkBtB;AAED,wBAAgB,eAAe,CAC7B,YAAY,EAAE,SAAS,wBAAwB,EAAE,GAChD,uBAAuB,CAMzB"}
|