total-recall-brain 3.47.2 → 3.47.3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "total-recall-brain",
3
- "version": "3.47.2",
3
+ "version": "3.47.3",
4
4
  "description": "The Vibe Coding Brain & Autonomous Software Factory: memory, rules, secrets, and 33 visual plugins automatically managed across all your devices.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "tr-plugin-meta-harness",
3
- "version": "0.4.2",
3
+ "version": "0.4.3",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "tr-plugin-meta-harness",
9
- "version": "0.4.2",
9
+ "version": "0.4.3",
10
10
  "dependencies": {
11
11
  "@gregiteen/ssss-cli": "0.14.5"
12
12
  },
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tr-plugin-meta-harness",
3
- "version": "0.4.2",
3
+ "version": "0.4.3",
4
4
  "description": "Total Recall Metaharness plugin",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "id": "meta-harness",
3
3
  "name": "Metaharness",
4
- "version": "0.4.2",
4
+ "version": "0.4.3",
5
5
  "description": "Discover, configure, document, track, and run coding agent harnesses through Total Recall across mesh nodes.",
6
6
  "gate": {
7
7
  "tasks": ["Run work in another agent harness", "Choose which harness takes a task", "Check harness versions, sign-in and quota", "Read a harness's official documentation"],
@@ -20,7 +20,11 @@ export function queryAiModels(harness, model, { bin = process.env.TOTAL_RECALL_B
20
20
  const line = output.trim().split('\n').filter(Boolean).at(-1);
21
21
  try {
22
22
  const answer = JSON.parse(line);
23
- return answer && typeof answer.ok === 'boolean' ? answer : null;
23
+ if (!answer || typeof answer.ok !== 'boolean') return null;
24
+ // An error reply (an older ai-models without `validate` answers invalid_arguments) is the command
25
+ // failing, not a verdict on the model; reading it as one would refuse every model.
26
+ if (answer.error != null || answer.code != null) return null;
27
+ return answer;
24
28
  } catch { return null; }
25
29
  }
26
30
 
@@ -32,7 +36,7 @@ export function createModelValidator({ aiModels = queryAiModels, catalog = getMo
32
36
  if (refusal) return { ok: false, harness, model, source: 'policy', reason: refusal };
33
37
  if (ownerAnswers) {
34
38
  const answer = aiModels(harness, model);
35
- if (answer) return { ok: answer.ok, harness, model, source: 'ai-models', ...(answer.ok ? {} : { reason: answer.reason || answer.error || `AI Models does not list ${model} for ${harness}` }) };
39
+ if (answer) return { ok: answer.ok, harness, model, source: 'ai-models', ...(answer.ok ? {} : { reason: answer.reason || `AI Models does not list ${model} for ${harness}` }) };
36
40
  ownerAnswers = false;
37
41
  }
38
42
  // Another node's catalog is not this one's: its destination validates against its own.
@@ -18,10 +18,10 @@ import { classifyTaskComplexity, selectOptimalHarness, computeEmpiricalScorecard
18
18
  import { inspectAgents } from './worker.mjs';
19
19
  import { inspectNode } from './executor.mjs';
20
20
  import { getModelCatalog, joinHarnessModels } from './model-catalog.mjs';
21
- import { readReceipts, activeQuotaWalls, activeCredentialBlocks, includedBillingReceipts } from './learner.mjs';
21
+ import { readReceipts, activeQuotaWalls, activeCredentialBlocks, includedBillingReceipts, recordRunReceipt } from './learner.mjs';
22
22
  import { resolvePool, exclusionReason, isLocalExecutionNode } from './pool.mjs';
23
23
  import { readCodexRateLimits, measuredWalls } from './telemetry.mjs';
24
- import { claudeProofCurrent, INCLUDED_AGENTS, readIncludedPolicy } from './included-usage.mjs';
24
+ import { claudeProofCurrent, INCLUDED_AGENTS, readIncludedPolicy, readCodexAllowance } from './included-usage.mjs';
25
25
  import { derivedDir } from './paths.mjs';
26
26
  import { createModelValidator, filterPoolByModel } from './model-selection.mjs';
27
27
 
@@ -286,7 +286,26 @@ export async function routeTask(taskDescription, options = {}) {
286
286
  ...(remote || lean.fleet ? {} : { fleet: complexity.tier === 'local' ? cachedFleet : () => ({ ok: false, error: 'Not read: this route places no local work', nodes: [] }) }),
287
287
  });
288
288
  const quotas = quotaReport.quotas;
289
- const routing = selectOptimalHarness(taskDescription, pool.ready.map(h => h.id), quotas, { ...options, tierOverride: complexity.tier, empiricalScorecard: computeEmpiricalScorecard(receipts) });
289
+ const rank = ready => selectOptimalHarness(taskDescription, ready.map(h => h.id), quotas, { ...options, tierOverride: complexity.tier, empiricalScorecard: computeEmpiricalScorecard(receipts) });
290
+ let excluded = pool.excluded;
291
+ let routing = rank(pool.ready);
292
+ // Quota walls come from launches this machine saw refused. With none recorded here, a route kept
293
+ // choosing a Codex that was out of quota, and the selected-harness write gate then blocked every
294
+ // other harness. Before choosing Codex, ask it for its allowance (no turn), and record a quota
295
+ // answer as the wall a refused launch records (A-124), so later routes skip it without asking.
296
+ if (policy.enabled && !remote && routing.selected === 'codex') {
297
+ const allowance = await (options.codexAllowance || readCodexAllowance)(options.cwd || process.cwd());
298
+ if (allowance?.ok === false && allowance.failureKind === 'quota') {
299
+ const resetsAt = allowance.resetsAt || null;
300
+ try {
301
+ await (options.recordReceipt || recordRunReceipt)({ harness: 'codex', role: 'Route', task: String(taskDescription).slice(0, 200),
302
+ success: false, failureKind: 'quota', billingMode: 'included', error: allowance.error, resetsAt });
303
+ } catch { /* the route still skips Codex; only the next route asks again */ }
304
+ excluded = [...excluded, { harness: 'codex', reason: resetsAt ? `out of quota until ${resetsAt}` : 'out of quota', failureKind: 'quota', resetsAt }];
305
+ quotas.codex = { ...quotas.codex, status: 'exhausted', wallMessage: allowance.error, ...(resetsAt ? { resetsAt } : {}) };
306
+ routing = rank(pool.ready.filter(h => h.id !== 'codex'));
307
+ }
308
+ }
290
309
  const selectedQuota = quotas[routing.selected] || {};
291
310
  const warnings = [];
292
311
  if (policy.enabled && options.jev) warnings.push('Included usage policy uses the local task classifier.');
@@ -298,8 +317,8 @@ export async function routeTask(taskDescription, options = {}) {
298
317
  if (selectedModel?.source === 'unverified') warnings.push(selectedModel.note);
299
318
  return {
300
319
  ok: Boolean(routing.selected), task: taskDescription, classifier, complexity,
301
- selected: routing.selected, tier: complexity.tier, model: options.model ?? null, ...(modelSelection ? { modelSelection } : {}), candidates: routing.candidates, excluded: pool.excluded,
302
- ...(policy.enabled && !routing.selected ? { deferred: pool.excluded.find(row => row.failureKind === 'quota') || null } : {}),
320
+ selected: routing.selected, tier: complexity.tier, model: options.model ?? null, ...(modelSelection ? { modelSelection } : {}), candidates: routing.candidates, excluded,
321
+ ...(policy.enabled && !routing.selected ? { deferred: excluded.find(row => row.failureKind === 'quota') || null } : {}),
303
322
  placement: complexity.tier === 'local' ? placeLocalWork(quotaReport.fleet) : null,
304
323
  scoring: 'Adapter quality and cost scores are configured priors, adjusted by pass rates measured on this machine.',
305
324
  quotaSnapshot: { selectedHarnessStatus: selectedQuota.status || null, selectedHarnessUsage: selectedQuota.usagePercent ?? null, freeMemGB: quotas.system.freeMemGB ?? null },