0xray 3.3.0 → 3.3.1
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/.opencode/codex.codex +1 -1
- package/dist/CHANGELOG.md +10 -0
- package/dist/integrations/grok/grok-cli.js +6 -0
- package/dist/mcps/index.js +1 -0
- package/dist/mcps/knowledge-skills/skill-invocation.server.js +3 -2
- package/dist/mcps/knowledge-skills/storyteller.server.js +167 -0
- package/dist/mcps/orchestrator/execution/execution-planner.js +14 -2
- package/dist/mcps/researcher-confidence.js +92 -0
- package/dist/mcps/researcher.server.js +19 -3
- package/dist/memory-routing/null-provider.js +12 -0
- package/package.json +1 -1
- package/scripts/node/install-bridges.cjs +364 -0
- package/scripts/node/postinstall.cjs +24 -83
- package/scripts/node/setup.cjs +2 -6
- package/scripts/node/universal-version-manager.js +2 -2
- package/src/mcps/index.ts +1 -0
- package/src/mcps/knowledge-skills/skill-invocation.server.ts +3 -2
- package/src/mcps/knowledge-skills/storyteller.server.ts +206 -0
- package/src/mcps/orchestrator/execution/execution-planner.ts +14 -2
- package/src/mcps/orchestrator/types.ts +4 -0
- package/src/mcps/researcher-confidence.ts +144 -0
- package/src/mcps/researcher.server.ts +28 -3
- package/src/opencode/codex.codex +1 -1
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Storyteller MCP Server
|
|
3
|
+
*
|
|
4
|
+
* Returns storyteller SKILL.md guidance plus a session-aware writing prompt.
|
|
5
|
+
* The host LLM writes the story; this server supplies the contract.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { execSync } from 'node:child_process';
|
|
9
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
10
|
+
import { dirname, join } from 'node:path';
|
|
11
|
+
import { fileURLToPath } from 'node:url';
|
|
12
|
+
import { XrayKnowledgeSkillBase } from '../shared/knowledge-skill-base.js';
|
|
13
|
+
|
|
14
|
+
const STORY_TYPES = ['reflection', 'saga', 'journey', 'narrative'] as const;
|
|
15
|
+
type StoryType = (typeof STORY_TYPES)[number];
|
|
16
|
+
|
|
17
|
+
interface WriteStoryArgs {
|
|
18
|
+
title?: string;
|
|
19
|
+
context?: Record<string, unknown>;
|
|
20
|
+
framework?: string;
|
|
21
|
+
output?: string;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function resolveSkillMd(): string {
|
|
25
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
26
|
+
const candidates = [
|
|
27
|
+
join(here, '../../../skills/storyteller/SKILL.md'),
|
|
28
|
+
join(here, '../../skills/storyteller/SKILL.md'),
|
|
29
|
+
join(process.cwd(), 'node_modules/0xray/dist/skills/storyteller/SKILL.md'),
|
|
30
|
+
join(process.cwd(), 'node_modules/xray/dist/skills/storyteller/SKILL.md'),
|
|
31
|
+
];
|
|
32
|
+
|
|
33
|
+
for (const path of candidates) {
|
|
34
|
+
if (existsSync(path)) {
|
|
35
|
+
return readFileSync(path, 'utf-8');
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return '# Storyteller\n\nWrite warmly candid technical reflections with scene-first openings.';
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function getStoryMeta(storyType: StoryType) {
|
|
43
|
+
const defaults: Record<
|
|
44
|
+
StoryType,
|
|
45
|
+
{ location: string; min_words: number; ideal_words: number; framework: string }
|
|
46
|
+
> = {
|
|
47
|
+
reflection: {
|
|
48
|
+
location: 'docs/reflections/',
|
|
49
|
+
min_words: 2000,
|
|
50
|
+
ideal_words: 5000,
|
|
51
|
+
framework: 'three_act_structure',
|
|
52
|
+
},
|
|
53
|
+
saga: {
|
|
54
|
+
location: 'docs/reflections/deep/',
|
|
55
|
+
min_words: 5000,
|
|
56
|
+
ideal_words: 15000,
|
|
57
|
+
framework: 'hero_journey',
|
|
58
|
+
},
|
|
59
|
+
journey: {
|
|
60
|
+
location: 'docs/reflections/deep/',
|
|
61
|
+
min_words: 1500,
|
|
62
|
+
ideal_words: 4000,
|
|
63
|
+
framework: 'three_act_structure',
|
|
64
|
+
},
|
|
65
|
+
narrative: {
|
|
66
|
+
location: 'docs/reflections/',
|
|
67
|
+
min_words: 1000,
|
|
68
|
+
ideal_words: 3000,
|
|
69
|
+
framework: 'three_act_structure',
|
|
70
|
+
},
|
|
71
|
+
};
|
|
72
|
+
return defaults[storyType];
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function gitContext(): string {
|
|
76
|
+
try {
|
|
77
|
+
const commits = execSync('git log --oneline -20 2>/dev/null', { encoding: 'utf-8' });
|
|
78
|
+
const files = execSync(
|
|
79
|
+
'git diff --name-only HEAD~10 2>/dev/null || git ls-files 2>/dev/null | head -50',
|
|
80
|
+
{ encoding: 'utf-8' },
|
|
81
|
+
);
|
|
82
|
+
return `Recent commits:\n${commits}\n\nRecent files:\n${files}`;
|
|
83
|
+
} catch {
|
|
84
|
+
return 'No git context available in this workspace.';
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function buildPrompt(
|
|
89
|
+
storyType: StoryType,
|
|
90
|
+
title: string,
|
|
91
|
+
meta: ReturnType<typeof getStoryMeta>,
|
|
92
|
+
extraContext?: Record<string, unknown>,
|
|
93
|
+
): string {
|
|
94
|
+
const contextBlock = extraContext
|
|
95
|
+
? `\n## Provided context\n${JSON.stringify(extraContext, null, 2)}\n`
|
|
96
|
+
: '';
|
|
97
|
+
|
|
98
|
+
return `Write a ${storyType} titled "${title}".
|
|
99
|
+
|
|
100
|
+
## Requirements
|
|
101
|
+
- Framework: ${meta.framework}
|
|
102
|
+
- Target length: ${meta.ideal_words} words (minimum: ${meta.min_words})
|
|
103
|
+
- Save to: ${meta.location}
|
|
104
|
+
- Follow storyteller SKILL.md voice (warmly candid, scene-first, no executive summary)
|
|
105
|
+
- Include Key Takeaways and What Next sections
|
|
106
|
+
|
|
107
|
+
## Session / repo context
|
|
108
|
+
${gitContext()}
|
|
109
|
+
${contextBlock}
|
|
110
|
+
|
|
111
|
+
Write the complete ${storyType} now.`;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function writeStoryTool(storyType: StoryType, args: WriteStoryArgs) {
|
|
115
|
+
const meta = getStoryMeta(storyType);
|
|
116
|
+
if (args.framework) meta.framework = args.framework;
|
|
117
|
+
|
|
118
|
+
const title =
|
|
119
|
+
args.title ??
|
|
120
|
+
`${storyType.charAt(0).toUpperCase() + storyType.slice(1)} - ${new Date().toISOString().split('T')[0]}`;
|
|
121
|
+
const skillMd = resolveSkillMd();
|
|
122
|
+
const prompt = buildPrompt(storyType, title, meta, args.context);
|
|
123
|
+
const slug = title
|
|
124
|
+
.toLowerCase()
|
|
125
|
+
.replace(/[^a-z0-9]+/g, '-')
|
|
126
|
+
.replace(/^-|-$/g, '');
|
|
127
|
+
const filename = `${storyType}-${slug}-${new Date().toISOString().split('T')[0]}.md`;
|
|
128
|
+
const outputPath = args.output ?? join(meta.location, filename);
|
|
129
|
+
|
|
130
|
+
const outputDir = join(process.cwd(), dirname(outputPath));
|
|
131
|
+
if (!existsSync(outputDir)) mkdirSync(outputDir, { recursive: true });
|
|
132
|
+
|
|
133
|
+
const fullPath = join(process.cwd(), outputPath);
|
|
134
|
+
const frontmatter = `---
|
|
135
|
+
story_type: ${storyType}
|
|
136
|
+
title: "${title}"
|
|
137
|
+
framework: ${meta.framework}
|
|
138
|
+
target_words: ${meta.ideal_words}
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
`;
|
|
142
|
+
|
|
143
|
+
writeFileSync(fullPath, `${frontmatter}\n${prompt}\n`, 'utf-8');
|
|
144
|
+
|
|
145
|
+
return {
|
|
146
|
+
content: [
|
|
147
|
+
{
|
|
148
|
+
type: 'text' as const,
|
|
149
|
+
text: [
|
|
150
|
+
`Storyteller ${storyType} brief prepared.`,
|
|
151
|
+
`Output template: ${outputPath}`,
|
|
152
|
+
'',
|
|
153
|
+
'--- SKILL (excerpt) ---',
|
|
154
|
+
skillMd.slice(0, 4000),
|
|
155
|
+
skillMd.length > 4000 ? '\n...(truncated; full SKILL.md on disk)' : '',
|
|
156
|
+
'',
|
|
157
|
+
'--- WRITING PROMPT ---',
|
|
158
|
+
prompt,
|
|
159
|
+
'',
|
|
160
|
+
'Host LLM: write the full story into the output path using the prompt above.',
|
|
161
|
+
].join('\n'),
|
|
162
|
+
},
|
|
163
|
+
],
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
class StorytellerServer extends XrayKnowledgeSkillBase {
|
|
168
|
+
constructor() {
|
|
169
|
+
super('storyteller', '1.0.0');
|
|
170
|
+
|
|
171
|
+
const writeSchema = {
|
|
172
|
+
type: 'object' as const,
|
|
173
|
+
properties: {
|
|
174
|
+
title: { type: 'string', description: 'Story title' },
|
|
175
|
+
context: { type: 'object', description: 'Session context (commits, changes, notes)' },
|
|
176
|
+
framework: { type: 'string', description: 'Storytelling framework override' },
|
|
177
|
+
output: { type: 'string', description: 'Relative output path' },
|
|
178
|
+
},
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
this.tools = STORY_TYPES.map((storyType) => ({
|
|
182
|
+
name: `write_${storyType}`,
|
|
183
|
+
description: `Prepare ${storyType} story brief using storyteller SKILL.md`,
|
|
184
|
+
inputSchema: writeSchema,
|
|
185
|
+
}));
|
|
186
|
+
|
|
187
|
+
this.handlers = {
|
|
188
|
+
write_reflection: async (args) => writeStoryTool('reflection', args as WriteStoryArgs),
|
|
189
|
+
write_saga: async (args) => writeStoryTool('saga', args as WriteStoryArgs),
|
|
190
|
+
write_journey: async (args) => writeStoryTool('journey', args as WriteStoryArgs),
|
|
191
|
+
write_narrative: async (args) => writeStoryTool('narrative', args as WriteStoryArgs),
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
this.setupToolHandlers();
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
if (import.meta.url === `file://${fileURLToPath(import.meta.url)}`) {
|
|
199
|
+
const server = new StorytellerServer();
|
|
200
|
+
server.run().catch((error) => {
|
|
201
|
+
process.stderr.write(`FATAL: ${String(error)}\n`);
|
|
202
|
+
process.exit(1);
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
export { StorytellerServer };
|
|
@@ -213,15 +213,18 @@ export class ExecutionPlanner {
|
|
|
213
213
|
agentAssignments: Map<string, OrchestrationTask[]>
|
|
214
214
|
): void {
|
|
215
215
|
for (const task of tasks) {
|
|
216
|
-
const complexity = task
|
|
216
|
+
const complexity = this.calculateTaskComplexity(task);
|
|
217
217
|
const requiredCaps = [
|
|
218
218
|
task.type,
|
|
219
219
|
...(task.metadata?.memorySignals ?? []),
|
|
220
220
|
];
|
|
221
|
+
const operationDescription = task.metadata?.memoryHighConfidenceTrap
|
|
222
|
+
? `${task.description} TYPE: ontological-trap`
|
|
223
|
+
: task.description;
|
|
221
224
|
const agent = this.capabilitiesManager.selectAgentForTask(
|
|
222
225
|
requiredCaps,
|
|
223
226
|
complexity,
|
|
224
|
-
|
|
227
|
+
operationDescription,
|
|
225
228
|
) || 'orchestrator';
|
|
226
229
|
|
|
227
230
|
if (!agentAssignments.has(agent)) {
|
|
@@ -346,6 +349,15 @@ export class ExecutionPlanner {
|
|
|
346
349
|
complexity += task.dependencies.length * 5;
|
|
347
350
|
}
|
|
348
351
|
|
|
352
|
+
if (task.metadata?.memoryComplexityBoost !== undefined) {
|
|
353
|
+
complexity += task.metadata.memoryComplexityBoost;
|
|
354
|
+
} else {
|
|
355
|
+
const provider = getProvider();
|
|
356
|
+
if (provider.id !== 'null' && provider.getTaskConfidence) {
|
|
357
|
+
complexity += provider.getTaskConfidence(toMemoryTask(task)).complexityBoost;
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
|
|
349
361
|
return Math.min(Math.max(Math.round(complexity), 1), 100);
|
|
350
362
|
}
|
|
351
363
|
|
|
@@ -19,6 +19,10 @@ export interface OrchestrationTaskMetadata {
|
|
|
19
19
|
synthesisContext?: string;
|
|
20
20
|
ontologicalTrapDetected?: boolean;
|
|
21
21
|
memoryProviderId?: string;
|
|
22
|
+
memorySignalConfidences?: Record<string, number>;
|
|
23
|
+
memoryAvgConfidence?: number;
|
|
24
|
+
memoryHighConfidenceTrap?: boolean;
|
|
25
|
+
memoryComplexityBoost?: number;
|
|
22
26
|
}
|
|
23
27
|
|
|
24
28
|
export interface OrchestrationTask {
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import { frameworkLogger } from '../core/framework-logger.js';
|
|
2
|
+
import { getMemoryRoutingProviderSync } from '../memory-routing/index.js';
|
|
3
|
+
import type {
|
|
4
|
+
MemoryRoutingContext,
|
|
5
|
+
MemoryTaskConfidence,
|
|
6
|
+
} from '../memory-routing/types.js';
|
|
7
|
+
|
|
8
|
+
const TRAP_LANGUAGE = /TYPE:\s*ontological-trap|ontological[- ]trap/i;
|
|
9
|
+
const DEFAULT_MIN_CONFIDENCE_GATE = 0.55;
|
|
10
|
+
|
|
11
|
+
export interface ResearcherMemoryContext {
|
|
12
|
+
providerId: string;
|
|
13
|
+
confidence: MemoryTaskConfidence;
|
|
14
|
+
matchedSignals: string[];
|
|
15
|
+
recommendedAgent: string | null;
|
|
16
|
+
triggeredBy: 'trap-language' | 'high-confidence-primitives';
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function shouldQueryRepertoireConfidence(
|
|
20
|
+
description: string,
|
|
21
|
+
proposalType = '',
|
|
22
|
+
): boolean {
|
|
23
|
+
const text = `${description} ${proposalType}`.trim();
|
|
24
|
+
return TRAP_LANGUAGE.test(text);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function hasHighConfidencePrimitiveMatch(
|
|
28
|
+
routingContext: MemoryRoutingContext,
|
|
29
|
+
minConfidence = DEFAULT_MIN_CONFIDENCE_GATE,
|
|
30
|
+
): boolean {
|
|
31
|
+
const confidences = routingContext.signalConfidences ?? {};
|
|
32
|
+
return Object.values(confidences).some((confidence) => confidence >= minConfidence);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function buildTaskText(
|
|
36
|
+
proposalTitle: string,
|
|
37
|
+
proposalDescription: string,
|
|
38
|
+
proposalType: string,
|
|
39
|
+
): string {
|
|
40
|
+
return [proposalTitle, proposalDescription, proposalType].filter(Boolean).join('\n');
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Resolve Repertoire task confidence for researcher proposal analysis.
|
|
45
|
+
* Triggered by ontological-trap language or high-confidence primitive matches.
|
|
46
|
+
*/
|
|
47
|
+
export function resolveResearcherMemoryContext(input: {
|
|
48
|
+
proposalTitle?: string;
|
|
49
|
+
proposalDescription?: string;
|
|
50
|
+
proposalType?: string;
|
|
51
|
+
}): ResearcherMemoryContext | null {
|
|
52
|
+
const proposalTitle = input.proposalTitle ?? '';
|
|
53
|
+
const proposalDescription = input.proposalDescription ?? '';
|
|
54
|
+
const proposalType = input.proposalType ?? '';
|
|
55
|
+
const taskText = buildTaskText(proposalTitle, proposalDescription, proposalType);
|
|
56
|
+
|
|
57
|
+
const provider = getMemoryRoutingProviderSync();
|
|
58
|
+
if (provider.id === 'null' || !provider.getTaskConfidence) {
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const trapLanguageDetected = shouldQueryRepertoireConfidence(
|
|
63
|
+
proposalDescription,
|
|
64
|
+
proposalType,
|
|
65
|
+
);
|
|
66
|
+
const routingContext = provider.buildRoutingContext(taskText);
|
|
67
|
+
const primitiveMatchDetected = hasHighConfidencePrimitiveMatch(routingContext);
|
|
68
|
+
|
|
69
|
+
if (!trapLanguageDetected && !primitiveMatchDetected) {
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const confidence = provider.getTaskConfidence({
|
|
74
|
+
id: 'researcher-proposal',
|
|
75
|
+
description: taskText,
|
|
76
|
+
type: proposalType || 'governance',
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
const matchedSignals =
|
|
80
|
+
confidence.matchedSignals.length > 0
|
|
81
|
+
? confidence.matchedSignals
|
|
82
|
+
: routingContext.matchedSignals;
|
|
83
|
+
|
|
84
|
+
const context: ResearcherMemoryContext = {
|
|
85
|
+
providerId: provider.id,
|
|
86
|
+
confidence,
|
|
87
|
+
matchedSignals,
|
|
88
|
+
recommendedAgent: confidence.recommendedAgent,
|
|
89
|
+
triggeredBy: trapLanguageDetected ? 'trap-language' : 'high-confidence-primitives',
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
if (confidence.highConfidenceTrapPresent) {
|
|
93
|
+
frameworkLogger.log('mcps/researcher', 'repertoire-trap-detected', 'info', {
|
|
94
|
+
providerId: provider.id,
|
|
95
|
+
matchedSignals,
|
|
96
|
+
complexityBoost: confidence.complexityBoost,
|
|
97
|
+
recommendedAgent: confidence.recommendedAgent,
|
|
98
|
+
triggeredBy: context.triggeredBy,
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
return context;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export function buildMemoryRoutingEvidence(
|
|
106
|
+
context: ResearcherMemoryContext,
|
|
107
|
+
): string[] {
|
|
108
|
+
const { confidence, matchedSignals, recommendedAgent } = context;
|
|
109
|
+
const signalSummary = confidence.signals
|
|
110
|
+
.map((entry) => `${entry.name} (${entry.confidence.toFixed(2)})`)
|
|
111
|
+
.join(', ');
|
|
112
|
+
|
|
113
|
+
const lines = [
|
|
114
|
+
`Repertoire memory routing (${context.providerId}, trigger: ${context.triggeredBy})`,
|
|
115
|
+
`Matched signals: ${matchedSignals.join(', ') || 'none'}`,
|
|
116
|
+
`Signal confidences: ${signalSummary || 'none'}`,
|
|
117
|
+
`High-confidence trap present: ${confidence.highConfidenceTrapPresent}`,
|
|
118
|
+
`Complexity boost: ${confidence.complexityBoost}`,
|
|
119
|
+
];
|
|
120
|
+
|
|
121
|
+
if (recommendedAgent) {
|
|
122
|
+
lines.push(`Recommended agent for trap handling: ${recommendedAgent}`);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
return lines;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export function formatMemoryRoutingBlock(context: ResearcherMemoryContext): string {
|
|
129
|
+
const { confidence, matchedSignals, recommendedAgent } = context;
|
|
130
|
+
const lines = [
|
|
131
|
+
'MEMORY_ROUTING:',
|
|
132
|
+
` provider: ${context.providerId}`,
|
|
133
|
+
` trigger: ${context.triggeredBy}`,
|
|
134
|
+
` matchedSignals: ${matchedSignals.join(', ') || 'none'}`,
|
|
135
|
+
` highConfidenceTrapPresent: ${confidence.highConfidenceTrapPresent}`,
|
|
136
|
+
` complexityBoost: ${confidence.complexityBoost}`,
|
|
137
|
+
];
|
|
138
|
+
|
|
139
|
+
if (recommendedAgent) {
|
|
140
|
+
lines.push(` recommendedAgent: ${recommendedAgent}`);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
return lines.join('\n');
|
|
144
|
+
}
|
|
@@ -13,6 +13,11 @@ import * as fs from "fs";
|
|
|
13
13
|
import * as path from "path";
|
|
14
14
|
import { frameworkLogger } from "../core/framework-logger.js";
|
|
15
15
|
import { tryLLMGovernance } from "../governance/llm-governance-provider.js";
|
|
16
|
+
import {
|
|
17
|
+
buildMemoryRoutingEvidence,
|
|
18
|
+
formatMemoryRoutingBlock,
|
|
19
|
+
resolveResearcherMemoryContext,
|
|
20
|
+
} from "./researcher-confidence.js";
|
|
16
21
|
import { XrayKnowledgeSkillBase } from "./shared/knowledge-skill-base.js";
|
|
17
22
|
|
|
18
23
|
interface SearchResult {
|
|
@@ -452,20 +457,40 @@ class XrayLibrarianServer extends XrayKnowledgeSkillBase {
|
|
|
452
457
|
async analyzeProposal(args: AnalyzeProposalArgs): Promise<CallToolResult> {
|
|
453
458
|
const { proposalTitle = "", proposalDescription = "", evidence = [], proposalType = "" } = args || {};
|
|
454
459
|
|
|
460
|
+
const memoryContext = resolveResearcherMemoryContext({
|
|
461
|
+
proposalTitle,
|
|
462
|
+
proposalDescription,
|
|
463
|
+
proposalType,
|
|
464
|
+
});
|
|
465
|
+
|
|
466
|
+
const enrichedEvidence = [...(evidence || [])];
|
|
467
|
+
if (memoryContext?.confidence.highConfidenceTrapPresent) {
|
|
468
|
+
enrichedEvidence.push(...buildMemoryRoutingEvidence(memoryContext));
|
|
469
|
+
}
|
|
470
|
+
|
|
455
471
|
const vote = await tryLLMGovernance(
|
|
456
472
|
"researcher",
|
|
457
473
|
proposalTitle || "",
|
|
458
474
|
proposalDescription || "",
|
|
459
|
-
|
|
475
|
+
enrichedEvidence,
|
|
460
476
|
proposalType || "",
|
|
461
477
|
);
|
|
462
478
|
|
|
479
|
+
const memoryRoutingBlock =
|
|
480
|
+
memoryContext?.confidence.highConfidenceTrapPresent
|
|
481
|
+
? `\n${formatMemoryRoutingBlock(memoryContext)}`
|
|
482
|
+
: "";
|
|
483
|
+
|
|
463
484
|
if (!vote) {
|
|
485
|
+
const abstainReason = memoryContext?.confidence.highConfidenceTrapPresent
|
|
486
|
+
? "No LLM governance provider configured. Repertoire detected a high-confidence ontological trap — route to the recommended agent before proceeding."
|
|
487
|
+
: "No LLM governance provider configured. Set XRAY_GOVERNANCE_LLM_ENABLED=true + XRAY_LLM_ENDPOINT, or install Hermes and run: hermes auth add xai-oauth --no-browser";
|
|
488
|
+
|
|
464
489
|
return {
|
|
465
490
|
content: [
|
|
466
491
|
{
|
|
467
492
|
type: "text",
|
|
468
|
-
text:
|
|
493
|
+
text: `DECISION: abstain\nCONFIDENCE: 0.50\nREASONING: ${abstainReason}${memoryRoutingBlock}`,
|
|
469
494
|
},
|
|
470
495
|
],
|
|
471
496
|
};
|
|
@@ -475,7 +500,7 @@ class XrayLibrarianServer extends XrayKnowledgeSkillBase {
|
|
|
475
500
|
content: [
|
|
476
501
|
{
|
|
477
502
|
type: "text",
|
|
478
|
-
text: `DECISION: ${vote.decision}\nCONFIDENCE: ${vote.confidence.toFixed(2)}\nREASONING: ${vote.reasoning}`,
|
|
503
|
+
text: `DECISION: ${vote.decision}\nCONFIDENCE: ${vote.confidence.toFixed(2)}\nREASONING: ${vote.reasoning}${memoryRoutingBlock}`,
|
|
479
504
|
},
|
|
480
505
|
],
|
|
481
506
|
};
|
package/src/opencode/codex.codex
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "3.3.
|
|
2
|
+
"version": "3.3.1",
|
|
3
3
|
"terms": [
|
|
4
4
|
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60
|
|
5
5
|
],
|