@hecer/yoke 1.21.1 → 1.23.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/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/CHANGELOG.md +48 -0
- package/README.md +8 -1
- package/TODOS.md +6 -0
- package/bench/analyze-codex-comparison.mjs +90 -17
- package/bench/compare-codex.mjs +159 -36
- package/bench/result-schema.mjs +132 -0
- package/canon/manifest.yaml +1 -1
- package/canon/skills/visual-verification/SKILL.md +25 -2
- package/canon/tools/codex-rtk-hook.mjs +6 -16
- package/dist/agents/pi-telemetry.js +2 -1
- package/dist/agents/process-streams.js +12 -64
- package/dist/agents/provider-selection.js +12 -0
- package/dist/agents/telemetry.js +52 -52
- package/dist/change/inbox.js +8 -3
- package/dist/check/command.js +69 -17
- package/dist/check/delivery.js +121 -0
- package/dist/cli.js +91 -3
- package/dist/code-intelligence/adapters/mcp.js +1 -0
- package/dist/code-intelligence/budgets.js +138 -0
- package/dist/code-intelligence/contracts.js +2 -0
- package/dist/code-intelligence/coordinator.js +159 -85
- package/dist/code-intelligence/evidence.js +87 -34
- package/dist/code-intelligence/index.js +1 -0
- package/dist/code-intelligence/mcp-client.js +25 -6
- package/dist/code-intelligence/mcp-server.js +14 -11
- package/dist/code-intelligence/preflight.js +71 -0
- package/dist/dashboard/analytics.js +5 -3
- package/dist/goals/command.js +183 -53
- package/dist/goals/usage.js +87 -0
- package/dist/loop/cache-isolation.js +36 -0
- package/dist/loop/candidate-cleanup.js +47 -17
- package/dist/loop/candidates.js +17 -11
- package/dist/loop/dispatcher.js +89 -26
- package/dist/loop/failure.js +104 -0
- package/dist/loop/gate-snapshot.js +19 -0
- package/dist/loop/git.js +1 -1
- package/dist/loop/loop.js +124 -70
- package/dist/loop/parallel-adapters.js +57 -6
- package/dist/loop/parallel-command.js +49 -7
- package/dist/loop/proof-retention.js +70 -0
- package/dist/loop/recovery.js +23 -5
- package/dist/loop/reporter.js +22 -5
- package/dist/loop/run-command.js +101 -47
- package/dist/loop/runner.js +6 -5
- package/dist/loop/worker.js +152 -91
- package/dist/observability/history.js +2 -1
- package/dist/observability/invocation.js +42 -0
- package/dist/observability/local-report.js +120 -0
- package/dist/observability/usage.js +19 -0
- package/dist/prd/command.js +20 -7
- package/dist/prd/decompose.js +5 -2
- package/dist/retrofit/config.js +29 -2
- package/dist/retrofit/gitignore.js +12 -0
- package/dist/retrofit/planners/codex.js +20 -20
- package/dist/routing/attempts.js +241 -0
- package/dist/routing/capability.js +13 -9
- package/dist/routing/optimization.js +73 -0
- package/dist/routing/registry.js +7 -1
- package/dist/routing/router.js +282 -127
- package/dist/setup/command.js +8 -2
- package/dist/smoke/command.js +387 -85
- package/dist/update/check.js +1 -1
- package/docs/BENCHMARK-MANIFEST.md +131 -0
- package/docs/CODE-INTELLIGENCE.md +43 -1
- package/docs/CODEX-COMPARISON-2026-09-29.md +15 -0
- package/docs/DELIVERY-JOURNEYS.md +206 -0
- package/docs/ECONOMIC-ROUTING.md +180 -0
- package/docs/GOALS.md +61 -4
- package/docs/RELEASE-VALIDATION-1.22.0.md +115 -0
- package/docs/RELEASE-VALIDATION-1.23.0.md +39 -0
- package/docs/benchmarks/2026-10-04-efficiency/ANALYSE.md +182 -0
- package/docs/benchmarks/2026-10-04-efficiency/compare-help.py +55 -0
- package/docs/benchmarks/2026-10-04-efficiency/manifest.json +125 -0
- package/docs/benchmarks/2026-10-04-efficiency/provenance-analysis.json +90 -0
- package/docs/benchmarks/2026-10-04-efficiency/provenance-design.json +90 -0
- package/docs/benchmarks/2026-10-04-efficiency/provenance-original-report.json +90 -0
- package/docs/benchmarks/2026-10-04-efficiency/raw/DEVELOPMENT_ANALYSIS.md +142 -0
- package/docs/benchmarks/2026-10-04-efficiency/raw/RESULT.md +21 -0
- package/docs/benchmarks/2026-10-04-efficiency/raw/commands.jsonl +26 -0
- package/docs/benchmarks/2026-10-04-efficiency/raw/environment.json +31 -0
- package/docs/benchmarks/2026-10-04-efficiency/raw/final-yoke-smoke.json +40 -0
- package/docs/benchmarks/2026-10-04-efficiency/raw/model-purpose-hints.csv +19 -0
- package/docs/benchmarks/2026-10-04-efficiency/raw/observations.jsonl +21 -0
- package/docs/benchmarks/2026-10-04-efficiency/raw/observer-command-phases.csv +12 -0
- package/docs/benchmarks/2026-10-04-efficiency/raw/roles.csv +5 -0
- package/docs/benchmarks/2026-10-04-efficiency/raw/shell-categories.csv +8 -0
- package/docs/benchmarks/2026-10-04-efficiency/raw/stories.csv +8 -0
- package/docs/benchmarks/2026-10-04-efficiency/raw/summary.json +469 -0
- package/docs/benchmarks/2026-10-04-efficiency/raw/yoke-history.jsonl +104 -0
- package/docs/benchmarks/2026-10-04-efficiency/raw/yoke-loop-1.log +58 -0
- package/docs/benchmarks/2026-10-04-efficiency/raw/yoke-loop-2.log +29 -0
- package/docs/benchmarks/2026-10-04-efficiency/raw/yoke-loop-3.log +5 -0
- package/docs/benchmarks/2026-10-04-efficiency/raw/yoke-loop-4.log +12 -0
- package/docs/benchmarks/2026-10-04-efficiency/raw/yoke-phases.csv +10 -0
- package/docs/benchmarks/2026-10-04-efficiency/regression-comparison.json +104 -0
- package/docs/parallel-execution.md +37 -9
- package/docs/superpowers/plans/2026-10-04-yoke-1.23-efficiency-prd.json +11 -0
- package/docs/superpowers/plans/2026-10-04-yoke-1.23-efficiency.md +83 -0
- package/docs/superpowers/specs/2026-10-04-yoke-1.23-efficiency-design.md +120 -0
- package/gemini-extension.json +1 -1
- package/package.json +1 -1
|
@@ -12,6 +12,7 @@ export class McpStdioClient {
|
|
|
12
12
|
pending = new Map();
|
|
13
13
|
nextId = 1;
|
|
14
14
|
stderrBytes = 0;
|
|
15
|
+
closing;
|
|
15
16
|
constructor(command, args, cwd, framing = 'content-length', maxBytes = 2_000_000) {
|
|
16
17
|
this.command = command;
|
|
17
18
|
this.args = args;
|
|
@@ -20,12 +21,26 @@ export class McpStdioClient {
|
|
|
20
21
|
this.maxBytes = maxBytes;
|
|
21
22
|
}
|
|
22
23
|
async call(tool, arguments_, timeoutMs) {
|
|
24
|
+
const deadline = Date.now() + timeoutMs;
|
|
23
25
|
await this.start(timeoutMs);
|
|
24
|
-
|
|
26
|
+
const remaining = deadline - Date.now();
|
|
27
|
+
if (remaining <= 0) {
|
|
28
|
+
void this.close();
|
|
29
|
+
throw new Error('MCP call deadline exceeded during initialization');
|
|
30
|
+
}
|
|
31
|
+
return this.request('tools/call', { name: tool, arguments: arguments_ }, remaining);
|
|
32
|
+
}
|
|
33
|
+
async listTools(timeoutMs) {
|
|
34
|
+
const deadline = Date.now() + timeoutMs;
|
|
35
|
+
await this.start(timeoutMs);
|
|
36
|
+
const result = await this.request('tools/list', {}, deadline - Date.now());
|
|
37
|
+
if (!Array.isArray(result.tools))
|
|
38
|
+
throw new Error('MCP backend did not advertise tools');
|
|
39
|
+
return result.tools.map(tool => tool.name).filter((name) => typeof name === 'string');
|
|
25
40
|
}
|
|
26
41
|
async close() {
|
|
27
42
|
if (!this.child)
|
|
28
|
-
return;
|
|
43
|
+
return this.closing;
|
|
29
44
|
const child = this.child;
|
|
30
45
|
this.child = undefined;
|
|
31
46
|
for (const pending of this.pending.values()) {
|
|
@@ -33,12 +48,14 @@ export class McpStdioClient {
|
|
|
33
48
|
pending.reject(new Error('MCP process closed'));
|
|
34
49
|
}
|
|
35
50
|
this.pending.clear();
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
child.kill('SIGKILL'); resolve(); }, 500);
|
|
51
|
+
this.closing = new Promise(resolve => {
|
|
52
|
+
const timer = setTimeout(() => { if (child.exitCode === null && child.signalCode === null)
|
|
53
|
+
child.kill('SIGKILL'); }, 500);
|
|
40
54
|
child.once('close', () => { clearTimeout(timer); resolve(); });
|
|
41
55
|
});
|
|
56
|
+
child.kill('SIGTERM');
|
|
57
|
+
await this.closing;
|
|
58
|
+
this.closing = undefined;
|
|
42
59
|
}
|
|
43
60
|
async start(timeoutMs) {
|
|
44
61
|
if (this.child)
|
|
@@ -60,6 +77,8 @@ export class McpStdioClient {
|
|
|
60
77
|
return Promise.resolve();
|
|
61
78
|
}
|
|
62
79
|
request(method, params, timeoutMs) {
|
|
80
|
+
if (timeoutMs <= 0)
|
|
81
|
+
return Promise.reject(new Error(`MCP request deadline exceeded: ${method}`));
|
|
63
82
|
if (!this.child)
|
|
64
83
|
return Promise.reject(new Error('MCP process is not running'));
|
|
65
84
|
const id = this.nextId++;
|
|
@@ -2,24 +2,27 @@
|
|
|
2
2
|
import { CodeIntelligenceCoordinator } from './coordinator.js';
|
|
3
3
|
import { TOOL_DEFINITIONS } from './contracts.js';
|
|
4
4
|
import { loadConfig } from '../retrofit/config.js';
|
|
5
|
+
import { workspaceId } from './snapshots.js';
|
|
5
6
|
const INPUT_SCHEMAS = {
|
|
6
7
|
code_context: { type: 'object', required: ['workspace_id', 'query'], properties: { workspace_id: { type: 'string' }, query: { type: 'string' }, snapshot_id: { type: 'string' }, mode: { type: 'string', enum: ['orient', 'locate', 'explain'] }, paths: { type: 'array', items: { type: 'string' } }, include_docs: { type: 'boolean' }, token_budget: { type: 'integer' }, timeout_ms: { type: 'integer' } } },
|
|
7
|
-
code_symbol: { type: 'object', required: ['workspace_id', 'snapshot_id'], properties: { workspace_id: { type: 'string' }, snapshot_id: { type: 'string' }, symbol_id: { type: 'string' }, query: { type: 'string' }, path: { type: 'string' }, include: { type: 'array' } } },
|
|
8
|
-
code_trace: { type: 'object', required: ['workspace_id', 'snapshot_id', 'symbol_id', 'direction', 'relations'], properties: { workspace_id: { type: 'string' }, snapshot_id: { type: 'string' }, symbol_id: { type: 'string' }, direction: { type: 'string', enum: ['in', 'out'] }, relations: { type: 'array' }, max_depth: { type: 'integer' }, max_nodes: { type: 'integer' } } },
|
|
9
|
-
code_impact: { type: 'object', required: ['workspace_id', 'snapshot_id'], properties: { workspace_id: { type: 'string' }, snapshot_id: { type: 'string' }, targets: { type: 'array' }, plan_id: { type: 'string' }, include_docs: { type: 'boolean' }, require_semantic: { type: 'boolean' } } },
|
|
10
|
-
code_edit_preview: { type: 'object', required: ['workspace_id', 'snapshot_id', 'operations', 'validation_profile'], properties: { workspace_id: { type: 'string' }, snapshot_id: { type: 'string' }, operations: { type: 'array' }, validation_profile: { type: 'string', enum: ['default', 'extended'] } } },
|
|
8
|
+
code_symbol: { type: 'object', required: ['workspace_id', 'snapshot_id'], properties: { workspace_id: { type: 'string' }, snapshot_id: { type: 'string' }, symbol_id: { type: 'string' }, query: { type: 'string' }, path: { type: 'string' }, include: { type: 'array' }, token_budget: { type: 'integer', minimum: 128, maximum: 16000 }, timeout_ms: { type: 'integer', minimum: 100, maximum: 60000 } } },
|
|
9
|
+
code_trace: { type: 'object', required: ['workspace_id', 'snapshot_id', 'symbol_id', 'direction', 'relations'], properties: { workspace_id: { type: 'string' }, snapshot_id: { type: 'string' }, symbol_id: { type: 'string' }, direction: { type: 'string', enum: ['in', 'out'] }, relations: { type: 'array' }, max_depth: { type: 'integer' }, max_nodes: { type: 'integer' }, require_resolved: { type: 'boolean' }, timeout_ms: { type: 'integer', minimum: 100, maximum: 60000 } } },
|
|
10
|
+
code_impact: { type: 'object', required: ['workspace_id', 'snapshot_id'], properties: { workspace_id: { type: 'string' }, snapshot_id: { type: 'string' }, targets: { type: 'array' }, plan_id: { type: 'string' }, include_docs: { type: 'boolean' }, require_semantic: { type: 'boolean' }, max_depth: { type: 'integer' }, timeout_ms: { type: 'integer', minimum: 100, maximum: 60000 } } },
|
|
11
|
+
code_edit_preview: { type: 'object', required: ['workspace_id', 'snapshot_id', 'operations', 'validation_profile'], properties: { workspace_id: { type: 'string' }, snapshot_id: { type: 'string' }, operations: { type: 'array' }, validation_profile: { type: 'string', enum: ['default', 'extended'] }, timeout_ms: { type: 'integer', minimum: 100, maximum: 600000 } } },
|
|
11
12
|
code_edit_apply: { type: 'object', required: ['workspace_id', 'plan_id', 'expected_snapshot_id', 'idempotency_key'], properties: { workspace_id: { type: 'string' }, plan_id: { type: 'string' }, expected_snapshot_id: { type: 'string' }, idempotency_key: { type: 'string' } } },
|
|
12
13
|
};
|
|
13
14
|
function arg(name, args) { return args.find(value => value.startsWith(`--${name}=`))?.slice(name.length + 3); }
|
|
14
15
|
function summary(response) { return `status=${response.status} snapshot=${response.snapshot_id} warnings=${response.warnings.length} (full result in structuredContent)`; }
|
|
15
|
-
export async function runCodeIntelligenceServer(argv = process.argv.slice(2)) {
|
|
16
|
+
export async function runCodeIntelligenceServer(argv = process.argv.slice(2), io = process) {
|
|
16
17
|
const workspace = arg('workspace', argv) ?? process.cwd();
|
|
17
18
|
const configured = loadConfig(workspace)?.codeIntelligence;
|
|
18
19
|
const mode = arg('mode', argv) ?? configured?.mode ?? 'active';
|
|
20
|
+
const workspaceIdentifier = configured?.workspaceId ?? workspaceId(workspace);
|
|
19
21
|
const coordinator = new CodeIntelligenceCoordinator(workspace, {
|
|
20
22
|
mode,
|
|
23
|
+
workspaceId: workspaceIdentifier,
|
|
21
24
|
policy: { excludePatterns: configured?.policy?.excludePatterns, maxFileBytes: configured?.policy?.maxFileBytes },
|
|
22
|
-
limits:
|
|
25
|
+
limits: configured?.limits,
|
|
23
26
|
graft: configured?.graft, graphify: configured?.graphify, serena: configured?.serena,
|
|
24
27
|
});
|
|
25
28
|
let framing = 'line';
|
|
@@ -27,9 +30,9 @@ export async function runCodeIntelligenceServer(argv = process.argv.slice(2)) {
|
|
|
27
30
|
const send = (message) => {
|
|
28
31
|
const payload = JSON.stringify(message);
|
|
29
32
|
if (framing === 'line')
|
|
30
|
-
|
|
33
|
+
io.stdout.write(`${payload}\n`);
|
|
31
34
|
else
|
|
32
|
-
|
|
35
|
+
io.stdout.write(`Content-Length: ${Buffer.byteLength(payload, 'utf8')}\r\n\r\n${payload}`);
|
|
33
36
|
};
|
|
34
37
|
const handle = async (message) => {
|
|
35
38
|
if (message.method === 'notifications/initialized' || message.method?.startsWith('notifications/'))
|
|
@@ -39,7 +42,7 @@ export async function runCodeIntelligenceServer(argv = process.argv.slice(2)) {
|
|
|
39
42
|
return;
|
|
40
43
|
}
|
|
41
44
|
if (message.method === 'tools/list') {
|
|
42
|
-
send({ jsonrpc: '2.0', id: message.id, result: { tools: TOOL_DEFINITIONS.map(tool => ({ ...tool, inputSchema: INPUT_SCHEMAS[tool.name] })) } });
|
|
45
|
+
send({ jsonrpc: '2.0', id: message.id, result: { tools: TOOL_DEFINITIONS.map(tool => ({ ...tool, inputSchema: { ...INPUT_SCHEMAS[tool.name], properties: { ...INPUT_SCHEMAS[tool.name].properties, workspace_id: { type: 'string', const: workspaceIdentifier, description: 'Accepted identifier for this configured workspace.' } } } })) } });
|
|
43
46
|
return;
|
|
44
47
|
}
|
|
45
48
|
if (message.method === 'tools/call') {
|
|
@@ -51,7 +54,7 @@ export async function runCodeIntelligenceServer(argv = process.argv.slice(2)) {
|
|
|
51
54
|
if (message.id !== undefined)
|
|
52
55
|
send({ jsonrpc: '2.0', id: message.id, error: { code: -32601, message: `method not found: ${message.method}` } });
|
|
53
56
|
};
|
|
54
|
-
|
|
57
|
+
io.stdin.on('data', chunk => {
|
|
55
58
|
buffer = Buffer.concat([buffer, Buffer.from(chunk)]);
|
|
56
59
|
while (buffer.length) {
|
|
57
60
|
let raw;
|
|
@@ -87,7 +90,7 @@ export async function runCodeIntelligenceServer(argv = process.argv.slice(2)) {
|
|
|
87
90
|
catch { /* malformed protocol input is ignored */ }
|
|
88
91
|
}
|
|
89
92
|
});
|
|
90
|
-
await new Promise(resolve => { const stop = () => { process.off('SIGTERM', stop); process.off('SIGINT', stop); void coordinator.close().finally(resolve); }; process.once('SIGTERM', stop); process.once('SIGINT', stop);
|
|
93
|
+
await new Promise(resolve => { const stop = () => { process.off('SIGTERM', stop); process.off('SIGINT', stop); io.stdin.off('end', stop); void coordinator.close().finally(resolve); }; process.once('SIGTERM', stop); process.once('SIGINT', stop); io.stdin.once('end', stop); });
|
|
91
94
|
}
|
|
92
95
|
if (process.argv[1]?.endsWith('code-intelligence-server.js'))
|
|
93
96
|
void runCodeIntelligenceServer();
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { spawnSync } from 'node:child_process';
|
|
2
|
+
import { existsSync, mkdtempSync, readFileSync, rmSync } from 'node:fs';
|
|
3
|
+
import { tmpdir } from 'node:os';
|
|
4
|
+
import { join } from 'node:path';
|
|
5
|
+
import { loadConfig } from '../retrofit/config.js';
|
|
6
|
+
import { workspaceId } from './snapshots.js';
|
|
7
|
+
import { createGraftAdapter, createGraphifyAdapter, createSerenaAdapter } from './adapters/index.js';
|
|
8
|
+
/** Probe protocol capabilities in an empty disposable cwd, never create a target snapshot.
|
|
9
|
+
* Configured commands are arbitrary code and cannot be promised read-only: leave them unprobed. */
|
|
10
|
+
export async function runToolPreflight(root, options = {}) {
|
|
11
|
+
const configured = loadConfig(root)?.codeIntelligence;
|
|
12
|
+
const timeout = Math.min(10000, Math.max(100, options.timeoutMs ?? 2000));
|
|
13
|
+
const version = spawnSync('rtk', ['--version'], { encoding: 'utf8', timeout });
|
|
14
|
+
const native = spawnSync('rtk', ['hook', 'codex'], {
|
|
15
|
+
encoding: 'utf8', timeout,
|
|
16
|
+
input: JSON.stringify({ hook_event_name: 'PreToolUse', permission_mode: 'default', tool_name: 'Bash', tool_input: { command: 'git status' } }),
|
|
17
|
+
});
|
|
18
|
+
let nativeRewrite = false;
|
|
19
|
+
try {
|
|
20
|
+
const result = JSON.parse(native.stdout);
|
|
21
|
+
nativeRewrite = native.status === 0 && result.hookSpecificOutput?.permissionDecision === 'allow' && result.hookSpecificOutput?.updatedInput?.command === 'rtk git status';
|
|
22
|
+
}
|
|
23
|
+
catch { /* native support unavailable */ }
|
|
24
|
+
let hookRegistration = 'missing';
|
|
25
|
+
const hooksPath = join(root, '.codex/hooks.json');
|
|
26
|
+
if (existsSync(hooksPath)) {
|
|
27
|
+
try {
|
|
28
|
+
const hooks = JSON.parse(readFileSync(hooksPath, 'utf8')).hooks?.PreToolUse;
|
|
29
|
+
if (Array.isArray(hooks) && hooks.some(block => ['Bash', '^Bash$'].includes(block.matcher) && Array.isArray(block.hooks) && block.hooks.some((hook) => hook.type === 'command' && hook.command === 'rtk hook codex')))
|
|
30
|
+
hookRegistration = 'configured';
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
hookRegistration = 'invalid';
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
const mode = configured?.mode ?? 'off';
|
|
37
|
+
const probeRoot = mkdtempSync(join(tmpdir(), 'yoke-tool-probe-'));
|
|
38
|
+
const backends = {};
|
|
39
|
+
const definitions = [
|
|
40
|
+
['graft', configured?.graft, createGraftAdapter, ['graft_find_code', 'graft_trace_calls']],
|
|
41
|
+
['graphify', configured?.graphify, createGraphifyAdapter, ['query_graph', 'get_node']],
|
|
42
|
+
['serena-lsp', configured?.serena, createSerenaAdapter, ['find_symbol', 'find_referencing_symbols']],
|
|
43
|
+
];
|
|
44
|
+
try {
|
|
45
|
+
for (const [name, custom, factory, required] of definitions) {
|
|
46
|
+
if (mode === 'off' || custom) {
|
|
47
|
+
backends[name] = { status: 'unprobed', tools: [], missingTools: [...required], reason: mode === 'off' ? 'Configured mode is off.' : 'Custom command/arguments were not executed; read-only behavior cannot be verified.' };
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
const adapter = factory(probeRoot);
|
|
51
|
+
try {
|
|
52
|
+
const tools = await adapter.probe(timeout);
|
|
53
|
+
const missingTools = required.filter(tool => !tools.includes(tool));
|
|
54
|
+
backends[name] = { status: missingTools.length ? 'unavailable' : 'available', tools, missingTools };
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
backends[name] = { status: 'unavailable', tools: [], missingTools: [...required], reason: 'Backend protocol initialization or tools/list failed; target indexing was not attempted.' };
|
|
58
|
+
}
|
|
59
|
+
finally {
|
|
60
|
+
await adapter.close();
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
finally {
|
|
65
|
+
rmSync(probeRoot, { recursive: true, force: true });
|
|
66
|
+
}
|
|
67
|
+
return {
|
|
68
|
+
rtk: { status: nativeRewrite ? 'available' : 'degraded', version: version.status === 0 ? version.stdout.trim() : null, nativeRewrite, hookRegistration, hostActivation: 'unverified', nestedCodeMode: 'unverified', fallback: nativeRewrite ? 'Explicit RTK prefixes remain required for unverified nested code-mode calls; project-hook activation depends on host support and trust.' : 'Use explicit RTK prefixes; update RTK outside this preflight if native Codex support is needed. Use rtk init --codex --dry-run to inspect supported setup flags.' },
|
|
69
|
+
codeIntelligence: { mode, workspaceId: configured?.workspaceId ?? workspaceId(root), status: mode === 'off' ? 'off' : Object.values(backends).every(backend => backend.status === 'available') ? 'available' : 'degraded', backends, probeScope: 'isolated protocol capabilities only', indexFreshness: 'unverified', fallback: 'Use rg and direct source reads; verify backend candidates against source. Target index freshness and exhaustive coverage are unverified.' },
|
|
70
|
+
};
|
|
71
|
+
}
|
|
@@ -50,7 +50,8 @@ export function aggregateMeasurements(events, period) {
|
|
|
50
50
|
for (const target of targets)
|
|
51
51
|
target.activity++;
|
|
52
52
|
if (event.type === 'tokens') {
|
|
53
|
-
const
|
|
53
|
+
const hasCallBreakdown = Array.isArray(data.calls) && data.calls.length > 0;
|
|
54
|
+
const calls = hasCallBreakdown ? data.calls : [{ ...data, actualModel: data.model, durationMs: event.durationMs }];
|
|
54
55
|
for (const item of calls) {
|
|
55
56
|
if (!item || typeof item !== 'object')
|
|
56
57
|
continue;
|
|
@@ -70,7 +71,8 @@ export function aggregateMeasurements(events, period) {
|
|
|
70
71
|
dimensionTargets.push(dimension);
|
|
71
72
|
}
|
|
72
73
|
for (const target of [...targets, get(models, key), get(modelBuckets, JSON.stringify([bucketOf(event.timestamp, period.bucket), provider, model, role])), ...dimensionTargets]) {
|
|
73
|
-
const usageAvailable = call.usageAvailable !== false &&
|
|
74
|
+
const usageAvailable = call.usageAvailable !== false && call.measurementComplete !== false
|
|
75
|
+
&& (hasCallBreakdown || (data.usageAvailable !== false && data.measurementComplete !== false));
|
|
74
76
|
if (usageAvailable) {
|
|
75
77
|
addMetric(target, 'inputTokens', call.inputTokens);
|
|
76
78
|
addMetric(target, 'outputTokens', call.outputTokens);
|
|
@@ -87,7 +89,7 @@ export function aggregateMeasurements(events, period) {
|
|
|
87
89
|
target.unknownCalls++;
|
|
88
90
|
if (finite(call.totalCostUsd))
|
|
89
91
|
target.costReportedCalls++;
|
|
90
|
-
if (call.costMeasurementComplete === false || data.costMeasurementComplete === false)
|
|
92
|
+
if (call.costMeasurementComplete === false || (!hasCallBreakdown && data.costMeasurementComplete === false))
|
|
91
93
|
target.incompleteCosts++;
|
|
92
94
|
}
|
|
93
95
|
}
|