@lloyal-labs/rig 1.2.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/README.md +188 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +36 -0
- package/dist/index.js.map +1 -0
- package/dist/reranker.d.ts +22 -0
- package/dist/reranker.d.ts.map +1 -0
- package/dist/reranker.js +76 -0
- package/dist/reranker.js.map +1 -0
- package/dist/resources/files.d.ts +28 -0
- package/dist/resources/files.d.ts.map +1 -0
- package/dist/resources/files.js +98 -0
- package/dist/resources/files.js.map +1 -0
- package/dist/resources/index.d.ts +9 -0
- package/dist/resources/index.d.ts.map +1 -0
- package/dist/resources/index.js +13 -0
- package/dist/resources/index.js.map +1 -0
- package/dist/resources/types.d.ts +39 -0
- package/dist/resources/types.d.ts.map +1 -0
- package/dist/resources/types.js +3 -0
- package/dist/resources/types.js.map +1 -0
- package/dist/sources/corpus-research.md +14 -0
- package/dist/sources/corpus.d.ts +48 -0
- package/dist/sources/corpus.d.ts.map +1 -0
- package/dist/sources/corpus.js +91 -0
- package/dist/sources/corpus.js.map +1 -0
- package/dist/sources/extract.md +5 -0
- package/dist/sources/index.d.ts +10 -0
- package/dist/sources/index.d.ts.map +1 -0
- package/dist/sources/index.js +14 -0
- package/dist/sources/index.js.map +1 -0
- package/dist/sources/search-extract.md +6 -0
- package/dist/sources/types.d.ts +28 -0
- package/dist/sources/types.d.ts.map +1 -0
- package/dist/sources/types.js +3 -0
- package/dist/sources/types.js.map +1 -0
- package/dist/sources/web-research.md +12 -0
- package/dist/sources/web.d.ts +78 -0
- package/dist/sources/web.d.ts.map +1 -0
- package/dist/sources/web.js +319 -0
- package/dist/sources/web.js.map +1 -0
- package/dist/tools/fetch-page.d.ts +26 -0
- package/dist/tools/fetch-page.d.ts.map +1 -0
- package/dist/tools/fetch-page.js +72 -0
- package/dist/tools/fetch-page.js.map +1 -0
- package/dist/tools/grep.d.ts +30 -0
- package/dist/tools/grep.d.ts.map +1 -0
- package/dist/tools/grep.js +79 -0
- package/dist/tools/grep.js.map +1 -0
- package/dist/tools/index.d.ts +39 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +49 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/plan.d.ts +76 -0
- package/dist/tools/plan.d.ts.map +1 -0
- package/dist/tools/plan.js +98 -0
- package/dist/tools/plan.js.map +1 -0
- package/dist/tools/read-file.d.ts +62 -0
- package/dist/tools/read-file.d.ts.map +1 -0
- package/dist/tools/read-file.js +123 -0
- package/dist/tools/read-file.js.map +1 -0
- package/dist/tools/report.d.ts +22 -0
- package/dist/tools/report.d.ts.map +1 -0
- package/dist/tools/report.js +26 -0
- package/dist/tools/report.js.map +1 -0
- package/dist/tools/research.d.ts +57 -0
- package/dist/tools/research.d.ts.map +1 -0
- package/dist/tools/research.js +117 -0
- package/dist/tools/research.js.map +1 -0
- package/dist/tools/search.d.ts +34 -0
- package/dist/tools/search.d.ts.map +1 -0
- package/dist/tools/search.js +69 -0
- package/dist/tools/search.js.map +1 -0
- package/dist/tools/types.d.ts +84 -0
- package/dist/tools/types.d.ts.map +1 -0
- package/dist/tools/types.js +3 -0
- package/dist/tools/types.js.map +1 -0
- package/dist/tools/web-research.d.ts +60 -0
- package/dist/tools/web-research.d.ts.map +1 -0
- package/dist/tools/web-research.js +136 -0
- package/dist/tools/web-research.js.map +1 -0
- package/dist/tools/web-search.d.ts +42 -0
- package/dist/tools/web-search.d.ts.map +1 -0
- package/dist/tools/web-search.js +83 -0
- package/dist/tools/web-search.js.map +1 -0
- package/package.json +45 -0
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ReadFileTool = void 0;
|
|
4
|
+
exports.subtractRanges = subtractRanges;
|
|
5
|
+
exports.mergeRanges = mergeRanges;
|
|
6
|
+
const lloyal_agents_1 = require("@lloyal-labs/lloyal-agents");
|
|
7
|
+
/**
|
|
8
|
+
* Subtract previously-covered ranges from a target range
|
|
9
|
+
*
|
|
10
|
+
* Given a target half-open interval `[s, e)` and an array of
|
|
11
|
+
* already-covered intervals, returns the sub-ranges of `[s, e)`
|
|
12
|
+
* that have not yet been covered. Used by {@link ReadFileTool}
|
|
13
|
+
* to avoid re-reading lines the agent has already seen.
|
|
14
|
+
*
|
|
15
|
+
* @param range - Target range `[start, end)` (0-indexed)
|
|
16
|
+
* @param covered - Array of previously-covered `[start, end)` ranges
|
|
17
|
+
* @returns Uncovered sub-ranges of the target
|
|
18
|
+
*
|
|
19
|
+
* @category Rig
|
|
20
|
+
*/
|
|
21
|
+
function subtractRanges([s, e], covered) {
|
|
22
|
+
let ranges = [[s, e]];
|
|
23
|
+
for (const [cs, ce] of covered) {
|
|
24
|
+
ranges = ranges.flatMap(([a, b]) => {
|
|
25
|
+
if (ce <= a || cs >= b)
|
|
26
|
+
return [[a, b]];
|
|
27
|
+
const result = [];
|
|
28
|
+
if (a < cs)
|
|
29
|
+
result.push([a, cs]);
|
|
30
|
+
if (ce < b)
|
|
31
|
+
result.push([ce, b]);
|
|
32
|
+
return result;
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
return ranges;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Merge overlapping or adjacent half-open ranges into a minimal set
|
|
39
|
+
*
|
|
40
|
+
* Sorts the input ranges by start position, then collapses any
|
|
41
|
+
* overlapping or touching intervals. Used by {@link ReadFileTool}
|
|
42
|
+
* to maintain a compact record of lines already read per agent.
|
|
43
|
+
*
|
|
44
|
+
* @param ranges - Array of `[start, end)` ranges to merge
|
|
45
|
+
* @returns Merged non-overlapping ranges sorted by start
|
|
46
|
+
*
|
|
47
|
+
* @category Rig
|
|
48
|
+
*/
|
|
49
|
+
function mergeRanges(ranges) {
|
|
50
|
+
if (ranges.length === 0)
|
|
51
|
+
return [];
|
|
52
|
+
const sorted = [...ranges].sort((a, b) => a[0] - b[0]);
|
|
53
|
+
const merged = [sorted[0]];
|
|
54
|
+
for (let i = 1; i < sorted.length; i++) {
|
|
55
|
+
const last = merged[merged.length - 1];
|
|
56
|
+
if (sorted[i][0] <= last[1]) {
|
|
57
|
+
last[1] = Math.max(last[1], sorted[i][1]);
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
merged.push(sorted[i]);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return merged;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Read content from corpus files by line range
|
|
67
|
+
*
|
|
68
|
+
* Tracks which lines each agent has already read and returns only
|
|
69
|
+
* the unread portions, preventing redundant context inflation.
|
|
70
|
+
* Line ranges typically come from {@link SearchTool} results.
|
|
71
|
+
*
|
|
72
|
+
* Uses {@link subtractRanges} and {@link mergeRanges} internally
|
|
73
|
+
* to maintain per-agent read tracking keyed by `agentId:filename`.
|
|
74
|
+
*
|
|
75
|
+
* @category Rig
|
|
76
|
+
*/
|
|
77
|
+
class ReadFileTool extends lloyal_agents_1.Tool {
|
|
78
|
+
name = 'read_file';
|
|
79
|
+
description = 'Read content from a file at specific line ranges. Use startLine/endLine from search results.';
|
|
80
|
+
parameters;
|
|
81
|
+
_resources;
|
|
82
|
+
_readRanges = new Map();
|
|
83
|
+
constructor(resources) {
|
|
84
|
+
super();
|
|
85
|
+
this._resources = resources;
|
|
86
|
+
this.parameters = {
|
|
87
|
+
type: 'object',
|
|
88
|
+
properties: {
|
|
89
|
+
filename: {
|
|
90
|
+
type: 'string',
|
|
91
|
+
description: 'Filename from search results',
|
|
92
|
+
enum: resources.map(r => r.name),
|
|
93
|
+
},
|
|
94
|
+
startLine: { type: 'number', description: 'Start line (1-indexed, from search results)' },
|
|
95
|
+
endLine: { type: 'number', description: 'End line (1-indexed, from search results)' },
|
|
96
|
+
},
|
|
97
|
+
required: ['filename'],
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
*execute(args, context) {
|
|
101
|
+
const filename = args.filename || args.path || '';
|
|
102
|
+
const file = this._resources.find(r => r.name === filename);
|
|
103
|
+
if (!file) {
|
|
104
|
+
return { error: `File not found: ${filename}. Available: ${this._resources.map(r => r.name).join(', ')}` };
|
|
105
|
+
}
|
|
106
|
+
const lines = file.content.split('\n');
|
|
107
|
+
const s = Math.max(0, (args.startLine ?? 1) - 1);
|
|
108
|
+
const e = Math.min(lines.length, args.endLine ?? Math.min(100, lines.length));
|
|
109
|
+
const key = context ? `${context.agentId}:${filename}` : filename;
|
|
110
|
+
const prev = this._readRanges.get(key) ?? [];
|
|
111
|
+
const unread = subtractRanges([s, e], prev);
|
|
112
|
+
if (unread.length === 0) {
|
|
113
|
+
return { file: file.name, note: `Lines ${s + 1}-${e} already read` };
|
|
114
|
+
}
|
|
115
|
+
this._readRanges.set(key, mergeRanges([...prev, [s, e]]));
|
|
116
|
+
const content = unread
|
|
117
|
+
.map(([a, b]) => lines.slice(a, b).join('\n'))
|
|
118
|
+
.join('\n...\n');
|
|
119
|
+
return { file: file.name, content, lines: unread.map(([a, b]) => `${a + 1}-${b}`) };
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
exports.ReadFileTool = ReadFileTool;
|
|
123
|
+
//# sourceMappingURL=read-file.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"read-file.js","sourceRoot":"","sources":["../../src/tools/read-file.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { Operation } from 'effection';
|
|
2
|
+
import { Tool } from '@lloyal-labs/lloyal-agents';
|
|
3
|
+
import type { JsonSchema } from '@lloyal-labs/lloyal-agents';
|
|
4
|
+
/**
|
|
5
|
+
* Terminal tool for submitting research findings
|
|
6
|
+
*
|
|
7
|
+
* Used as the `terminalTool` in agent pools -- when an agent calls
|
|
8
|
+
* this tool, the pool records the findings string and marks the
|
|
9
|
+
* agent as finished. The tool itself is a no-op; the agent pool
|
|
10
|
+
* intercepts the call and extracts the `findings` argument.
|
|
11
|
+
*
|
|
12
|
+
* @category Rig
|
|
13
|
+
*/
|
|
14
|
+
export declare class ReportTool extends Tool<{
|
|
15
|
+
findings: string;
|
|
16
|
+
}> {
|
|
17
|
+
readonly name = "report";
|
|
18
|
+
readonly description = "Submit your final research findings. Call this when you have gathered enough information to answer the question.";
|
|
19
|
+
readonly parameters: JsonSchema;
|
|
20
|
+
execute(): Operation<unknown>;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=report.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../../src/tools/report.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,IAAI,EAAE,MAAM,4BAA4B,CAAC;AAClD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAE7D;;;;;;;;;GASG;AACH,qBAAa,UAAW,SAAQ,IAAI,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC;IACxD,QAAQ,CAAC,IAAI,YAAY;IACzB,QAAQ,CAAC,WAAW,sHAAsH;IAC1I,QAAQ,CAAC,UAAU,EAAE,UAAU,CAI7B;IAED,OAAO,IAAI,SAAS,CAAC,OAAO,CAAC;CAC/B"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ReportTool = void 0;
|
|
4
|
+
const lloyal_agents_1 = require("@lloyal-labs/lloyal-agents");
|
|
5
|
+
/**
|
|
6
|
+
* Terminal tool for submitting research findings
|
|
7
|
+
*
|
|
8
|
+
* Used as the `terminalTool` in agent pools -- when an agent calls
|
|
9
|
+
* this tool, the pool records the findings string and marks the
|
|
10
|
+
* agent as finished. The tool itself is a no-op; the agent pool
|
|
11
|
+
* intercepts the call and extracts the `findings` argument.
|
|
12
|
+
*
|
|
13
|
+
* @category Rig
|
|
14
|
+
*/
|
|
15
|
+
class ReportTool extends lloyal_agents_1.Tool {
|
|
16
|
+
name = 'report';
|
|
17
|
+
description = 'Submit your final research findings. Call this when you have gathered enough information to answer the question.';
|
|
18
|
+
parameters = {
|
|
19
|
+
type: 'object',
|
|
20
|
+
properties: { findings: { type: 'string', description: 'Your research findings and answer' } },
|
|
21
|
+
required: ['findings'],
|
|
22
|
+
};
|
|
23
|
+
*execute() { return {}; }
|
|
24
|
+
}
|
|
25
|
+
exports.ReportTool = ReportTool;
|
|
26
|
+
//# sourceMappingURL=report.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"report.js","sourceRoot":"","sources":["../../src/tools/report.ts"],"names":[],"mappings":";;;AACA,8DAAkD;AAGlD;;;;;;;;;GASG;AACH,MAAa,UAAW,SAAQ,oBAA0B;IAC/C,IAAI,GAAG,QAAQ,CAAC;IAChB,WAAW,GAAG,kHAAkH,CAAC;IACjI,UAAU,GAAe;QAChC,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE,EAAE,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,mCAAmC,EAAE,EAAE;QAC9F,QAAQ,EAAE,CAAC,UAAU,CAAC;KACvB,CAAC;IAEF,CAAC,OAAO,KAAyB,OAAO,EAAE,CAAC,CAAC,CAAC;CAC9C;AAVD,gCAUC"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import type { Operation } from 'effection';
|
|
2
|
+
import { Tool } from '@lloyal-labs/lloyal-agents';
|
|
3
|
+
import type { JsonSchema, Toolkit, PressureThresholds } from '@lloyal-labs/lloyal-agents';
|
|
4
|
+
/**
|
|
5
|
+
* Configuration for {@link ResearchTool}
|
|
6
|
+
*
|
|
7
|
+
* @category Rig
|
|
8
|
+
*/
|
|
9
|
+
export interface ResearchToolOpts {
|
|
10
|
+
/** System prompt for each spawned research agent */
|
|
11
|
+
systemPrompt: string;
|
|
12
|
+
/** Prompt pair used to extract findings from hard-cut agents */
|
|
13
|
+
reporterPrompt: {
|
|
14
|
+
system: string;
|
|
15
|
+
user: string;
|
|
16
|
+
};
|
|
17
|
+
/** Maximum tool-use turns per research agent (default: 20) */
|
|
18
|
+
maxTurns?: number;
|
|
19
|
+
/** Enable trace logging for sub-agent pools */
|
|
20
|
+
trace?: boolean;
|
|
21
|
+
/** Context pressure thresholds for sub-agent pools */
|
|
22
|
+
pressure?: PressureThresholds;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Spawn parallel research agents for sub-questions (corpus source)
|
|
26
|
+
*
|
|
27
|
+
* Creates a {@link withSharedRoot | shared root} and runs a
|
|
28
|
+
* {@link useAgentPool | pool} of research agents, one per question.
|
|
29
|
+
* Each agent has access to the full toolkit (search, read_file,
|
|
30
|
+
* grep, report). Agents that hit the turn limit without reporting
|
|
31
|
+
* are forced through a reporter pass that extracts partial findings.
|
|
32
|
+
*
|
|
33
|
+
* Call {@link ResearchTool.setToolkit | setToolkit()} before first
|
|
34
|
+
* execution to wire the toolkit into the sub-agent pool.
|
|
35
|
+
*
|
|
36
|
+
* @category Rig
|
|
37
|
+
*/
|
|
38
|
+
export declare class ResearchTool extends Tool<{
|
|
39
|
+
questions: string[];
|
|
40
|
+
}> {
|
|
41
|
+
readonly name = "research";
|
|
42
|
+
readonly description = "Spawn parallel research agents to investigate sub-questions. Each question gets its own agent.";
|
|
43
|
+
readonly parameters: JsonSchema;
|
|
44
|
+
private _systemPrompt;
|
|
45
|
+
private _reporterPrompt;
|
|
46
|
+
private _maxTurns;
|
|
47
|
+
private _trace;
|
|
48
|
+
private _pressure?;
|
|
49
|
+
private _toolkit;
|
|
50
|
+
constructor(opts: ResearchToolOpts);
|
|
51
|
+
/** Inject the toolkit that sub-agents will use. Must be called before execute. */
|
|
52
|
+
setToolkit(toolkit: Toolkit): void;
|
|
53
|
+
execute(args: {
|
|
54
|
+
questions: string[];
|
|
55
|
+
}): Operation<unknown>;
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=research.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"research.d.ts","sourceRoot":"","sources":["../../src/tools/research.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,IAAI,EAA8D,MAAM,4BAA4B,CAAC;AAC9G,OAAO,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAE1F;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC/B,oDAAoD;IACpD,YAAY,EAAE,MAAM,CAAC;IACrB,gEAAgE;IAChE,cAAc,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IACjD,8DAA8D;IAC9D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,+CAA+C;IAC/C,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,sDAAsD;IACtD,QAAQ,CAAC,EAAE,kBAAkB,CAAC;CAC/B;AAED;;;;;;;;;;;;;GAaG;AACH,qBAAa,YAAa,SAAQ,IAAI,CAAC;IAAE,SAAS,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC;IAC7D,QAAQ,CAAC,IAAI,cAAc;IAC3B,QAAQ,CAAC,WAAW,oGAAoG;IACxH,QAAQ,CAAC,UAAU,EAAE,UAAU,CAU7B;IAEF,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,eAAe,CAAmC;IAC1D,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,MAAM,CAAU;IACxB,OAAO,CAAC,SAAS,CAAC,CAAqB;IACvC,OAAO,CAAC,QAAQ,CAAwB;gBAE5B,IAAI,EAAE,gBAAgB;IASlC,kFAAkF;IAClF,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAIjC,OAAO,CAAC,IAAI,EAAE;QAAE,SAAS,EAAE,MAAM,EAAE,CAAA;KAAE,GAAG,SAAS,CAAC,OAAO,CAAC;CAoE5D"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ResearchTool = void 0;
|
|
4
|
+
const lloyal_agents_1 = require("@lloyal-labs/lloyal-agents");
|
|
5
|
+
/**
|
|
6
|
+
* Spawn parallel research agents for sub-questions (corpus source)
|
|
7
|
+
*
|
|
8
|
+
* Creates a {@link withSharedRoot | shared root} and runs a
|
|
9
|
+
* {@link useAgentPool | pool} of research agents, one per question.
|
|
10
|
+
* Each agent has access to the full toolkit (search, read_file,
|
|
11
|
+
* grep, report). Agents that hit the turn limit without reporting
|
|
12
|
+
* are forced through a reporter pass that extracts partial findings.
|
|
13
|
+
*
|
|
14
|
+
* Call {@link ResearchTool.setToolkit | setToolkit()} before first
|
|
15
|
+
* execution to wire the toolkit into the sub-agent pool.
|
|
16
|
+
*
|
|
17
|
+
* @category Rig
|
|
18
|
+
*/
|
|
19
|
+
class ResearchTool extends lloyal_agents_1.Tool {
|
|
20
|
+
name = 'research';
|
|
21
|
+
description = 'Spawn parallel research agents to investigate sub-questions. Each question gets its own agent.';
|
|
22
|
+
parameters = {
|
|
23
|
+
type: 'object',
|
|
24
|
+
properties: {
|
|
25
|
+
questions: {
|
|
26
|
+
type: 'array',
|
|
27
|
+
items: { type: 'string' },
|
|
28
|
+
description: 'Sub-questions to research in parallel',
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
required: ['questions'],
|
|
32
|
+
};
|
|
33
|
+
_systemPrompt;
|
|
34
|
+
_reporterPrompt;
|
|
35
|
+
_maxTurns;
|
|
36
|
+
_trace;
|
|
37
|
+
_pressure;
|
|
38
|
+
_toolkit = null;
|
|
39
|
+
constructor(opts) {
|
|
40
|
+
super();
|
|
41
|
+
this._systemPrompt = opts.systemPrompt;
|
|
42
|
+
this._reporterPrompt = opts.reporterPrompt;
|
|
43
|
+
this._maxTurns = opts.maxTurns ?? 20;
|
|
44
|
+
this._trace = opts.trace ?? false;
|
|
45
|
+
this._pressure = opts.pressure;
|
|
46
|
+
}
|
|
47
|
+
/** Inject the toolkit that sub-agents will use. Must be called before execute. */
|
|
48
|
+
setToolkit(toolkit) {
|
|
49
|
+
this._toolkit = toolkit;
|
|
50
|
+
}
|
|
51
|
+
*execute(args) {
|
|
52
|
+
const questions = args?.questions;
|
|
53
|
+
if (!Array.isArray(questions) || questions.length === 0) {
|
|
54
|
+
return { error: 'questions must be a non-empty array of strings', example: '{"questions": ["q1", "q2"]}' };
|
|
55
|
+
}
|
|
56
|
+
if (!this._toolkit)
|
|
57
|
+
throw new Error('ResearchTool: setToolkit() must be called before execute');
|
|
58
|
+
const tw = yield* lloyal_agents_1.Trace.expect();
|
|
59
|
+
const scope = (0, lloyal_agents_1.traceScope)(tw, null, 'researchTool', { questionCount: questions.length });
|
|
60
|
+
const toolkit = this._toolkit;
|
|
61
|
+
const systemPrompt = this._systemPrompt;
|
|
62
|
+
const reporterPrompt = this._reporterPrompt;
|
|
63
|
+
const maxTurns = this._maxTurns;
|
|
64
|
+
const trace = this._trace;
|
|
65
|
+
const pressure = this._pressure;
|
|
66
|
+
return yield* (0, lloyal_agents_1.withSharedRoot)({ systemPrompt, tools: toolkit.toolsJson }, function* (root) {
|
|
67
|
+
const pool = yield* (0, lloyal_agents_1.useAgentPool)({
|
|
68
|
+
tasks: questions.map(q => ({
|
|
69
|
+
systemPrompt,
|
|
70
|
+
content: q,
|
|
71
|
+
tools: toolkit.toolsJson,
|
|
72
|
+
parent: root,
|
|
73
|
+
})),
|
|
74
|
+
tools: toolkit.toolMap,
|
|
75
|
+
terminalTool: 'report',
|
|
76
|
+
maxTurns,
|
|
77
|
+
trace,
|
|
78
|
+
pressure,
|
|
79
|
+
});
|
|
80
|
+
// Force hard-cut agents to report — same pattern as prior harness reportPass
|
|
81
|
+
const hardCut = pool.agents.filter(a => !a.findings && !a.branch.disposed);
|
|
82
|
+
if (hardCut.length > 0) {
|
|
83
|
+
for (const a of pool.agents) {
|
|
84
|
+
if (a.findings && !a.branch.disposed)
|
|
85
|
+
a.branch.pruneSync();
|
|
86
|
+
}
|
|
87
|
+
const reportTool = toolkit.toolMap.get('report');
|
|
88
|
+
const reporters = yield* (0, lloyal_agents_1.runAgents)({
|
|
89
|
+
tasks: hardCut.map(a => ({
|
|
90
|
+
systemPrompt: reporterPrompt.system,
|
|
91
|
+
content: reporterPrompt.user,
|
|
92
|
+
tools: JSON.stringify([reportTool.schema]),
|
|
93
|
+
parent: a.branch,
|
|
94
|
+
})),
|
|
95
|
+
tools: new Map([['report', reportTool]]),
|
|
96
|
+
terminalTool: 'report',
|
|
97
|
+
trace,
|
|
98
|
+
pressure: { softLimit: 200, hardLimit: 64 },
|
|
99
|
+
});
|
|
100
|
+
hardCut.forEach((a, i) => {
|
|
101
|
+
if (reporters.agents[i]?.findings)
|
|
102
|
+
a.findings = reporters.agents[i].findings;
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
const result = {
|
|
106
|
+
findings: pool.agents.map(a => a.findings).filter(Boolean),
|
|
107
|
+
agentCount: pool.agents.length,
|
|
108
|
+
totalTokens: pool.totalTokens,
|
|
109
|
+
totalToolCalls: pool.totalToolCalls,
|
|
110
|
+
};
|
|
111
|
+
scope.close();
|
|
112
|
+
return result;
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
exports.ResearchTool = ResearchTool;
|
|
117
|
+
//# sourceMappingURL=research.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"research.js","sourceRoot":"","sources":["../../src/tools/research.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { Operation } from 'effection';
|
|
2
|
+
import { Tool } from '@lloyal-labs/lloyal-agents';
|
|
3
|
+
import type { JsonSchema, ToolContext } from '@lloyal-labs/lloyal-agents';
|
|
4
|
+
import type { Chunk } from '../resources/types';
|
|
5
|
+
import type { Reranker } from './types';
|
|
6
|
+
/**
|
|
7
|
+
* Semantic search over corpus chunks via a {@link Reranker}
|
|
8
|
+
*
|
|
9
|
+
* Scores all chunks against the query and returns ranked results
|
|
10
|
+
* with file names, headings, scores, and line ranges. Progress is
|
|
11
|
+
* reported through the optional {@link ToolContext.onProgress}
|
|
12
|
+
* callback as the reranker streams intermediate results.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```typescript
|
|
16
|
+
* const search = new SearchTool(chunks, reranker);
|
|
17
|
+
* ```
|
|
18
|
+
*
|
|
19
|
+
* @category Rig
|
|
20
|
+
*/
|
|
21
|
+
export declare class SearchTool extends Tool<{
|
|
22
|
+
query: string;
|
|
23
|
+
}> {
|
|
24
|
+
readonly name = "search";
|
|
25
|
+
readonly description = "Search the knowledge base. Returns sections ranked by relevance with line ranges for read_file.";
|
|
26
|
+
readonly parameters: JsonSchema;
|
|
27
|
+
private _chunks;
|
|
28
|
+
private _reranker;
|
|
29
|
+
constructor(chunks: Chunk[], reranker: Reranker);
|
|
30
|
+
execute(args: {
|
|
31
|
+
query: string;
|
|
32
|
+
}, context?: ToolContext): Operation<unknown>;
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=search.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../src/tools/search.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,IAAI,EAAS,MAAM,4BAA4B,CAAC;AACzD,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAC1E,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,KAAK,EAAE,QAAQ,EAAe,MAAM,SAAS,CAAC;AAErD;;;;;;;;;;;;;;GAcG;AACH,qBAAa,UAAW,SAAQ,IAAI,CAAC;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;IACrD,QAAQ,CAAC,IAAI,YAAY;IACzB,QAAQ,CAAC,WAAW,qGAAqG;IACzH,QAAQ,CAAC,UAAU,EAAE,UAAU,CAI7B;IAEF,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,SAAS,CAAW;gBAEhB,MAAM,EAAE,KAAK,EAAE,EAAE,QAAQ,EAAE,QAAQ;IAM9C,OAAO,CAAC,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC,OAAO,CAAC;CAiC7E"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SearchTool = void 0;
|
|
4
|
+
const effection_1 = require("effection");
|
|
5
|
+
const lloyal_agents_1 = require("@lloyal-labs/lloyal-agents");
|
|
6
|
+
/**
|
|
7
|
+
* Semantic search over corpus chunks via a {@link Reranker}
|
|
8
|
+
*
|
|
9
|
+
* Scores all chunks against the query and returns ranked results
|
|
10
|
+
* with file names, headings, scores, and line ranges. Progress is
|
|
11
|
+
* reported through the optional {@link ToolContext.onProgress}
|
|
12
|
+
* callback as the reranker streams intermediate results.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```typescript
|
|
16
|
+
* const search = new SearchTool(chunks, reranker);
|
|
17
|
+
* ```
|
|
18
|
+
*
|
|
19
|
+
* @category Rig
|
|
20
|
+
*/
|
|
21
|
+
class SearchTool extends lloyal_agents_1.Tool {
|
|
22
|
+
name = 'search';
|
|
23
|
+
description = 'Search the knowledge base. Returns sections ranked by relevance with line ranges for read_file.';
|
|
24
|
+
parameters = {
|
|
25
|
+
type: 'object',
|
|
26
|
+
properties: { query: { type: 'string', description: 'Search query' } },
|
|
27
|
+
required: ['query'],
|
|
28
|
+
};
|
|
29
|
+
_chunks;
|
|
30
|
+
_reranker;
|
|
31
|
+
constructor(chunks, reranker) {
|
|
32
|
+
super();
|
|
33
|
+
this._chunks = chunks;
|
|
34
|
+
this._reranker = reranker;
|
|
35
|
+
}
|
|
36
|
+
*execute(args, context) {
|
|
37
|
+
const query = args.query?.trim();
|
|
38
|
+
if (!query)
|
|
39
|
+
return { error: 'query must not be empty' };
|
|
40
|
+
const tw = yield* lloyal_agents_1.Trace.expect();
|
|
41
|
+
const reranker = this._reranker;
|
|
42
|
+
const chunks = this._chunks;
|
|
43
|
+
const t0 = performance.now();
|
|
44
|
+
tw.write({
|
|
45
|
+
traceId: tw.nextId(), parentTraceId: null, ts: t0,
|
|
46
|
+
type: 'rerank:start', query, chunkCount: chunks.length,
|
|
47
|
+
});
|
|
48
|
+
const results = yield* (0, effection_1.call)(async () => {
|
|
49
|
+
let last = [];
|
|
50
|
+
for await (const { results, filled, total } of reranker.score(query, chunks)) {
|
|
51
|
+
if (context?.onProgress)
|
|
52
|
+
context.onProgress({ filled, total });
|
|
53
|
+
last = results;
|
|
54
|
+
}
|
|
55
|
+
return last;
|
|
56
|
+
});
|
|
57
|
+
tw.write({
|
|
58
|
+
traceId: tw.nextId(), parentTraceId: null, ts: performance.now(),
|
|
59
|
+
type: 'rerank:end',
|
|
60
|
+
topResults: results.slice(0, 5).map(r => ({ file: r.file, heading: r.heading, score: r.score })),
|
|
61
|
+
selectedPassageCount: results.length,
|
|
62
|
+
totalChars: 0,
|
|
63
|
+
durationMs: performance.now() - t0,
|
|
64
|
+
});
|
|
65
|
+
return results;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
exports.SearchTool = SearchTool;
|
|
69
|
+
//# sourceMappingURL=search.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search.js","sourceRoot":"","sources":["../../src/tools/search.ts"],"names":[],"mappings":";;;AAAA,yCAAiC;AAEjC,8DAAyD;AAKzD;;;;;;;;;;;;;;GAcG;AACH,MAAa,UAAW,SAAQ,oBAAuB;IAC5C,IAAI,GAAG,QAAQ,CAAC;IAChB,WAAW,GAAG,iGAAiG,CAAC;IAChH,UAAU,GAAe;QAChC,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,cAAc,EAAE,EAAE;QACtE,QAAQ,EAAE,CAAC,OAAO,CAAC;KACpB,CAAC;IAEM,OAAO,CAAU;IACjB,SAAS,CAAW;IAE5B,YAAY,MAAe,EAAE,QAAkB;QAC7C,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;QACtB,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC;IAC5B,CAAC;IAED,CAAC,OAAO,CAAC,IAAuB,EAAE,OAAqB;QACrD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC;QACjC,IAAI,CAAC,KAAK;YAAE,OAAO,EAAE,KAAK,EAAE,yBAAyB,EAAE,CAAC;QACxD,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,qBAAK,CAAC,MAAM,EAAE,CAAC;QACjC,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC;QAChC,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC;QAE5B,MAAM,EAAE,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;QAC7B,EAAE,CAAC,KAAK,CAAC;YACP,OAAO,EAAE,EAAE,CAAC,MAAM,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE;YACjD,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,CAAC,MAAM;SACvD,CAAC,CAAC;QAEH,MAAM,OAAO,GAAkB,KAAK,CAAC,CAAC,IAAA,gBAAI,EAAC,KAAK,IAAI,EAAE;YACpD,IAAI,IAAI,GAAkB,EAAE,CAAC;YAC7B,IAAI,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,QAAQ,CAAC,KAAK,CAAC,KAAK,EAAE,MAAM,CAAC,EAAE,CAAC;gBAC7E,IAAI,OAAO,EAAE,UAAU;oBAAE,OAAO,CAAC,UAAU,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;gBAC/D,IAAI,GAAG,OAAO,CAAC;YACjB,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,KAAK,CAAC;YACP,OAAO,EAAE,EAAE,CAAC,MAAM,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,EAAE,EAAE,WAAW,CAAC,GAAG,EAAE;YAChE,IAAI,EAAE,YAAY;YAClB,UAAU,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;YAChG,oBAAoB,EAAE,OAAO,CAAC,MAAM;YACpC,UAAU,EAAE,CAAC;YACb,UAAU,EAAE,WAAW,CAAC,GAAG,EAAE,GAAG,EAAE;SACnC,CAAC,CAAC;QAEH,OAAO,OAAO,CAAC;IACjB,CAAC;CACF;AAnDD,gCAmDC"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import type { Chunk } from '../resources/types';
|
|
2
|
+
/**
|
|
3
|
+
* A single chunk scored by the {@link Reranker} against a query
|
|
4
|
+
*
|
|
5
|
+
* Returned as part of {@link ScoredResult} from reranker scoring.
|
|
6
|
+
* Contains the file location, heading, relevance score, and line
|
|
7
|
+
* range so downstream tools (e.g. {@link ReadFileTool}) can fetch
|
|
8
|
+
* the exact content.
|
|
9
|
+
*
|
|
10
|
+
* @category Rig
|
|
11
|
+
*/
|
|
12
|
+
export interface ScoredChunk {
|
|
13
|
+
/** Source filename containing the chunk */
|
|
14
|
+
file: string;
|
|
15
|
+
/** Section heading the chunk belongs to */
|
|
16
|
+
heading: string;
|
|
17
|
+
/** Relevance score (higher = more relevant) */
|
|
18
|
+
score: number;
|
|
19
|
+
/** Start line in the source file (1-indexed) */
|
|
20
|
+
startLine: number;
|
|
21
|
+
/** End line in the source file (1-indexed) */
|
|
22
|
+
endLine: number;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Progressive reranker output emitted during scoring
|
|
26
|
+
*
|
|
27
|
+
* Streamed from {@link Reranker.score} as an async iterable,
|
|
28
|
+
* allowing callers to report progress while scoring is in flight.
|
|
29
|
+
*
|
|
30
|
+
* @category Rig
|
|
31
|
+
*/
|
|
32
|
+
export interface ScoredResult {
|
|
33
|
+
/** Scored chunks accumulated so far, ordered by relevance */
|
|
34
|
+
results: ScoredChunk[];
|
|
35
|
+
/** Number of chunks scored so far */
|
|
36
|
+
filled: number;
|
|
37
|
+
/** Total number of chunks to score */
|
|
38
|
+
total: number;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Embedding-based reranker for scoring corpus chunks against a query
|
|
42
|
+
*
|
|
43
|
+
* Implementations tokenize chunks up front via {@link tokenizeChunks},
|
|
44
|
+
* then stream progressive results from {@link score}. Used by
|
|
45
|
+
* {@link SearchTool} to rank knowledge-base passages.
|
|
46
|
+
*
|
|
47
|
+
* @category Rig
|
|
48
|
+
*/
|
|
49
|
+
export interface Reranker {
|
|
50
|
+
/** Score chunks against a query, streaming progressive results */
|
|
51
|
+
score(query: string, chunks: Chunk[]): AsyncIterable<ScoredResult>;
|
|
52
|
+
/** Pre-tokenize chunks for subsequent scoring calls */
|
|
53
|
+
tokenizeChunks(chunks: Chunk[]): Promise<void>;
|
|
54
|
+
/** Release reranker resources */
|
|
55
|
+
dispose(): void;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* A single result from a {@link SearchProvider} web search
|
|
59
|
+
*
|
|
60
|
+
* @category Rig
|
|
61
|
+
*/
|
|
62
|
+
export interface SearchResult {
|
|
63
|
+
/** Page title */
|
|
64
|
+
title: string;
|
|
65
|
+
/** Page URL */
|
|
66
|
+
url: string;
|
|
67
|
+
/** Excerpt or snippet from the page content */
|
|
68
|
+
snippet: string;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Adapter interface for web search backends
|
|
72
|
+
*
|
|
73
|
+
* Implement this to plug in a search provider (e.g. Tavily, Brave,
|
|
74
|
+
* SerpAPI). Pass the implementation to {@link WebSearchTool}.
|
|
75
|
+
*
|
|
76
|
+
* @see {@link TavilyProvider} for the default implementation
|
|
77
|
+
*
|
|
78
|
+
* @category Rig
|
|
79
|
+
*/
|
|
80
|
+
export interface SearchProvider {
|
|
81
|
+
/** Execute a web search and return ranked results */
|
|
82
|
+
search(query: string, maxResults: number): Promise<SearchResult[]>;
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/tools/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAEhD;;;;;;;;;GASG;AACH,MAAM,WAAW,WAAW;IAC1B,2CAA2C;IAC3C,IAAI,EAAE,MAAM,CAAC;IACb,2CAA2C;IAC3C,OAAO,EAAE,MAAM,CAAC;IAChB,+CAA+C;IAC/C,KAAK,EAAE,MAAM,CAAC;IACd,gDAAgD;IAChD,SAAS,EAAE,MAAM,CAAC;IAClB,8CAA8C;IAC9C,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,YAAY;IAC3B,6DAA6D;IAC7D,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,qCAAqC;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,sCAAsC;IACtC,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,QAAQ;IACvB,kEAAkE;IAClE,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,aAAa,CAAC,YAAY,CAAC,CAAC;IACnE,uDAAuD;IACvD,cAAc,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/C,iCAAiC;IACjC,OAAO,IAAI,IAAI,CAAC;CACjB;AAID;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC3B,iBAAiB;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,eAAe;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,+CAA+C;IAC/C,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,cAAc;IAC7B,qDAAqD;IACrD,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;CACpE"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/tools/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import type { Operation } from "effection";
|
|
2
|
+
import { Tool } from "@lloyal-labs/lloyal-agents";
|
|
3
|
+
import type { JsonSchema, Toolkit, PressureThresholds } from "@lloyal-labs/lloyal-agents";
|
|
4
|
+
/**
|
|
5
|
+
* Configuration for {@link WebResearchTool}.
|
|
6
|
+
*
|
|
7
|
+
* @category Rig
|
|
8
|
+
*/
|
|
9
|
+
export interface WebResearchToolOpts {
|
|
10
|
+
/** Override the tool name exposed to the model. @defaultValue "research" */
|
|
11
|
+
name?: string;
|
|
12
|
+
/** Override the tool description exposed to the model. */
|
|
13
|
+
description?: string;
|
|
14
|
+
/** System prompt given to each spawned web-research sub-agent. */
|
|
15
|
+
systemPrompt: string;
|
|
16
|
+
/** Prompts used for grammar-constrained scratchpad extraction on hard-cut agents. */
|
|
17
|
+
reporterPrompt: {
|
|
18
|
+
system: string;
|
|
19
|
+
user: string;
|
|
20
|
+
};
|
|
21
|
+
/** Maximum tool-use turns per sub-agent before hard cut. @defaultValue 20 */
|
|
22
|
+
maxTurns?: number;
|
|
23
|
+
/** Enable trace output for sub-agent execution. @defaultValue false */
|
|
24
|
+
trace?: boolean;
|
|
25
|
+
/** Context pressure thresholds for the sub-agent pool. */
|
|
26
|
+
pressure?: PressureThresholds;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Spawn parallel web-research sub-agents for a set of questions.
|
|
30
|
+
*
|
|
31
|
+
* Similar to {@link ResearchTool} but designed for web-source pipelines.
|
|
32
|
+
* Each question gets its own agent in a shared-root pool with access
|
|
33
|
+
* to web_search, fetch_page, and report tools. Hard-cut agents that
|
|
34
|
+
* exhaust their turns without reporting get a grammar-constrained
|
|
35
|
+
* scratchpad extraction via {@link generate} to recover partial findings.
|
|
36
|
+
*
|
|
37
|
+
* Must call {@link setToolkit} before the tool is executed.
|
|
38
|
+
*
|
|
39
|
+
* @category Rig
|
|
40
|
+
*/
|
|
41
|
+
export declare class WebResearchTool extends Tool<{
|
|
42
|
+
questions: string[];
|
|
43
|
+
}> {
|
|
44
|
+
readonly name: string;
|
|
45
|
+
readonly description: string;
|
|
46
|
+
readonly parameters: JsonSchema;
|
|
47
|
+
private _systemPrompt;
|
|
48
|
+
private _reporterPrompt;
|
|
49
|
+
private _maxTurns;
|
|
50
|
+
private _trace;
|
|
51
|
+
private _pressure?;
|
|
52
|
+
private _toolkit;
|
|
53
|
+
constructor(opts: WebResearchToolOpts);
|
|
54
|
+
/** Inject the toolkit that sub-agents will use. Must be called before execute. */
|
|
55
|
+
setToolkit(toolkit: Toolkit): void;
|
|
56
|
+
execute(args: {
|
|
57
|
+
questions: string[];
|
|
58
|
+
}): Operation<unknown>;
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=web-research.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"web-research.d.ts","sourceRoot":"","sources":["../../src/tools/web-research.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EACL,IAAI,EAOL,MAAM,4BAA4B,CAAC;AACpC,OAAO,KAAK,EACV,UAAU,EACV,OAAO,EACP,kBAAkB,EACnB,MAAM,4BAA4B,CAAC;AAEpC;;;;GAIG;AACH,MAAM,WAAW,mBAAmB;IAClC,4EAA4E;IAC5E,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,0DAA0D;IAC1D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kEAAkE;IAClE,YAAY,EAAE,MAAM,CAAC;IACrB,qFAAqF;IACrF,cAAc,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IACjD,6EAA6E;IAC7E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,uEAAuE;IACvE,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,0DAA0D;IAC1D,QAAQ,CAAC,EAAE,kBAAkB,CAAC;CAC/B;AAED;;;;;;;;;;;;GAYG;AACH,qBAAa,eAAgB,SAAQ,IAAI,CAAC;IAAE,SAAS,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC;IAChE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,UAAU,EAAE,UAAU,CAU7B;IAEF,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,eAAe,CAAmC;IAC1D,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,MAAM,CAAU;IACxB,OAAO,CAAC,SAAS,CAAC,CAAqB;IACvC,OAAO,CAAC,QAAQ,CAAwB;gBAE5B,IAAI,EAAE,mBAAmB;IAarC,kFAAkF;IAClF,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAIjC,OAAO,CAAC,IAAI,EAAE;QAAE,SAAS,EAAE,MAAM,EAAE,CAAA;KAAE,GAAG,SAAS,CAAC,OAAO,CAAC;CA2F5D"}
|