@stackfactor/agent-utils 1.9.0 → 1.11.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/index.d.ts +3 -1
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +3 -1
- package/dist/cjs/referenceContext.d.ts +191 -0
- package/dist/cjs/referenceContext.d.ts.map +1 -0
- package/dist/cjs/referenceContext.js +299 -0
- package/dist/cjs/stackfactorKnowledge.d.ts +8 -1
- package/dist/cjs/stackfactorKnowledge.d.ts.map +1 -1
- package/dist/cjs/stackfactorKnowledge.js +30 -20
- package/dist/esm/index.d.ts +3 -1
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +2 -1
- package/dist/esm/referenceContext.d.ts +191 -0
- package/dist/esm/referenceContext.d.ts.map +1 -0
- package/dist/esm/referenceContext.js +284 -0
- package/dist/esm/stackfactorKnowledge.d.ts +8 -1
- package/dist/esm/stackfactorKnowledge.d.ts.map +1 -1
- package/dist/esm/stackfactorKnowledge.js +30 -20
- package/package.json +1 -1
|
@@ -19,7 +19,9 @@
|
|
|
19
19
|
// generates without it.
|
|
20
20
|
//
|
|
21
21
|
// A reference points at the content and never copies it: the passage is
|
|
22
|
-
// searched again, under the reader's own access, whenever it is used.
|
|
22
|
+
// searched again, under the reader's own access, whenever it is used. Its
|
|
23
|
+
// `url` is the document's page at its source (GitHub, Confluence…), when the
|
|
24
|
+
// platform knows it, so a person can open what was cited. It is
|
|
23
25
|
// EDIT-only (`visibility: "EDIT"`): the platform strips it from what is
|
|
24
26
|
// published, so a knowledge base's titles never reach a learner; agents read
|
|
25
27
|
// it from the draft.
|
|
@@ -48,6 +50,8 @@ const CONCURRENCY = 4;
|
|
|
48
50
|
/** Statuses that mean the person may not read the knowledge base, or it is gone. */
|
|
49
51
|
const NO_ACCESS = new Set([401, 403, 404]);
|
|
50
52
|
const text = (value) => (typeof value === "string" ? value.trim() : "");
|
|
53
|
+
/** An http(s) address, or null: a reference's url lands in an `href`. */
|
|
54
|
+
const webUrl = (value) => (/^https?:\/\//i.test(text(value)) ? text(value) : null);
|
|
51
55
|
const id = (value) => typeof value === "string" ? value.trim() : value != null && typeof value === "object" ? String(value) : "";
|
|
52
56
|
/**
|
|
53
57
|
* The knowledge bases, and the documents in them, that a list of references
|
|
@@ -200,6 +204,7 @@ const retrievePassages = async (options) => {
|
|
|
200
204
|
chunkId,
|
|
201
205
|
documentId: id(chunk.documentId),
|
|
202
206
|
documentName: text(chunk.documentName) || null,
|
|
207
|
+
documentUrl: webUrl(chunk.documentUrl),
|
|
203
208
|
knowledgeBaseId: id(chunk.knowledgeBaseId) || knowledgeBaseId,
|
|
204
209
|
pageNumber: typeof chunk.pageNumber === "number" ? chunk.pageNumber : null,
|
|
205
210
|
score: typeof chunk.score === "number" ? chunk.score : null,
|
|
@@ -229,7 +234,8 @@ exports.passagesForPrompt = passagesForPrompt;
|
|
|
229
234
|
/**
|
|
230
235
|
* STACKFACTOR references for passages: one per passage, in their order, with no
|
|
231
236
|
* cap. With `tags`, only the passages the model cited by tag (any tag it made
|
|
232
|
-
* up is passed over); without, every passage.
|
|
237
|
+
* up is passed over); without, every passage. Each links to its document's
|
|
238
|
+
* page at the source (`url`) when the passage has one.
|
|
233
239
|
* @param passages From `retrievePassages`
|
|
234
240
|
* @param tags The tags the model cited ("k3", "K3" and " k3 " alike)
|
|
235
241
|
* @returns The references, ready for a skill's, a microskill's or a question's `references`
|
|
@@ -241,24 +247,28 @@ const referencesFor = (passages, tags) => {
|
|
|
241
247
|
: null;
|
|
242
248
|
return list
|
|
243
249
|
.filter((passage) => !cited || cited.has(passage.tag.toLowerCase()))
|
|
244
|
-
.map((passage) =>
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
250
|
+
.map((passage) => {
|
|
251
|
+
const url = webUrl(passage.documentUrl);
|
|
252
|
+
return {
|
|
253
|
+
description: passage.sectionTitle,
|
|
254
|
+
kind: exports.STACKFACTOR_REFERENCE.KIND,
|
|
255
|
+
knowledgeBase: {
|
|
256
|
+
chunkId: passage.chunkId,
|
|
257
|
+
documentId: passage.documentId,
|
|
258
|
+
knowledgeBaseId: passage.knowledgeBaseId,
|
|
259
|
+
sectionTitle: passage.sectionTitle,
|
|
260
|
+
},
|
|
261
|
+
origin: exports.STACKFACTOR_REFERENCE.ORIGIN,
|
|
262
|
+
target: {
|
|
263
|
+
elementId: passage.documentId,
|
|
264
|
+
elementType: exports.STACKFACTOR_REFERENCE.TARGET_ELEMENT_TYPE,
|
|
265
|
+
parentId: passage.knowledgeBaseId,
|
|
266
|
+
},
|
|
267
|
+
title: passage.documentName || passage.sectionTitle || "Knowledge base document",
|
|
268
|
+
...(url ? { url } : {}),
|
|
269
|
+
visibility: exports.STACKFACTOR_REFERENCE.VISIBILITY,
|
|
270
|
+
};
|
|
271
|
+
});
|
|
262
272
|
};
|
|
263
273
|
exports.referencesFor = referencesFor;
|
|
264
274
|
exports.default = {
|
package/dist/esm/index.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ import { callAgent, checkAgent } from "./client.js";
|
|
|
7
7
|
import * as runtimeContext from "./runtimeContext.js";
|
|
8
8
|
import { recordUsage, USAGE_UNITS } from "./usage.js";
|
|
9
9
|
import stackfactorKnowledge from "./stackfactorKnowledge.js";
|
|
10
|
+
import referenceContext from "./referenceContext.js";
|
|
10
11
|
import { checkUrlsReachable } from "./tavily.js";
|
|
11
12
|
export { constants };
|
|
12
13
|
export { errorHandling, AppError };
|
|
@@ -23,6 +24,7 @@ export type { AgentExecuteRequest, CallAgentOptions, CheckAgentOptions, AgentHea
|
|
|
23
24
|
export { runtimeContext };
|
|
24
25
|
export { recordUsage, USAGE_UNITS };
|
|
25
26
|
export type { UsageEntry, UsageUnit } from "./usage.js";
|
|
26
|
-
export { stackfactorKnowledge };
|
|
27
|
+
export { stackfactorKnowledge, referenceContext };
|
|
27
28
|
export type { GroundingPassage, KnowledgeChunk, KnowledgeSearch, KnowledgeSource, SkippedSource, StackFactorReference, } from "./stackfactorKnowledge.js";
|
|
29
|
+
export type { ReferenceContext, ReferencePage, ReferencePassage, SourceGuidance, StoredReference, } from "./referenceContext.js";
|
|
28
30
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/esm/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,YAAY,CAAC;AACnC,OAAO,aAAa,EAAE,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC7D,OAAO,SAAS,MAAM,gBAAgB,CAAC;AACvC,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC/E,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,KAAK,cAAc,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACtD,OAAO,oBAAoB,MAAM,2BAA2B,CAAC;AAC7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEjD,OAAO,EAAE,SAAS,EAAE,CAAC;AAErB,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,CAAC;AAEnC,YAAY,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEtD,OAAO,EAAE,SAAS,EAAE,CAAC;AAErB,YAAY,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEnD,OAAO,EAAE,kBAAkB,EAAE,CAAC;AAE9B,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAEhE,OAAO,EAAE,MAAM,EAAE,CAAC;AAElB,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAE,CAAC;AAE7D,OAAO,EAAE,SAAS,EAAE,CAAC;AAErB,OAAO,EAAE,UAAU,EAAE,CAAC;AAEtB,YAAY,EACV,mBAAmB,EACnB,gBAAgB,EAChB,iBAAiB,EACjB,WAAW,GACZ,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,cAAc,EAAE,CAAC;AAE1B,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,CAAC;AAEpC,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAExD,OAAO,EAAE,oBAAoB,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,YAAY,CAAC;AACnC,OAAO,aAAa,EAAE,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC7D,OAAO,SAAS,MAAM,gBAAgB,CAAC;AACvC,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC/E,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,KAAK,cAAc,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACtD,OAAO,oBAAoB,MAAM,2BAA2B,CAAC;AAC7D,OAAO,gBAAgB,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEjD,OAAO,EAAE,SAAS,EAAE,CAAC;AAErB,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,CAAC;AAEnC,YAAY,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEtD,OAAO,EAAE,SAAS,EAAE,CAAC;AAErB,YAAY,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEnD,OAAO,EAAE,kBAAkB,EAAE,CAAC;AAE9B,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAEhE,OAAO,EAAE,MAAM,EAAE,CAAC;AAElB,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAE,CAAC;AAE7D,OAAO,EAAE,SAAS,EAAE,CAAC;AAErB,OAAO,EAAE,UAAU,EAAE,CAAC;AAEtB,YAAY,EACV,mBAAmB,EACnB,gBAAgB,EAChB,iBAAiB,EACjB,WAAW,GACZ,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,cAAc,EAAE,CAAC;AAE1B,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,CAAC;AAEpC,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAExD,OAAO,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,CAAC;AAElD,YAAY,EACV,gBAAgB,EAChB,cAAc,EACd,eAAe,EACf,eAAe,EACf,aAAa,EACb,oBAAoB,GACrB,MAAM,2BAA2B,CAAC;AAEnC,YAAY,EACV,gBAAgB,EAChB,aAAa,EACb,gBAAgB,EAChB,cAAc,EACd,eAAe,GAChB,MAAM,uBAAuB,CAAC"}
|
package/dist/esm/index.js
CHANGED
|
@@ -7,6 +7,7 @@ import { callAgent, checkAgent } from "./client.js";
|
|
|
7
7
|
import * as runtimeContext from "./runtimeContext.js";
|
|
8
8
|
import { recordUsage, USAGE_UNITS } from "./usage.js";
|
|
9
9
|
import stackfactorKnowledge from "./stackfactorKnowledge.js";
|
|
10
|
+
import referenceContext from "./referenceContext.js";
|
|
10
11
|
import { checkUrlsReachable } from "./tavily.js";
|
|
11
12
|
export { constants };
|
|
12
13
|
export { errorHandling, AppError };
|
|
@@ -18,4 +19,4 @@ export { callAgent };
|
|
|
18
19
|
export { checkAgent };
|
|
19
20
|
export { runtimeContext };
|
|
20
21
|
export { recordUsage, USAGE_UNITS };
|
|
21
|
-
export { stackfactorKnowledge };
|
|
22
|
+
export { stackfactorKnowledge, referenceContext };
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
import { KnowledgeSearch, SkippedSource } from "./stackfactorKnowledge.js";
|
|
2
|
+
/** The prompt key the passages are handed to the model under. */
|
|
3
|
+
export declare const REFERENCE_PASSAGES_KEY = "Knowledge Base Passages";
|
|
4
|
+
/** A web or publication page a reference points at. */
|
|
5
|
+
export interface ReferencePage {
|
|
6
|
+
/** The reference's short id, "r0"… */
|
|
7
|
+
id: string;
|
|
8
|
+
title: string;
|
|
9
|
+
url: string;
|
|
10
|
+
}
|
|
11
|
+
/** A passage of a document that references cite. */
|
|
12
|
+
export interface ReferencePassage {
|
|
13
|
+
/** The short ids of every STACKFACTOR reference that cites this passage's document. */
|
|
14
|
+
references: string[];
|
|
15
|
+
document: string | null;
|
|
16
|
+
section: string | null;
|
|
17
|
+
text: string;
|
|
18
|
+
chunkId: string;
|
|
19
|
+
documentId: string;
|
|
20
|
+
knowledgeBaseId: string;
|
|
21
|
+
}
|
|
22
|
+
/** What a list of references points at. */
|
|
23
|
+
export interface ReferenceContext {
|
|
24
|
+
pages: ReferencePage[];
|
|
25
|
+
passages: ReferencePassage[];
|
|
26
|
+
skipped: SkippedSource[];
|
|
27
|
+
/** True when the references cite at least one knowledge base document, whether or not it could be read. */
|
|
28
|
+
citesKnowledge: boolean;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* What a list of references points at: its pages, and the passages of the
|
|
32
|
+
* documents its STACKFACTOR references cite. One search per knowledge base per
|
|
33
|
+
* query (per batch of 500 documents), however many references there are. With
|
|
34
|
+
* no token no search is made and the pages are still listed. A knowledge base
|
|
35
|
+
* the person cannot open is in `skipped`; the other passages stand.
|
|
36
|
+
* @param options `references` (a skill's, a microskill's…), `queries` to
|
|
37
|
+
* search the cited documents with, `search` (client-api
|
|
38
|
+
* `knowledgeBaseAgent.search`), `token` (the run's AGENT token), `topK` per
|
|
39
|
+
* search (default 5)
|
|
40
|
+
* @returns `{ pages, passages, skipped, citesKnowledge }`
|
|
41
|
+
*/
|
|
42
|
+
export declare const gatherReferenceContext: (options: {
|
|
43
|
+
references: unknown;
|
|
44
|
+
queries: string[];
|
|
45
|
+
search: KnowledgeSearch;
|
|
46
|
+
token: string | null | undefined;
|
|
47
|
+
topK?: number;
|
|
48
|
+
}) => Promise<ReferenceContext>;
|
|
49
|
+
/**
|
|
50
|
+
* The passages as a prompt shows them: who cites each, where it came from, and
|
|
51
|
+
* its text. The ids that locate it in the platform are left out.
|
|
52
|
+
* @param context From `gatherReferenceContext`
|
|
53
|
+
* @returns `[{ references, document, section, text }]`, for the model's input
|
|
54
|
+
*/
|
|
55
|
+
export declare const referencePassagesForPrompt: (context: ReferenceContext) => {
|
|
56
|
+
references: string[];
|
|
57
|
+
document: string | null;
|
|
58
|
+
section: string | null;
|
|
59
|
+
text: string;
|
|
60
|
+
}[];
|
|
61
|
+
/** The guidance an agent's config gives for each kind of source it may be handed. */
|
|
62
|
+
export interface SourceGuidance {
|
|
63
|
+
pages: string;
|
|
64
|
+
passages: string;
|
|
65
|
+
none: string;
|
|
66
|
+
}
|
|
67
|
+
/** A reference as the platform stores it. `visibility` is left to the caller. */
|
|
68
|
+
export interface StoredReference {
|
|
69
|
+
kind: string;
|
|
70
|
+
title: string;
|
|
71
|
+
description?: string;
|
|
72
|
+
url?: string;
|
|
73
|
+
publication?: {
|
|
74
|
+
author?: string;
|
|
75
|
+
publisher?: string;
|
|
76
|
+
identifier?: string;
|
|
77
|
+
locator?: string;
|
|
78
|
+
};
|
|
79
|
+
origin: string;
|
|
80
|
+
visibility?: string;
|
|
81
|
+
target?: {
|
|
82
|
+
elementType: string;
|
|
83
|
+
elementId: string;
|
|
84
|
+
parentId?: string;
|
|
85
|
+
};
|
|
86
|
+
knowledgeBase?: {
|
|
87
|
+
knowledgeBaseId: string;
|
|
88
|
+
documentId: string;
|
|
89
|
+
chunkId?: string;
|
|
90
|
+
sectionTitle?: string | null;
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* The tools a run is given. Never `search`, `map` or `crawl`: a run reads what
|
|
95
|
+
* its references point at and discovers nothing. `extract` only, and only when
|
|
96
|
+
* there are pages to open.
|
|
97
|
+
* @param context From `gatherReferenceContext`
|
|
98
|
+
* @returns `{ tavily: { tools: ["extract"] } }` with pages, else `{}`. With no
|
|
99
|
+
* pages it returns `{}`, so a caller spreading it over a config that already
|
|
100
|
+
* has a `tavily` key keeps that key (and `tavily: true` means search plus
|
|
101
|
+
* extract): callers must not carry a base `tavily` key.
|
|
102
|
+
*/
|
|
103
|
+
export declare const toolsFor: (context: ReferenceContext) => {
|
|
104
|
+
tavily?: {
|
|
105
|
+
tools: string[];
|
|
106
|
+
};
|
|
107
|
+
};
|
|
108
|
+
/**
|
|
109
|
+
* The stage prompt followed by the guidance for each kind of source the run
|
|
110
|
+
* has: pages, then passages; when it has neither, the `none` guidance. An empty
|
|
111
|
+
* guidance adds nothing.
|
|
112
|
+
* @param stagePrompt The stage's own prompt
|
|
113
|
+
* @param context From `gatherReferenceContext`
|
|
114
|
+
* @param guidance From `sourceGuidanceFrom`
|
|
115
|
+
* @returns The sections joined with a blank line
|
|
116
|
+
*/
|
|
117
|
+
export declare const composeSourceInstructions: (stagePrompt: string, context: ReferenceContext, guidance: SourceGuidance) => string;
|
|
118
|
+
/**
|
|
119
|
+
* A reference as a model is shown it. A STACKFACTOR reference loses its pointer
|
|
120
|
+
* and its url (ids mean nothing to a model, and the url is behind the
|
|
121
|
+
* organization's own sign-in); the model cites it by short id.
|
|
122
|
+
* @param reference A supplied reference
|
|
123
|
+
* @returns The reference; a STACKFACTOR one without `_id`, `origin`, `visibility`,
|
|
124
|
+
* `target`, `knowledgeBase` and `url`
|
|
125
|
+
*/
|
|
126
|
+
export declare const referenceForModel: <T extends {
|
|
127
|
+
kind?: string;
|
|
128
|
+
}>(reference: T) => T;
|
|
129
|
+
/**
|
|
130
|
+
* The supplied references as a model is shown them, each under its short id
|
|
131
|
+
* `r<N>` (N the index in the supplied list) as `_id`, set last so a stored
|
|
132
|
+
* reference's own id never wins. Non-object entries are skipped but keep their
|
|
133
|
+
* index, so the ids stay aligned with `citedReferences`.
|
|
134
|
+
* @param references The supplied list
|
|
135
|
+
*/
|
|
136
|
+
export declare const referencesForModel: (references: unknown) => Array<Record<string, unknown>>;
|
|
137
|
+
/**
|
|
138
|
+
* A reference from the flat projection the host sends (or the flat shape a
|
|
139
|
+
* model emits) in the shape the platform stores: nested `publication`,
|
|
140
|
+
* `relatedTo` folded into `description`, a STACKFACTOR reference's pointer and
|
|
141
|
+
* target kept. `visibility` is never set; the caller decides it.
|
|
142
|
+
* @param reference The flat reference
|
|
143
|
+
* @param origin Default `"AI_GENERATED"`
|
|
144
|
+
*/
|
|
145
|
+
export declare const toStoredReference: (reference: any, origin?: string) => StoredReference;
|
|
146
|
+
/**
|
|
147
|
+
* The supplied references a model cited by short id, stored. Ids are matched
|
|
148
|
+
* trimmed and case-insensitively; unknown and non-string ids are dropped and
|
|
149
|
+
* each reference appears once, at its first citation.
|
|
150
|
+
* @param ids The model's cited ids (`["r0", "r3"]`)
|
|
151
|
+
* @param supplied The list the ids index into
|
|
152
|
+
* @param origin Default `"AI_GENERATED"`
|
|
153
|
+
*/
|
|
154
|
+
export declare const citedReferences: (ids: unknown, supplied: unknown, origin?: string) => StoredReference[];
|
|
155
|
+
/**
|
|
156
|
+
* The three guidance texts an agent's config holds. A missing or non-string
|
|
157
|
+
* value is an empty string.
|
|
158
|
+
* @param config The agent's config
|
|
159
|
+
*/
|
|
160
|
+
export declare const sourceGuidanceFrom: (config: Record<string, unknown>) => SourceGuidance;
|
|
161
|
+
declare const _default: {
|
|
162
|
+
REFERENCE_PASSAGES_KEY: string;
|
|
163
|
+
citedReferences: (ids: unknown, supplied: unknown, origin?: string) => StoredReference[];
|
|
164
|
+
composeSourceInstructions: (stagePrompt: string, context: ReferenceContext, guidance: SourceGuidance) => string;
|
|
165
|
+
gatherReferenceContext: (options: {
|
|
166
|
+
references: unknown;
|
|
167
|
+
queries: string[];
|
|
168
|
+
search: KnowledgeSearch;
|
|
169
|
+
token: string | null | undefined;
|
|
170
|
+
topK?: number;
|
|
171
|
+
}) => Promise<ReferenceContext>;
|
|
172
|
+
referenceForModel: <T extends {
|
|
173
|
+
kind?: string;
|
|
174
|
+
}>(reference: T) => T;
|
|
175
|
+
referencePassagesForPrompt: (context: ReferenceContext) => {
|
|
176
|
+
references: string[];
|
|
177
|
+
document: string | null;
|
|
178
|
+
section: string | null;
|
|
179
|
+
text: string;
|
|
180
|
+
}[];
|
|
181
|
+
referencesForModel: (references: unknown) => Array<Record<string, unknown>>;
|
|
182
|
+
sourceGuidanceFrom: (config: Record<string, unknown>) => SourceGuidance;
|
|
183
|
+
toStoredReference: (reference: any, origin?: string) => StoredReference;
|
|
184
|
+
toolsFor: (context: ReferenceContext) => {
|
|
185
|
+
tavily?: {
|
|
186
|
+
tools: string[];
|
|
187
|
+
};
|
|
188
|
+
};
|
|
189
|
+
};
|
|
190
|
+
export default _default;
|
|
191
|
+
//# sourceMappingURL=referenceContext.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"referenceContext.d.ts","sourceRoot":"","sources":["../../src/referenceContext.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Reference context — gathering what a list of references points at
|
|
3
|
+
//
|
|
4
|
+
// An agent that reads its references never discovers new sources. It reads
|
|
5
|
+
// what they point at:
|
|
6
|
+
//
|
|
7
|
+
// - pages: WEB and PUBLICATION references with an http(s) url, which the
|
|
8
|
+
// agent opens through Tavily `extract`. A STACKFACTOR reference's url is
|
|
9
|
+
// the document's page at its source and is never opened as a page;
|
|
10
|
+
// - passages: the passages of the knowledge base documents STACKFACTOR
|
|
11
|
+
// references cite, searched under the run's own token, so a run reads only
|
|
12
|
+
// what the person it acts for may open.
|
|
13
|
+
//
|
|
14
|
+
// A reference is cited by its short id `r<N>`, N being its index in the
|
|
15
|
+
// supplied list, whatever its kind.
|
|
16
|
+
//
|
|
17
|
+
import logger from "./logger.js";
|
|
18
|
+
import { STACKFACTOR_REFERENCE, retrievePassages, sourcesFromReferences, } from "./stackfactorKnowledge.js";
|
|
19
|
+
/** How many passages one search asks for when the caller does not say. */
|
|
20
|
+
const DEFAULT_REFERENCE_TOP_K = 5;
|
|
21
|
+
/** The prompt key the passages are handed to the model under. */
|
|
22
|
+
export const REFERENCE_PASSAGES_KEY = "Knowledge Base Passages";
|
|
23
|
+
const text = (value) => (typeof value === "string" ? value.trim() : "");
|
|
24
|
+
const id = (value) => typeof value === "string" ? value.trim() : value != null && typeof value === "object" ? String(value) : "";
|
|
25
|
+
const shortId = (index) => `r${index}`;
|
|
26
|
+
/** The document a STACKFACTOR reference cites, or "" when it cites none. */
|
|
27
|
+
const documentOf = (reference) => {
|
|
28
|
+
const target = reference.target ?? {};
|
|
29
|
+
return (id(reference.knowledgeBase?.documentId) ||
|
|
30
|
+
(target.elementType === STACKFACTOR_REFERENCE.TARGET_ELEMENT_TYPE ? id(target.elementId) : ""));
|
|
31
|
+
};
|
|
32
|
+
/** The kinds the platform retired; it reads them as PUBLICATION. */
|
|
33
|
+
const RETIRED_KINDS = new Set(["DOCUMENT", "KNOWLEDGE_BASE", "NOTE"]);
|
|
34
|
+
/** A reference's kind as the platform reads it: missing or retired is PUBLICATION. */
|
|
35
|
+
const resolveKind = (reference) => {
|
|
36
|
+
const kind = reference?.kind;
|
|
37
|
+
return typeof kind !== "string" || kind === "" || RETIRED_KINDS.has(kind) ? "PUBLICATION" : kind;
|
|
38
|
+
};
|
|
39
|
+
/** The pages among the references, each url once, under the first reference that has it. */
|
|
40
|
+
const pagesOf = (references) => {
|
|
41
|
+
const pages = [];
|
|
42
|
+
const seen = new Set();
|
|
43
|
+
references.forEach((reference, index) => {
|
|
44
|
+
if (!reference || typeof reference !== "object")
|
|
45
|
+
return;
|
|
46
|
+
const kind = resolveKind(reference);
|
|
47
|
+
if (kind !== "WEB" && kind !== "PUBLICATION")
|
|
48
|
+
return;
|
|
49
|
+
const url = text(reference.url);
|
|
50
|
+
if (!/^https?:\/\//i.test(url) || seen.has(url))
|
|
51
|
+
return;
|
|
52
|
+
seen.add(url);
|
|
53
|
+
pages.push({ id: shortId(index), title: text(reference.title) || url, url });
|
|
54
|
+
});
|
|
55
|
+
return pages;
|
|
56
|
+
};
|
|
57
|
+
/** The short ids of the STACKFACTOR references citing each document. */
|
|
58
|
+
const citersByDocument = (references) => {
|
|
59
|
+
const citers = new Map();
|
|
60
|
+
references.forEach((reference, index) => {
|
|
61
|
+
if (reference?.kind !== STACKFACTOR_REFERENCE.KIND)
|
|
62
|
+
return;
|
|
63
|
+
const documentId = documentOf(reference);
|
|
64
|
+
if (documentId)
|
|
65
|
+
citers.set(documentId, [...(citers.get(documentId) ?? []), shortId(index)]);
|
|
66
|
+
});
|
|
67
|
+
return citers;
|
|
68
|
+
};
|
|
69
|
+
/**
|
|
70
|
+
* What a list of references points at: its pages, and the passages of the
|
|
71
|
+
* documents its STACKFACTOR references cite. One search per knowledge base per
|
|
72
|
+
* query (per batch of 500 documents), however many references there are. With
|
|
73
|
+
* no token no search is made and the pages are still listed. A knowledge base
|
|
74
|
+
* the person cannot open is in `skipped`; the other passages stand.
|
|
75
|
+
* @param options `references` (a skill's, a microskill's…), `queries` to
|
|
76
|
+
* search the cited documents with, `search` (client-api
|
|
77
|
+
* `knowledgeBaseAgent.search`), `token` (the run's AGENT token), `topK` per
|
|
78
|
+
* search (default 5)
|
|
79
|
+
* @returns `{ pages, passages, skipped, citesKnowledge }`
|
|
80
|
+
*/
|
|
81
|
+
export const gatherReferenceContext = async (options) => {
|
|
82
|
+
const references = Array.isArray(options.references) ? options.references : [];
|
|
83
|
+
const sources = sourcesFromReferences(references);
|
|
84
|
+
const citesKnowledge = sources.length > 0;
|
|
85
|
+
const pages = pagesOf(references);
|
|
86
|
+
if (!options.token || !citesKnowledge) {
|
|
87
|
+
logContext(pages.length, 0, [], citesKnowledge && !options.token);
|
|
88
|
+
return { citesKnowledge, pages, passages: [], skipped: [] };
|
|
89
|
+
}
|
|
90
|
+
const found = await retrievePassages({
|
|
91
|
+
queries: options.queries,
|
|
92
|
+
search: options.search,
|
|
93
|
+
sources,
|
|
94
|
+
token: options.token,
|
|
95
|
+
topK: options.topK ?? DEFAULT_REFERENCE_TOP_K,
|
|
96
|
+
});
|
|
97
|
+
const citers = citersByDocument(references);
|
|
98
|
+
const passages = found.passages
|
|
99
|
+
.filter((passage) => citers.has(passage.documentId))
|
|
100
|
+
.map((passage) => ({
|
|
101
|
+
chunkId: passage.chunkId,
|
|
102
|
+
document: passage.documentName,
|
|
103
|
+
documentId: passage.documentId,
|
|
104
|
+
knowledgeBaseId: passage.knowledgeBaseId,
|
|
105
|
+
references: citers.get(passage.documentId),
|
|
106
|
+
section: passage.sectionTitle,
|
|
107
|
+
text: passage.text,
|
|
108
|
+
}));
|
|
109
|
+
logContext(pages.length, passages.length, found.skipped, false);
|
|
110
|
+
return { citesKnowledge, pages, passages, skipped: found.skipped };
|
|
111
|
+
};
|
|
112
|
+
/** The one summary line of a gathering, for the logs. */
|
|
113
|
+
const logContext = (pages, passages, skipped, noToken) => {
|
|
114
|
+
const parts = [`${pages} page${pages === 1 ? "" : "s"}`, `${passages} passage${passages === 1 ? "" : "s"}`];
|
|
115
|
+
if (skipped.length > 0) {
|
|
116
|
+
parts.push(`skipped knowledge bases: ${skipped.map((s) => `${s.knowledgeBaseId} (noAccess: ${s.noAccess})`).join(", ")}`);
|
|
117
|
+
}
|
|
118
|
+
if (noToken)
|
|
119
|
+
parts.push("no token, so no passages");
|
|
120
|
+
logger.log(null, logger.levels.info, `Reference context: ${parts.join("; ")}`);
|
|
121
|
+
};
|
|
122
|
+
/**
|
|
123
|
+
* The passages as a prompt shows them: who cites each, where it came from, and
|
|
124
|
+
* its text. The ids that locate it in the platform are left out.
|
|
125
|
+
* @param context From `gatherReferenceContext`
|
|
126
|
+
* @returns `[{ references, document, section, text }]`, for the model's input
|
|
127
|
+
*/
|
|
128
|
+
export const referencePassagesForPrompt = (context) => context.passages.map((passage) => ({
|
|
129
|
+
document: passage.document,
|
|
130
|
+
references: passage.references,
|
|
131
|
+
section: passage.section,
|
|
132
|
+
text: passage.text,
|
|
133
|
+
}));
|
|
134
|
+
/**
|
|
135
|
+
* The tools a run is given. Never `search`, `map` or `crawl`: a run reads what
|
|
136
|
+
* its references point at and discovers nothing. `extract` only, and only when
|
|
137
|
+
* there are pages to open.
|
|
138
|
+
* @param context From `gatherReferenceContext`
|
|
139
|
+
* @returns `{ tavily: { tools: ["extract"] } }` with pages, else `{}`. With no
|
|
140
|
+
* pages it returns `{}`, so a caller spreading it over a config that already
|
|
141
|
+
* has a `tavily` key keeps that key (and `tavily: true` means search plus
|
|
142
|
+
* extract): callers must not carry a base `tavily` key.
|
|
143
|
+
*/
|
|
144
|
+
export const toolsFor = (context) => context.pages.length > 0 ? { tavily: { tools: ["extract"] } } : {};
|
|
145
|
+
/**
|
|
146
|
+
* The stage prompt followed by the guidance for each kind of source the run
|
|
147
|
+
* has: pages, then passages; when it has neither, the `none` guidance. An empty
|
|
148
|
+
* guidance adds nothing.
|
|
149
|
+
* @param stagePrompt The stage's own prompt
|
|
150
|
+
* @param context From `gatherReferenceContext`
|
|
151
|
+
* @param guidance From `sourceGuidanceFrom`
|
|
152
|
+
* @returns The sections joined with a blank line
|
|
153
|
+
*/
|
|
154
|
+
export const composeSourceInstructions = (stagePrompt, context, guidance) => {
|
|
155
|
+
const sections = [];
|
|
156
|
+
if (context.pages.length > 0)
|
|
157
|
+
sections.push(guidance.pages);
|
|
158
|
+
if (context.passages.length > 0)
|
|
159
|
+
sections.push(guidance.passages);
|
|
160
|
+
if (sections.length === 0)
|
|
161
|
+
sections.push(guidance.none);
|
|
162
|
+
return [stagePrompt, ...sections].filter(Boolean).join("\n\n");
|
|
163
|
+
};
|
|
164
|
+
/**
|
|
165
|
+
* A reference as a model is shown it. A STACKFACTOR reference loses its pointer
|
|
166
|
+
* and its url (ids mean nothing to a model, and the url is behind the
|
|
167
|
+
* organization's own sign-in); the model cites it by short id.
|
|
168
|
+
* @param reference A supplied reference
|
|
169
|
+
* @returns The reference; a STACKFACTOR one without `_id`, `origin`, `visibility`,
|
|
170
|
+
* `target`, `knowledgeBase` and `url`
|
|
171
|
+
*/
|
|
172
|
+
export const referenceForModel = (reference) => {
|
|
173
|
+
if (reference?.kind !== STACKFACTOR_REFERENCE.KIND)
|
|
174
|
+
return reference;
|
|
175
|
+
const { _id: _i, origin: _o, visibility: _v, target: _target, knowledgeBase: _knowledgeBase, url: _url, ...rest } = reference;
|
|
176
|
+
return rest;
|
|
177
|
+
};
|
|
178
|
+
/**
|
|
179
|
+
* The supplied references as a model is shown them, each under its short id
|
|
180
|
+
* `r<N>` (N the index in the supplied list) as `_id`, set last so a stored
|
|
181
|
+
* reference's own id never wins. Non-object entries are skipped but keep their
|
|
182
|
+
* index, so the ids stay aligned with `citedReferences`.
|
|
183
|
+
* @param references The supplied list
|
|
184
|
+
*/
|
|
185
|
+
export const referencesForModel = (references) => {
|
|
186
|
+
const shown = [];
|
|
187
|
+
(Array.isArray(references) ? references : []).forEach((reference, index) => {
|
|
188
|
+
if (!reference || typeof reference !== "object")
|
|
189
|
+
return;
|
|
190
|
+
const { _id: _ignored, ...rest } = referenceForModel(reference);
|
|
191
|
+
shown.push({ ...rest, _id: shortId(index) });
|
|
192
|
+
});
|
|
193
|
+
return shown;
|
|
194
|
+
};
|
|
195
|
+
/** What a STACKFACTOR reference points at, as the platform stores it. */
|
|
196
|
+
const stackfactorPointers = (reference) => {
|
|
197
|
+
if (reference.kind !== STACKFACTOR_REFERENCE.KIND)
|
|
198
|
+
return {};
|
|
199
|
+
const pointer = reference.knowledgeBase;
|
|
200
|
+
if (pointer?.knowledgeBaseId && pointer?.documentId) {
|
|
201
|
+
return {
|
|
202
|
+
knowledgeBase: { ...pointer },
|
|
203
|
+
target: {
|
|
204
|
+
elementType: STACKFACTOR_REFERENCE.TARGET_ELEMENT_TYPE,
|
|
205
|
+
elementId: pointer.documentId,
|
|
206
|
+
parentId: pointer.knowledgeBaseId,
|
|
207
|
+
},
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
return reference.target?.elementType && reference.target?.elementId ? { target: { ...reference.target } } : {};
|
|
211
|
+
};
|
|
212
|
+
/**
|
|
213
|
+
* A reference from the flat projection the host sends (or the flat shape a
|
|
214
|
+
* model emits) in the shape the platform stores: nested `publication`,
|
|
215
|
+
* `relatedTo` folded into `description`, a STACKFACTOR reference's pointer and
|
|
216
|
+
* target kept. `visibility` is never set; the caller decides it.
|
|
217
|
+
* @param reference The flat reference
|
|
218
|
+
* @param origin Default `"AI_GENERATED"`
|
|
219
|
+
*/
|
|
220
|
+
export const toStoredReference = (reference, origin = "AI_GENERATED") => {
|
|
221
|
+
const publication = {
|
|
222
|
+
...(reference.author ? { author: reference.author } : {}),
|
|
223
|
+
...(reference.publisher ? { publisher: reference.publisher } : {}),
|
|
224
|
+
...(reference.identifier ? { identifier: reference.identifier } : {}),
|
|
225
|
+
...(reference.locator ? { locator: reference.locator } : {}),
|
|
226
|
+
...(reference.publication || {}),
|
|
227
|
+
};
|
|
228
|
+
const description = [reference.description, reference.relatedTo ? `Related to: ${reference.relatedTo}` : null]
|
|
229
|
+
.filter(Boolean)
|
|
230
|
+
.join(" \u2014 ");
|
|
231
|
+
return {
|
|
232
|
+
kind: reference.kind,
|
|
233
|
+
title: reference.title,
|
|
234
|
+
...(description ? { description } : {}),
|
|
235
|
+
...(reference.url ? { url: reference.url } : {}),
|
|
236
|
+
...(Object.keys(publication).length > 0 ? { publication } : {}),
|
|
237
|
+
...stackfactorPointers(reference),
|
|
238
|
+
origin,
|
|
239
|
+
};
|
|
240
|
+
};
|
|
241
|
+
/**
|
|
242
|
+
* The supplied references a model cited by short id, stored. Ids are matched
|
|
243
|
+
* trimmed and case-insensitively; unknown and non-string ids are dropped and
|
|
244
|
+
* each reference appears once, at its first citation.
|
|
245
|
+
* @param ids The model's cited ids (`["r0", "r3"]`)
|
|
246
|
+
* @param supplied The list the ids index into
|
|
247
|
+
* @param origin Default `"AI_GENERATED"`
|
|
248
|
+
*/
|
|
249
|
+
export const citedReferences = (ids, supplied, origin) => {
|
|
250
|
+
const list = Array.isArray(supplied) ? supplied : [];
|
|
251
|
+
const taken = new Set();
|
|
252
|
+
const cited = [];
|
|
253
|
+
for (const raw of Array.isArray(ids) ? ids : []) {
|
|
254
|
+
const match = typeof raw === "string" ? /^r(\d+)$/.exec(raw.trim().toLowerCase()) : null;
|
|
255
|
+
const index = match ? Number(match[1]) : -1;
|
|
256
|
+
if (!list[index] || typeof list[index] !== "object" || taken.has(index))
|
|
257
|
+
continue;
|
|
258
|
+
taken.add(index);
|
|
259
|
+
cited.push(toStoredReference(list[index], origin));
|
|
260
|
+
}
|
|
261
|
+
return cited;
|
|
262
|
+
};
|
|
263
|
+
/**
|
|
264
|
+
* The three guidance texts an agent's config holds. A missing or non-string
|
|
265
|
+
* value is an empty string.
|
|
266
|
+
* @param config The agent's config
|
|
267
|
+
*/
|
|
268
|
+
export const sourceGuidanceFrom = (config) => ({
|
|
269
|
+
pages: text(config?.referencedPagesGuidance),
|
|
270
|
+
passages: text(config?.knowledgeBasePassagesGuidance),
|
|
271
|
+
none: text(config?.noReferencesGuidance),
|
|
272
|
+
});
|
|
273
|
+
export default {
|
|
274
|
+
REFERENCE_PASSAGES_KEY,
|
|
275
|
+
citedReferences,
|
|
276
|
+
composeSourceInstructions,
|
|
277
|
+
gatherReferenceContext,
|
|
278
|
+
referenceForModel,
|
|
279
|
+
referencePassagesForPrompt,
|
|
280
|
+
referencesForModel,
|
|
281
|
+
sourceGuidanceFrom,
|
|
282
|
+
toStoredReference,
|
|
283
|
+
toolsFor,
|
|
284
|
+
};
|
|
@@ -17,6 +17,8 @@ export interface KnowledgeChunk {
|
|
|
17
17
|
knowledgeBaseId?: string;
|
|
18
18
|
documentId: string;
|
|
19
19
|
documentName?: string | null;
|
|
20
|
+
/** The document's page at its source (sent by the platform's search since backend-core #630). */
|
|
21
|
+
documentUrl?: string | null;
|
|
20
22
|
sectionTitle?: string | null;
|
|
21
23
|
pageNumber?: number | null;
|
|
22
24
|
text?: string;
|
|
@@ -48,6 +50,8 @@ export interface GroundingPassage {
|
|
|
48
50
|
knowledgeBaseId: string;
|
|
49
51
|
documentId: string;
|
|
50
52
|
documentName: string | null;
|
|
53
|
+
/** The document's page at its source, an http(s) address; null when the platform has none. */
|
|
54
|
+
documentUrl?: string | null;
|
|
51
55
|
sectionTitle: string | null;
|
|
52
56
|
pageNumber: number | null;
|
|
53
57
|
text: string;
|
|
@@ -72,6 +76,8 @@ export interface StackFactorReference {
|
|
|
72
76
|
kind: "STACKFACTOR";
|
|
73
77
|
title: string;
|
|
74
78
|
description: string | null;
|
|
79
|
+
/** The document's page at its source; absent when the platform has none. */
|
|
80
|
+
url?: string;
|
|
75
81
|
target: {
|
|
76
82
|
elementType: "KNOWLEDGE_BASE_DOCUMENT";
|
|
77
83
|
elementId: string;
|
|
@@ -142,7 +148,8 @@ export declare const passagesForPrompt: (passages: GroundingPassage[]) => {
|
|
|
142
148
|
/**
|
|
143
149
|
* STACKFACTOR references for passages: one per passage, in their order, with no
|
|
144
150
|
* cap. With `tags`, only the passages the model cited by tag (any tag it made
|
|
145
|
-
* up is passed over); without, every passage.
|
|
151
|
+
* up is passed over); without, every passage. Each links to its document's
|
|
152
|
+
* page at the source (`url`) when the passage has one.
|
|
146
153
|
* @param passages From `retrievePassages`
|
|
147
154
|
* @param tags The tags the model cited ("k3", "K3" and " k3 " alike)
|
|
148
155
|
* @returns The references, ready for a skill's, a microskill's or a question's `references`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stackfactorKnowledge.d.ts","sourceRoot":"","sources":["../../src/stackfactorKnowledge.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"stackfactorKnowledge.d.ts","sourceRoot":"","sources":["../../src/stackfactorKnowledge.ts"],"names":[],"mappings":"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"}
|