opencode-ultra 0.9.6 → 0.9.8
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/config.d.ts +85 -0
- package/dist/hooks/comment-checker.d.ts +1 -1
- package/dist/hooks/token-truncation.d.ts +2 -2
- package/dist/index.js +37 -12
- package/dist/safety/sanitizer.d.ts +2 -2
- package/dist/threadweaver/complexity-router.d.ts +35 -0
- package/dist/threadweaver/index.d.ts +9 -0
- package/dist/threadweaver/prompts.d.ts +25 -0
- package/dist/threadweaver/protocol.d.ts +17 -0
- package/dist/threadweaver/roles.d.ts +15 -0
- package/dist/threadweaver/threadweaver-tool.d.ts +9 -0
- package/dist/threadweaver/types.d.ts +81 -0
- package/dist/threadweaver/weighting.d.ts +36 -0
- package/package.json +1 -1
package/dist/config.d.ts
CHANGED
|
@@ -82,6 +82,91 @@ declare const PluginConfigSchema: z.ZodObject<{
|
|
|
82
82
|
implementAgent: z.ZodOptional<z.ZodString>;
|
|
83
83
|
reviewAgent: z.ZodOptional<z.ZodString>;
|
|
84
84
|
}, z.core.$strip>>;
|
|
85
|
+
activeProfile: z.ZodOptional<z.ZodString>;
|
|
86
|
+
profiles: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
87
|
+
agents: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodOptional<z.ZodObject<{
|
|
88
|
+
model: z.ZodOptional<z.ZodString>;
|
|
89
|
+
variant: z.ZodOptional<z.ZodString>;
|
|
90
|
+
category: z.ZodOptional<z.ZodString>;
|
|
91
|
+
temperature: z.ZodOptional<z.ZodNumber>;
|
|
92
|
+
top_p: z.ZodOptional<z.ZodNumber>;
|
|
93
|
+
prompt: z.ZodOptional<z.ZodString>;
|
|
94
|
+
prompt_append: z.ZodOptional<z.ZodString>;
|
|
95
|
+
disable: z.ZodOptional<z.ZodBoolean>;
|
|
96
|
+
description: z.ZodOptional<z.ZodString>;
|
|
97
|
+
mode: z.ZodOptional<z.ZodEnum<{
|
|
98
|
+
subagent: "subagent";
|
|
99
|
+
primary: "primary";
|
|
100
|
+
all: "all";
|
|
101
|
+
}>>;
|
|
102
|
+
maxTokens: z.ZodOptional<z.ZodNumber>;
|
|
103
|
+
thinking: z.ZodOptional<z.ZodObject<{
|
|
104
|
+
type: z.ZodEnum<{
|
|
105
|
+
enabled: "enabled";
|
|
106
|
+
disabled: "disabled";
|
|
107
|
+
}>;
|
|
108
|
+
budgetTokens: z.ZodOptional<z.ZodNumber>;
|
|
109
|
+
}, z.core.$strip>>;
|
|
110
|
+
reasoningEffort: z.ZodOptional<z.ZodEnum<{
|
|
111
|
+
low: "low";
|
|
112
|
+
medium: "medium";
|
|
113
|
+
high: "high";
|
|
114
|
+
xhigh: "xhigh";
|
|
115
|
+
}>>;
|
|
116
|
+
}, z.core.$loose>>>>;
|
|
117
|
+
categories: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
118
|
+
model: z.ZodOptional<z.ZodString>;
|
|
119
|
+
variant: z.ZodOptional<z.ZodString>;
|
|
120
|
+
}, z.core.$loose>>>;
|
|
121
|
+
fragments: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodArray<z.ZodString>>>;
|
|
122
|
+
prompt_renderer: z.ZodOptional<z.ZodObject<{
|
|
123
|
+
default: z.ZodOptional<z.ZodEnum<{
|
|
124
|
+
markdown: "markdown";
|
|
125
|
+
xml: "xml";
|
|
126
|
+
json: "json";
|
|
127
|
+
}>>;
|
|
128
|
+
model_overrides: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodEnum<{
|
|
129
|
+
markdown: "markdown";
|
|
130
|
+
xml: "xml";
|
|
131
|
+
json: "json";
|
|
132
|
+
}>>>;
|
|
133
|
+
}, z.core.$strip>>;
|
|
134
|
+
disabled_agents: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
135
|
+
disabled_hooks: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
136
|
+
disabled_tools: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
137
|
+
disabled_mcps: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
138
|
+
token_truncation: z.ZodOptional<z.ZodObject<{
|
|
139
|
+
maxChars: z.ZodOptional<z.ZodNumber>;
|
|
140
|
+
}, z.core.$strip>>;
|
|
141
|
+
demote_builtin: z.ZodOptional<z.ZodBoolean>;
|
|
142
|
+
background_task: z.ZodOptional<z.ZodObject<{
|
|
143
|
+
defaultConcurrency: z.ZodOptional<z.ZodNumber>;
|
|
144
|
+
providerConcurrency: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodNumber>>;
|
|
145
|
+
modelConcurrency: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodNumber>>;
|
|
146
|
+
staleTimeoutMs: z.ZodOptional<z.ZodNumber>;
|
|
147
|
+
}, z.core.$strip>>;
|
|
148
|
+
comment_checker: z.ZodOptional<z.ZodObject<{
|
|
149
|
+
maxRatio: z.ZodOptional<z.ZodNumber>;
|
|
150
|
+
slopThreshold: z.ZodOptional<z.ZodNumber>;
|
|
151
|
+
}, z.core.$strip>>;
|
|
152
|
+
todo_enforcer: z.ZodOptional<z.ZodObject<{
|
|
153
|
+
maxEnforcements: z.ZodOptional<z.ZodNumber>;
|
|
154
|
+
}, z.core.$strip>>;
|
|
155
|
+
mcp_api_keys: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
156
|
+
safety: z.ZodOptional<z.ZodObject<{
|
|
157
|
+
maxTotalSpawned: z.ZodOptional<z.ZodNumber>;
|
|
158
|
+
agentTimeoutMs: z.ZodOptional<z.ZodNumber>;
|
|
159
|
+
}, z.core.$strip>>;
|
|
160
|
+
evolve_exe: z.ZodOptional<z.ZodObject<{
|
|
161
|
+
maxIterations: z.ZodOptional<z.ZodNumber>;
|
|
162
|
+
iterationTimeoutMs: z.ZodOptional<z.ZodNumber>;
|
|
163
|
+
totalTimeoutMs: z.ZodOptional<z.ZodNumber>;
|
|
164
|
+
skipReview: z.ZodOptional<z.ZodBoolean>;
|
|
165
|
+
skipTests: z.ZodOptional<z.ZodBoolean>;
|
|
166
|
+
implementAgent: z.ZodOptional<z.ZodString>;
|
|
167
|
+
reviewAgent: z.ZodOptional<z.ZodString>;
|
|
168
|
+
}, z.core.$strip>>;
|
|
169
|
+
}, z.core.$loose>>>;
|
|
85
170
|
}, z.core.$loose>;
|
|
86
171
|
export type PluginConfig = z.infer<typeof PluginConfigSchema>;
|
|
87
172
|
export declare function parsePluginConfig(raw: unknown): PluginConfig;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
export declare function truncateMiddle(input:
|
|
1
|
+
export declare function truncateMiddle(input: unknown, maxChars: number): string;
|
|
2
2
|
export declare function createTokenTruncationHook(internalSessions: Set<string>, maxChars?: number): (input: {
|
|
3
3
|
tool: string | {
|
|
4
4
|
name: string;
|
|
5
5
|
};
|
|
6
6
|
sessionID: string;
|
|
7
7
|
}, output: {
|
|
8
|
-
output:
|
|
8
|
+
output: unknown;
|
|
9
9
|
}) => void;
|
package/dist/index.js
CHANGED
|
@@ -14661,7 +14661,7 @@ var CategoryConfigSchema = exports_external.object({
|
|
|
14661
14661
|
model: exports_external.string().optional(),
|
|
14662
14662
|
variant: exports_external.string().optional()
|
|
14663
14663
|
}).passthrough();
|
|
14664
|
-
var
|
|
14664
|
+
var BaseConfigSchema = exports_external.object({
|
|
14665
14665
|
agents: AgentOverridesSchema.optional(),
|
|
14666
14666
|
categories: exports_external.record(exports_external.string(), CategoryConfigSchema).optional(),
|
|
14667
14667
|
fragments: exports_external.record(exports_external.string(), exports_external.array(exports_external.string())).optional(),
|
|
@@ -14705,6 +14705,10 @@ var PluginConfigSchema = exports_external.object({
|
|
|
14705
14705
|
reviewAgent: exports_external.string().optional()
|
|
14706
14706
|
}).optional()
|
|
14707
14707
|
}).passthrough();
|
|
14708
|
+
var PluginConfigSchema = BaseConfigSchema.extend({
|
|
14709
|
+
activeProfile: exports_external.string().optional(),
|
|
14710
|
+
profiles: exports_external.record(exports_external.string(), BaseConfigSchema).optional()
|
|
14711
|
+
});
|
|
14708
14712
|
function parsePluginConfig(raw) {
|
|
14709
14713
|
const result = PluginConfigSchema.safeParse(raw);
|
|
14710
14714
|
if (result.success)
|
|
@@ -14772,6 +14776,23 @@ function detectConfigFile(basePath) {
|
|
|
14772
14776
|
return basePath + ".json";
|
|
14773
14777
|
return null;
|
|
14774
14778
|
}
|
|
14779
|
+
function resolveProfile(config2) {
|
|
14780
|
+
const profiles = config2.profiles;
|
|
14781
|
+
if (!profiles)
|
|
14782
|
+
return config2;
|
|
14783
|
+
const profileName = process.env.OPENCODE_ULTRA_PROFILE || config2.activeProfile;
|
|
14784
|
+
if (!profileName)
|
|
14785
|
+
return config2;
|
|
14786
|
+
const profile = profiles[profileName];
|
|
14787
|
+
if (!profile) {
|
|
14788
|
+
log(`Profile "${profileName}" not found. Available: ${Object.keys(profiles).join(", ")}`);
|
|
14789
|
+
return config2;
|
|
14790
|
+
}
|
|
14791
|
+
const { profiles: _p, activeProfile: _a2, ...base } = config2;
|
|
14792
|
+
const merged = mergeConfigs(base, profile);
|
|
14793
|
+
log(`Profile "${profileName}" activated`);
|
|
14794
|
+
return merged;
|
|
14795
|
+
}
|
|
14775
14796
|
function loadConfig(projectDir) {
|
|
14776
14797
|
const userPath = detectConfigFile(path.join(getConfigDir(), "opencode-ultra"));
|
|
14777
14798
|
let config2 = {};
|
|
@@ -14795,6 +14816,7 @@ function loadConfig(projectDir) {
|
|
|
14795
14816
|
log(`Error loading project config: ${err}`);
|
|
14796
14817
|
}
|
|
14797
14818
|
}
|
|
14819
|
+
config2 = resolveProfile(config2);
|
|
14798
14820
|
return config2;
|
|
14799
14821
|
}
|
|
14800
14822
|
|
|
@@ -27942,7 +27964,8 @@ var INJECTION_PATTERNS = [
|
|
|
27942
27964
|
{ pattern: /(?:\u65B0\u3057\u3044|\u66F4\u65B0\u3055\u308C\u305F)\u6307\u793A\s*[:\uFF1A]/i, label: "new-instructions-ja" }
|
|
27943
27965
|
];
|
|
27944
27966
|
var SUSPICIOUS_UNICODE = /[\u200B-\u200F\u202A-\u202E\u2060-\u2069\uFEFF\u00AD]/g;
|
|
27945
|
-
function sanitizeAgentOutput(
|
|
27967
|
+
function sanitizeAgentOutput(input) {
|
|
27968
|
+
let text = typeof input === "string" ? input : JSON.stringify(input) ?? "";
|
|
27946
27969
|
const warnings = [];
|
|
27947
27970
|
const invisibleCount = (text.match(SUSPICIOUS_UNICODE) || []).length;
|
|
27948
27971
|
if (invisibleCount > 0) {
|
|
@@ -28277,7 +28300,7 @@ async function runAgent(ctx, task, toolCtx, internalSessions, resilience, provid
|
|
|
28277
28300
|
}), { maxAttempts: 3 });
|
|
28278
28301
|
const messages = messagesResp.data ?? [];
|
|
28279
28302
|
const lastAssistant = messages.filter((m) => m.info?.role === "assistant").pop();
|
|
28280
|
-
const rawResult = lastAssistant?.parts?.filter((p) => p.type === "text" && p.text).map((p) => p.text).join(`
|
|
28303
|
+
const rawResult = lastAssistant?.parts?.filter((p) => p.type === "text" && p.text).map((p) => typeof p.text === "string" ? p.text : JSON.stringify(p.text)).join(`
|
|
28281
28304
|
`) ?? "(No response from agent)";
|
|
28282
28305
|
internalSessions.delete(id);
|
|
28283
28306
|
await ctx.client.session.delete({ path: { id }, query: { directory: ctx.directory } }).catch(() => {});
|
|
@@ -30534,7 +30557,8 @@ function createCommentCheckerHook(internalSessions, maxRatio = 0.3, slopThreshol
|
|
|
30534
30557
|
const content = fs12.readFileSync(filePath, "utf-8");
|
|
30535
30558
|
const result = checkComments(content, filePath, maxRatio, slopThreshold);
|
|
30536
30559
|
if (result.shouldWarn) {
|
|
30537
|
-
output.output
|
|
30560
|
+
const current = typeof output.output === "string" ? output.output : JSON.stringify(output.output) ?? "";
|
|
30561
|
+
output.output = current + `
|
|
30538
30562
|
|
|
30539
30563
|
[Comment Checker] ${result.message}`;
|
|
30540
30564
|
log(`Comment Checker warning: ${filePath}`, {
|
|
@@ -30549,13 +30573,14 @@ function createCommentCheckerHook(internalSessions, maxRatio = 0.3, slopThreshol
|
|
|
30549
30573
|
// src/hooks/token-truncation.ts
|
|
30550
30574
|
var DEFAULT_MAX_CHARS = 30000;
|
|
30551
30575
|
function truncateMiddle(input, maxChars) {
|
|
30576
|
+
const text = typeof input === "string" ? input : JSON.stringify(input) ?? "";
|
|
30552
30577
|
if (!Number.isFinite(maxChars) || maxChars <= 0)
|
|
30553
|
-
return
|
|
30554
|
-
if (
|
|
30555
|
-
return
|
|
30578
|
+
return text;
|
|
30579
|
+
if (text.length <= maxChars)
|
|
30580
|
+
return text;
|
|
30556
30581
|
if (maxChars < 32)
|
|
30557
|
-
return
|
|
30558
|
-
const len =
|
|
30582
|
+
return text.slice(0, maxChars);
|
|
30583
|
+
const len = text.length;
|
|
30559
30584
|
let head = Math.floor(maxChars * 0.4);
|
|
30560
30585
|
let tail = Math.floor(maxChars * 0.4);
|
|
30561
30586
|
head = Math.min(Math.max(head, 1), maxChars);
|
|
@@ -30577,9 +30602,9 @@ function truncateMiddle(input, maxChars) {
|
|
|
30577
30602
|
const marker22 = buildMarker(removed22);
|
|
30578
30603
|
const budget = h + marker22.length + finalTail2;
|
|
30579
30604
|
if (budget > maxChars) {
|
|
30580
|
-
return
|
|
30605
|
+
return text.slice(0, maxChars);
|
|
30581
30606
|
}
|
|
30582
|
-
return
|
|
30607
|
+
return text.slice(0, h) + marker22 + text.slice(len - finalTail2);
|
|
30583
30608
|
};
|
|
30584
30609
|
const removed = Math.max(0, len - head - tail);
|
|
30585
30610
|
const marker = buildMarker(removed);
|
|
@@ -30596,7 +30621,7 @@ function createTokenTruncationHook(internalSessions, maxChars = DEFAULT_MAX_CHAR
|
|
|
30596
30621
|
return (input, output) => {
|
|
30597
30622
|
if (internalSessions.has(input.sessionID))
|
|
30598
30623
|
return;
|
|
30599
|
-
const before = output.output;
|
|
30624
|
+
const before = typeof output.output === "string" ? output.output : JSON.stringify(output.output) ?? "";
|
|
30600
30625
|
const after = truncateMiddle(before, budget);
|
|
30601
30626
|
if (after !== before) {
|
|
30602
30627
|
output.output = after;
|
|
@@ -11,9 +11,9 @@ export interface SanitizeResult {
|
|
|
11
11
|
* Sanitize text from agent outputs to prevent prompt injection.
|
|
12
12
|
* Returns the cleaned text plus any warnings.
|
|
13
13
|
*/
|
|
14
|
-
export declare function sanitizeAgentOutput(
|
|
14
|
+
export declare function sanitizeAgentOutput(input: unknown): SanitizeResult;
|
|
15
15
|
/**
|
|
16
16
|
* Apply sanitizer to a spawn_agent result string.
|
|
17
17
|
* Adds a warning banner if injection was detected.
|
|
18
18
|
*/
|
|
19
|
-
export declare function sanitizeSpawnResult(result:
|
|
19
|
+
export declare function sanitizeSpawnResult(result: unknown): string;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ThreadWeaver — Complexity Router
|
|
3
|
+
* Determines standard/heavy mode and sparse-activates relevant agents.
|
|
4
|
+
*/
|
|
5
|
+
import type { AgentRole, ComplexityAnalysis, ThreadWeaverConfig } from "./types";
|
|
6
|
+
/**
|
|
7
|
+
* Compute complexity score (0-11).
|
|
8
|
+
*
|
|
9
|
+
* Token score: 0-3
|
|
10
|
+
* Domain score: 0-3
|
|
11
|
+
* Heavy signal score: 0-3
|
|
12
|
+
* Question score: 0-2
|
|
13
|
+
*/
|
|
14
|
+
export declare function computeComplexityScore(query: string): {
|
|
15
|
+
score: number;
|
|
16
|
+
tokens: number;
|
|
17
|
+
domainCount: number;
|
|
18
|
+
matchedDomains: string[];
|
|
19
|
+
heavySignals: number;
|
|
20
|
+
questions: number;
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Compute domain relevance score for a specialist agent against the query.
|
|
24
|
+
* Returns 0.0-1.0 indicating how relevant this agent is.
|
|
25
|
+
*/
|
|
26
|
+
export declare function computeDomainRelevance(agent: AgentRole, query: string): number;
|
|
27
|
+
/**
|
|
28
|
+
* Sparse-activate specialist agents based on query domain relevance.
|
|
29
|
+
* Returns only specialists above the activation threshold.
|
|
30
|
+
*/
|
|
31
|
+
export declare function sparseActivate(query: string, threshold: number): AgentRole[];
|
|
32
|
+
/**
|
|
33
|
+
* Route complexity and select activated agents.
|
|
34
|
+
*/
|
|
35
|
+
export declare function routeComplexity(query: string, config: ThreadWeaverConfig): ComplexityAnalysis;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ThreadWeaver — Public Exports
|
|
3
|
+
*/
|
|
4
|
+
export { createThreadWeaverTool } from "./threadweaver-tool";
|
|
5
|
+
export { runThreadWeaver, type ThreadWeaverDeps } from "./protocol";
|
|
6
|
+
export { routeComplexity, computeComplexityScore, computeDomainRelevance, sparseActivate } from "./complexity-router";
|
|
7
|
+
export { computeDynamicWeights, extractConfidence, parseCritiques, computeCrossAgreement } from "./weighting";
|
|
8
|
+
export { CORE_ROLES, SPECIALIST_ROLES, ALL_ROLES, getCoreRoles, getAllRoles, findRole } from "./roles";
|
|
9
|
+
export { type ThreadWeaverConfig, type ThreadWeaverResult, type ComplexityLevel, type ComplexityAnalysis, type AgentRole, type AgentOutput, type AgentWeight, type Critique, type Dissent, type RoundResult, type RoundType, DEFAULT_THREADWEAVER_CONFIG, } from "./types";
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ThreadWeaver — Prompt Templates
|
|
3
|
+
* Structured prompts for each round of the debate protocol.
|
|
4
|
+
*/
|
|
5
|
+
import type { AgentRole, AgentOutput, Critique } from "./types";
|
|
6
|
+
/**
|
|
7
|
+
* Build the analysis prompt for Round 1 (parallel initial analysis).
|
|
8
|
+
*/
|
|
9
|
+
export declare function buildAnalysisPrompt(role: AgentRole, query: string): string;
|
|
10
|
+
/**
|
|
11
|
+
* Build the cross-critique prompt for Round 2.
|
|
12
|
+
*/
|
|
13
|
+
export declare function buildCritiquePrompt(role: AgentRole, query: string, round1Outputs: AgentOutput[]): string;
|
|
14
|
+
/**
|
|
15
|
+
* Build the revision prompt for Round 3.
|
|
16
|
+
*/
|
|
17
|
+
export declare function buildRevisionPrompt(role: AgentRole, query: string, ownRound1Output: AgentOutput, critiquesOfMe: Critique[]): string;
|
|
18
|
+
/**
|
|
19
|
+
* Build the synthesis prompt for the Captain (final round).
|
|
20
|
+
*/
|
|
21
|
+
export declare function buildSynthesisPrompt(query: string, round3Outputs: AgentOutput[], weights: Array<{
|
|
22
|
+
agentId: string;
|
|
23
|
+
role: string;
|
|
24
|
+
finalWeight: number;
|
|
25
|
+
}>): string;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ThreadWeaver — Debate Protocol
|
|
3
|
+
* Orchestrates the 3-round debate loop with parallel agent execution.
|
|
4
|
+
*/
|
|
5
|
+
import type { PluginInput, ToolContext } from "@opencode-ai/plugin";
|
|
6
|
+
import { ProviderResilience } from "../shared";
|
|
7
|
+
import type { ConcurrencyPool } from "../concurrency";
|
|
8
|
+
import type { ThreadWeaverConfig, ThreadWeaverResult } from "./types";
|
|
9
|
+
export interface ThreadWeaverDeps {
|
|
10
|
+
pool?: ConcurrencyPool;
|
|
11
|
+
resilience?: ProviderResilience;
|
|
12
|
+
internalSessions: Set<string>;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Main entry point: Run the ThreadWeaver debate protocol.
|
|
16
|
+
*/
|
|
17
|
+
export declare function runThreadWeaver(ctx: PluginInput, query: string, userConfig: Partial<ThreadWeaverConfig>, deps: ThreadWeaverDeps, toolCtx: ToolContext): Promise<ThreadWeaverResult>;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ThreadWeaver — Agent Role Definitions
|
|
3
|
+
* Standard (4 core) + Heavy (16 = 4 core + 12 specialists)
|
|
4
|
+
*/
|
|
5
|
+
import type { AgentRole } from "./types";
|
|
6
|
+
export declare const CORE_ROLES: AgentRole[];
|
|
7
|
+
export declare const SPECIALIST_ROLES: AgentRole[];
|
|
8
|
+
/** All 16 roles (4 core + 12 specialists) */
|
|
9
|
+
export declare const ALL_ROLES: AgentRole[];
|
|
10
|
+
/** Get core roles only (standard mode) */
|
|
11
|
+
export declare function getCoreRoles(): AgentRole[];
|
|
12
|
+
/** Get all roles (heavy mode) */
|
|
13
|
+
export declare function getAllRoles(): AgentRole[];
|
|
14
|
+
/** Find a role by ID */
|
|
15
|
+
export declare function findRole(id: string): AgentRole | undefined;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ThreadWeaver — Tool Registration
|
|
3
|
+
* Registers the threadweaver tool with the OpenCode plugin system.
|
|
4
|
+
*/
|
|
5
|
+
import type { PluginInput } from "@opencode-ai/plugin";
|
|
6
|
+
import { tool } from "@opencode-ai/plugin";
|
|
7
|
+
import type { ThreadWeaverConfig } from "./types";
|
|
8
|
+
import { type ThreadWeaverDeps } from "./protocol";
|
|
9
|
+
export declare function createThreadWeaverTool(ctx: PluginInput, twConfig: Partial<ThreadWeaverConfig>, deps: ThreadWeaverDeps): ReturnType<typeof tool>;
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ThreadWeaver — Multi-Agent Debate Protocol
|
|
3
|
+
* All TypeScript type definitions.
|
|
4
|
+
*/
|
|
5
|
+
export type ComplexityLevel = "standard" | "heavy";
|
|
6
|
+
export interface ThreadWeaverConfig {
|
|
7
|
+
debateRounds: number;
|
|
8
|
+
heavyThreshold: number;
|
|
9
|
+
forceComplexity: ComplexityLevel | null;
|
|
10
|
+
model: string | null;
|
|
11
|
+
activationThreshold: number;
|
|
12
|
+
roundTimeoutMs: number;
|
|
13
|
+
totalTimeoutMs: number;
|
|
14
|
+
saveLedger: boolean;
|
|
15
|
+
}
|
|
16
|
+
export declare const DEFAULT_THREADWEAVER_CONFIG: ThreadWeaverConfig;
|
|
17
|
+
export interface AgentRole {
|
|
18
|
+
id: string;
|
|
19
|
+
role: string;
|
|
20
|
+
grokEquiv: string;
|
|
21
|
+
focus: string;
|
|
22
|
+
/** Domain keywords for sparse activation relevance scoring */
|
|
23
|
+
domains: string[];
|
|
24
|
+
/** For specialist agents, reference to the core role they extend */
|
|
25
|
+
parentRole?: string;
|
|
26
|
+
}
|
|
27
|
+
export type RoundType = "analysis" | "critique" | "revision";
|
|
28
|
+
export interface AgentOutput {
|
|
29
|
+
agentId: string;
|
|
30
|
+
role: string;
|
|
31
|
+
content: string;
|
|
32
|
+
selfConfidence: number;
|
|
33
|
+
durationMs: number;
|
|
34
|
+
error?: string;
|
|
35
|
+
}
|
|
36
|
+
export interface Critique {
|
|
37
|
+
criticId: string;
|
|
38
|
+
targetId: string;
|
|
39
|
+
/** -1 (disagree), 0 (neutral), 1 (agree) */
|
|
40
|
+
agreement: number;
|
|
41
|
+
issues: string[];
|
|
42
|
+
strengths: string[];
|
|
43
|
+
}
|
|
44
|
+
export interface RoundResult {
|
|
45
|
+
roundNumber: number;
|
|
46
|
+
roundType: RoundType;
|
|
47
|
+
outputs: AgentOutput[];
|
|
48
|
+
critiques?: Critique[];
|
|
49
|
+
durationMs: number;
|
|
50
|
+
}
|
|
51
|
+
export interface AgentWeight {
|
|
52
|
+
agentId: string;
|
|
53
|
+
role: string;
|
|
54
|
+
selfConfidence: number;
|
|
55
|
+
crossAgreement: number;
|
|
56
|
+
domainRelevance: number;
|
|
57
|
+
finalWeight: number;
|
|
58
|
+
}
|
|
59
|
+
export interface Dissent {
|
|
60
|
+
topic: string;
|
|
61
|
+
positions: Array<{
|
|
62
|
+
agentId: string;
|
|
63
|
+
position: string;
|
|
64
|
+
}>;
|
|
65
|
+
}
|
|
66
|
+
export interface ThreadWeaverResult {
|
|
67
|
+
query: string;
|
|
68
|
+
complexity: ComplexityLevel;
|
|
69
|
+
activatedAgents: string[];
|
|
70
|
+
rounds: RoundResult[];
|
|
71
|
+
weights: AgentWeight[];
|
|
72
|
+
synthesis: string;
|
|
73
|
+
dissents: Dissent[];
|
|
74
|
+
totalDurationMs: number;
|
|
75
|
+
partial?: boolean;
|
|
76
|
+
}
|
|
77
|
+
export interface ComplexityAnalysis {
|
|
78
|
+
level: ComplexityLevel;
|
|
79
|
+
score: number;
|
|
80
|
+
activatedAgents: AgentRole[];
|
|
81
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ThreadWeaver — Dynamic Weighting
|
|
3
|
+
* Computes final weights from self-confidence, cross-agreement, and domain relevance.
|
|
4
|
+
*/
|
|
5
|
+
import type { AgentOutput, AgentWeight, Critique, AgentRole } from "./types";
|
|
6
|
+
/**
|
|
7
|
+
* Extract self-reported confidence from agent output.
|
|
8
|
+
* Looks for "Confidence: X/10" pattern at end of content.
|
|
9
|
+
* Returns 0.0-1.0 (normalized from 0-10 scale).
|
|
10
|
+
* Default: 0.5 if not found.
|
|
11
|
+
*/
|
|
12
|
+
export declare function extractConfidence(content: string): number;
|
|
13
|
+
/**
|
|
14
|
+
* Parse critique blocks from an agent's round-2 output.
|
|
15
|
+
*
|
|
16
|
+
* Expected format:
|
|
17
|
+
* ## Re: [agent-id]
|
|
18
|
+
* Agreement: 1 (or 0, -1)
|
|
19
|
+
* Issues: ...
|
|
20
|
+
* Strengths: ...
|
|
21
|
+
*/
|
|
22
|
+
export declare function parseCritiques(criticId: string, content: string): Critique[];
|
|
23
|
+
/**
|
|
24
|
+
* Compute cross-agreement score for an agent.
|
|
25
|
+
* Average of all agreement values from other agents, normalized to 0-1.
|
|
26
|
+
* agreement: -1 → 0.0, 0 → 0.5, 1 → 1.0
|
|
27
|
+
*/
|
|
28
|
+
export declare function computeCrossAgreement(agentId: string, allCritiques: Critique[]): number;
|
|
29
|
+
/**
|
|
30
|
+
* Compute dynamic weights for all agents after all rounds.
|
|
31
|
+
*
|
|
32
|
+
* Formula:
|
|
33
|
+
* raw_weight = (selfConfidence * 0.25) + (crossAgreement * 0.45) + (domainRelevance * 0.30)
|
|
34
|
+
* final_weight = raw_weight / sum(all_raw_weights)
|
|
35
|
+
*/
|
|
36
|
+
export declare function computeDynamicWeights(outputs: AgentOutput[], allCritiques: Critique[], activatedRoles: AgentRole[], query: string): AgentWeight[];
|