Skip to content
#small language model Open access

yologdev/yoagent: v0.25.0

Oct 2026 · Zenodo (CERN European Organization for Nuclear Research)

Abstract

Added Extensions (yoagent::extension, #241): one plug-in contract for the agent lifecycle. An Extension is installed with Agent::with_extension / SubAgentTool::with_extension (an Arc is one too), and each run gets fresh RunHooks from start_run, so state for one run is isolated. The hooks: tools (once per run); on_input; before_model (note, stop or fail); before_tool (allow, modify or deny; &self, so parallel calls are judged concurrently); after_tool (edit the ToolOutput); on_stop (accept, continue or fail the final answer); on_event (every event, in order); finish (with a RunOutcome whose end() is a RunEnd). Advisory or required: a required extension's failure fails the run, which ends with an Error message prefixed EXTENSION_FAILED_PREFIX; tool calls not started yet are not run. Every hook watches the run's cancellation, and finish is bounded. Partial tool output is withheld while an extension filters tool output. A rechecking policy judges rewritten arguments again. ClonedHooks wraps hooks cloned per run. with_tree_extension applies an extension to every delegated run at any depth, so host policy reaches sub-agents (a parent's ToolMiddleware never did); a custom delegation tool passes the tree on with Agent::delegated_from / AgentLoopConfig::delegated_from, reading ToolContext::{tree_extensions, delegation_depth, run_label}. Also new: Agent::with_run_label and Agent::with_max_stop_continues. Guide: docs/concepts/extensions.md. RunHooks::take_failure: a defaulted hook through which an extension hands over a failure it recorded but could not raise in place (from on_event, or background work). The loop asks before each turn, before a response's tools, before on_stop and when the run ends, so a required extension's recorded failure fails the run however it ends. yoagent-rutis uses it for plugin on_event / tools failures. extension::Budget: a dollar limit, checked before each model request: once spend reaches it, the run stops (the request that goes past it still completes). Per run (a sub-agent's reported spend included), or .across_runs() (a session, or a whole delegation tree with with_tree_extension; spent_usd() reads the total). Budget::for_model returns None for an unpriced model; a negative or NaN limit panics. Extension examples: extension_policy (deny/modify with ClonedHooks, rechecks_modified_calls), extension_redact (after_tool + filters_tool_output), extension_verifier (on_stop continues, finish reading RunOutcome::end()), extension_budget (per run and .across_runs()), extension_tree (with_tree_extension over a SubAgentTool and a hand-written Agent::delegated_from tool) and extension_audit (on_event + finish). Each runs offline on a scripted MockProvider and checks its own result, and CI runs them all; -- --live drives a real model (DEEPSEEK_API_KEY or ANTHROPIC_API_KEY). New tests/extension_combos_test.rs covers extensions together with every tool strategy, compaction, steering, prompt_structured, provider retries (with Budget), and middleware plus the tool gate on one call. The OpenAI Responses provider (the GPT-6 presets) and Azure OpenAI can carry reasoning across tool calls (#228) — opt-in, off by default, and not yet verified against the live API (checked against recorded request shapes only): ModelConfig::with_encrypted_reasoning(true) (OpenAiCompat::encrypted_reasoning). With it off, requests are as in 0.24. Opted in, a reasoning model's request asks for include: ["reasoning.encrypted_content"], the finished reasoning item is kept on its Content::Thinking block (redacted holds its id, summary and encrypted_content as JSON, redacted_protocol the API it came from; the readable summary stays in thinking), and the next request sends it back in place as a reasoning input item, before the call or message it led to — what OpenAI recommends for function calling with reasoning models. That call or message is replayed with its output item id (fc_… / msg_…, recorded in the same JSON as call_ids / message_id), since OpenAI refuses a reasoning item without its paired item; items with no replayed reasoning before them still go without ids. It goes only to the API that produced it: OpenAI's and Azure's encrypted reasoning do not cross, and Anthropic's or Bedrock's never reach either. A reasoning item with no output after it in its turn is not sent. include is sent, and reasoning items are replayed, only for a reasoning model (ModelConfig::reasoning, or a request that sends a reasoning effort), because a non-reasoning model rejects both with a 400 — so after Agent::set_model to gpt-4.1 the history goes without reasoning items and without item ids; a custom Azure config has reasoning: false, so set it for a reasoning deployment. store is still not sent. A summary that arrives only in the finished item now becomes the thinking text. Verified against mock servers only; tests/integration_openai_responses.rs (--ignored, needs OPENAI_API_KEY) runs the two-turn exchange live. prompt_cache_key on the Responses API (OpenAI and Azure, #228): the same key Chat Completions sends — CacheConfig::session_key, else derived from the system prompt — and none when caching hints are off. Not gated on a compat flag: the field belongs to the Responses API, and Azure documents it. OpenAI's Decisions API as a decision backend (feature decision): OpenAiDecisionBackend (POST /v1/decisions, key from OPENAI_API_KEY at call time, with_api_key / with_base_url / with_retry / with_safety_identifier / with_capabilities) and the preset DecisionModel::gpt_6_luna(); another model id with with_model, a configured backend with DecisionModel::from_openai_backend. Noul → predicate, Choice → choice, Score → score, question ids → name, a JSON state → pretty-printed input text; answers matched by name (by position only when unnamed and one per question). A refusal answer fails the call with DecisionError::Refused naming the question (not retried, and it ends a fallback chain), so the tool gate and the input guard fail closed. Priced, after prices::enable_bundled(), from the new bundled entry openai-decisions/gpt-6-luna ($0.10 per million input tokens, output free) only while requests go to api.openai.com. Image input is not supported. Tested against mock servers only — not run against the live API. DecisionError::Refused { message } (+ DecisionError::refused, is_refusal; feature decision): an OpenAI refusal returns it, and DecisionModel::or returns it at once instead of asking the next model, so a fallback never answers what the first model declined. The tool gate and the input guard still fail closed. LlmCompaction::reprice(&self) and a defaulted CompactionStrategy::reprice; Agent::reprice now also re-prices the compaction summarizer, so an agent built before the pricing opt-in can be priced afterwards. A one-time warn! per model when a first-party price lookup misses while only YOAGENT_PRICES / install_override / install_fetched is in effect (no bundled snapshot). LivePrices is #[must_use]. SessionStats::compaction (CompactionSpend { usage, cost_usd, requests }) and Agent::compaction_spend(): what LlmCompaction's summarization requests cost, priced at the summarizer's own cost. See the fix below. yoagent-rutis (unpublished): TypeScript and Python hooks get a cancel handle. Every hook but on_event finds it in its first argument, as the field signal: a real AbortSignal in JavaScript, rutis's Signal in Python (.cancelled, await signal.wait()). It is aborted when the bridge gives the call up — the run cancelled (Agent::abort()), the hook's timeout passed, the plugin unloaded mid-call — and never once the call completed. A call_tool that passes call.signal on (to fetch, a child process, dsh's execute) now stops when its run is cancelled; before, a JavaScript hook always ran to completion. A field rather than an extra positional argument, so fixed-signature Python methods keep working. It is not plain data: Python's json.dumps(call) now refuses the argument (drop signal first). Tested end to end in both languages (cancel and timeout abort it; a completed call's handle never is). No yoagent core change. yoagent-rutis (unpublished): dsh tools as yoagent tools. plugins/dsh/dsh-tools-adapter.ts offers every tool of a DeepSeek Harness tool registry (@deepseek-ai/dsh-tools' tools service) to yoagent agents: call_tool runs dsh's execute with the bridge's cancel handle as dsh's signal, an isError result is an error tool result, and before_model adds the system-prompt sections dsh plugins wrote (the harness's own left out, capped at 2000 characters) as a turn note. dsh plugins run unchanged in rutis's Node runtime; plugins/dsh/package.json pins dsh 0.2.0-rc.2, @deepseek-ai/cordis 4.0.4 and dsh-free-search 0.8.1, in its own install (the language tests' stays small). examples/dsh_tools.rs (feature node) runs the unchanged dsh-free-search plugin's platform_search for a scripted model (it searches the web: needs network) or DeepSeek (--live) and checks its outcome. tests/dsh_test.rs covers the adapter with a no-network fixture dsh plugin (plugins/dsh/fixture-tools.ts): tools offered, text, isError, the prompt note, and a cancelled run aborting a slow dsh tool through its signal; CI's rutis-bridge-languages job installs plugins/dsh too. yoagent-rutis (unpublished): rutis-agent's tools as yoagent tools, an example workspace (examples/rutis-agent-tools/, its own [workspace], not built with the crate): a rutis plugin maps every ToolDef of rutis-agent's ToolRegistry to a yoagent tool per run (failures are ToolErrors, yoagent's cancel token is the one rutis-agent's execute watches), shown with rutis-agent's real replace_text, a tool registered into the registry while the host runs (offered on the next run), and a cancelled call; scripted, or --live with DeepSeek, self-checking. rutis-agent comes from git (the rutis repository at tag v0.7.0, the one on rutis 0.6; crates.io's 0.2.0 is on rutis 0.2) with a [patch.cr

View source

Similar papers

#small language model Dataset Open access Oct 2026

Socratic guiding questions in synthetic arithmetic data: matched LoRA runs (revision v2)

Supporting data, adapters, predictions and code for the article *Low-Cost LoRA Fine-Tuning of Small Language Models for Multi-Step Arithmetic Reasoning* by Jake O'Grady, Asena Isik Gürhan, Chee Fong Ting and Effirul Ramlan (University of Galway). We generated 20,000 GSM8K-derived arithmetic problems with step-by-step s...

O'Grady, Jake, Gürhan, Asena Isik, Chee, Fong Ting et al. · 465 citations
#computer vision Open access Jun 2016

Software Development in Startup Companies: The Greenfield Startup Model

The results are packaged in the Greenfield Startup Model (GSM), which explains the priority of startups to release the product as quickly as possible, and the need to shorten time-to-market, by speeding up the development through low-precision engineering activities.

Carmine Giardino, Nicolò Paternoster, M. Unterkalmsteiner et al. · 178 citations · ⚡14
#computer vision Open access Oct 2016

Software Startups - A Research Agenda

Software startup companies develop innovative, software-intensive products within limited timeframes and with few resources, searching for sustainable and scalable business models.

M. Unterkalmsteiner, P. Abrahamsson, Xiaofeng Wang et al. · 157 citations · ⚡17
#machine learning Review Open access Oct 2016

“Failures” to be celebrated: an analysis of major pivots of software startups

This study conducts a case survey study based on the secondary data of the major pivots happened in 49 software startups, and demonstrates that customer need pivot is the most common among all pivot types.

Sohaib Shahid Bajwa, Xiaofeng Wang, Anh Nguyen-Duc et al. · 127 citations · ⚡15
#computer vision Review Open access May 2015

A survey study on major technical barriers affecting the decision to adopt cloud services

The comparison of adopter and non-adopter sample reveals three potential adoption inhibitor, security, data privacy, and portability, which underlines the importance of the technical and security perspectives for research investigating the adoption of technology.

Nattakarn Phaphoom, Xiaofeng Wang, S. Samuel et al. · 111 citations · ⚡8
#computer vision Open access Feb 2018

Lean Internal Startups for Software Product Innovation in Large Companies: Enablers and Inhibitors

This study investigates how Lean internal startup facilitates software product innovation in large companies and identifies its enablers and inhibitors, and shows the potential of the method-in-action framework to investigate the Lean startup approach in non-startup context.

Henry Edison, Nina M. Smørsgård, Xiaofeng Wang et al. · 78 citations · ⚡6

Related blog posts

MIT News · Artificial Intelligence Oct 15, 2026

AI model decodes the language cells use to communicate

A new computational approach reveals how cells communicate to assemble into tissues. This could accelerate stem cell engineering, improve disease models, and inform therapies.

Microsoft Research Blog Oct 15, 2026

Proof-based general-purpose computing with Magnetar

Zero-knowledge proofs can verify computing results without rerunning workloads or exposing sensitive data. Magnetar helps bring them into the mainstream with support for standard programming languages, major speed gains, and quantum-resistant security. The post Proof-based general-purpose computing with Magnetar appeared first on Microsoft Research.

We use cookies to run the site and, with your consent, for analytics and to show ads. See our Cookie Policy.