Repository navigation
Release v1.13.0 - #399
Merged
Merged
Release v1.13.0#399
Conversation
… omission; streamed turns record served_model (#391, #394) ToolCallRequest gains response_format, parallel_tool_calls and omit_temperature (and derives Default, so a literal can name only what it sets). OpenAI-compatible bodies send response_format and parallel_tool_calls; Anthropic states the schema in the system text and maps parallel_tool_calls=false to disable_parallel_tool_use; Ollama sends format. The three stream accumulators read the served model the way the whole-response parsers do. RequestProfile parses the bindings' llm_profile JSON and can pin a temperature value; resolve_toolcall_with_profile installs one on a transport. Co-Authored-By: Claude <noreply@anthropic.com>
…mic tools (#391, #392, #393) NodeExecutor::Abstract carries the node's frozen LlmNodeConfig. The first message takes its instruction from the block (literal or a pointer into the node's input, a miss failing the node SchemaValidationFailed, unretried) and only the selected state keys; each turn journals the block's request fields under input.llm (response_format already in wire shape); a node's max_tokens is its reservation. A response declaration gets one corrective re-prompt, then fails the node. tool_results_into collects every call of the attempt in effect_seq order from the journaled outcomes. OfferedTool gains locked (merged over the model's arguments, lock wins, the strict check judging the merged input) and dynamic (a tools_from entry: its own schema checked first, arguments optionally wrapped, dispatched as Host under its own name with the Definition's address). A node with no block builds byte-identical commands and state; no epoch bump. Co-Authored-By: Claude <noreply@anthropic.com>
…cked_params (#391, #392, #393) A plan's `llm: {node: {...}}` is validated at start (unknown keys, shapes, a `tools` name or dispatch Definition the plan did not pin, duplicate or colliding dynamic names — each refused naming the node and entry) and frozen onto the abstract node's pin, `tools_from` resolved against the run input. The driver builds each turn's request from the journaled `input.llm`: system text, temperature or none, the node's ceiling, response_format and parallel_tool_calls. Offered schemas lose their locked keys. A Definition's locked_params are frozen with its pin. A model-issued call now finds its Definition by frozen address rather than by node, so a call to a code-carrying Definition from an abstract node runs the pinned blob instead of falling through to --tool-cmd; a dynamic tool journals under its own name and executes as the Definition it dispatches (exec_name). run inspect shows the frozen block and locks. Co-Authored-By: Claude <noreply@anthropic.com>
…e; the CLI reads its --llm-* profile flags (#394) A trailing JSON-string argument (appended, so every positional caller keeps its meaning): {"temperature": "omit" | n, "token_field": ..., "extra_body": {...}}, parsed by RequestProfile::from_json and installed through resolve_toolcall_with_profile. Unknown keys, a profile without a model, and a profile the ollama transport cannot honour are refused before a run exists. The run pins the profile digest, so a resume passes the same one. The CLI's USAGE has listed --llm-token-field, --llm-no-temperature and --llm-extra-body since #285 but nothing read them; run_stack now builds the same profile from them (with $AREEV_RUN_LLM_* twins). Co-Authored-By: Claude <noreply@anthropic.com>
…; the merged input is judged by the Definition's schema (#392) `llm.<node>.dispatch: [name | hash]` resolves each entry as an unbound node's same-named Definition is resolved (the run's namespace, then the plan grain's; RUN-E004 naming the entry on a miss), pins it into the manifest's dispatch_pins with its code address, runtime, capabilities and locks, checks it at start like a binding, and never offers it to the model. A tools_from entry may dispatch through those pins or a host pin of the plan, nothing else. dispatch.arguments_into is renamed args_into (the shape the first pack is written against). The Definition's input_schema is frozen beside each entry and the merged input {...locked, [args_into]: args} is validated against it whether or not the Definition is strict. Tests cover a nested instruction_from pointer (/prompt/text). Co-Authored-By: Claude <noreply@anthropic.com>
…1.13 Unreleased entries (#391-#394) docs/run.md gains "Configuring an LLM node (llm)" under LLM nodes, with every key, the dispatch list and tools_from, what is journaled, the start refusals, the locked_params rule and the bindings' llm_profile. docs/blessed-tools.md shows mcp.call behind tools_from. ARCHITECTURE.md §10 names the decision; both run crates' notes record the pinned rules. The console opens a plan carrying an llm block view-only, as it does for reads, since a resave would drop the block. Co-Authored-By: Claude <noreply@anthropic.com>
… dependency requirements The workspace, areev-js (package.json, Cargo.toml, the generated index.js), areev-py's pyproject, areev-sandbox and the three lockfiles move to 1.13.0, and so do the crates' internal requirements, as a minor release needs. The CHANGELOG's Unreleased section becomes "1.13.0 — unreleased" with a fresh Unreleased above it and the compare links updated. Not tagged, not published. Co-Authored-By: Claude <noreply@anthropic.com>
…cribed in the ask (#396) llm.<node>.narrow: false keeps a node's whole offer under a calibrated decision backend; narrow: {top_k: n} (1-254) moves the K for that node; true (the default) normalizes to nothing, so no manifest changes bytes. Frozen in the manifest with the rest of the block; a malformed value is RUN-E019. The narrowing question describes a tools_from tool by the first line of its own description, read off the node's offer (two nodes may declare one name), exactly as a pinned Definition's tool_description is carried; the run-wide table no longer carries dynamic names. Co-Authored-By: Claude <noreply@anthropic.com>
A tools_from entry's input_schema carrying $schema (as MCP servers publish them) was refused RUN-E019. json_schema_subset::strip_annotations removes $schema, $id, $comment, deprecated, readOnly, writeOnly and x-* at every keyword position (a property NAMED $id survives) before the subset check, for dynamic tool schemas and response.json_schema at run start and for a Definition's input/output schema at write time. title, description, examples and default stay (already portable); $ref/oneOf/anyOf/allOf/patternProperties are still refused. Co-Authored-By: Claude <noreply@anthropic.com>
…fe locks and strict-mode schemas at start; JSON-mode, fences, tools_from out of the prompt (review 1-5, 6b)
1. A dynamic entry's schema is closed: a key it does not name, or (without
args_into) a key the host locked, is an argument violation and re-prompts.
2. The model's arguments are validated against the schema it was SHOWN
(locked keys stripped, run-core DynamicTool::model_schema, shared with the
driver's offer), then the merged input against the Definition's.
3. A lock key equal to args_into, or a dotted lock key (entry or Definition),
is RUN-E019 naming the entry: locks are top-level keys only.
4. response {json: true} with a node system text and instruction that never
say JSON gets one sentence appended (OpenAI json_object mode 400s
otherwise); a json_schema strict mode would refuse is RUN-E019 at start,
naming the first violation by pointer.
5. A fenced final answer (```json ... ```) satisfies a response
declaration and merges.
6b. Under the whole-state default, the value tools_from points at (and the
locks inside it) is removed from messages[0].
Co-Authored-By: Claude <noreply@anthropic.com>
…boundary pseudonymized (review 6a) The request's system text was read off the raw turn input, not the masked copy the messages are built from, so under an egress policy an llm.system naming a person reached the provider in the clear; a tools_from entry's description and schema prose (description, title, default, examples) did too. Both now go through pseudonymize_for_model; structural schema strings and the response schema are sent as declared, because arguments and answers are checked against them as declared. Co-Authored-By: Claude <noreply@anthropic.com>
…adow a bound Definition's name; client/decision locked_params are a warning (review 7-9) 7. shadow_plan re-resolved the candidate manifest and froze the Definition's locked_params even for an incumbent that never froze any (every 1.12 run), so an unchanged plan rehearsed a different validation and went out of support. Locks now come from the incumbent's own pins by hash (none when absent). 8. An llm.dispatch entry by content address could pin another version of a Definition a node binds under the same tool_name and overwrite its schema in the strict table. RUN-E019 at start, naming both hashes. 9. A client or decision Definition with locked_params was refused at start — a break for plans 1.12 ran. The locks are ignored, as before, and the start records RUN-W001 in the manifest's new `warnings` (shown by run inspect). Co-Authored-By: Claude <noreply@anthropic.com>
…view 10) OpenAiCompat never overrode effective_temperature, and Anthropic's ignored the profile, so under an llm_profile that omits or pins a temperature the span's gen_ai.request.temperature (and the intent's llm.temperature, which is the plan's ask) claimed a value that was not sent. Both transports now answer from RequestProfile::effective_temperature, and an LLM result records temperature_sent (null when none went out) whenever the turn carries an llm block or the transport a non-default profile — every other turn's result is unchanged. Co-Authored-By: Claude <noreply@anthropic.com>
…eev eval; off means off; a bare switch takes no value (review 11) - triggerRun/triggerDeliver (Node) and trigger_run/trigger_deliver (Python) take a trailing llm_profile like runStart/run_start. - With no llm_profile, the bindings read $AREEV_RUN_LLM_TOKEN_FIELD, $AREEV_RUN_LLM_NO_TEMPERATURE and $AREEV_RUN_LLM_EXTRA_BODY (RequestProfile::from_env), as the CLI does. - areev eval --model builds the same profile as areev run. - profile::is_truthy: false, 0, off and no (any case) are off, for the flag, its env twin and the bindings. - parse_args: --llm-no-temperature never swallows the next positional; --llm-no-temperature=off spells it off. Co-Authored-By: Claude <noreply@anthropic.com>
… apply; the review hardening documented (review 12, 13)
12. a_resume_uses_the_pinned_block_not_the_live_input now parks on a client
gate before the agent runs, supersedes the plan with a different block and
publishes a newer mcp_call of the same name, then resumes: the agent sends
the frozen system text and tool list and runs the Definition pinned at
start.
13. docs/run.md says locked_params are applied by run dispatch (areev-run)
and not by areev-loop, areev-server or areev-mcp; RUN-W001; the review's
rules (closed entries, top-level locks, strict-mode schemas, the JSON
sentence, fences, the pruned prompt, pseudonymized system text,
temperature_sent, profile coverage). CHANGELOG #393's note updated.
Co-Authored-By: Claude <noreply@anthropic.com>
…river rules CHANGELOG [1.13.0] dated 2026-10-20 under a fresh empty [Unreleased], compare links current. crates/areev-run/CLAUDE.md records the shared model schema, shadow's incumbent locks, manifest warnings (RUN-W001) and the pseudonymized system text. Lockfiles and crates/areev-js/index.js were already at 1.13.0 (cargo metadata x3 and napi build left them unchanged). Not tagged. Co-Authored-By: Claude <noreply@anthropic.com>
cargo deny check failed on four rustls 0.23.45 advisories (published after the base tag; the lockfile is unchanged from v1.12.2 there). A lockfile-only patch update in the root and areev-js lockfiles (areev-sandbox does not use rustls); no manifest or license change, so THIRD-PARTY-NOTICES.md (which lists licenses, not versions) is unchanged. Co-Authored-By: Claude <noreply@anthropic.com>
…is closed (delta review 1)
With args_into the arguments are the remote tool's, and an MCP tool's
published {"type": "object"} refused every key. The closed-schema rule now
applies only when args_into is unset (where an unnamed key is a Definition
parameter the host never offered); with it, only additionalProperties: false
closes the entry.
Co-Authored-By: Claude <noreply@anthropic.com>
…name (delta review 2) Within a node or across nodes: the strict-argument table is keyed by tool_name, so the second version overwrote the first's schema. RUN-E019 at start, naming both hashes and both nodes. Co-Authored-By: Claude <noreply@anthropic.com>
…rties and nullable object types (delta review 3) strict_mode_violation treated only type: "object" (or a properties key) as an object and descended only into properties and items, so a nullable ["object", "null"] object, an anyOf alternative or a schema under additionalProperties reached OpenAI unchecked and 400'd on the first turn. Co-Authored-By: Claude <noreply@anthropic.com>
…red (delta review 4) A stale, malformed variable (AREEV_RUN_LLM_TOKEN_FIELD=tokens, say) failed every run_start/runStart, including runs that call no model. The twins are now parsed only when a model spec is given; an explicit llm_profile is still refused without one. Co-Authored-By: Claude <noreply@anthropic.com>
…f (delta review 5) Co-Authored-By: Claude <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Release v1.13.0: a plan configures each LLM node, tools come from the run input, and locked parameters are applied.
Closes #391, closes #392, closes #393, closes #394, closes #396, closes #397.
What ships (see CHANGELOG
[1.13.0])llmblock on a plan. It setssystem,instructionorinstruction_from,state,tools,response(json_schemaorjson),temperature(a number or"omit"),max_tokens,parallel_tool_callsandtool_results_into. The block is frozen in the manifest, journaled as sent underinput.llm, and shown byrun inspect.tools_from, tools declared in the run input. Each one dispatches through a pinned Definition withlockedandargs_into.llm.dispatchpins a Definition that no node binds, such asmcp.call, and never offers it to the model.locked_paramsare applied by run dispatch. They are merged over the model's arguments with the lock winning, stripped from the offered schema, journaled merged and frozen with the pin. A client or decision Definition carrying them is ignored with aRUN-W001warning instead of being refused.served_model.parallel_tool_callsis a request field.llm_profileis the last argument of runStart/runResume/triggerRun/triggerDeliver (Node) and of their Python twins. The bindings read theAREEV_RUN_LLM_*variables, and the CLI's--llm-*profile flags now take effect.narrow: false | {top_k}), and dynamic tools are described in the narrowing question.$schema,$id,$comment,deprecated,readOnly,writeOnly,x-*) are accepted and dropped instead of refused.Hardening from the branch reviews
args_into, a dynamic entry's schema is closed: unnamed keys and locked keys are refused. Withargs_into, the entry's ownadditionalPropertiesdecides.args_intokey, are refused at start.json_objectmode adds "Answer with a JSON object." to a node system text that never says JSON. Ajson_schemathat strict mode would reject is refused at start; the check walks nested properties, items,anyOf, a schema-valuedadditionalPropertiesand nullable object types.```json) final answers are accepted.llm.systemand a dynamic tool's prose are pseudonymized. Thetools_fromlist is left out of the whole-state prompt.sameon an unchanged plan.tool_nameis refused.locked_paramson client or decision tools produce a warning (RUN-W001), not an error, so 1.12 plans keep running.temperature_sent.areev eval. The env twins are read only when a model is configured.off,no,0andfalsemean off, and a bare--llm-no-temperaturetakes no value. Note: the space form--llm-no-temperature falseno longer means off; write--llm-no-temperature=false.areev-run, not loop/server/mcp).Dependencies
Notes
llmblock journals byte-identically, so the scheduler epoch did not move.Pre-flight (local)
cargo test --workspace --locked(3,468 passed), clippy-D warnings,cargo doc,cargo deny check,check_versions.py,repo_stats.py --check, the areev-js build plusnode --test(115 passed), pytest (185 passed),cargo +nightly fuzz build, andcargo publish --workspace --dry-run(13 crates) all pass.