You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Add the inception cloud runtime for Inception's Mercury diffusion models, authenticated from INCEPTION_API_KEY against https://api.inceptionlabs.ai/v1, with mercury-2.5, mercury-2, and mercury-edit-2 as its known wire models. Mercury denoises whole blocks of tokens in parallel instead of emitting them left to right, which is what makes it fast enough for a latency-sensitive slot a frontier model cannot fill. No rates ship for these models; cost accounting reads the target's own targets[].pricing block as it does for any other configured target.
Wire two surfaces. Chat runs at /v1/chat/completions through the ordinary pi-ai transport with tool calling and json-schema structured outputs. Fill-in-the-middle runs at /v1/fim/completions through the existing infill() verb, so callers reach it exactly as they reach llama.cpp's, and a target that names no defaultModel infills with the edit-tuned mercury-edit-2. /v1/edit/completions is left out; its next-edit prediction needs a contract verb of its own and its context-tag request format is not covered by the published reference.
Declare reasoning false and pin reasoning_effort: instant. Mercury accepts the field, but above instant the response carries content: null with reasoning_summary: null and the streaming path leaks a raw <|think_end|> token, so there is nothing to show the operator. Omitting the field is worse than pinning it: Mercury then reasons by default, spends the whole token budget on hidden reasoning, and returns an empty completion with finish_reason: "length".
Give catalog-backed model synthesis compat and samplingParams passthrough, so a runtime can declare the wire quirks it knows about its own endpoint over whatever the catalog entry says. Inception rejects the developer role, so without it every request carrying a system prompt is a 400. A provider can be OpenAI-compatible in shape without being compatible in vocabulary.
Correct capabilities from the live /models listing, reading context_length and max_output_length per model over the pre-probe placeholder, and fail the probe by name when a configured model is not in the listing rather than attempting it.
System One decision models
Add the hidden typesafe-jev cloud runtime, authenticated from TYPESAFE_API_KEY against https://api.typesafe.ai/v1, with jev-latest and jev-preview as its known wire models. A System One model does not generate prose: every question names a closed answer shape up front and the model returns a calibrated distribution over it, which makes it a substrate for the harness's micro-decisions where a chat model is both slower and unparseable. The descriptor declares chat: false, so Jev never appears as a conversational target and the configure wizard does not offer it.
Add decide() to RuntimeDescriptor. It answers a batch of independent typed questions against one body of evidence in a single round trip and covers the three primitives the API exposes: noul for a truth probability, choice for an option with its distribution, and score for a position on a criteria ladder. A question's criteria carries what each answer means, so the caller defines the scale rather than hoping a prompt implies it.
Parse confidence as a separate axis from the answer, because they are different questions. A noul of 0.5 at high confidence is a decided coin-flip; at low confidence it is an abstention, and a caller gating on the result must be able to tell them apart. The readers in decisions.ts return null rather than false below a confidence floor.
Derive a noul's certainty rather than reading it. The wire response omits confidence on a noul entirely, so reading the absent field as zero made every minConfidence check abstain unconditionally. A noul is a two-outcome distribution and the provider's own peakedness formula reduces at n = 2 to the probability's distance from the coin-flip, so a noul of 0.65 now reports the same certainty as a two-option choice at the same mass.
Throw on a missing or unrecognised answer rather than defaulting one. Callers index by the ids they submitted, so a dropped answer is a contract break, and a caller gating dispatch must never receive a decision the model did not make.
Bind harness decision sites through fleet.decisionProfiles, a map from site to an existing fleet.profiles name. A decision model is a provider rather than an agent, so it reaches the harness through the profile machinery that already validates a target and a model instead of through a namespace of its own. Four sites name moments in a turn: routing picks a worker at dispatch, skills and memory narrow what the prompt carries, and toolRisk rates a command's blast radius for the approval prompt.
Leave every site off until it is bound. A site with no entry resolves to nothing and its caller keeps the behavior it had before the site existed, so the capability is opt-in by absence with no enable flag to retire when it leaves alpha, and a site that misbehaves can be unbound without giving up the other three. Abstention and provider failure take that same path.
Reject an unknown site name and a profile fleet.profiles does not define at validation time, because either would sit silently inert and leave the operator debugging a feature they believe they enabled. inspectDecisionSite separates an operator who configured nothing from one who configured something broken, and checks the decide verb rather than the declared capability, since a target bound here by mistake is likelier to be an ordinary chat model.
Answer the routing site with calibrated task features. Unbound, classifyAgentTask reads the task with an ordered regex list and reports a confidence of 0.3 or 0.7 depending only on whether its first rule matched, which is a placeholder rather than a measurement, and routing keys off it. The rules also miss whenever the wording differs from the pattern: on "Review the auth middleware for timing attacks, then fix anything you find and add regression tests" the word-count ladder returns simple and the conjunction rule returns indivisible, and both are wrong. The live provider returns complexity 1.86 of 3 and decomposable 0.81 for that task, using 718 input and 188 output tokens in 249ms, and those answers are pinned in the test.
Send the site's four questions in one call, because they are independent and batching them costs nothing. Every field falls back to the regex value on its own: an abstention on complexity does not discard a confident answer on domain, and an answer outside the option keys it was given is treated as an abstention rather than widening the enum. An unbound site, a provider outage, and an uncertain answer all produce the same result and dispatch cannot tell them apart, which is the regex classification it had before the site existed; a failure leaves a diagnostic and nothing else.
Resolve the features once in admitDispatchAttempt, while admission can still await, and ride them down to agentRouteCandidates, whose candidate evaluation is synchronous. routeValidationProjection strips the field on the same terms as the reservation, so a model cannot author the task features its own routing reads.
The wire contract is pinned against a recorded live response, and all four sites are consumed in this release.
Rank the skills listing rather than filtering it. A skill the model cannot see is a capability it cannot use and has no way to know was withheld, so a wrong judgment would become an invisible failure. Rows are ordered by relevance and every row stays present, with the bounded paging added in 0.5.2 doing the cutting it already did. A row that abstains keeps its position, because an unscored skill is not a low-scored one.
Score a parked call's blast radius at the approval prompt. The rating is advisory and never changes what is permitted, so a decision model cannot widen or narrow what an operator is asked to approve.
Select durable memory against decision-site scores. Prompt selection is synchronous, so scores are resolved once at the turn boundary and consumed as precomputed values, and the existing lexical ranking is untouched when the site is unbound. The prompt-cache key carries the scores, because a new pass that reused the previous turn's cached section would be a correctness bug rather than a stale optimization.
Batch a turn's relevance questions into one call. Questions are independent, so a single request carries each candidate's text once and names it by id from the question. Measured against the live API, a four-candidate fan-out cost 593 input and 81 output tokens in 274ms, and swapping the text behind an id moved that id's score from 0.25 to 0.07, confirming the model resolves the id against the state rather than reading the id itself. The request therefore grows linearly with the catalog rather than quadratically.
Harness eval baselines
Record and check committed per-task baselines. A threshold applies one bound to every run in a suite, so it can bound a metric across the matrix but cannot say that one named scenario reproduces one exact value. A suite now declares baseline: {file, pin}, and eval baseline record|check writes and verifies it. eval run performs the same check inline, for the reason it already evaluates thresholds there: a reference that only a later command consults leaves the run that broke it exiting zero.
Refuse to record an unstable value. A pinned metric that is absent from a task or disagrees across repeats is not a baseline, and recording one makes the next check fail for a reason nobody can act on. Pins are limited to properties of the harness, so wall time, RSS and CPU stay out; pinning them would fail the check on a busier laptop and teach everyone to ignore it.
Sort the recorded file by task and by metric with one value per line, so its git diff is the behavioral changelog. A change that moves one tool's result shape appears as that scenario's custom.digest.behavior line changing, and the review question becomes whether the change was intended.
Add the bash tool-bench suite, bringing coverage to six tools and 230 pinned scenarios across both splits. Autonomy becomes a per-scenario property defaulting to auto-edit: an execute-plane call parks for confirmation there, so execution scenarios declare full-auto while the parked ones keep their lower level and pin the admission decision itself. Raising the driver's autonomy globally would have silently changed what all 186 previously recorded scenarios exercise. A contract test enforces that no bash scenario removes a path or reaches the network, because a bench that depends on the safety net to stop a destructive command is one admission change away from deleting the checkout it runs in.
Extend the same discipline off the tool path and onto the harness itself, with five offline model-free suites under evals/machinery/ covering dispatch admission authority, prompt layering and layout version, context budget admission at all three boundaries, durable memory selection freezing, and continuity handoff transactions end to end. Together with the tool bench that is 261 pinned scenarios. A contract test gates the committed suites against their generator and the pinned metric list against the harness-property set.
Rename tracked-metrics-baseline.yaml to tracked-metrics-suite.yaml. It is a suite, and the word now means something else.
Cached MCP discovery
Answer gateway(op="find") and describe from a recorded catalog instead of launching servers. An unrestricted find discovered every declared server concurrently before the query was applied, so a find for a builtin still tried to start every trusted MCP server, and describe could launch a process just to read a schema. Both now read recorded metadata; only call and an explicit refresh connect, and each connects only the owning or named server. A contract runs the whole arc across sessions: one session fills a catalog with a scoped refresh, closes, and a second session answers find and describe with no server process at all.
Persist a bounded tool catalog per declared server in src/domains/gateway/mcp/metadata-cache.ts, filled from an explicit refresh and from any ordinary connection's successful tools/list. Identity binds the project root, declaration scope and path, server id, declaration digest and resolved cwd, so a re-declared server replaces its own catalog rather than stranding the old one. A listing stopped at the 500-tool or 100-page client cap reads back as incomplete rather than as a full census. Nothing that runs a server is written: no command, args, env, timeout or trust decision, and authority is recomputed from the trust file every session.
Report catalog provenance as a field of its own next to status. A cache hit describes a trusted server with a cached catalog and never a connected one, an untrusted or stale declaration reads no catalog at all, and servers with no recorded catalog are named in missingCatalogs with the one call that fills them. Cached descriptors stay out of the registry and a name the registry already holds is served by its live spec, so a cached descriptor can never shadow a connected one or skip live setup.
Add server and refresh inputs to find, adding 142 bytes to the attached gateway schema. refresh without a server, an undeclared server, and either input on describe or call are refused. A restricted surface refuses both, because letting a recipe launch a server through refresh would stop its tool ceiling from being a ceiling on what the run can start.
Leave call untouched. It resolves the owner live and validates arguments against the server's current schema, so a stale cached schema is never what a call is checked against and a tool the server no longer offers fails instead of running. A scoped find filters by the same longest-prefix ownership rule the source enforces rather than by name prefix, so a server id containing __ cannot claim another server's tools.