7a0d4d0ee2
Makes the research feature runnable end-to-end, off by default. - config: [tools.research] (enabled, searxng_url, max_results, max_fetch_bytes). - registration: web_search/web_fetch are built into BOTH the default and per-workspace tool registries when research.enabled, sharing one HTTP client threaded from Main (none built on the static path). Egress stays harness-enforced: web_fetch is T2 (operator-approved) and the existing NetworkHostRule still applies. - workflow: examples/workflows/research.toml — decompose → gather → report, with the three artifact schemas and prompts. Fan-out (search per sub-question, fetch per source) runs as repeated tool calls inside the gather stage (Correx has no parallel agents); per-source synthesis into the dossier is the compression step, so the report stage consumes summaries, never raw pages. ResearchWorkflowTest validates the graph contract. To run: set [tools.research].enabled, register the 3 [[artifacts]], copy research.toml + prompts + schemas into the workflows dir, start SearXNG. Launch like any workflow (the T2 fetch approval surfaces as an approval card; the report opens in the artifact viewer). Follow-ups (noted, not blocking): batch fetch-approval at the source-list level (§3), a dedicated SourceFetched/LowQualityExtraction event (quality + content hash are already in tool-result metadata), dynamic per-session egress allowlist, and the web approval client (§6).
30 lines
1.0 KiB
JSON
30 lines
1.0 KiB
JSON
{
|
|
"type": "object",
|
|
"properties": {
|
|
"sources": {
|
|
"type": "array",
|
|
"description": "one entry per fetched source — each summarized on its own (per-source synthesis). This is the compression step: raw page text must never be copied here, only what the source contributes.",
|
|
"minItems": 1,
|
|
"items": {
|
|
"type": "object",
|
|
"properties": {
|
|
"url": { "type": "string", "description": "the fetched source URL (a citation handle)" },
|
|
"title": { "type": "string" },
|
|
"summary": {
|
|
"type": "string",
|
|
"description": "what this source contributes to the question, in your own words — not a copy of the page"
|
|
},
|
|
"relevance": {
|
|
"type": "string",
|
|
"description": "which sub-question(s) this source bears on, and how strongly"
|
|
}
|
|
},
|
|
"required": ["url", "summary"],
|
|
"additionalProperties": true
|
|
}
|
|
}
|
|
},
|
|
"required": ["sources"],
|
|
"additionalProperties": true
|
|
}
|