Repository navigation
local cognition: add tool-calling and orchestration SLM portfolio #20
Description
Goal
Add a measured local-model portfolio for tool calling/orchestration to z0intelligence rather than treating one model as a universal winner.
z0intelligence owns the cognition/model-selection plane. The runtime harnesses execute the selected action. AODL remains model-agnostic typed intent/IR, JEV/OpenJev remains the bounded fast decision lane, and deterministic capability/security policy remains authoritative.
Seed candidates
Runtime candidates:
nvidia/Nemotron-Orchestrator-8B— learned orchestration over heterogeneous tools/models; explicitly optimized for quality, latency/cost, and user preferences.Qwen/Qwen3.5-9B— general local reasoning + native agent/tool use candidate.Qwen/Qwen3.5-4B— smaller/faster general agent candidate; evaluate separately rather than assuming 9B dominates every control task.MadeAgents/Hammer2.1-3band optionallyHammer2.1-7b— dedicated multi-step/multi-turn function-calling candidates with irrelevant-tool rejection.google/functiongemma-270m-it— tiny function-calling foundation intended for task-specific fine-tuning; treat as a specialist/action compiler candidate, not a general chat model.
Training method, not a runtime model entry:
- Agent0 — zero-data/self-evolving curriculum + executor training with tool-integrated reasoning. Evolution Lab should own experiments based on this idea.
Primary references:
- https://huggingface.co/nvidia/Nemotron-Orchestrator-8B
- https://huggingface.co/Qwen/Qwen3.5-9B
- https://huggingface.co/Qwen/Qwen3.5-4B
- https://huggingface.co/MadeAgents/Hammer2.1-3b
- https://huggingface.co/MadeAgents/Hammer2.1-7b
- https://huggingface.co/google/functiongemma-270m-it
- https://github.com/aiming-lab/Agent0
Model manifest
Introduce or extend a versioned model/capability manifest with fields such as:
model_id / revision
role_tags
parameter_count
license / gating notes
supported runtimes
quantization
measured_vram
context_limit_tested
tool_template / parser
structured-output support
single / parallel / multi-step / multi-turn calls
irrelevant-tool rejection
supports model-as-tool orchestration
cold_start_ms
ttft_ms
decode_tok_s
decision_latency_ms
confidence / abstention behavior
benchmark_receipt_ids
Do not encode benchmark marketing claims as runtime truth. Store source-reported results separately from reproduced local results.
Control-plane split
Target escalation path:
deterministic algorithm / state machine
-> tiny learned specialist
-> JEV/OpenJev bounded scorer
-> local orchestration SLM
-> local general SLM
-> remote specialist/frontier fallback
The controller should escalate on uncertainty/risk and capability need, not merely prompt length or a static model tier.
The SLM should choose among already legal actions. Graph legality, dependencies, leases, queues, retries, budgets, permissions and destructive-action authority belong to deterministic runtime mechanisms.
First dogfood target
Use one reversible model/tool-routing lane already aligned with #14. Shadow-run candidate decisions against current behavior, preserve complete distributions/receipts where available, and fail open.
Acceptance
- seed candidates represented in a versioned capability/model inventory
- model-specific tool templates/parsers are isolated behind backend adapters
- local runtime probe records real 3080 Ti measurements instead of guessed throughput
- JEV/OpenJev and SLM roles are distinct in the controller
- legal-action filtering occurs before learned selection
- deterministic capability/security policy remains authoritative
- every learned decision can emit a replayable receipt
- runtime can A/B candidates without changing harness semantics
- source-reported benchmark data is separated from reproduced evidence
- Agent0 is linked as a training/evolution recipe, not misclassified as a serving checkpoint
Related: #14.
Activity
kvnloo commentedon Sep 21, 2026
Cross-repo implementation trackers created from this portfolio:
AODL intentionally gets no model-specific tracker. Its contract stays model-agnostic; learned controllers consume legal typed actions rather than becoming IR node kinds.
kvnloo commentedon Sep 21, 2026
Free-capacity execution path now has a concrete DSH credential surface:
z0/bws-free-tier-providersGROQ_API_KEY,CEREBRAS_API_KEYz0intelligence should treat Kerdoios' remaining free capacity as an execution constraint/objective, not own provider quota accounting.
Desired behavior:
Important: route real work to compatible free capacity before it expires, but never lower verified quality just to burn quota. Free-only mode must fail closed before paid spill.
kvnloo commentedon Sep 30, 2026
Hermes is now the next real dogfood harness for this portfolio: kvnloo/hermes-agent#319. Initial matrix is deterministic baseline + JEV reference where available + Laya + Julia-1 + Qwen 3B/current candidate, all shadow-only until outcome-grounded evidence exists.
results(summarize-faithfulness): v0 measured; groot qwen3-8b does not…
kvnloo commentedon Oct 9, 2026
Native OMP trace/stats visibility — plugin-first ownership (2026-10-09)
Kevin correctly challenged placing the complete feature in the OMP repository. The product implementation stays here, using existing
omp-extensions/local-cognition,src/z0int/cognition/shadow.py, cognition receipts and Tokenomics; no new z0 subsystem.Minimal z0intelligence slice:
tool_calland a single configured shadow backend; preserve actual native session ID, tool-call ID and stable z0 receipt/workstream identity. TodaybuildShadowPayloadsupplies a tool-call ID insidefacts, but the Python shadow JSONL receipt does not persist it; random shadow IDs alone are not a reliable join.pi.appendEntrywithout new model-facing messages, tool calls or independent store. Capture successful model invocation separately from request/send success, empty model set, abstain, timeout, invalid proposal, and unavailable./z0int-cognition-statusand add a targeted smoke fixture; no automatic activation, serving or model downloads. Preserve session ownership across late async result/session-switch/restart./trace/stats, while keeping original z0 receipts authoritative. Compute correctness and savings only from independently joined evaluation/outcome evidence.The missing generic browser-native OMP consumer is separately isolated as oh-my-pi#148; that issue has been narrowed from the original overbroad product request. OMP's extension API has
pi.appendEntryand custom-message renderers, but the current native trace parser skips other custom records and stats ingestion has no extension aggregator; hence no supported plugin-only path to its built-in browser dashboards was found on the inspected fork head. If the installed build exposes such an API, use it and close #148. No OMP-specific z0 policy logic.Related existing identities/outcomes: #47, #54, #62; Tokenomics#4. This is a source-backed gap/ownership note, not a runtime qualification or claim that the native UI now displays z0. Preserve contributions from OMP's trace/extension maintainers and z0intelligence's local-cognition authors.
kvnloo commentedon Oct 10, 2026
READY — ZI-20-S (Claude Code lane): local SLM shadow, session/tool correlation, coverage
factory/claude/20-shadow-identity@d1a9f3a915efa16798913d7958b72e3f7f68d4da(three commits on4ac01fc:e068f3e,c8da134,a90e3be,d1a9f3a). Not merged.omp-extensions/local-cognition/{index.ts,index.test.ts,shadow.real-omp.test.ts,README.md},src/z0int/cognition/shadow.py,tests/test_cognition_shadow.py. No reuse/bridge core file touched.Against the plan above:
tool_call_idandtool_name, so it joins without the session entry.z0int-cognition-shadowentry per observation viapi.appendEntry; no model-facing message, tool input not copied. Outcomes distinguish model executed, compiler only (empty model set), unavailable, timeout, error and no transport; per model, selected, abstained, invalid call, unavailable, timeout. A model that never ran is not reported as an abstention./z0int-cognition-statusreports coverage by outcome. A result arriving after a session switch is not written into the new session; it stays in the status ring markedsession_changed.Tests.
bun test omp-extensions/local-cognition/: 20 pass, 1 skip (the gated live test), exit 0.pytest tests/test_cognition_shadow.py tests/test_cognition_surface.py tests/test_cognition_server.py tests/test_bridge_worker.py: 72 passed. New tests were RED before each change.Live qualification (
Z0INT_COGNITION_LIVE_SLM=<model>, real OMP session and extension runtime, real bridge worker, scripted parent model):functiongemma_270mandhammer2.1_3bon the llama.cpp supervisor each gave 3 of 3 tool calls observed, settled as model executed, with session ids, tool-call ids, trace ids and receipt tool-call ids all matching, and zero model-facing messages.Negative evidence.
hammer2.1_3btook about 11 s, above the lane's 4 s timeout; first observations after a load record as timeouts.pi.appendEntrythrows until the runtime is initialized; the live test binds it with OMP's owninitializeExtensions.Omitted: correctness or savings claims; nothing here measures whether the shadow model's choice was right. Consumer: Codex for integration; z0evals for any outcome join.
kvnloo commentedon Oct 10, 2026
READY — shadow lane: one time budget for the extension and the worker (cold-load behavior)
factory/claude/20-shadow-timeout-budget@c7256f11aee74e1e9a2649e0ad7a224fa272d874; baseline:bd07c5d(tip offactory/claude/20-shadow-identity). Not merged.omp-extensions/local-cognition/{index.ts,index.test.ts,README.md},tests/test_cognition_shadow.py. No Python source change.Defect. The extension gives up after 4 s but sent no budget; the worker defaulted to 30 s. On a slow model the session entry said
timeoutwith no model detail while the worker kept waiting and later wrote a receipt saying the model answered. Two records of one tool call disagreed.Fix. The extension sends 80% of its timeout as
timeout_ms. Offline, with a worker stand-in and a model needing 250 ms against a 100 ms budget:timeout, no model rowstimeout, model rowtimeouttimeout, inside the budgetTests.
bun test omp-extensions/local-cognition/: 22 pass, 1 skip (gated live test), exit 0; the new extension test failed on the baseline.pytest tests/test_cognition_shadow.py tests/test_cognition_surface.py tests/test_cognition_server.py tests/test_bridge_worker.py: 74 passed. The two new Python tests pin existing worker behavior (it honorstimeout_mson a slow backend, previously untested); they are not RED→GREEN.Not fixed, by design. A cold load (about 11 s measured for
hammer2.1_3b) still exceeds a 4 s budget; those observations are now timeouts in both records. No model service was started for this change. Cost: no model calls.kvnloo commentedon Oct 10, 2026
READY (Claude lane): cold-load timeout behavior, bounded offline tests
Branch
factory/claude/20-shadow-timeout-evidence@f299b1a5706b21aa382b84a68d24176945944567, one commit onc7256f1(factory/claude/20-shadow-timeout-budget). Files:src/z0int/cognition/shadow.py,tests/test_cognition_shadow.py. No model server was started; every test uses a fake backend.Defect. A shadow call that hit its budget was written as
error: shadow_timeoutwithlatency_ms: 0.0and nothing else. A model still loading was indistinguishable from an instant miss, and averaging latency over rows pulled the number down.Change. Timeout rows now carry
timed_out: trueandwaited_ms.latency_msstays 0 because no inference completed. Rows that failed for another reason (unreachable, not served) carry neither field.Tests
c7256f1: 2 of the 3 new tests fail withKeyError: 'timed_out'.f299b1a:tests/test_cognition_shadow.py27 passed; the timeout tests passed on 3 consecutive runs; alltests/test_cognition_*.py193 passed; extensionindex.test.ts22 pass.Not run.
ruffis not installed in this environment. Whole-suite collection has 2 pre-existing errors (tests/test_backend_bench.py,tests/test_tokenomics_bridge.py) unrelated to these files. No live model was used, so the 11 s cold load measured earlier forhammer2.1_3bwas not re-measured.Cost. About 6 tool calls, under 10 s of local test time, no model inference outside this session.
kvnloo commentedon Oct 10, 2026
Independent verification of
f299b1a, and a follow-up fix for what it found (Claude lane). Supports #20.Verifier's result on
factory/claude/20-shadow-timeout-evidence@f299b1a: every stated claim reproduced (27 and 193 tests, RED atc7256f1, extension tests 22 pass, the abandoned call finishing its load). Over 900 natural runs at the deadline no mixed row appeared, andwaited_mswas correct per row with two models. It found:timed_out: true. The extension would classify that row differently from the receipt.run_shadowpromises not to raise, but a budget of 1e18 ms, infinity or a huge integer raisedOverflowError, also through the environment override.Fix:
factory/claude/20-shadow-timeout-race@9f482632c307f8b20d9a18d110cdb89cea6954f0, one commit onf299b1a.tests/test_cognition_shadow.py33 passed; alltests/test_cognition_*.py199 passed.srcortests.Cost. Verifier: 18 tool calls; 65,983 uncached input, 937,253 cache-read, 4,380 output tokens recorded. Fix: about 6 tool calls in the main session, which exposes no per-item token figure.
Keep every shadow budget as it resolved before the cap
kvnloo commentedon Oct 10, 2026
Independent verification of
9f48263found a behavior change I had not declared; fixed (Claude lane). Usefactory/claude/20-shadow-timeout-race@79104c4765e9d81a5f3db3244980686d4f89c771(one more commit on9f48263). Supports #20.What the verifier found on
9f48263. The race fix holds (removing the new gate makes the test fail). But its 293-row table of resolved budgets showed 81 differences fromf299b1a, and two kinds were not intended:Fix. Each channel resolves exactly as before the cap existed. The only remaining change is that a value too large for the platform's timers becomes the one-hour cap. Eight new test cases fail on
9f48263and pass now; 41 and 207 tests pass.Still as the verifier noted: budgets above one hour that used to run with a larger finite value are now capped, which is the stated intent of the cap. This last commit has not been independently verified.
Cost: verifier 20 tool calls (73,289 uncached input / 1,503,668 cache-read / 5,154 output tokens recorded); fix about 3 tool calls in the main session.
kvnloo commentedon Oct 10, 2026
Independent verification of
79104c4(Claude lane): holds. Supports #20.The verifier rebuilt the budget table across the three channels and compared
f299b1awith79104c4. Every difference is one of the two intended kinds: a wait above one hour is capped, and 202 inputs that used to raiseOverflowErrornow resolve to the cap. The race fix still fails its test when the gate is removed. 41 and 207 tests pass.One edge outside the stated claims: an explicit negative budget too large for a float used to raise and now resolves to the 0.1 s minimum. Nothing in the repository passes an explicit budget.
factory/claude/20-shadow-timeout-race@79104c4765e9d81a5f3db3244980686d4f89c771is the head to use for this work.Cost: 24 tool calls; 70,653 uncached input / 1,522,843 cache-read / 5,838 output tokens recorded.
kvnloo commentedon Oct 10, 2026
Independent verification: holds.
factory/claude/20-shadow-on-master@7914cd962ce7b19ccd1e7e01bd91002766268d4bis the shadow work as a small change on master. Supports #20.The nine shadow commits were made on top of Codex's unmerged
codex/multiharness-integration. This branch applies them directly onto master (5873723) so they can be reviewed on their own: 7 files, +911/-41, instead of about 15,800 lines.What a separate verifier confirmed, from a fresh clone and a clean environment
git range-diffand patch ids), with author, dates, messages and trailers kept. All seven files are byte-identical to the already-verified head79104c4. Codex's 23 commits touch none of them.cognition_shadowoperation is listed, dispatched and run there. A request built by the extension and piped to the real bridge worker returned a correlated shadow receipt.test_agentweb_bridge_overload) failed once while other jobs were running and passed in isolation and on rerun; it is the same flaky test seen in CI earlier today.08831a2(feat(capacity): emit read-only capacity snapshot v1 #134) plus66e1765(Stop the e2e hot-path tax and sidestep 402/429 off Cursor #141) merge with no conflict and share no files.Not run: the shadow decision path against a real served model (unit tests with fake backends only), and tests on the three-way merged tree.
Cost. Verifier: 27 tool calls. Building and pushing the branch: about 3 tool calls in the main session.
kvnloo commentedon Oct 27, 2026
Bounded slice (2026-10-27): SLM portfolio routing table + tests on
masterThe portfolio branches (
feat/slm-portfolio,feat/local-cognition-portfolio,exp/tool-calling-portfolio-v0,integrate/slm-methods-release-20261024) are 56–154 commits ahead ofmasterand too large to land as one PR. Onmaster@52aed5bb,manifests/capabilities.v1.jsonlists every text-worker entry (summarization,research,code_review,coding_implementation,cheap_bounded_worker, including the localqwen2.5:3blane) witheligible: false, soroute()can never pick a worker. Nobody can see that at a glance.This slice makes the current portfolio state visible and testable. It changes no routing behavior.
Base / branch: base
master, branchfeat/zo6-slm-routing-table, Draft PR intomaster.Allowed write paths (exclusive):
src/z0int/routing_table.py(new),tests/test_routing_table.py(new).Spec
build_table(registry: dict) -> list[dict]: one row per manifest entry withfunction,provider,model,route,local,eligible,evidenced(usez0int.automatic.evidenced(entry)), andblocker: the first ofNOT_ELIGIBLE,NO_EVIDENCE,REMOTE_NEEDS_AUTH(non-local entries), orNone.summary(rows) -> dict: per function, counts of rows, eligible, evidenced, routable (blocker is None), and the list of local SLM candidates.render_markdown(rows) -> str: a stable table sorted by function, then local first, then provider.python -m z0int.routing_table [--manifest PATH] [--json]; default manifest isz0int.intelligence.REGISTRY.Acceptance (tests)
summaryreports 0 routable rows for each text-worker function, and each such row has blockerNOT_ELIGIBLE(this pins today's truth; the test must be updated on purpose when a lane is promoted).eligible: trueand evidence (noteevidenced()hasheseval_source.pathrelative to the repo root; point it at an existing committed file and compute its sha256 in the test), that row hasblocker is Noneand the function'sroutable == 1.REMOTE_NEEDS_AUTH.--jsonoutput parses.Test command:
pip install -e '.[test]' && pytest -q tests/test_routing_table.pyNext slice after this one (not in scope): promote one local SLM lane with recorded evidence and capture one real routed receipt.
kvnloo commentedon Oct 28, 2026
N27-ZO6-ROUTINGTABLE
PR URL: #283 (Draft, base master)
Branch: feat/zo6-slm-routing-table
Head SHA: 7703048
Changed: Added src/z0int/routing_table.py with pure build_table/summary/stable Markdown/CLI over manifests/capabilities.v1.json, using z0int.automatic.evidenced, plus tests/test_routing_table.py covering zero statically routable text workers, synthetic hashed local evidence, remote authorization, blocker precedence, deterministic output, summary, and CLI JSON. No routing behavior change. Only the two allowed files changed.
Remains: execute pytest and review CI; actual local-SLM promotion and a real routed receipt are separate future work. tests NOT RUN - ChatGPT cannot execute code.
Test commands (repo root):
pip install -e '.[test]'
pytest -q tests/test_routing_table.py
python -m z0int.routing_table --json
python -m z0int.routing_table