@appinternalleads/ui 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/agent/base.js +25 -0
- package/dist/cjs/agent/base.js.map +1 -0
- package/dist/cjs/agent/catalog.js +0 -32
- package/dist/cjs/agent/catalog.js.map +1 -1
- package/dist/cjs/agent/core.js +22 -20
- package/dist/cjs/agent/core.js.map +1 -1
- package/dist/cjs/agent/index.js +6 -5
- package/dist/cjs/agent/index.js.map +1 -1
- package/dist/cjs/agent/search/document.js +50 -0
- package/dist/cjs/agent/search/document.js.map +1 -0
- package/dist/cjs/agent/search/embedding.js +107 -0
- package/dist/cjs/agent/search/embedding.js.map +1 -0
- package/dist/cjs/agent/search/index.js +25 -0
- package/dist/cjs/agent/search/index.js.map +1 -0
- package/dist/cjs/agent/search/lexical.js +28 -0
- package/dist/cjs/agent/search/lexical.js.map +1 -0
- package/dist/cjs/agent/search/normalize.js +15 -0
- package/dist/cjs/agent/search/normalize.js.map +1 -0
- package/dist/cjs/agent/search/search.js +123 -0
- package/dist/cjs/agent/search/search.js.map +1 -0
- package/dist/cjs/agent/search/searchIndex.js +120 -0
- package/dist/cjs/agent/search/searchIndex.js.map +1 -0
- package/dist/cjs/agent/search/types.js +8 -0
- package/dist/cjs/agent/search/types.js.map +1 -0
- package/dist/cjs/agent/search/weights.js +34 -0
- package/dist/cjs/agent/search/weights.js.map +1 -0
- package/dist/cjs/agent/search/wordvectors.json +1 -0
- package/dist/cjs/index.js +1 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/esm/agent/base.d.ts +11 -0
- package/dist/esm/agent/base.d.ts.map +1 -0
- package/dist/esm/agent/base.js +11 -0
- package/dist/esm/agent/base.js.map +1 -0
- package/dist/esm/agent/catalog.d.ts +0 -8
- package/dist/esm/agent/catalog.d.ts.map +1 -1
- package/dist/esm/agent/catalog.js +0 -31
- package/dist/esm/agent/catalog.js.map +1 -1
- package/dist/esm/agent/core.d.ts +6 -7
- package/dist/esm/agent/core.d.ts.map +1 -1
- package/dist/esm/agent/core.js +6 -7
- package/dist/esm/agent/core.js.map +1 -1
- package/dist/esm/agent/index.d.ts +6 -5
- package/dist/esm/agent/index.d.ts.map +1 -1
- package/dist/esm/agent/index.js +6 -5
- package/dist/esm/agent/index.js.map +1 -1
- package/dist/esm/agent/search/document.d.ts +6 -0
- package/dist/esm/agent/search/document.d.ts.map +1 -0
- package/dist/esm/agent/search/document.js +46 -0
- package/dist/esm/agent/search/document.js.map +1 -0
- package/dist/esm/agent/search/embedding.d.ts +31 -0
- package/dist/esm/agent/search/embedding.d.ts.map +1 -0
- package/dist/esm/agent/search/embedding.js +103 -0
- package/dist/esm/agent/search/embedding.js.map +1 -0
- package/dist/esm/agent/search/index.d.ts +10 -0
- package/dist/esm/agent/search/index.d.ts.map +1 -0
- package/dist/esm/agent/search/index.js +17 -0
- package/dist/esm/agent/search/index.js.map +1 -0
- package/dist/esm/agent/search/lexical.d.ts +3 -0
- package/dist/esm/agent/search/lexical.d.ts.map +1 -0
- package/dist/esm/agent/search/lexical.js +25 -0
- package/dist/esm/agent/search/lexical.js.map +1 -0
- package/dist/esm/agent/search/normalize.d.ts +13 -0
- package/dist/esm/agent/search/normalize.d.ts.map +1 -0
- package/dist/esm/agent/search/normalize.js +12 -0
- package/dist/esm/agent/search/normalize.js.map +1 -0
- package/dist/esm/agent/search/search.d.ts +42 -0
- package/dist/esm/agent/search/search.d.ts.map +1 -0
- package/dist/esm/agent/search/search.js +119 -0
- package/dist/esm/agent/search/search.js.map +1 -0
- package/dist/esm/agent/search/searchIndex.d.ts +42 -0
- package/dist/esm/agent/search/searchIndex.d.ts.map +1 -0
- package/dist/esm/agent/search/searchIndex.js +114 -0
- package/dist/esm/agent/search/searchIndex.js.map +1 -0
- package/dist/esm/agent/search/types.d.ts +67 -0
- package/dist/esm/agent/search/types.d.ts.map +1 -0
- package/dist/esm/agent/search/types.js +7 -0
- package/dist/esm/agent/search/types.js.map +1 -0
- package/dist/esm/agent/search/weights.d.ts +22 -0
- package/dist/esm/agent/search/weights.d.ts.map +1 -0
- package/dist/esm/agent/search/weights.js +31 -0
- package/dist/esm/agent/search/weights.js.map +1 -0
- package/dist/esm/agent/search/wordvectors.json +1 -0
- package/dist/esm/index.js +1 -1
- package/dist/esm/index.js.map +1 -1
- package/package.json +2 -1
- package/src/agent/base.ts +17 -0
- package/src/agent/catalog.ts +0 -32
- package/src/agent/core.ts +6 -14
- package/src/agent/index.ts +6 -5
- package/src/agent/search/document.ts +46 -0
- package/src/agent/search/embedding.ts +95 -0
- package/src/agent/search/index.ts +20 -0
- package/src/agent/search/lexical.ts +25 -0
- package/src/agent/search/normalize.ts +17 -0
- package/src/agent/search/search.ts +148 -0
- package/src/agent/search/searchIndex.ts +107 -0
- package/src/agent/search/types.ts +68 -0
- package/src/agent/search/weights.ts +32 -0
- package/src/index.ts +1 -1
- package/tools/ask/dist/components.mjs +348 -12
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { AgentCapability, CapabilityCard } from '../types';
|
|
2
|
+
import { SearchIndex } from './searchIndex';
|
|
3
|
+
import type { EmbeddingProvider, ScoreBreakdown, SearchDocument, SearchOptions, SearchWeights } from './types';
|
|
4
|
+
/**
|
|
5
|
+
* **Component search: intent → candidates.**
|
|
6
|
+
*
|
|
7
|
+
* normalizeQuery → retrieveCandidates (semantic + lexical) → applyEligibility → rankCandidates → cards
|
|
8
|
+
*
|
|
9
|
+
* Semantic similarity comes from an `EmbeddingProvider` over each component's search document
|
|
10
|
+
* (`document.ts`, derived from its capability); lexical similarity is 0.3.0's scorer. If semantic
|
|
11
|
+
* retrieval is unavailable — no provider, an index that fails to build, a query with no known
|
|
12
|
+
* words — the ranking is exactly the lexical one. Eligibility (approved, and allowed by the host)
|
|
13
|
+
* is applied after retrieval and is authoritative: relevance never makes a component usable.
|
|
14
|
+
* Ties break on catalogue order, so the same query and catalogue give the same list.
|
|
15
|
+
*/
|
|
16
|
+
export type SearchCard = CapabilityCard & {
|
|
17
|
+
score: number;
|
|
18
|
+
};
|
|
19
|
+
export type ComponentSearch = {
|
|
20
|
+
search(query: string, limit?: number, options?: SearchOptions): SearchCard[];
|
|
21
|
+
/** Development: every component's scores, best first — never part of the agent's result. */
|
|
22
|
+
explain(query: string, options?: SearchOptions): ScoreBreakdown[] & {
|
|
23
|
+
mode: 'hybrid' | 'lexical';
|
|
24
|
+
version: string;
|
|
25
|
+
};
|
|
26
|
+
/** The index in use (null when searching lexically). */
|
|
27
|
+
index(): SearchIndex | null;
|
|
28
|
+
};
|
|
29
|
+
export declare function searchCatalog(): {
|
|
30
|
+
caps: AgentCapability[];
|
|
31
|
+
docs: SearchDocument[];
|
|
32
|
+
};
|
|
33
|
+
export declare function createComponentSearch(opts: {
|
|
34
|
+
provider?: EmbeddingProvider | null;
|
|
35
|
+
weights: SearchWeights;
|
|
36
|
+
/** Where the documents come from — the approved catalogue by default. */
|
|
37
|
+
catalog?: () => {
|
|
38
|
+
caps: AgentCapability[];
|
|
39
|
+
docs: SearchDocument[];
|
|
40
|
+
};
|
|
41
|
+
}): ComponentSearch;
|
|
42
|
+
//# sourceMappingURL=search.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../../../src/agent/search/search.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAEhE,OAAO,EAAE,WAAW,EAA6D,MAAM,eAAe,CAAC;AAGvG,OAAO,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAE,cAAc,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAE/G;;;;;;;;;;;GAWG;AAEH,MAAM,MAAM,UAAU,GAAG,cAAc,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAE5D,MAAM,MAAM,eAAe,GAAG;IAC5B,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,UAAU,EAAE,CAAC;IAC7E,4FAA4F;IAC5F,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,cAAc,EAAE,GAAG;QAAE,IAAI,EAAE,QAAQ,GAAG,SAAS,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IACpH,wDAAwD;IACxD,KAAK,IAAI,WAAW,GAAG,IAAI,CAAC;CAC7B,CAAC;AAOF,wBAAgB,aAAa,IAAI;IAAE,IAAI,EAAE,eAAe,EAAE,CAAC;IAAC,IAAI,EAAE,cAAc,EAAE,CAAA;CAAE,CAMnF;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE;IAC1C,QAAQ,CAAC,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACpC,OAAO,EAAE,aAAa,CAAC;IACvB,yEAAyE;IACzE,OAAO,CAAC,EAAE,MAAM;QAAE,IAAI,EAAE,eAAe,EAAE,CAAC;QAAC,IAAI,EAAE,cAAc,EAAE,CAAA;KAAE,CAAC;CACrE,GAAG,eAAe,CAkGlB"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { AGENT_COMPONENTS, describeComponent, isAgentComponent } from '../catalog';
|
|
2
|
+
import { searchDocumentOf } from './document';
|
|
3
|
+
import { SearchIndex, cosine, indexVersion } from './searchIndex';
|
|
4
|
+
import { lexicalScore } from './lexical';
|
|
5
|
+
import { normalizeQuery } from './normalize';
|
|
6
|
+
const round = (x) => Math.round(x * 1000) / 1000;
|
|
7
|
+
const cardOf = (c) => ({ component: c.component, name: c.name, kind: c.kind, purpose: c.purpose, signals: c.signals });
|
|
8
|
+
/** The approved catalogue, in order, and its search documents — derived once per module. */
|
|
9
|
+
let catalogCache = null;
|
|
10
|
+
export function searchCatalog() {
|
|
11
|
+
if (!catalogCache) {
|
|
12
|
+
const caps = AGENT_COMPONENTS.map(id => describeComponent(id));
|
|
13
|
+
catalogCache = { caps, docs: caps.map((c, i) => searchDocumentOf(c, i, AGENT_COMPONENTS)) };
|
|
14
|
+
}
|
|
15
|
+
return catalogCache;
|
|
16
|
+
}
|
|
17
|
+
export function createComponentSearch(opts) {
|
|
18
|
+
const catalog = opts.catalog ?? searchCatalog;
|
|
19
|
+
const w = opts.weights;
|
|
20
|
+
let built = null;
|
|
21
|
+
let failed = null;
|
|
22
|
+
/* The index for the catalogue as it is now — rebuilt whenever its version (documents + provider) changes. */
|
|
23
|
+
const indexFor = (docs) => {
|
|
24
|
+
const provider = opts.provider;
|
|
25
|
+
if (!provider)
|
|
26
|
+
return null;
|
|
27
|
+
const version = indexVersion(docs, provider);
|
|
28
|
+
if (built?.version === version)
|
|
29
|
+
return built;
|
|
30
|
+
if (failed === version)
|
|
31
|
+
return null;
|
|
32
|
+
try {
|
|
33
|
+
built = new SearchIndex(provider, version).build(docs);
|
|
34
|
+
return built;
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
failed = version;
|
|
38
|
+
built = null;
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
const queryVector = (q, index) => {
|
|
43
|
+
try {
|
|
44
|
+
const v = index.provider.embed([q.text])[0];
|
|
45
|
+
if (!v || v.length !== index.mean?.length || !v.some(x => x !== 0) || v.some(x => !Number.isFinite(x)))
|
|
46
|
+
return null;
|
|
47
|
+
return v;
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
function retrieveCandidates(q) {
|
|
54
|
+
const { caps, docs } = catalog();
|
|
55
|
+
const index = q.empty ? null : indexFor(docs);
|
|
56
|
+
const qv = index ? queryVector(q, index) : null;
|
|
57
|
+
const centring = { mean: w.centre !== 'none' ? index?.mean ?? null : null, principal: w.centre === 'pc' ? index?.principal ?? null : null };
|
|
58
|
+
return {
|
|
59
|
+
mode: (qv ? 'hybrid' : 'lexical'),
|
|
60
|
+
version: index?.version ?? '',
|
|
61
|
+
candidates: caps.map((c, order) => {
|
|
62
|
+
const lexical = q.empty ? 0 : lexicalScore(c, q.original);
|
|
63
|
+
if (!qv || !index)
|
|
64
|
+
return { cap: c, order, lexical, semantic: null, negative: null };
|
|
65
|
+
const e = index.entries.get(c.component);
|
|
66
|
+
if (!e)
|
|
67
|
+
return { cap: c, order, lexical, semantic: null, negative: null };
|
|
68
|
+
const { pos, posMax } = fieldScore(qv, e, centring);
|
|
69
|
+
const neg = e.negative.length ? Math.max(...e.negative.map(n => cosine(qv, n, centring))) : 0;
|
|
70
|
+
return { cap: c, order, lexical, semantic: pos - w.negative * Math.max(0, neg - posMax), negative: neg };
|
|
71
|
+
}),
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
/* How close a query vector is to a component: the mean of its `topK` closest fields (weighted by kind), and the closest one. */
|
|
75
|
+
function fieldScore(qv, e, centring) {
|
|
76
|
+
const sims = e.positive.filter(p => w.fields[p.type] > 0).map(p => { const raw = cosine(qv, p.vector, centring); return { raw, weighted: w.fields[p.type] * raw }; });
|
|
77
|
+
const top = sims.map(x => x.weighted).sort((a, b) => b - a).slice(0, w.topK);
|
|
78
|
+
return { pos: top.length ? top.reduce((a, b) => a + b, 0) / top.length : 0, posMax: sims.length ? Math.max(...sims.map(x => x.raw)) : 0 };
|
|
79
|
+
}
|
|
80
|
+
const applyEligibility = (list, options = {}) => list.map(x => ({
|
|
81
|
+
...x,
|
|
82
|
+
availability: isAgentComponent(x.cap.component) && (!options.available || options.available.includes(x.cap.component)) ? 1 : 0,
|
|
83
|
+
metadata: !options.kinds || options.kinds.includes(x.cap.kind) ? 1 : 0,
|
|
84
|
+
}));
|
|
85
|
+
function rankCandidates(query, options) {
|
|
86
|
+
const q = normalizeQuery(query);
|
|
87
|
+
const r = retrieveCandidates(q);
|
|
88
|
+
const scored = applyEligibility(r.candidates, options).map(x => ({
|
|
89
|
+
...x,
|
|
90
|
+
final: r.mode === 'lexical' || x.semantic === null
|
|
91
|
+
? x.lexical
|
|
92
|
+
: w.semantic * x.semantic + w.lexical * (x.lexical / (x.lexical + w.lexicalHalf)),
|
|
93
|
+
}));
|
|
94
|
+
scored.sort((a, b) => b.final - a.final || a.order - b.order);
|
|
95
|
+
return { ...r, scored };
|
|
96
|
+
}
|
|
97
|
+
return {
|
|
98
|
+
search(query, limit = 5, options) {
|
|
99
|
+
const r = rankCandidates(query, options);
|
|
100
|
+
const eligible = r.scored.filter(x => x.availability && x.metadata);
|
|
101
|
+
const kept = r.mode === 'lexical'
|
|
102
|
+
? eligible.filter(x => x.final > 0)
|
|
103
|
+
: (() => { const best = eligible[0]?.final ?? 0; return eligible.filter(x => x.final >= w.minScore && (best <= 0 || x.final >= best * w.relative)); })();
|
|
104
|
+
return kept.slice(0, Math.max(0, limit)).map(x => ({ ...cardOf(x.cap), score: round(x.final) }));
|
|
105
|
+
},
|
|
106
|
+
explain(query, options) {
|
|
107
|
+
const r = rankCandidates(query, options);
|
|
108
|
+
const out = r.scored.map(x => ({
|
|
109
|
+
component: x.cap.component, semantic: x.semantic === null ? null : round(x.semantic), negative: x.negative === null ? null : round(x.negative),
|
|
110
|
+
lexical: round(x.lexical), metadata: x.metadata, availability: x.availability, final: round(x.final),
|
|
111
|
+
}));
|
|
112
|
+
out.mode = r.mode;
|
|
113
|
+
out.version = r.version;
|
|
114
|
+
return out;
|
|
115
|
+
},
|
|
116
|
+
index: () => indexFor(catalog().docs),
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=search.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search.js","sourceRoot":"","sources":["../../../../src/agent/search/search.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { EmbeddingProvider, FieldType, SearchDocument } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* **The search index — derived, rebuildable, never the source of truth.** Each component's document
|
|
4
|
+
* fields as vectors, plus the catalogue mean (for centring). Its `version` is the documents' hash
|
|
5
|
+
* plus the provider's id: if the catalogue or the model changes, the version does, and a cached
|
|
6
|
+
* index for the old one is never served (`indexFor`).
|
|
7
|
+
*/
|
|
8
|
+
export type IndexedDocument = {
|
|
9
|
+
component: string;
|
|
10
|
+
order: number;
|
|
11
|
+
positive: {
|
|
12
|
+
type: FieldType;
|
|
13
|
+
vector: Float32Array;
|
|
14
|
+
}[];
|
|
15
|
+
negative: Float32Array[];
|
|
16
|
+
};
|
|
17
|
+
export declare class SearchIndex {
|
|
18
|
+
readonly provider: EmbeddingProvider;
|
|
19
|
+
version: string;
|
|
20
|
+
readonly entries: Map<string, IndexedDocument>;
|
|
21
|
+
mean: Float32Array | null;
|
|
22
|
+
/** The first principal component of the (centred) document vectors — the direction every text shares most (SIF's common-component removal). */
|
|
23
|
+
principal: Float32Array | null;
|
|
24
|
+
constructor(provider: EmbeddingProvider, version: string);
|
|
25
|
+
/** Throw away everything and index these documents. */
|
|
26
|
+
build(docs: readonly SearchDocument[]): this;
|
|
27
|
+
/** Add or replace one component. */
|
|
28
|
+
upsert(doc: SearchDocument, allDocs?: readonly SearchDocument[]): this;
|
|
29
|
+
remove(component: string, allDocs?: readonly SearchDocument[]): this;
|
|
30
|
+
private put;
|
|
31
|
+
/** The mean of every positive field vector: what all documents share, subtracted before comparing when centring. */
|
|
32
|
+
private recentre;
|
|
33
|
+
}
|
|
34
|
+
export declare const indexVersion: (docs: readonly SearchDocument[], provider: EmbeddingProvider) => string;
|
|
35
|
+
/** What is compared: the vector less the shared mean and, if given, less its projection on the shared direction. */
|
|
36
|
+
export type Centring = {
|
|
37
|
+
mean: Float32Array | null;
|
|
38
|
+
principal: Float32Array | null;
|
|
39
|
+
};
|
|
40
|
+
/** Cosine similarity after centring. */
|
|
41
|
+
export declare function cosine(a: Float32Array, b: Float32Array, c?: Centring): number;
|
|
42
|
+
//# sourceMappingURL=searchIndex.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"searchIndex.d.ts","sourceRoot":"","sources":["../../../../src/agent/search/searchIndex.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAE5E;;;;;GAKG;AACH,MAAM,MAAM,eAAe,GAAG;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE;QAAE,IAAI,EAAE,SAAS,CAAC;QAAC,MAAM,EAAE,YAAY,CAAA;KAAE,EAAE,CAAC;IACtD,QAAQ,EAAE,YAAY,EAAE,CAAC;CAC1B,CAAC;AAEF,qBAAa,WAAW;IAKV,QAAQ,CAAC,QAAQ,EAAE,iBAAiB;IAAS,OAAO,EAAE,MAAM;IAJxE,QAAQ,CAAC,OAAO,+BAAsC;IACtD,IAAI,EAAE,YAAY,GAAG,IAAI,CAAQ;IACjC,+IAA+I;IAC/I,SAAS,EAAE,YAAY,GAAG,IAAI,CAAQ;gBACjB,QAAQ,EAAE,iBAAiB,EAAS,OAAO,EAAE,MAAM;IAExE,uDAAuD;IACvD,KAAK,CAAC,IAAI,EAAE,SAAS,cAAc,EAAE,GAAG,IAAI;IAQ5C,oCAAoC;IACpC,MAAM,CAAC,GAAG,EAAE,cAAc,EAAE,OAAO,CAAC,EAAE,SAAS,cAAc,EAAE,GAAG,IAAI;IAMtE,MAAM,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS,cAAc,EAAE,GAAG,IAAI;IAMpE,OAAO,CAAC,GAAG;IAWX,oHAAoH;IACpH,OAAO,CAAC,QAAQ;CAYjB;AAED,eAAO,MAAM,YAAY,GAAI,MAAM,SAAS,cAAc,EAAE,EAAE,UAAU,iBAAiB,WAAwC,CAAC;AAmBlI,oHAAoH;AACpH,MAAM,MAAM,QAAQ,GAAG;IAAE,IAAI,EAAE,YAAY,GAAG,IAAI,CAAC;IAAC,SAAS,EAAE,YAAY,GAAG,IAAI,CAAA;CAAE,CAAC;AASrF,wCAAwC;AACxC,wBAAgB,MAAM,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,YAAY,EAAE,CAAC,GAAE,QAA0C,GAAG,MAAM,CAK9G"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { versionOf } from './document';
|
|
2
|
+
export class SearchIndex {
|
|
3
|
+
provider;
|
|
4
|
+
version;
|
|
5
|
+
entries = new Map();
|
|
6
|
+
mean = null;
|
|
7
|
+
/** The first principal component of the (centred) document vectors — the direction every text shares most (SIF's common-component removal). */
|
|
8
|
+
principal = null;
|
|
9
|
+
constructor(provider, version) {
|
|
10
|
+
this.provider = provider;
|
|
11
|
+
this.version = version;
|
|
12
|
+
}
|
|
13
|
+
/** Throw away everything and index these documents. */
|
|
14
|
+
build(docs) {
|
|
15
|
+
this.entries.clear();
|
|
16
|
+
for (const d of docs)
|
|
17
|
+
this.put(d);
|
|
18
|
+
this.version = indexVersion(docs, this.provider);
|
|
19
|
+
return this.recentre();
|
|
20
|
+
}
|
|
21
|
+
/** Add or replace one component. */
|
|
22
|
+
upsert(doc, allDocs) {
|
|
23
|
+
this.put(doc);
|
|
24
|
+
if (allDocs)
|
|
25
|
+
this.version = indexVersion(allDocs, this.provider);
|
|
26
|
+
return this.recentre();
|
|
27
|
+
}
|
|
28
|
+
remove(component, allDocs) {
|
|
29
|
+
this.entries.delete(component);
|
|
30
|
+
if (allDocs)
|
|
31
|
+
this.version = indexVersion(allDocs, this.provider);
|
|
32
|
+
return this.recentre();
|
|
33
|
+
}
|
|
34
|
+
put(d) {
|
|
35
|
+
const vectors = this.provider.embed([...d.positive.map(p => p.text), ...d.negative.map(n => n.text)]);
|
|
36
|
+
if (vectors.length !== d.positive.length + d.negative.length)
|
|
37
|
+
throw new Error(`${this.provider.id} returned ${vectors.length} vectors for ${d.component}`);
|
|
38
|
+
this.entries.set(d.component, {
|
|
39
|
+
component: d.component,
|
|
40
|
+
order: d.order,
|
|
41
|
+
positive: d.positive.map((p, i) => ({ type: p.type, vector: vectors[i] })),
|
|
42
|
+
negative: vectors.slice(d.positive.length),
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
/** The mean of every positive field vector: what all documents share, subtracted before comparing when centring. */
|
|
46
|
+
recentre() {
|
|
47
|
+
let sum = null;
|
|
48
|
+
let n = 0;
|
|
49
|
+
for (const e of this.entries.values())
|
|
50
|
+
for (const p of e.positive) {
|
|
51
|
+
sum ??= new Float32Array(p.vector.length);
|
|
52
|
+
for (let i = 0; i < sum.length; i++)
|
|
53
|
+
sum[i] += p.vector[i];
|
|
54
|
+
n++;
|
|
55
|
+
}
|
|
56
|
+
if (sum && n)
|
|
57
|
+
for (let i = 0; i < sum.length; i++)
|
|
58
|
+
sum[i] /= n;
|
|
59
|
+
this.mean = sum;
|
|
60
|
+
this.principal = sum ? firstComponent([...this.entries.values()].flatMap(e => e.positive.map(p => p.vector)), sum) : null;
|
|
61
|
+
return this;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
export const indexVersion = (docs, provider) => `${versionOf(docs)}:${provider.id}`;
|
|
65
|
+
/** Power iteration — deterministic start, fixed iterations. */
|
|
66
|
+
function firstComponent(vectors, mean) {
|
|
67
|
+
const d = mean.length;
|
|
68
|
+
let u = new Float32Array(d).fill(1 / Math.sqrt(d));
|
|
69
|
+
for (let it = 0; it < 30; it++) {
|
|
70
|
+
const next = new Float32Array(d);
|
|
71
|
+
for (const v of vectors) {
|
|
72
|
+
let dot = 0;
|
|
73
|
+
for (let i = 0; i < d; i++)
|
|
74
|
+
dot += (v[i] - mean[i]) * u[i];
|
|
75
|
+
for (let i = 0; i < d; i++)
|
|
76
|
+
next[i] += dot * (v[i] - mean[i]);
|
|
77
|
+
}
|
|
78
|
+
let n = 0;
|
|
79
|
+
for (const x of next)
|
|
80
|
+
n += x * x;
|
|
81
|
+
n = Math.sqrt(n) || 1;
|
|
82
|
+
for (let i = 0; i < d; i++)
|
|
83
|
+
next[i] /= n;
|
|
84
|
+
u = next;
|
|
85
|
+
}
|
|
86
|
+
return u;
|
|
87
|
+
}
|
|
88
|
+
function centred(v, c) {
|
|
89
|
+
if (!c.mean && !c.principal)
|
|
90
|
+
return v;
|
|
91
|
+
const out = new Float32Array(v.length);
|
|
92
|
+
for (let i = 0; i < v.length; i++)
|
|
93
|
+
out[i] = v[i] - (c.mean ? c.mean[i] : 0);
|
|
94
|
+
if (c.principal) {
|
|
95
|
+
let dot = 0;
|
|
96
|
+
for (let i = 0; i < v.length; i++)
|
|
97
|
+
dot += out[i] * c.principal[i];
|
|
98
|
+
for (let i = 0; i < v.length; i++)
|
|
99
|
+
out[i] -= dot * c.principal[i];
|
|
100
|
+
}
|
|
101
|
+
return out;
|
|
102
|
+
}
|
|
103
|
+
/** Cosine similarity after centring. */
|
|
104
|
+
export function cosine(a, b, c = { mean: null, principal: null }) {
|
|
105
|
+
const x = centred(a, c), y = centred(b, c);
|
|
106
|
+
let dot = 0, na = 0, nb = 0;
|
|
107
|
+
for (let i = 0; i < x.length; i++) {
|
|
108
|
+
dot += x[i] * y[i];
|
|
109
|
+
na += x[i] * x[i];
|
|
110
|
+
nb += y[i] * y[i];
|
|
111
|
+
}
|
|
112
|
+
return na && nb ? dot / Math.sqrt(na * nb) : 0;
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=searchIndex.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"searchIndex.js","sourceRoot":"","sources":["../../../../src/agent/search/searchIndex.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAgBvC,MAAM,OAAO,WAAW;IAKD;IAAoC;IAJhD,OAAO,GAAG,IAAI,GAAG,EAA2B,CAAC;IACtD,IAAI,GAAwB,IAAI,CAAC;IACjC,+IAA+I;IAC/I,SAAS,GAAwB,IAAI,CAAC;IACtC,YAAqB,QAA2B,EAAS,OAAe;QAAnD,aAAQ,GAAR,QAAQ,CAAmB;QAAS,YAAO,GAAP,OAAO,CAAQ;IAAG,CAAC;IAE5E,uDAAuD;IACvD,KAAK,CAAC,IAA+B;QACnC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QACrB,KAAK,MAAM,CAAC,IAAI,IAAI;YAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAClC,IAAI,CAAC,OAAO,GAAG,YAAY,CAAC,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;QACjD,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAC;IACzB,CAAC;IAGD,oCAAoC;IACpC,MAAM,CAAC,GAAmB,EAAE,OAAmC;QAC7D,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACd,IAAI,OAAO;YAAE,IAAI,CAAC,OAAO,GAAG,YAAY,CAAC,OAAO,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;QACjE,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAC;IACzB,CAAC;IAED,MAAM,CAAC,SAAiB,EAAE,OAAmC;QAC3D,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAC/B,IAAI,OAAO;YAAE,IAAI,CAAC,OAAO,GAAG,YAAY,CAAC,OAAO,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;QACjE,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAC;IACzB,CAAC;IAEO,GAAG,CAAC,CAAiB;QAC3B,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACtG,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,QAAQ,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,EAAE,aAAa,OAAO,CAAC,MAAM,gBAAgB,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC;QAC3J,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,EAAE;YAC5B,SAAS,EAAE,CAAC,CAAC,SAAS;YACtB,KAAK,EAAE,CAAC,CAAC,KAAK;YACd,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAE,EAAE,CAAC,CAAC;YAC3E,QAAQ,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC;SAC3C,CAAC,CAAC;IACL,CAAC;IAED,oHAAoH;IAC5G,QAAQ;QACd,IAAI,GAAG,GAAwB,IAAI,CAAC;QAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC/C,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE;YAAE,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC;gBAClE,GAAG,KAAK,IAAI,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;gBAC1C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE;oBAAE,GAAG,CAAC,CAAC,CAAE,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC;gBAC7D,CAAC,EAAE,CAAC;YACN,CAAC;QACD,IAAI,GAAG,IAAI,CAAC;YAAE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE;gBAAE,GAAG,CAAC,CAAC,CAAE,IAAI,CAAC,CAAC;QAChE,IAAI,CAAC,IAAI,GAAG,GAAG,CAAC;QAChB,IAAI,CAAC,SAAS,GAAG,GAAG,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAC1H,OAAO,IAAI,CAAC;IACd,CAAC;CACF;AAED,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,IAA+B,EAAE,QAA2B,EAAE,EAAE,CAAC,GAAG,SAAS,CAAC,IAAI,CAAC,IAAI,QAAQ,CAAC,EAAE,EAAE,CAAC;AAElI,+DAA+D;AAC/D,SAAS,cAAc,CAAC,OAAuB,EAAE,IAAkB;IACjE,MAAM,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC;IACtB,IAAI,CAAC,GAAG,IAAI,YAAY,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IACnD,KAAK,IAAI,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC;QAC/B,MAAM,IAAI,GAAG,IAAI,YAAY,CAAC,CAAC,CAAC,CAAC;QACjC,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;YACxB,IAAI,GAAG,GAAG,CAAC,CAAC;YAAC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE;gBAAE,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAE,GAAG,IAAI,CAAC,CAAC,CAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAE,CAAC;YAC3E,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE;gBAAE,IAAI,CAAC,CAAC,CAAE,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAE,GAAG,IAAI,CAAC,CAAC,CAAE,CAAC,CAAC;QACnE,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,CAAC;QAAC,KAAK,MAAM,CAAC,IAAI,IAAI;YAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAAC,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QACnE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE;YAAE,IAAI,CAAC,CAAC,CAAE,IAAI,CAAC,CAAC;QAC1C,CAAC,GAAG,IAAI,CAAC;IACX,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC;AAID,SAAS,OAAO,CAAC,CAAe,EAAE,CAAW;IAC3C,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,SAAS;QAAE,OAAO,CAAC,CAAC;IACtC,MAAM,GAAG,GAAG,IAAI,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IACvC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE;QAAE,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9E,IAAI,CAAC,CAAC,SAAS,EAAE,CAAC;QAAC,IAAI,GAAG,GAAG,CAAC,CAAC;QAAC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE;YAAE,GAAG,IAAI,GAAG,CAAC,CAAC,CAAE,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,CAAE,CAAC;QAAC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE;YAAE,GAAG,CAAC,CAAC,CAAE,IAAI,GAAG,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,CAAE,CAAC;IAAC,CAAC;IAC3K,OAAO,GAAG,CAAC;AACb,CAAC;AAED,wCAAwC;AACxC,MAAM,UAAU,MAAM,CAAC,CAAe,EAAE,CAAe,EAAE,IAAc,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE;IACpG,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC3C,IAAI,GAAG,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;IAC5B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAE,GAAG,CAAC,CAAC,CAAC,CAAE,CAAC;QAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAE,GAAG,CAAC,CAAC,CAAC,CAAE,CAAC;QAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAE,GAAG,CAAC,CAAC,CAAC,CAAE,CAAC;IAAC,CAAC;IACtG,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACjD,CAAC"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* **Component search — its internal types.** None of this is part of the agent contract: the agent
|
|
3
|
+
* calls `searchComponents(query)` and gets cards. How candidates are found — lexical, semantic,
|
|
4
|
+
* in memory or not — can change without it knowing.
|
|
5
|
+
*/
|
|
6
|
+
/** Turns text into vectors. Swap it for a hosted model without touching the search. */
|
|
7
|
+
export interface EmbeddingProvider {
|
|
8
|
+
/** Changes whenever the vectors would: part of the index version. */
|
|
9
|
+
readonly id: string;
|
|
10
|
+
embed(texts: readonly string[]): Float32Array[];
|
|
11
|
+
}
|
|
12
|
+
/** The same, for a provider that has to wait (a hosted embedding API). */
|
|
13
|
+
export interface AsyncEmbeddingProvider {
|
|
14
|
+
readonly id: string;
|
|
15
|
+
embed(texts: readonly string[]): Promise<Float32Array[]>;
|
|
16
|
+
}
|
|
17
|
+
/** What each piece of a component's search document says about it. */
|
|
18
|
+
export type FieldType = 'name' | 'purpose' | 'signal' | 'useWhen' | 'scenario' | 'action' | 'state' | 'event' | 'data';
|
|
19
|
+
/** A component, as search sees it: what problem it solves (positive) and what it is not for (negative). Built from its capability — nothing is written for search alone. */
|
|
20
|
+
export type SearchDocument = {
|
|
21
|
+
component: string;
|
|
22
|
+
/** Catalogue order: the stable tie-break. */
|
|
23
|
+
order: number;
|
|
24
|
+
positive: {
|
|
25
|
+
type: FieldType;
|
|
26
|
+
text: string;
|
|
27
|
+
}[];
|
|
28
|
+
negative: {
|
|
29
|
+
text: string;
|
|
30
|
+
}[];
|
|
31
|
+
};
|
|
32
|
+
export type SearchWeights = {
|
|
33
|
+
/** How much each kind of field counts when it is the closest to the query (0 leaves it out). */
|
|
34
|
+
fields: Record<FieldType, number>;
|
|
35
|
+
/** The semantic score is the mean of the best `topK` field similarities. */
|
|
36
|
+
topK: number;
|
|
37
|
+
/** How hard a query nearer to what a component is *not* for pushes it down. */
|
|
38
|
+
negative: number;
|
|
39
|
+
/** Before comparing: subtract the catalogue's mean vector (`mean`), and also its first principal component (`pc`) — what every document shares. */
|
|
40
|
+
centre: 'none' | 'mean' | 'pc';
|
|
41
|
+
semantic: number;
|
|
42
|
+
lexical: number;
|
|
43
|
+
/** The lexical score saturates: `s / (s + lexicalHalf)`. */
|
|
44
|
+
lexicalHalf: number;
|
|
45
|
+
/** Below this final score a component is not a candidate. */
|
|
46
|
+
minScore: number;
|
|
47
|
+
/** …nor if it scores below this share of the best one. */
|
|
48
|
+
relative: number;
|
|
49
|
+
};
|
|
50
|
+
export type ScoreBreakdown = {
|
|
51
|
+
component: string;
|
|
52
|
+
semantic: number | null;
|
|
53
|
+
negative: number | null;
|
|
54
|
+
lexical: number;
|
|
55
|
+
/** 1 when the component passes the request's filters (kinds), else 0. */
|
|
56
|
+
metadata: number;
|
|
57
|
+
/** 1 when the host may use it, else 0. */
|
|
58
|
+
availability: number;
|
|
59
|
+
final: number;
|
|
60
|
+
};
|
|
61
|
+
export type SearchOptions = {
|
|
62
|
+
/** Host policy: only these components may be offered. Absent → every approved component. */
|
|
63
|
+
available?: readonly string[];
|
|
64
|
+
/** Only components of these kinds. */
|
|
65
|
+
kinds?: readonly string[];
|
|
66
|
+
};
|
|
67
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/agent/search/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,uFAAuF;AACvF,MAAM,WAAW,iBAAiB;IAChC,qEAAqE;IACrE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,YAAY,EAAE,CAAC;CACjD;AAED,0EAA0E;AAC1E,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;CAC1D;AAED,sEAAsE;AACtE,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,SAAS,GAAG,QAAQ,GAAG,SAAS,GAAG,UAAU,GAAG,QAAQ,GAAG,OAAO,GAAG,OAAO,GAAG,MAAM,CAAC;AAEvH,4KAA4K;AAC5K,MAAM,MAAM,cAAc,GAAG;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,6CAA6C;IAC7C,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE;QAAE,IAAI,EAAE,SAAS,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC9C,QAAQ,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CAC9B,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,gGAAgG;IAChG,MAAM,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IAClC,4EAA4E;IAC5E,IAAI,EAAE,MAAM,CAAC;IACb,+EAA+E;IAC/E,QAAQ,EAAE,MAAM,CAAC;IACjB,mJAAmJ;IACnJ,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,4DAA4D;IAC5D,WAAW,EAAE,MAAM,CAAC;IACpB,6DAA6D;IAC7D,QAAQ,EAAE,MAAM,CAAC;IACjB,0DAA0D;IAC1D,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,yEAAyE;IACzE,QAAQ,EAAE,MAAM,CAAC;IACjB,0CAA0C;IAC1C,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,4FAA4F;IAC5F,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC9B,sCAAsC;IACtC,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC3B,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* **Component search — its internal types.** None of this is part of the agent contract: the agent
|
|
3
|
+
* calls `searchComponents(query)` and gets cards. How candidates are found — lexical, semantic,
|
|
4
|
+
* in memory or not — can change without it knowing.
|
|
5
|
+
*/
|
|
6
|
+
export {};
|
|
7
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/agent/search/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { SearchWeights } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* **The ranking weights — measured, not guessed.** Chosen on the dev half of the evaluation set
|
|
4
|
+
* (`tests/agent/search-eval.ts`) with `tools/search/tune.ts` and a threshold sweep; the test half is
|
|
5
|
+
* reported, never tuned on. The record of why is in docs/DECISIONS.md §19.
|
|
6
|
+
*
|
|
7
|
+
* - Every document field counts; the ones about what a person does with the component (actions,
|
|
8
|
+
* states, events, data) a little less than what it is for.
|
|
9
|
+
* - The semantic score is the mean of the three closest fields, after removing the catalogue mean.
|
|
10
|
+
* - A query closer to a component's `avoidWhen` than to anything it is for is pushed down by half
|
|
11
|
+
* the difference.
|
|
12
|
+
* - Lexical matching adds up to 0.3 — a confident phrase or name match keeps its place; a shared
|
|
13
|
+
* word alone cannot outvote meaning.
|
|
14
|
+
* - A candidate needs 0.3, and 60% of the best — so an ambiguous request keeps its alternatives and
|
|
15
|
+
* a clear one does not trail five weak ones. (Off-topic and on-topic scores overlap; 0.3 rejects
|
|
16
|
+
* about half the off-topic requests without losing on-topic ones.)
|
|
17
|
+
*
|
|
18
|
+
* Measured and not adopted: word-level alignment, reciprocal rank fusion, hubness (CSLS) correction
|
|
19
|
+
* and principal-component removal — none beat this on the development data.
|
|
20
|
+
*/
|
|
21
|
+
export declare const DEFAULT_WEIGHTS: SearchWeights;
|
|
22
|
+
//# sourceMappingURL=weights.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"weights.d.ts","sourceRoot":"","sources":["../../../../src/agent/search/weights.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAE7C;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,eAAe,EAAE,aAU7B,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* **The ranking weights — measured, not guessed.** Chosen on the dev half of the evaluation set
|
|
3
|
+
* (`tests/agent/search-eval.ts`) with `tools/search/tune.ts` and a threshold sweep; the test half is
|
|
4
|
+
* reported, never tuned on. The record of why is in docs/DECISIONS.md §19.
|
|
5
|
+
*
|
|
6
|
+
* - Every document field counts; the ones about what a person does with the component (actions,
|
|
7
|
+
* states, events, data) a little less than what it is for.
|
|
8
|
+
* - The semantic score is the mean of the three closest fields, after removing the catalogue mean.
|
|
9
|
+
* - A query closer to a component's `avoidWhen` than to anything it is for is pushed down by half
|
|
10
|
+
* the difference.
|
|
11
|
+
* - Lexical matching adds up to 0.3 — a confident phrase or name match keeps its place; a shared
|
|
12
|
+
* word alone cannot outvote meaning.
|
|
13
|
+
* - A candidate needs 0.3, and 60% of the best — so an ambiguous request keeps its alternatives and
|
|
14
|
+
* a clear one does not trail five weak ones. (Off-topic and on-topic scores overlap; 0.3 rejects
|
|
15
|
+
* about half the off-topic requests without losing on-topic ones.)
|
|
16
|
+
*
|
|
17
|
+
* Measured and not adopted: word-level alignment, reciprocal rank fusion, hubness (CSLS) correction
|
|
18
|
+
* and principal-component removal — none beat this on the development data.
|
|
19
|
+
*/
|
|
20
|
+
export const DEFAULT_WEIGHTS = {
|
|
21
|
+
fields: { name: 1, purpose: 1, signal: 1, useWhen: 1, scenario: 1, action: 0.8, state: 0.8, event: 0.8, data: 0.8 },
|
|
22
|
+
topK: 3,
|
|
23
|
+
negative: 0.5,
|
|
24
|
+
centre: 'mean',
|
|
25
|
+
semantic: 1,
|
|
26
|
+
lexical: 0.3,
|
|
27
|
+
lexicalHalf: 6,
|
|
28
|
+
minScore: 0.3,
|
|
29
|
+
relative: 0.6,
|
|
30
|
+
};
|
|
31
|
+
//# sourceMappingURL=weights.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"weights.js","sourceRoot":"","sources":["../../../../src/agent/search/weights.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,CAAC,MAAM,eAAe,GAAkB;IAC5C,MAAM,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE;IACnH,IAAI,EAAE,CAAC;IACP,QAAQ,EAAE,GAAG;IACb,MAAM,EAAE,MAAM;IACd,QAAQ,EAAE,CAAC;IACX,OAAO,EAAE,GAAG;IACZ,WAAW,EAAE,CAAC;IACd,QAAQ,EAAE,GAAG;IACb,QAAQ,EAAE,GAAG;CACd,CAAC"}
|