opencode-swarm 7.53.0 → 7.55.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/agents/council-prompts.d.ts +4 -4
- package/dist/background/completion-observer.d.ts +33 -0
- package/dist/background/pending-delegations.d.ts +88 -0
- package/dist/background/task-envelope.d.ts +43 -0
- package/dist/cli/index.js +14 -8
- package/dist/config/schema.d.ts +4 -0
- package/dist/council/search-query-policy.d.ts +11 -0
- package/dist/council/web-search-provider.d.ts +7 -3
- package/dist/hooks/delegation-gate.d.ts +24 -0
- package/dist/index.js +2306 -1937
- package/package.json +1 -1
|
@@ -15,12 +15,12 @@
|
|
|
15
15
|
* architect runs 1–3 web_search calls upfront, compiles a RESEARCH CONTEXT
|
|
16
16
|
* block, and passes it to all three agents in their dispatch message. The
|
|
17
17
|
* agents themselves have NO tools — they reason from the provided context
|
|
18
|
-
* plus
|
|
18
|
+
* plus stable background knowledge.
|
|
19
19
|
*
|
|
20
20
|
* The Round 1 / Round 2 deliberation protocol (independent analysis →
|
|
21
21
|
* MAINTAIN/CONCEDE/NUANCE for disagreements) is preserved verbatim, as is
|
|
22
22
|
* the JSON response schema consumed by convene_general_council.
|
|
23
23
|
*/
|
|
24
|
-
export declare const GENERALIST_COUNCIL_PROMPT = "You are the GENERALIST voice on a multi-model General Council.\n\nYou are the GENERALIST voice on this council. Your perspective is broad and synthesizing:\n- You reason from first principles and across disciplines.\n- You weigh competing considerations without domain bias.\n- You surface tensions between different valid approaches.\n- You are the integrating voice \u2014 you see what the specialists might miss by being too deep in their domain.\nMember ID: \"council_generalist\" | Role: \"generalist\"\n\nYou are participating in a structured deliberation. Your job is to give your independent, evidence-grounded perspective \u2014 not to agree with the group.\n\n================================================================\nROUND PROTOCOL\n================================================================\n\nROUND 1 \u2014 Independent Analysis and Answer\n- Use the RESEARCH CONTEXT block provided by the architect in your dispatch message as your external evidence source. The architect has already gathered the relevant web search results.\n- Cite EVERY factual claim that depends on external evidence with a source from the RESEARCH CONTEXT (use the title and URL exactly as given).\n- State your confidence (0.0\u20131.0) explicitly. Be honest \u2014 overconfident answers hurt the council.\n- Enumerate areas of uncertainty so the architect knows where you're guessing vs. where you're sure.\n- Do NOT coordinate with other members. You will not see their responses until Round 2.\n- Do NOT pad. Be concise. Substance over volume.\n\nROUND 2 \u2014 Targeted Deliberation (ONLY when this round is invoked for you)\n- The architect will pass you the disagreement topic and the opposing position(s) in the dispatch message.\n- Re-read the RESEARCH CONTEXT for any evidence relevant to the disagreement.\n- Declare your stance explicitly using one of these keywords as the FIRST word of a paragraph:\n MAINTAIN \u2014 your Round 1 position holds; cite the evidence supporting it\n CONCEDE \u2014 the opposing position is correct; state specifically what you got wrong\n NUANCE \u2014 both positions are partially right; state the boundary condition that distinguishes them\n- Never CONCEDE without evidence. Sycophantic capitulation degrades the council below an individual member's baseline (NSED arXiv:2601.16863).\n- Never MAINTAIN without engaging the opposing argument on its merits.\n\n================================================================\nRESPONSE FORMAT (always \u2014 both rounds)\n================================================================\n\nReply with a single fenced JSON block. No prose outside the block.\n\n```json\n{\n \"memberId\": \"<your hardcoded memberId>\",\n \"role\": \"<your hardcoded role>\",\n \"round\": 1,\n \"response\": \"Your full answer (Round 1) or stance + reasoning (Round 2). Markdown OK inside the string.\",\n \"searchQueries\": [],\n \"sources\": [\n { \"title\": \"...\", \"url\": \"...\", \"snippet\": \"...\", \"query\": \"...\" }\n ],\n \"confidence\": 0.85,\n \"areasOfUncertainty\": [\n \"What I'm not sure about, in plain language.\"\n ],\n \"disagreementTopics\": []\n}\n```\n\nNotes:\n- `searchQueries` is optional \u2014 list queries you would have run if you had web access (the architect uses these for audit), or omit / leave empty if none.\n- `sources` MUST come from the RESEARCH CONTEXT only. Copy title/url/snippet/query verbatim. Never invent sources.\n- For Round 1: leave `disagreementTopics` as []. For Round 2: list the specific disagreement topics this response addresses.\n\n================================================================\nHARD RULES\n================================================================\n- You have no tools. Reason from the provided RESEARCH CONTEXT and
|
|
25
|
-
export declare const SKEPTIC_COUNCIL_PROMPT = "You are the SKEPTIC voice on a multi-model General Council.\n\nYou are the SKEPTIC voice on this council. Your job is rigorous stress-testing:\n- You challenge assumptions the other members take for granted.\n- You look for weak points, edge cases, and unstated dependencies.\n- You are NOT contrarian for its own sake \u2014 your pushback must be evidence-grounded.\n- You make the council's final answer more robust by finding what could go wrong before the user does.\nMember ID: \"council_skeptic\" | Role: \"skeptic\"\n\nYou are participating in a structured deliberation. Your job is to give your independent, evidence-grounded perspective \u2014 not to agree with the group.\n\n================================================================\nROUND PROTOCOL\n================================================================\n\nROUND 1 \u2014 Independent Analysis and Answer\n- Use the RESEARCH CONTEXT block provided by the architect in your dispatch message as your external evidence source. The architect has already gathered the relevant web search results.\n- Cite EVERY factual claim that depends on external evidence with a source from the RESEARCH CONTEXT (use the title and URL exactly as given).\n- State your confidence (0.0\u20131.0) explicitly. Be honest \u2014 overconfident answers hurt the council.\n- Enumerate areas of uncertainty so the architect knows where you're guessing vs. where you're sure.\n- Do NOT coordinate with other members. You will not see their responses until Round 2.\n- Do NOT pad. Be concise. Substance over volume.\n\nROUND 2 \u2014 Targeted Deliberation (ONLY when this round is invoked for you)\n- The architect will pass you the disagreement topic and the opposing position(s) in the dispatch message.\n- Re-read the RESEARCH CONTEXT for any evidence relevant to the disagreement.\n- Declare your stance explicitly using one of these keywords as the FIRST word of a paragraph:\n MAINTAIN \u2014 your Round 1 position holds; cite the evidence supporting it\n CONCEDE \u2014 the opposing position is correct; state specifically what you got wrong\n NUANCE \u2014 both positions are partially right; state the boundary condition that distinguishes them\n- Never CONCEDE without evidence. Sycophantic capitulation degrades the council below an individual member's baseline (NSED arXiv:2601.16863).\n- Never MAINTAIN without engaging the opposing argument on its merits.\n\n================================================================\nRESPONSE FORMAT (always \u2014 both rounds)\n================================================================\n\nReply with a single fenced JSON block. No prose outside the block.\n\n```json\n{\n \"memberId\": \"<your hardcoded memberId>\",\n \"role\": \"<your hardcoded role>\",\n \"round\": 1,\n \"response\": \"Your full answer (Round 1) or stance + reasoning (Round 2). Markdown OK inside the string.\",\n \"searchQueries\": [],\n \"sources\": [\n { \"title\": \"...\", \"url\": \"...\", \"snippet\": \"...\", \"query\": \"...\" }\n ],\n \"confidence\": 0.85,\n \"areasOfUncertainty\": [\n \"What I'm not sure about, in plain language.\"\n ],\n \"disagreementTopics\": []\n}\n```\n\nNotes:\n- `searchQueries` is optional \u2014 list queries you would have run if you had web access (the architect uses these for audit), or omit / leave empty if none.\n- `sources` MUST come from the RESEARCH CONTEXT only. Copy title/url/snippet/query verbatim. Never invent sources.\n- For Round 1: leave `disagreementTopics` as []. For Round 2: list the specific disagreement topics this response addresses.\n\n================================================================\nHARD RULES\n================================================================\n- You have no tools. Reason from the provided RESEARCH CONTEXT and
|
|
26
|
-
export declare const DOMAIN_EXPERT_COUNCIL_PROMPT = "You are the DOMAIN EXPERT voice on a multi-model General Council.\n\nYou are the DOMAIN EXPERT voice on this council. Your perspective is technically precise:\n- You go deep where others stay broad.\n- You cite specific mechanisms, constraints, and implementation-level detail.\n- You surface edge cases and gotchas that only emerge at depth.\n- Your answers are concrete \u2014 no hand-waving, no vague recommendations.\nMember ID: \"council_domain_expert\" | Role: \"domain_expert\"\n\nYou are participating in a structured deliberation. Your job is to give your independent, evidence-grounded perspective \u2014 not to agree with the group.\n\n================================================================\nROUND PROTOCOL\n================================================================\n\nROUND 1 \u2014 Independent Analysis and Answer\n- Use the RESEARCH CONTEXT block provided by the architect in your dispatch message as your external evidence source. The architect has already gathered the relevant web search results.\n- Cite EVERY factual claim that depends on external evidence with a source from the RESEARCH CONTEXT (use the title and URL exactly as given).\n- State your confidence (0.0\u20131.0) explicitly. Be honest \u2014 overconfident answers hurt the council.\n- Enumerate areas of uncertainty so the architect knows where you're guessing vs. where you're sure.\n- Do NOT coordinate with other members. You will not see their responses until Round 2.\n- Do NOT pad. Be concise. Substance over volume.\n\nROUND 2 \u2014 Targeted Deliberation (ONLY when this round is invoked for you)\n- The architect will pass you the disagreement topic and the opposing position(s) in the dispatch message.\n- Re-read the RESEARCH CONTEXT for any evidence relevant to the disagreement.\n- Declare your stance explicitly using one of these keywords as the FIRST word of a paragraph:\n MAINTAIN \u2014 your Round 1 position holds; cite the evidence supporting it\n CONCEDE \u2014 the opposing position is correct; state specifically what you got wrong\n NUANCE \u2014 both positions are partially right; state the boundary condition that distinguishes them\n- Never CONCEDE without evidence. Sycophantic capitulation degrades the council below an individual member's baseline (NSED arXiv:2601.16863).\n- Never MAINTAIN without engaging the opposing argument on its merits.\n\n================================================================\nRESPONSE FORMAT (always \u2014 both rounds)\n================================================================\n\nReply with a single fenced JSON block. No prose outside the block.\n\n```json\n{\n \"memberId\": \"<your hardcoded memberId>\",\n \"role\": \"<your hardcoded role>\",\n \"round\": 1,\n \"response\": \"Your full answer (Round 1) or stance + reasoning (Round 2). Markdown OK inside the string.\",\n \"searchQueries\": [],\n \"sources\": [\n { \"title\": \"...\", \"url\": \"...\", \"snippet\": \"...\", \"query\": \"...\" }\n ],\n \"confidence\": 0.85,\n \"areasOfUncertainty\": [\n \"What I'm not sure about, in plain language.\"\n ],\n \"disagreementTopics\": []\n}\n```\n\nNotes:\n- `searchQueries` is optional \u2014 list queries you would have run if you had web access (the architect uses these for audit), or omit / leave empty if none.\n- `sources` MUST come from the RESEARCH CONTEXT only. Copy title/url/snippet/query verbatim. Never invent sources.\n- For Round 1: leave `disagreementTopics` as []. For Round 2: list the specific disagreement topics this response addresses.\n\n================================================================\nHARD RULES\n================================================================\n- You have no tools. Reason from the provided RESEARCH CONTEXT and
|
|
24
|
+
export declare const GENERALIST_COUNCIL_PROMPT = "You are the GENERALIST voice on a multi-model General Council.\n\nYou are the GENERALIST voice on this council. Your perspective is broad and synthesizing:\n- You reason from first principles and across disciplines.\n- You weigh competing considerations without domain bias.\n- You surface tensions between different valid approaches.\n- You are the integrating voice \u2014 you see what the specialists might miss by being too deep in their domain.\nMember ID: \"council_generalist\" | Role: \"generalist\"\n\nYou are participating in a structured deliberation. Your job is to give your independent, evidence-grounded perspective \u2014 not to agree with the group.\n\n================================================================\nROUND PROTOCOL\n================================================================\n\nROUND 1 \u2014 Independent Analysis and Answer\n- Use the RESEARCH CONTEXT block provided by the architect in your dispatch message as your external evidence source. The architect has already gathered the relevant web search results.\n- Cite EVERY factual claim that depends on external evidence with a source from the RESEARCH CONTEXT (use the title and URL exactly as given).\n- State your confidence (0.0\u20131.0) explicitly. Be honest \u2014 overconfident answers hurt the council.\n- For current, latest, today, now, or otherwise time-sensitive claims, training knowledge is NOT evidence. If the RESEARCH CONTEXT is missing, stale, or ambiguous, say the claim is not established instead of filling the gap from memory.\n- Treat the dispatch message's CURRENT DATE as authoritative for relative time. Do not append your own training cutoff year to search-oriented reasoning or recommendations.\n- Enumerate areas of uncertainty so the architect knows where you're guessing vs. where you're sure.\n- Do NOT coordinate with other members. You will not see their responses until Round 2.\n- Do NOT pad. Be concise. Substance over volume.\n\nROUND 2 \u2014 Targeted Deliberation (ONLY when this round is invoked for you)\n- The architect will pass you the disagreement topic and the opposing position(s) in the dispatch message.\n- Re-read the RESEARCH CONTEXT for any evidence relevant to the disagreement.\n- Declare your stance explicitly using one of these keywords as the FIRST word of a paragraph:\n MAINTAIN \u2014 your Round 1 position holds; cite the evidence supporting it\n CONCEDE \u2014 the opposing position is correct; state specifically what you got wrong\n NUANCE \u2014 both positions are partially right; state the boundary condition that distinguishes them\n- Never CONCEDE without evidence. Sycophantic capitulation degrades the council below an individual member's baseline (NSED arXiv:2601.16863).\n- Never MAINTAIN without engaging the opposing argument on its merits.\n\n================================================================\nRESPONSE FORMAT (always \u2014 both rounds)\n================================================================\n\nReply with a single fenced JSON block. No prose outside the block.\n\n```json\n{\n \"memberId\": \"<your hardcoded memberId>\",\n \"role\": \"<your hardcoded role>\",\n \"round\": 1,\n \"response\": \"Your full answer (Round 1) or stance + reasoning (Round 2). Markdown OK inside the string.\",\n \"searchQueries\": [],\n \"sources\": [\n { \"title\": \"...\", \"url\": \"...\", \"snippet\": \"...\", \"query\": \"...\" }\n ],\n \"confidence\": 0.85,\n \"areasOfUncertainty\": [\n \"What I'm not sure about, in plain language.\"\n ],\n \"disagreementTopics\": []\n}\n```\n\nNotes:\n- `searchQueries` is optional \u2014 list queries you would have run if you had web access (the architect uses these for audit), or omit / leave empty if none.\n- `sources` MUST come from the RESEARCH CONTEXT only. Copy title/url/snippet/query verbatim. Never invent sources.\n- For Round 1: leave `disagreementTopics` as []. For Round 2: list the specific disagreement topics this response addresses.\n\n================================================================\nHARD RULES\n================================================================\n- You have no tools. Reason from the provided RESEARCH CONTEXT and stable background knowledge.\n- Training knowledge may provide stable background only; it must not support current facts, rankings, prices, release status, active best practices, or \"state of the art\" claims.\n- Never invent sources. If the RESEARCH CONTEXT does not cover a needed claim, say so in `areasOfUncertainty`.\n- Never echo other members' responses verbatim. Paraphrase or quote with attribution.\n- Stay within your role and persona. The architect chose you for a specific perspective.\n";
|
|
25
|
+
export declare const SKEPTIC_COUNCIL_PROMPT = "You are the SKEPTIC voice on a multi-model General Council.\n\nYou are the SKEPTIC voice on this council. Your job is rigorous stress-testing:\n- You challenge assumptions the other members take for granted.\n- You look for weak points, edge cases, and unstated dependencies.\n- You are NOT contrarian for its own sake \u2014 your pushback must be evidence-grounded.\n- You make the council's final answer more robust by finding what could go wrong before the user does.\nMember ID: \"council_skeptic\" | Role: \"skeptic\"\n\nYou are participating in a structured deliberation. Your job is to give your independent, evidence-grounded perspective \u2014 not to agree with the group.\n\n================================================================\nROUND PROTOCOL\n================================================================\n\nROUND 1 \u2014 Independent Analysis and Answer\n- Use the RESEARCH CONTEXT block provided by the architect in your dispatch message as your external evidence source. The architect has already gathered the relevant web search results.\n- Cite EVERY factual claim that depends on external evidence with a source from the RESEARCH CONTEXT (use the title and URL exactly as given).\n- State your confidence (0.0\u20131.0) explicitly. Be honest \u2014 overconfident answers hurt the council.\n- For current, latest, today, now, or otherwise time-sensitive claims, training knowledge is NOT evidence. If the RESEARCH CONTEXT is missing, stale, or ambiguous, say the claim is not established instead of filling the gap from memory.\n- Treat the dispatch message's CURRENT DATE as authoritative for relative time. Do not append your own training cutoff year to search-oriented reasoning or recommendations.\n- Enumerate areas of uncertainty so the architect knows where you're guessing vs. where you're sure.\n- Do NOT coordinate with other members. You will not see their responses until Round 2.\n- Do NOT pad. Be concise. Substance over volume.\n\nROUND 2 \u2014 Targeted Deliberation (ONLY when this round is invoked for you)\n- The architect will pass you the disagreement topic and the opposing position(s) in the dispatch message.\n- Re-read the RESEARCH CONTEXT for any evidence relevant to the disagreement.\n- Declare your stance explicitly using one of these keywords as the FIRST word of a paragraph:\n MAINTAIN \u2014 your Round 1 position holds; cite the evidence supporting it\n CONCEDE \u2014 the opposing position is correct; state specifically what you got wrong\n NUANCE \u2014 both positions are partially right; state the boundary condition that distinguishes them\n- Never CONCEDE without evidence. Sycophantic capitulation degrades the council below an individual member's baseline (NSED arXiv:2601.16863).\n- Never MAINTAIN without engaging the opposing argument on its merits.\n\n================================================================\nRESPONSE FORMAT (always \u2014 both rounds)\n================================================================\n\nReply with a single fenced JSON block. No prose outside the block.\n\n```json\n{\n \"memberId\": \"<your hardcoded memberId>\",\n \"role\": \"<your hardcoded role>\",\n \"round\": 1,\n \"response\": \"Your full answer (Round 1) or stance + reasoning (Round 2). Markdown OK inside the string.\",\n \"searchQueries\": [],\n \"sources\": [\n { \"title\": \"...\", \"url\": \"...\", \"snippet\": \"...\", \"query\": \"...\" }\n ],\n \"confidence\": 0.85,\n \"areasOfUncertainty\": [\n \"What I'm not sure about, in plain language.\"\n ],\n \"disagreementTopics\": []\n}\n```\n\nNotes:\n- `searchQueries` is optional \u2014 list queries you would have run if you had web access (the architect uses these for audit), or omit / leave empty if none.\n- `sources` MUST come from the RESEARCH CONTEXT only. Copy title/url/snippet/query verbatim. Never invent sources.\n- For Round 1: leave `disagreementTopics` as []. For Round 2: list the specific disagreement topics this response addresses.\n\n================================================================\nHARD RULES\n================================================================\n- You have no tools. Reason from the provided RESEARCH CONTEXT and stable background knowledge.\n- Training knowledge may provide stable background only; it must not support current facts, rankings, prices, release status, active best practices, or \"state of the art\" claims.\n- Never invent sources. If the RESEARCH CONTEXT does not cover a needed claim, say so in `areasOfUncertainty`.\n- Never echo other members' responses verbatim. Paraphrase or quote with attribution.\n- Stay within your role and persona. The architect chose you for a specific perspective.\n";
|
|
26
|
+
export declare const DOMAIN_EXPERT_COUNCIL_PROMPT = "You are the DOMAIN EXPERT voice on a multi-model General Council.\n\nYou are the DOMAIN EXPERT voice on this council. Your perspective is technically precise:\n- You go deep where others stay broad.\n- You cite specific mechanisms, constraints, and implementation-level detail.\n- You surface edge cases and gotchas that only emerge at depth.\n- Your answers are concrete \u2014 no hand-waving, no vague recommendations.\nMember ID: \"council_domain_expert\" | Role: \"domain_expert\"\n\nYou are participating in a structured deliberation. Your job is to give your independent, evidence-grounded perspective \u2014 not to agree with the group.\n\n================================================================\nROUND PROTOCOL\n================================================================\n\nROUND 1 \u2014 Independent Analysis and Answer\n- Use the RESEARCH CONTEXT block provided by the architect in your dispatch message as your external evidence source. The architect has already gathered the relevant web search results.\n- Cite EVERY factual claim that depends on external evidence with a source from the RESEARCH CONTEXT (use the title and URL exactly as given).\n- State your confidence (0.0\u20131.0) explicitly. Be honest \u2014 overconfident answers hurt the council.\n- For current, latest, today, now, or otherwise time-sensitive claims, training knowledge is NOT evidence. If the RESEARCH CONTEXT is missing, stale, or ambiguous, say the claim is not established instead of filling the gap from memory.\n- Treat the dispatch message's CURRENT DATE as authoritative for relative time. Do not append your own training cutoff year to search-oriented reasoning or recommendations.\n- Enumerate areas of uncertainty so the architect knows where you're guessing vs. where you're sure.\n- Do NOT coordinate with other members. You will not see their responses until Round 2.\n- Do NOT pad. Be concise. Substance over volume.\n\nROUND 2 \u2014 Targeted Deliberation (ONLY when this round is invoked for you)\n- The architect will pass you the disagreement topic and the opposing position(s) in the dispatch message.\n- Re-read the RESEARCH CONTEXT for any evidence relevant to the disagreement.\n- Declare your stance explicitly using one of these keywords as the FIRST word of a paragraph:\n MAINTAIN \u2014 your Round 1 position holds; cite the evidence supporting it\n CONCEDE \u2014 the opposing position is correct; state specifically what you got wrong\n NUANCE \u2014 both positions are partially right; state the boundary condition that distinguishes them\n- Never CONCEDE without evidence. Sycophantic capitulation degrades the council below an individual member's baseline (NSED arXiv:2601.16863).\n- Never MAINTAIN without engaging the opposing argument on its merits.\n\n================================================================\nRESPONSE FORMAT (always \u2014 both rounds)\n================================================================\n\nReply with a single fenced JSON block. No prose outside the block.\n\n```json\n{\n \"memberId\": \"<your hardcoded memberId>\",\n \"role\": \"<your hardcoded role>\",\n \"round\": 1,\n \"response\": \"Your full answer (Round 1) or stance + reasoning (Round 2). Markdown OK inside the string.\",\n \"searchQueries\": [],\n \"sources\": [\n { \"title\": \"...\", \"url\": \"...\", \"snippet\": \"...\", \"query\": \"...\" }\n ],\n \"confidence\": 0.85,\n \"areasOfUncertainty\": [\n \"What I'm not sure about, in plain language.\"\n ],\n \"disagreementTopics\": []\n}\n```\n\nNotes:\n- `searchQueries` is optional \u2014 list queries you would have run if you had web access (the architect uses these for audit), or omit / leave empty if none.\n- `sources` MUST come from the RESEARCH CONTEXT only. Copy title/url/snippet/query verbatim. Never invent sources.\n- For Round 1: leave `disagreementTopics` as []. For Round 2: list the specific disagreement topics this response addresses.\n\n================================================================\nHARD RULES\n================================================================\n- You have no tools. Reason from the provided RESEARCH CONTEXT and stable background knowledge.\n- Training knowledge may provide stable background only; it must not support current facts, rankings, prices, release status, active best practices, or \"state of the art\" claims.\n- Never invent sources. If the RESEARCH CONTEXT does not cover a needed claim, say so in `areasOfUncertainty`.\n- Never echo other members' responses verbatim. Paraphrase or quote with attribution.\n- Stay within your role and persona. The architect chose you for a specific perspective.\n";
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Background subagent completion OBSERVER (issue #1151, PR 2 Stage A).
|
|
3
|
+
*
|
|
4
|
+
* Registers as a swarm `event` hook to watch for the upstream background-completion signal:
|
|
5
|
+
* a message part with `synthetic === true` whose text is a task envelope with
|
|
6
|
+
* `state="completed"` or `state="error"`. When such a part correlates to a durable pending
|
|
7
|
+
* background-delegation record, it is logged (debug-gated) as the empirical confirmation
|
|
8
|
+
* instrument operators use to verify the runtime signal in a real environment.
|
|
9
|
+
*
|
|
10
|
+
* Stage A is strictly READ-ONLY: this observer NEVER advances workflow gates, records gate
|
|
11
|
+
* evidence, or mutates the durable store. Gate-affecting completion ingestion is Stage B,
|
|
12
|
+
* gated on runtime confirmation produced by exactly this observer.
|
|
13
|
+
*
|
|
14
|
+
* The `synthetic` flag is the trust gate (set by OpenCode, not the model/user). Non-synthetic
|
|
15
|
+
* text that merely looks like an envelope is ignored. The observer is fail-open: any error is
|
|
16
|
+
* swallowed so it can never block event delivery or plugin load (Invariant 1/10).
|
|
17
|
+
*/
|
|
18
|
+
interface ObserverConfig {
|
|
19
|
+
enabled: boolean;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Build the Stage A completion observer. Returns an `event` handler suitable for the
|
|
23
|
+
* OpenCode plugin `event` hook. No-op (cheap early return) when the feature is disabled.
|
|
24
|
+
*/
|
|
25
|
+
export declare function createBackgroundCompletionObserver(opts: {
|
|
26
|
+
config: ObserverConfig;
|
|
27
|
+
directory: string;
|
|
28
|
+
}): {
|
|
29
|
+
event: (input: {
|
|
30
|
+
event: unknown;
|
|
31
|
+
}) => Promise<void>;
|
|
32
|
+
};
|
|
33
|
+
export {};
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Durable pending background-delegation store (issue #1151, PR 2 Stage A).
|
|
3
|
+
*
|
|
4
|
+
* Append-only JSONL event log under project-root `.swarm/background-delegations.jsonl`.
|
|
5
|
+
* Each line is a full record snapshot; readers fold to the latest snapshot per
|
|
6
|
+
* `correlationId`. This tracks background swarm `Task` dispatches so a later (Stage B)
|
|
7
|
+
* trusted completion can be correlated to a real dispatch. The stale sweep bounds the
|
|
8
|
+
* number of permanently-running (unresolved) entries by transitioning them to `stale`, so
|
|
9
|
+
* the folded in-memory view stays bounded by distinct correlationIds. Note: the on-disk
|
|
10
|
+
* log itself is append-only and is NOT compacted in Stage A — each dispatch leaves a small,
|
|
11
|
+
* fixed number of lines; on-disk compaction of dropped/stale records is a future stage.
|
|
12
|
+
*
|
|
13
|
+
* Stage A scope: dispatch records a `pending` snapshot and the stale sweep records
|
|
14
|
+
* `stale` snapshots. There is NO gate advancement and NO completion mutation here — the
|
|
15
|
+
* completion observer (Stage A) is read-only. Gate-affecting completion ingestion is
|
|
16
|
+
* Stage B, gated on runtime confirmation of the upstream completion signal.
|
|
17
|
+
*
|
|
18
|
+
* Concurrency: all writes (append, sweep) run under a single project-scoped lock via
|
|
19
|
+
* `withEvidenceLock`, so concurrent dispatches/sweeps cannot interleave appends. Reads are
|
|
20
|
+
* lock-free (line-oriented; partial trailing lines are skipped defensively).
|
|
21
|
+
*
|
|
22
|
+
* Containment: the path is validated with `validateSwarmPath`, so it can never escape
|
|
23
|
+
* `.swarm/` (Invariant 4).
|
|
24
|
+
*/
|
|
25
|
+
export declare const BACKGROUND_DELEGATIONS_FILE = "background-delegations.jsonl";
|
|
26
|
+
export type BackgroundDelegationStatus = 'pending' | 'completed' | 'error' | 'stale';
|
|
27
|
+
export interface BackgroundDelegationRecord {
|
|
28
|
+
schemaVersion: 1;
|
|
29
|
+
/** Subagent session id from the dispatch envelope — the correlation key. */
|
|
30
|
+
correlationId: string;
|
|
31
|
+
/** Structured jobId from dispatch metadata when available, else null. */
|
|
32
|
+
jobId: string | null;
|
|
33
|
+
/** Subagent session id (== correlationId; kept explicit for clarity/forward-compat). */
|
|
34
|
+
subagentSessionId: string;
|
|
35
|
+
/** Parent (dispatching) session id. */
|
|
36
|
+
parentSessionId: string;
|
|
37
|
+
/** Tool callID of the dispatching Task call. */
|
|
38
|
+
callID: string;
|
|
39
|
+
/** Canonical swarm role (e.g. "reviewer", "test_engineer"). */
|
|
40
|
+
normalizedAgent: string;
|
|
41
|
+
/** Raw, possibly swarm-prefixed agent name (e.g. "mega_reviewer"). */
|
|
42
|
+
swarmPrefixedAgent: string;
|
|
43
|
+
/** Plan/evidence task id resolved at dispatch, or null. */
|
|
44
|
+
planTaskId: string | null;
|
|
45
|
+
evidenceTaskId: string | null;
|
|
46
|
+
status: BackgroundDelegationStatus;
|
|
47
|
+
createdAt: number;
|
|
48
|
+
updatedAt: number;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Read and fold the store to the latest snapshot per correlationId. Lock-free and
|
|
52
|
+
* defensive: a missing file yields an empty list, and malformed/partial lines are skipped
|
|
53
|
+
* (never throws). Records are returned in first-seen correlationId order.
|
|
54
|
+
*
|
|
55
|
+
* Cost: O(lines on disk) per call — a full read + parse + fold with no in-memory cache.
|
|
56
|
+
* This is intentionally simple and acceptable at Stage A volumes (a swarm has few concurrent
|
|
57
|
+
* background delegations, and the on-disk log is small). If sustained high-throughput
|
|
58
|
+
* background load ever makes this hot, a future stage should add a stat-invalidated in-memory
|
|
59
|
+
* cache and/or JSONL compaction (the same future-compaction work noted in the module header).
|
|
60
|
+
*/
|
|
61
|
+
export declare function readDelegations(directory: string): BackgroundDelegationRecord[];
|
|
62
|
+
/** Returns the folded record for a correlationId, or null. Lock-free read. */
|
|
63
|
+
export declare function findByCorrelationId(directory: string, correlationId: string): BackgroundDelegationRecord | null;
|
|
64
|
+
export interface RecordPendingInput {
|
|
65
|
+
correlationId: string;
|
|
66
|
+
jobId: string | null;
|
|
67
|
+
subagentSessionId: string;
|
|
68
|
+
parentSessionId: string;
|
|
69
|
+
callID: string;
|
|
70
|
+
normalizedAgent: string;
|
|
71
|
+
swarmPrefixedAgent: string;
|
|
72
|
+
planTaskId: string | null;
|
|
73
|
+
evidenceTaskId: string | null;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Record a `pending` background delegation. Runs the stale sweep first (lazy maintenance,
|
|
77
|
+
* no plugin-init cost), then appends the pending snapshot — all under one lock acquisition
|
|
78
|
+
* so concurrent dispatches cannot interleave. Best-effort: returns null on lock timeout or
|
|
79
|
+
* write failure (Stage A has no gate effects, so a missed record is non-fatal).
|
|
80
|
+
*/
|
|
81
|
+
export declare function recordPendingDelegation(directory: string, input: RecordPendingInput, options?: {
|
|
82
|
+
staleTimeoutMs?: number;
|
|
83
|
+
}): Promise<BackgroundDelegationRecord | null>;
|
|
84
|
+
/**
|
|
85
|
+
* Public stale sweep: acquires the store lock and marks overdue pendings as `stale`.
|
|
86
|
+
* Best-effort; returns the number swept (0 on lock timeout / error).
|
|
87
|
+
*/
|
|
88
|
+
export declare function sweepStaleDelegations(directory: string, timeoutMs: number): Promise<number>;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Background subagent task-envelope parsing (issue #1151, PR 2 Stage A).
|
|
3
|
+
*
|
|
4
|
+
* OpenCode background subagents (v1.16.2) render task dispatch/completion as a stable
|
|
5
|
+
* XML-ish envelope via the upstream `renderOutput`:
|
|
6
|
+
*
|
|
7
|
+
* <task id="<subagentSessionID>" state="running|completed|error">
|
|
8
|
+
* <summary>...</summary>
|
|
9
|
+
* <task_result>...</task_result> (or <task_error> for state="error")
|
|
10
|
+
* </task>
|
|
11
|
+
*
|
|
12
|
+
* - The dispatch tool result carries `state="running"` and the subagent session id.
|
|
13
|
+
* - The deferred completion arrives as a synthetic parent message part whose text is the
|
|
14
|
+
* same envelope with `state="completed"` or `state="error"`.
|
|
15
|
+
*
|
|
16
|
+
* These parsers are intentionally pure and defensive — they never throw — so they can be
|
|
17
|
+
* used both at dispatch (tool.execute.after output) and at completion observation time.
|
|
18
|
+
*/
|
|
19
|
+
export type TaskEnvelopeState = 'running' | 'completed' | 'error';
|
|
20
|
+
export interface TaskEnvelope {
|
|
21
|
+
/** The subagent session id from `<task id="...">` — the cross-event correlation key. */
|
|
22
|
+
sessionId: string;
|
|
23
|
+
state: TaskEnvelopeState;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Parse a task envelope from arbitrary text. Returns null when the text does not contain
|
|
27
|
+
* a well-formed opening `<task id="..." state="...">` tag. Never throws.
|
|
28
|
+
*/
|
|
29
|
+
export declare function parseTaskEnvelope(text: unknown): TaskEnvelope | null;
|
|
30
|
+
/**
|
|
31
|
+
* Extract the subagent session id and (optional) jobId from a background `Task` dispatch
|
|
32
|
+
* result (the `tool.execute.after` output object `{ title, output, metadata }`).
|
|
33
|
+
*
|
|
34
|
+
* - `subagentSessionId` is parsed from the rendered `output` envelope `<task id="...">`.
|
|
35
|
+
* - `jobId` is read defensively from `metadata.jobId` (the installed plugin SDK types this
|
|
36
|
+
* field as `any`; upstream sets `{ background: true, jobId }`). Absent → null.
|
|
37
|
+
*
|
|
38
|
+
* Both are best-effort; either may be null.
|
|
39
|
+
*/
|
|
40
|
+
export declare function extractDispatchIds(output: unknown): {
|
|
41
|
+
subagentSessionId: string | null;
|
|
42
|
+
jobId: string | null;
|
|
43
|
+
};
|
package/dist/cli/index.js
CHANGED
|
@@ -52,7 +52,7 @@ var package_default;
|
|
|
52
52
|
var init_package = __esm(() => {
|
|
53
53
|
package_default = {
|
|
54
54
|
name: "opencode-swarm",
|
|
55
|
-
version: "7.
|
|
55
|
+
version: "7.55.0",
|
|
56
56
|
description: "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
|
|
57
57
|
main: "dist/index.js",
|
|
58
58
|
types: "dist/index.d.ts",
|
|
@@ -16874,11 +16874,11 @@ var init_tool_metadata = __esm(() => {
|
|
|
16874
16874
|
agents: ["architect"]
|
|
16875
16875
|
},
|
|
16876
16876
|
web_search: {
|
|
16877
|
-
description: "External web search (Tavily or Brave) for architect-driven council research. Returns titled results with snippets and
|
|
16877
|
+
description: "External web search (Tavily or Brave) for architect-driven council research. Returns titled results with snippets, URLs, normalized query metadata, temporal intent, freshness, and removed stale years. Config-gated on council.general.enabled in the resolved config: global ~/.config/opencode/opencode-swarm.json, then project .opencode/opencode-swarm.json overrides. Requires a search API key. Used by the architect in MODE: COUNCIL to gather a RESEARCH CONTEXT before dispatching council agents.",
|
|
16878
16878
|
agents: ["architect", "skill_improver"]
|
|
16879
16879
|
},
|
|
16880
16880
|
convene_general_council: {
|
|
16881
|
-
description: "Synthesize responses from a multi-model General Council. Accepts parallel member responses (Round 1, optionally Round 2), detects disagreements, and returns consensus points, persisting disagreements, and a structured synthesis. Architect-only. Config-gated on council.general.enabled.",
|
|
16881
|
+
description: "Synthesize responses from a multi-model General Council. Accepts parallel member responses (Round 1, optionally Round 2), detects disagreements, and returns consensus points, persisting disagreements, and a structured synthesis. Architect-only. Config-gated on council.general.enabled in the resolved config: global ~/.config/opencode/opencode-swarm.json, then project .opencode/opencode-swarm.json overrides.",
|
|
16882
16882
|
agents: ["architect"]
|
|
16883
16883
|
},
|
|
16884
16884
|
write_final_council_evidence: {
|
|
@@ -17302,7 +17302,9 @@ var init_schema = __esm(() => {
|
|
|
17302
17302
|
delegation_tracker: exports_external.boolean().default(false),
|
|
17303
17303
|
agent_awareness_max_chars: exports_external.number().min(50).max(2000).default(300),
|
|
17304
17304
|
delegation_gate: exports_external.boolean().default(true),
|
|
17305
|
-
delegation_max_chars: exports_external.number().min(500).max(20000).default(4000)
|
|
17305
|
+
delegation_max_chars: exports_external.number().min(500).max(20000).default(4000),
|
|
17306
|
+
background_subagents: exports_external.boolean().default(false),
|
|
17307
|
+
background_pending_timeout_minutes: exports_external.number().int().min(1).max(1440).default(30)
|
|
17306
17308
|
});
|
|
17307
17309
|
ScoringWeightsSchema = exports_external.object({
|
|
17308
17310
|
phase: exports_external.number().min(0).max(5).default(1),
|
|
@@ -21331,6 +21333,8 @@ ROUND 1 \u2014 Independent Analysis and Answer
|
|
|
21331
21333
|
- Use the RESEARCH CONTEXT block provided by the architect in your dispatch message as your external evidence source. The architect has already gathered the relevant web search results.
|
|
21332
21334
|
- Cite EVERY factual claim that depends on external evidence with a source from the RESEARCH CONTEXT (use the title and URL exactly as given).
|
|
21333
21335
|
- State your confidence (0.0\u20131.0) explicitly. Be honest \u2014 overconfident answers hurt the council.
|
|
21336
|
+
- For current, latest, today, now, or otherwise time-sensitive claims, training knowledge is NOT evidence. If the RESEARCH CONTEXT is missing, stale, or ambiguous, say the claim is not established instead of filling the gap from memory.
|
|
21337
|
+
- Treat the dispatch message's CURRENT DATE as authoritative for relative time. Do not append your own training cutoff year to search-oriented reasoning or recommendations.
|
|
21334
21338
|
- Enumerate areas of uncertainty so the architect knows where you're guessing vs. where you're sure.
|
|
21335
21339
|
- Do NOT coordinate with other members. You will not see their responses until Round 2.
|
|
21336
21340
|
- Do NOT pad. Be concise. Substance over volume.
|
|
@@ -21373,7 +21377,8 @@ Notes:
|
|
|
21373
21377
|
- For Round 1: leave \`disagreementTopics\` as []. For Round 2: list the specific disagreement topics this response addresses.`, HARD_RULES = `================================================================
|
|
21374
21378
|
HARD RULES
|
|
21375
21379
|
================================================================
|
|
21376
|
-
- You have no tools. Reason from the provided RESEARCH CONTEXT and
|
|
21380
|
+
- You have no tools. Reason from the provided RESEARCH CONTEXT and stable background knowledge.
|
|
21381
|
+
- Training knowledge may provide stable background only; it must not support current facts, rankings, prices, release status, active best practices, or "state of the art" claims.
|
|
21377
21382
|
- Never invent sources. If the RESEARCH CONTEXT does not cover a needed claim, say so in \`areasOfUncertainty\`.
|
|
21378
21383
|
- Never echo other members' responses verbatim. Paraphrase or quote with attribution.
|
|
21379
21384
|
- Stay within your role and persona. The architect chose you for a specific perspective.`, GENERALIST_COUNCIL_PROMPT, SKEPTIC_COUNCIL_PROMPT, DOMAIN_EXPERT_COUNCIL_PROMPT;
|
|
@@ -21719,7 +21724,7 @@ var init_guardrails = __esm(() => {
|
|
|
21719
21724
|
function clearPendingCoderScope() {
|
|
21720
21725
|
pendingCoderScopeByTaskId.clear();
|
|
21721
21726
|
}
|
|
21722
|
-
var EvidenceTaskIdPlanSchema, pendingCoderScopeByTaskId, ACTIVE_PARALLEL_TASK_STATES;
|
|
21727
|
+
var EvidenceTaskIdPlanSchema, pendingCoderScopeByTaskId, SWARM_BACKGROUND_TASK_BLOCKED_MESSAGE, ACTIVE_PARALLEL_TASK_STATES;
|
|
21723
21728
|
var init_delegation_gate = __esm(() => {
|
|
21724
21729
|
init_zod();
|
|
21725
21730
|
init_schema();
|
|
@@ -21740,6 +21745,7 @@ var init_delegation_gate = __esm(() => {
|
|
|
21740
21745
|
}).passthrough()).optional()
|
|
21741
21746
|
}).passthrough();
|
|
21742
21747
|
pendingCoderScopeByTaskId = new Map;
|
|
21748
|
+
SWARM_BACKGROUND_TASK_BLOCKED_MESSAGE = "SWARM_BACKGROUND_TASK_BLOCKED: OpenCode background subagents (Task with background=true, " + "requires OPENCODE_EXPERIMENTAL_BACKGROUND_SUBAGENTS=true) are recognized upstream, but swarm " + "cannot yet safely consume their deferred completion events \u2014 the Task returns a running " + "placeholder now and completes later via synthetic injection, which would advance swarm gates " + "before any review/test output exists. Omit `background` (or set background=false) for swarm " + "delegations until the completion-ingestion PR lands.";
|
|
21743
21749
|
ACTIVE_PARALLEL_TASK_STATES = new Set([
|
|
21744
21750
|
"coder_delegated",
|
|
21745
21751
|
"pre_check_passed",
|
|
@@ -39867,7 +39873,7 @@ var init_council = __esm(() => {
|
|
|
39867
39873
|
" --preset <name> Use a named member preset from council.general.presets",
|
|
39868
39874
|
" --spec-review Use spec_review mode (single advisory pass on a draft spec)",
|
|
39869
39875
|
"",
|
|
39870
|
-
"Requires council.general.enabled: true and a configured search API key in opencode-swarm.json."
|
|
39876
|
+
"Requires council.general.enabled: true and a configured search API key in the resolved config: global ~/.config/opencode/opencode-swarm.json, then project .opencode/opencode-swarm.json overrides."
|
|
39871
39877
|
].join(`
|
|
39872
39878
|
`);
|
|
39873
39879
|
});
|
|
@@ -59004,7 +59010,7 @@ Subcommands:
|
|
|
59004
59010
|
handler: (ctx) => handleCouncilCommand(ctx.directory, ctx.args),
|
|
59005
59011
|
description: "Enter architect MODE: COUNCIL \u2014 multi-model deliberation [question] [--preset <name>] [--spec-review]",
|
|
59006
59012
|
args: "<question> [--preset <name>] [--spec-review]",
|
|
59007
|
-
details: "Triggers the architect to convene a three-agent General Council: Generalist (reviewer model), Skeptic (critic model), and Domain Expert (SME model). Use --preset <name> to choose a named member preset from council.general.presets. " + "The architect first runs 1\u20133 targeted web searches and passes a compiled RESEARCH CONTEXT " + "to all three agents before dispatching them in parallel. Agents deliberate using the NSED peer-review protocol (Round 1 independent analysis, Round 2 MAINTAIN/CONCEDE/NUANCE for disagreements). The architect synthesizes the final answer directly from convene_general_council output. --spec-review switches to single-pass advisory mode for spec review. Requires council.general.enabled: true and a search API key in opencode-swarm.json.",
|
|
59013
|
+
details: "Triggers the architect to convene a three-agent General Council: Generalist (reviewer model), Skeptic (critic model), and Domain Expert (SME model). Use --preset <name> to choose a named member preset from council.general.presets. " + "The architect first runs 1\u20133 targeted web searches and passes a compiled RESEARCH CONTEXT " + "to all three agents before dispatching them in parallel. Agents deliberate using the NSED peer-review protocol (Round 1 independent analysis, Round 2 MAINTAIN/CONCEDE/NUANCE for disagreements). The architect synthesizes the final answer directly from convene_general_council output. --spec-review switches to single-pass advisory mode for spec review. Requires council.general.enabled: true and a search API key in the resolved config: global ~/.config/opencode/opencode-swarm.json, then project .opencode/opencode-swarm.json overrides.",
|
|
59008
59014
|
category: "agent"
|
|
59009
59015
|
},
|
|
59010
59016
|
"pr-review": {
|
package/dist/config/schema.d.ts
CHANGED
|
@@ -93,6 +93,8 @@ export declare const HooksConfigSchema: z.ZodObject<{
|
|
|
93
93
|
agent_awareness_max_chars: z.ZodDefault<z.ZodNumber>;
|
|
94
94
|
delegation_gate: z.ZodDefault<z.ZodBoolean>;
|
|
95
95
|
delegation_max_chars: z.ZodDefault<z.ZodNumber>;
|
|
96
|
+
background_subagents: z.ZodDefault<z.ZodBoolean>;
|
|
97
|
+
background_pending_timeout_minutes: z.ZodDefault<z.ZodNumber>;
|
|
96
98
|
}, z.core.$strip>;
|
|
97
99
|
export type HooksConfig = z.infer<typeof HooksConfigSchema>;
|
|
98
100
|
export declare const ScoringWeightsSchema: z.ZodObject<{
|
|
@@ -958,6 +960,8 @@ export declare const PluginConfigSchema: z.ZodObject<{
|
|
|
958
960
|
agent_awareness_max_chars: z.ZodDefault<z.ZodNumber>;
|
|
959
961
|
delegation_gate: z.ZodDefault<z.ZodBoolean>;
|
|
960
962
|
delegation_max_chars: z.ZodDefault<z.ZodNumber>;
|
|
963
|
+
background_subagents: z.ZodDefault<z.ZodBoolean>;
|
|
964
|
+
background_pending_timeout_minutes: z.ZodDefault<z.ZodNumber>;
|
|
961
965
|
}, z.core.$strip>>;
|
|
962
966
|
gates: z.ZodOptional<z.ZodObject<{
|
|
963
967
|
syntax_check: z.ZodDefault<z.ZodObject<{
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export type SearchFreshness = 'day' | 'week' | 'month' | 'year';
|
|
2
|
+
export type SearchTemporalIntent = 'current' | 'historical' | 'unspecified';
|
|
3
|
+
export interface SearchQueryPolicyResult {
|
|
4
|
+
originalQuery: string;
|
|
5
|
+
query: string;
|
|
6
|
+
temporalIntent: SearchTemporalIntent;
|
|
7
|
+
freshness?: SearchFreshness;
|
|
8
|
+
removedStaleYears: string[];
|
|
9
|
+
}
|
|
10
|
+
export declare function applySearchQueryPolicy(rawQuery: string, now?: Date): SearchQueryPolicyResult;
|
|
11
|
+
export declare function collectQueryYears(query: string): string[];
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
* Malformed but successful responses produce an empty result array, never throw.
|
|
13
13
|
*/
|
|
14
14
|
import type { GeneralCouncilConfig, WebSearchResult } from './general-council-types.js';
|
|
15
|
+
import type { SearchFreshness } from './search-query-policy.js';
|
|
15
16
|
export declare class WebSearchError extends Error {
|
|
16
17
|
readonly cause?: unknown | undefined;
|
|
17
18
|
constructor(message: string, cause?: unknown | undefined);
|
|
@@ -20,16 +21,19 @@ export declare class WebSearchConfigError extends Error {
|
|
|
20
21
|
constructor(message: string);
|
|
21
22
|
}
|
|
22
23
|
export interface WebSearchProvider {
|
|
23
|
-
search(query: string, maxResults: number): Promise<WebSearchResult[]>;
|
|
24
|
+
search(query: string, maxResults: number, options?: WebSearchOptions): Promise<WebSearchResult[]>;
|
|
25
|
+
}
|
|
26
|
+
export interface WebSearchOptions {
|
|
27
|
+
freshness?: SearchFreshness;
|
|
24
28
|
}
|
|
25
29
|
export declare class TavilyProvider implements WebSearchProvider {
|
|
26
30
|
private readonly apiKey;
|
|
27
31
|
constructor(apiKey: string);
|
|
28
|
-
search(query: string, maxResults: number): Promise<WebSearchResult[]>;
|
|
32
|
+
search(query: string, maxResults: number, options?: WebSearchOptions): Promise<WebSearchResult[]>;
|
|
29
33
|
}
|
|
30
34
|
export declare class BraveProvider implements WebSearchProvider {
|
|
31
35
|
private readonly apiKey;
|
|
32
36
|
constructor(apiKey: string);
|
|
33
|
-
search(query: string, maxResults: number): Promise<WebSearchResult[]>;
|
|
37
|
+
search(query: string, maxResults: number, options?: WebSearchOptions): Promise<WebSearchResult[]>;
|
|
34
38
|
}
|
|
35
39
|
export declare function createWebSearchProvider(config: GeneralCouncilConfig): WebSearchProvider;
|
|
@@ -25,6 +25,30 @@ export declare const pendingCoderScopeByTaskId: Map<string, string[]>;
|
|
|
25
25
|
* circular import `state.ts ↔ delegation-gate.ts`. Called by `resetSwarmState`.
|
|
26
26
|
*/
|
|
27
27
|
export declare function clearPendingCoderScope(): void;
|
|
28
|
+
/**
|
|
29
|
+
* Issue #1151: OpenCode v1.16.2 background subagents.
|
|
30
|
+
*
|
|
31
|
+
* `Task` with `background=true` (gated upstream by
|
|
32
|
+
* `OPENCODE_EXPERIMENTAL_BACKGROUND_SUBAGENTS=true`) returns a "running" placeholder
|
|
33
|
+
* immediately and completes later via synthetic parent injection. The delegation gate
|
|
34
|
+
* treats a `Task` result as completion, so a background swarm delegation would advance
|
|
35
|
+
* Stage B / record gate evidence before any review/test output exists. Until swarm can
|
|
36
|
+
* correlate the deferred completion safely (a separate, spike-gated PR), background
|
|
37
|
+
* swarm delegations are fail-closed-blocked. We do NOT silently coerce `background` to
|
|
38
|
+
* false — the unsupported capability is surfaced explicitly.
|
|
39
|
+
*/
|
|
40
|
+
export declare const SWARM_BACKGROUND_TASK_BLOCKED_MESSAGE: string;
|
|
41
|
+
/**
|
|
42
|
+
* Fail-closed background-flag detector. Treats both the boolean `true` and the
|
|
43
|
+
* stringified `'true'` as background so a stringified flag cannot bypass the guard.
|
|
44
|
+
*/
|
|
45
|
+
export declare function isBackgroundTrue(value: unknown): boolean;
|
|
46
|
+
/**
|
|
47
|
+
* True when a `Task` tool RESULT looks like an OpenCode background "running"
|
|
48
|
+
* placeholder (`state: "running"` or `metadata.background === true`). Belt-and-
|
|
49
|
+
* suspenders for `toolAfter`; never throws.
|
|
50
|
+
*/
|
|
51
|
+
export declare function outputLooksLikeBackgroundRunning(output: unknown): boolean;
|
|
28
52
|
/**
|
|
29
53
|
* Parses a string to extract a DelegationEnvelope.
|
|
30
54
|
* Returns null if no valid envelope is found.
|