Skip to content

Releases: vstorm-co/pydantic-deepagents

0.3.43

Choose a tag to compare

@DEENUU1 DEENUU1 released this 05 Aug 17:11
32b57ba

Changed

  • Requires subagents-pydantic-ai>=0.2.18 (#199) — the subagent toolset no longer defaults default_model to a library-chosen model; deep-agent construction already passes a model and is unaffected.
  • Requires pydantic-ai-backend>=0.2.25 (#192) — maintenance bump for the console and docker extras.

Full changelog: https://github.com/vstorm-co/pydantic-deepagents/blob/main/CHANGELOG.md

0.3.42

Choose a tag to compare

@DEENUU1 DEENUU1 released this 01 Aug 10:19
a63095d

Changed

  • Requires pydantic-ai-backend>=0.2.18, which is a bug-fix release worth
    taking: a directory listing reported shell-quoted paths, so a directory with a
    space in its name was unreachable — the model was handed a path it could not
    read back; a glob aborted its whole walk on one unreadable entry and returned a
    silently short listing; and a Kubernetes exec reported an unknown status as
    success, so every truncated command looked like it had passed.

Added

  • AsyncBaseSandbox and is_async_backend re-exported from
    pydantic_deep, alongside BaseSandbox. Subclass AsyncBaseSandbox for a
    sandbox reached over an async transport — asyncssh, an async HTTP SDK — and
    implement execute and edit as coroutines; every other file operation is
    derived from shell commands, as with the synchronous base.

    Prefer it to wrapping async code in a synchronous facade. ensure_async cannot
    see through a facade, so it thread-wraps it and each call then occupies a worker
    thread that has to hop back onto the event loop; a sandbox whose own recovery
    path also needs a thread deadlocks against its own pool. is_async_backend is
    the check ensure_async performs, exposed so a host can ask the same question.

0.3.41

Choose a tag to compare

@DEENUU1 DEENUU1 released this 01 Aug 09:25
efea442

Changed

  • A subagent blocked in ask_parent now waits 60s, not 300s.
    subagents-pydantic-ai defaults to a five-minute wait, which a team member
    inherits: one that asks a question while the lead is not polling holds its slot
    for the whole timeout, and five minutes of that is indistinguishable from a hung
    agent. After the timeout the subagent is told to proceed on its own judgment
    rather than being cancelled, so the work still finishes.

Added

  • create_deep_agent(subagent_ask_timeout_seconds=...) and
    DEFAULT_SUBAGENT_ASK_TIMEOUT_SECONDS (60.0), for raising the wait back up when
    a human is reliably in the loop.

0.3.40

Choose a tag to compare

@DEENUU1 DEENUU1 released this 31 Jul 23:15
cf4e3bd

Agent teams were wired to the subagent execution engine but never actually ran a
member. Four defects compounded, each of them silent: the tools reported success
and the team produced nothing.

Requires subagents-pydantic-ai >= 0.2.12, which adds the programmatic
answer_task / steer_task surface and exposes SubAgentToolset.registry.

Fixed

  • Teams registered members in a registry the subagent engine never reads. With
    subagent_registry=None — the create_deep_agent default — the team block built
    a fresh DynamicAgentRegistry(), so spawn_team put its members somewhere the
    subagent task tool does not look and every assign_task came back
    Error: Unknown subagent. Teams plus subagents was broken in the default
    configuration. Teams now share subagent_toolset.registry.
  • A refused delegation was recorded as a started task. The subagent task tool
    reports an unknown subagent or a busy chat trace as an error string rather than
    raising, so assign_task's except never fired: it set the member to running
    and appended the error to an "Agent running in background" message. The member
    then sat at running forever. A started task is now identified by its Task ID:
    line, and a refusal marks the member failed with the reason.
  • message_teammate delivered nothing. It wrote to TeamMessageBus, which no
    running member reads — a member is a background subagent and only sees what the
    subagent engine hands it, and TeamMessageBus.receive() is called from tests
    only. It now routes through the engine: answer_task when the member is blocked
    in ask_parent, steer_task while it runs, and it says plainly when there is
    nothing to deliver into instead of reporting "Message sent".
  • A finished member left its shared task in_progress forever, so the lead read
    completed work as outstanding. AgentTeam.sync_member completes the todo when a
    member completes, and releases the claim when one fails so the lead can reassign
    it rather than watching a dead member hold it.

Added

  • create_team_toolset(subagent_toolset=...) — the subagent toolset backing
    execution, which is what makes message_teammate able to deliver. The existing
    registry / task_fn / task_manager arguments still work.
  • TeamMemberHandle.todo_id, linking a member to the shared-todo item it
    claimed so finishing the task can close the todo.
  • TestTeamSubagentWiring in tests/test_teams.py, which fails on each of the
    four defects independently.

Changed

  • TestCreateTeamToolset::test_message_teammate asserted the "Message sent" that
    the third defect shows was a lie; it now asserts the honest outcome.

0.3.38

Choose a tag to compare

@DEENUU1 DEENUU1 released this 24 Jul 21:54

[0.3.38] - 2026-07-24

MCP resources and skills reach the model, the CLI talks to any
OpenAI-compatible local endpoint, and the todo list stops invalidating the
provider's prompt cache on every mutation.

Added

  • MCP resources and skill:// skills are now visible to the model (#180, closes #178) (pydantic_deep/mcp/resources.py, pydantic_deep/mcp/registry.py, pydantic_deep/mcp/config.py, pydantic_deep/mcp/loader.py). pydantic-ai surfaces only an MCP server's tools, so a server publishing skills through FastMCP's SkillsDirectoryProvider was unreachable from a delegated agent unless the app hand-rolled a bridge. Set include_resources / include_skills on an MCPServerConfig (or in the mcpServers JSON) and MCPRegistry.build_active() attaches a second toolset with list_mcp_resources / read_mcp_resource and, for skills, list_mcp_skills / load_mcp_skill. It binds to the same MCPToolset, so tools and resources share one connection and one resource cache. Both flags default to off.
    • The resource tools are prefixed per server (the config's tool_prefix, else its name), so several servers can expose their resources in the same run — without a prefix their identical tool names collide and pydantic-ai fails the run.
    • With include_skills, the server's skills are listed in the system prompt, so the model knows the guidance exists before it starts calling the server's operational tools.
    • An unreachable server returns the failure as tool text rather than raising out of agent.run(), matching how make_resilient degrades the tools toolset.
    • New export: create_mcp_resources_toolset (also MCPResourceProvider, SKILL_URI_SCHEME, SKILL_DOC_NAME from pydantic_deep.mcp).
  • OpenAI-compatible local endpoints in the CLI (#176, closes #175) (apps/cli/config.py, apps/cli/providers.py, apps/cli/agent.py, apps/cli/screens/onboarding.py, apps/cli/commands.py, docs/cli/settings.md). Only Ollama worked from the CLI, because it has a provider prefix pydantic-ai recognises; llama.cpp, LM Studio, vLLM and text-generation-webui need an OpenAIChatModel built with a custom base_url, which a plain model string can't carry. CliConfig gains base_url and local_api_key, an openai-compatible provider entry is added to the picker, and the openai-compatible:<name> sentinel is resolved into a real model pointed at that endpoint. /provider routes the choice to a new LocalEndpointModal (base URL + model name + optional key), and keyless local providers report as ready in onboarding. Contributed by @OchnikBartek, requested by @nenoro.

Fixed

  • The openai-compatible: sentinel is now resolved everywhere, not just in create_cli_agent (#176) (apps/cli/model_resolve.py, apps/cli/agent.py, apps/cli/reminder.py, apps/cli/goal.py, apps/cli/commands.py, apps/cli/credentials.py, apps/cli/screens/onboarding.py). The sentinel is a CLI-only marker that pydantic-ai's infer_model rejects with ValueError: Unknown provider: openai-compatible, and only the primary model was being converted — so fallback_model, /remind llm (which degraded to the zero-cost generator with a log warning), /goal (which answered "Evaluator error; continuing." every turn and never completed) and /improve all received the raw string. The conversion moves into resolve_cli_model, which every site now goes through; plain strings and already-built Model instances pass through untouched, and the /improve chain takes str | Model.

    • OPENAI_COMPATIBLE_API_KEY is registered in credentials.py. /provider wrote it, but keys list, keys set and /keys all iterate CREDENTIALS, so it was invisible and unfixable from the UI. It deliberately has no provider_id, so it stays out of the key-first first-run flow where picking it would set a model with no endpoint.
    • LocalEndpointModal rejects a scheme-less base URL. localhost:8080/v1 built a provider fine and only failed on the first message, with an httpx protocol error that reads like an agent bug.
    • Known gap: /fork branch models and the merge judge model can still be set to the sentinel from the model picker. MergeStrategy.judge_model and BranchSpec.model are strings by design (vote-model detection, cache keys), so that fix belongs in its own change.
  • Todo mutations no longer rewrite the system prompt (#182) (pydantic_deep/instructions.py, pydantic_deep/agent.py, pydantic_deep/spec.py, pydantic_deep/deps.py). create_deep_agent doesn't use TodoCapability — it builds its own instruction providers — so the static-by-default prompt introduced in pydantic-ai-todo 0.2.7 never applied here: make_todo_section called get_todo_system_prompt(proxy), which appends ## Current Todos whenever the run has any. The instructions open the provider's prompt-cache prefix, so every write_todos / update_todo_status invalidated the whole cached prefix mid-run. The todo section is now the static TODO_SYSTEM_PROMPT, with the live list behind a new include_current_todos=True (also a DeepAgentSpec field), matching the upstream flag name. Reported by @jb2197.

    • The instruction providers no longer touch the todo proxy at all, so build_instruction_providers drops its todo_proxy argument. _TodoProxyBinder re-binds the proxy in each tool's own contextvars context (issue #148), which was always the only binding the tools saw. The end-to-end write_todos persistence test covers this.
    • The opt-in list is appended as its own section, so it composes with tool_search=True instead of being dropped by the lean todo section.
    • DeepAgentDeps.get_todo_prompt() — until now unused by the library — is what renders that section, and now includes each todo's id (- [ ] [id] content, matching upstream) so the model can address a task with update_todo_status without re-reading the list.
    • The 0.3.37 note below claimed pydantic-deep's prompt behavior was unaffected by the upstream default. It wasn't; this is that fix.

Changed

  • vstorm-co dependency floors raised (#184) (pyproject.toml):
    • summarization-pydantic-ai>=0.1.11 — compression no longer produces a history that providers reject. With keep=("messages", 0) (the ContextManagerCapability default) the rebuilt history was a single ModelRequest of system parts only, which Anthropic and Google route into the top-level system parameter — mapping to zero provider messages, so any run long enough to cross the compression threshold failed deterministically. A zero keep also no longer summarizes away the in-flight request, and summaries stop accumulating in the system channel. Note for anything reading a summary back out of a compressed history: it's carried by a UserPromptPart now, not a SystemPromptPart.
    • subagents-pydantic-ai>=0.2.10wait_tasks used to hard-slice a completed task's result to 2000 characters with no marker, so the orchestrator read a well-formed answer that stopped mid-sentence, assumed the subagent was cut off, and re-delegated work that was already done. Truncated results now say so and name the check_task(...) call that returns the full text, and the budget is configurable via max_result_chars.
  • ruff capped below 0.16 in the lint group (pyproject.toml). uv.lock is gitignored, so CI resolved the latest release on every run; ruff 0.16.0 started formatting code blocks inside Markdown, which flags 49 docs and examples/skills/*/SKILL.md files that have never been formatted — turning ruff format --check red on unrelated PRs. Lifting the cap belongs in a dedicated commit that reformats those files in one go.

0.3.37

Choose a tag to compare

@DEENUU1 DEENUU1 released this 22 Jul 10:25

[0.3.37] - 2026-07-22

A CLI paste fix and raised floors on the vstorm-co packages, bringing backend
permission-rule hardening, stateful subagent conversations, and a
cache-friendly todo system prompt upstream.

Fixed

  • Single-line paste no longer inserts the text twice in the CLI prompt (#179) (apps/cli/widgets/input_area.py). Textual dispatches a Paste event to both the subclass and the base-class handler, and PromptInput._on_paste additionally called Input._on_paste directly — so a plain single-line paste landed once from the direct call and once again when MessagePump reached the base handler. The multi-line path (routing to multiline mode) is unchanged; a single-line paste now falls through to normal dispatch and is inserted exactly once. Ships with a regression test. Contributed by @Sanjays2402.

Changed

  • vstorm-co dependency floors raised (#174) (pyproject.toml):
    • pydantic-ai-backend[console]>=0.2.16 (also the sandbox extra) — permission rules are now enforced on every content-returning path of LocalBackend: read_bytes (closes the image/document leak through read_file), grep_raw, ls_info/glob_info, and a best-effort path guard on execute, so a deny rule like **/restricted/** can no longer be bypassed.
    • subagents-pydantic-ai>=0.2.9 — stateful subagent conversations via chat_trace_id (a task result's trace ID can be passed back to resume the same subagent with full history) and rich per-task observability on TaskHandle (usage, cost, message history, trace/span IDs), with check_task/wait_tasks no longer embedding usage details in tool-return text.
  • pydantic-ai-todo>=0.2.7 (pyproject.toml) — upstream TodoCapability no longer injects the live todo list into the system prompt by default, which was invalidating the provider's prompt-cache prefix on every todo mutation (opt back in with include_current_todos=True). pydantic-deep builds its todo instructions through the unchanged get_todo_system_prompt() helper, so its own prompt behavior is unaffected by the new default.

0.3.36

Choose a tag to compare

@DEENUU1 DEENUU1 released this 17 Jul 22:43

[0.3.36] - 2026-07-18

A configurable MCP handshake timeout for slow-starting servers, and LiteParse
pinned to the 1.x line.

Added

  • init_timeout on MCPServerConfig for slow-starting MCP servers (#167, #171) (pydantic_deep/mcp/config.py, pydantic_deep/mcp/registry.py). pydantic-ai caps the initial connect + initialize handshake at 5s, so a server that does real work on startup (e.g. opens a database connection, ~8s) failed with "Failed to initialize server session" — and re-wrapping with a longer timeout isn't possible, since MCPToolset rejects init_timeout alongside a pre-built client. The new optional field (validated positive; None keeps the 5s default) is forwarded by build_mcp_server to every MCPToolset construction (stdio, OAuth, http/sse), only when set, and round-trips through to_dict/from_dict so the CLI persists it in mcp.json. The /mcp Test action's probe window now scales with it — max(10s, init_timeout + 5s), OAuth keeps 180s — so a slow server that connects fine at runtime no longer fails its connection test (apps/cli/modals/mcp_view.py).

Fixed

  • LiteParse pinned to the 1.x line (#172, #173) (pyproject.toml, pydantic_deep/features/liteparse/toolset.py, docs/advanced/liteparse.md). The liteparse extra's lower bound moves to >=1.1.0 — the first release of the Python binding that ships the async API (parse_async/screenshot_async) the toolset uses — and gains a <2.0.0 cap, since 2.x dropped that API. The npm CLI install command in the toolset docstrings, the runtime "not installed" message, and the docs is pinned to match (npm install -g @llamaindex/liteparse@^1.2.0), so auto-install and copy-pasted setup can't pull an incompatible 2.x CLI.

0.3.35

Choose a tag to compare

@DEENUU1 DEENUU1 released this 03 Jul 18:37

[0.3.35] - 2026-07-03

Onboarding and per-user configuration, a dynamic model catalogue in the picker,
credential management from the CLI/TUI, reasoning-effort and project-init
commands, a prompt/reminder overhaul, and a Terminal-Bench harness.

Added

CLI / TUI

  • First-run onboarding — on first launch (when no model is configured
    anywhere) the CLI walks you through picking a provider, entering its key, and
    choosing a model. The choice is saved to the user-level config so it carries
    across every project. Re-runnable any time with pydantic-deep onboard.
  • Credential managementpydantic-deep keys list / set / remove and an
    in-TUI /keys picker set any of the known credentials (model providers,
    Vertex, Logfire, AWS, Azure) from one registry into a git-ignored keystore.
    Keys are user-global by default (~/.pydantic-deep/keys.toml) and loaded into
    the environment on startup; --project scopes them to one repo. Real env vars
    always win.
  • Dynamic model catalogue — the /model picker (aliased /models)
    now lists recently-used models, the live OpenRouter catalogue (fetched and
    cached under ~/.pydantic-deep/cache/, refreshed in the background), and every
    native provider pydantic-ai recognises (read from its KnownModelName, keyed
    providers first), all with real fuzzy search. On the CLI: pydantic-deep models recent / openrouter / select. Recently-used models are remembered per user.
  • /thinking — change reasoning effort (off → xhigh) from a picker or
    /thinking <level>; it applies live and persists.
  • /init — analyse the project and write an AGENTS.md so the agent has
    context (and seed MEMORY.md).
  • Welcome hero — the splash now renders a magenta pydantic ASCII wordmark
    and a rotating tip (it was previously a defined-but-never-mounted widget).
  • Interactive CLI pickerskeys set and models select open
    arrow-selectable lists with hidden value entry (prompt_toolkit) when run
    without arguments; the argument forms stay scriptable.

Framework

  • Submodels inherit the primary model when not explicitly configured — an
    undefined summarization / reminder / judge model now falls back to the main
    model instead of a hard-coded default.

Benchmark

  • apps/harbor — a Harbor BaseInstalledAgent adapter to evaluate the CLI
    agent on Terminal-Bench 2.0, with Logfire tracing and per-task trace tags,
    installing pydantic-deep into the task container and forwarding the full agent
    feature set. A benchmark AGENTS.md encodes the task-solving rules.

Changed

  • User-level vs project configurationload_config() now merges a global
    ~/.pydantic-deep/config.toml (user defaults: model, theme, thinking) as the
    base with the project .pydantic-deep/config.toml as overrides; environment
    variables win over both. The model chosen during onboarding lives in the global
    config so new projects don't re-prompt.
  • Onboarding is triggered by "no model configured" (env / project / global
    config) rather than by the absence of ~/.pydantic-deep/, which incidental
    caches (update check, keystore) created too early to be a reliable signal.
  • Context files are no longer auto-created. AGENTS.md, SOUL.md and
    MEMORY.md are written only by the agent when it decides to (write_memory /
    write_file), by /init, or by the user — never scaffolded on launch. Missing
    files are silently skipped and write_memory creates MEMORY.md on demand, so
    the agent works with or without them.
  • System prompt consolidated into pydantic_deep/prompts/ — one set of
    composable fragments + a builder, replacing the scattered CLI/prompt strings;
    the old apps/cli/prompts.py is now a thin re-export.
  • Periodic reminder cadence relaxed to every 15 turns (first after 15, no
    per-run cap) so long tasks aren't nagged as often.
  • Ctrl+C aligns with Claude Code / Codex (#154) — it now copies the current
    text selection to the clipboard when there is one, and an idle Ctrl+C arms exit
    (a second press within 2 s quits) instead of closing on the first press. A
    running agent is still interrupted by a single Ctrl+C. Text selection (dragging
    to highlight agent output) works via Textual's built-in selection.

Fixed

  • /model was effectively unusable — the picker didn't focus its input (you
    couldn't type), the "filter" never actually filtered the list, and pressing
    Enter on a typed term submitted the raw text (qwen"Unknown model:
    qwen"
    ) instead of selecting the highlighted match. All three fixed; a
    duplicate-id crash when a model appeared in both "recent" and a provider list
    was resolved.
  • Changing the model now updates the input footer live — the session line
    under the prompt read model_name lazily and only refreshed after an app
    restart.
  • Headless runs survive flaky provider responses — the graceful-exit path
    now also catches transport/gateway failures (ModelHTTPError,
    httpx.HTTPError, and json.JSONDecodeError from a non-JSON gateway body) and
    exits 0 so downstream verification can still grade the filesystem, instead of a
    hard non-zero crash.
  • MCP subagents failed in the TUI with [Errno 9] Bad file descriptor
    (#167). run_tui() built the agent before app.run(), so a subagent
    agent_factory that spins up an MCPToolset(StdioTransport(...)) bound
    fastmcp's async primitives to the orphaned pre-app.run() event loop; when a
    task() delegation later used them inside Textual's loop, the stdio connection
    died instantly. Agent construction is now deferred to DeepApp.on_mount
    (agent_factory built via _build_deferred_agent, before the chat screen
    mounts) so those transports bind to the running Textual loop. The "launch the
    TUI anyway on failure so the key can be fixed via /provider" behaviour is
    preserved.

0.3.34

Choose a tag to compare

@DEENUU1 DEENUU1 released this 27 Jun 15:27
f2224c5

[0.3.34] - 2026-06-27

A large release: a full CLI/TUI overhaul, a vertical-slice re-organization of the
framework into features/, a new Monitor capability, broad edge-case
hardening, and a documentation rewrite.

Added

Framework

  • Monitor — watch & react (pydantic_deep/features/monitoring/). The agent starts a long-lived command (log tail, CI poll, file watch, dev server) with start_monitor / list_monitors / stop_monitor; each new line of matching output is pushed back into the conversation via the message queue, so the agent reacts without polling. MonitorManager drains the process on an interval, filters lines by an optional regex, and emits MonitorEvent batches through an on_event sink. Enabled by default (include_monitoring=True); needs a background-capable backend.
  • Background process tools surfaced from pydantic-ai-backend 0.2.15 (run_in_background / read_output / kill_shell / list_shells), so dev servers and watchers outlive a single execute() call (which kills its whole process tree on timeout).
  • ToolSearch capability (pydantic_deep/features/tool_search/) — defer situational toolsets so the model discovers them on demand. Off by default in the library, on in the CLI.
  • A built-in general-purpose subagent so the agent can delegate arbitrary multi-step work.

CLI / TUI

  • New slash commands: /retry (re-run the last prompt, dropping the previous turn), /export [path] (save the conversation to Markdown), /shells (list background processes).
  • Ctrl+P input-history picker with fuzzy search; fuzzy subsequence matching in the / command and @ file pickers (new apps/cli/fuzzy.py).
  • Background-shells panel pinned in the activity dock.
  • Multi-line paste switches the input to multiline, preserving code blocks.
  • Visible attachment chips + drag-and-drop files onto the input; clipboard image paste; quoted @"path with spaces" so spaced screenshots attach as images.
  • Interactive /settings modal (changes apply immediately) and an /info modal; /help and the command picker now list every command, guarded by a coverage test.
  • Warm amber (Tau-inspired) default theme with theme-aware chrome (header, status line, input, tool calls, diffs), animated welcome, and a boxed prompt.

Changed

  • @file references now pass the path (backticked) to the agent instead of inlining the whole file — the agent decides how to read it (full, sliced, or grep). Images still attach as multimodal content.
  • !shell and /diff run off the event loop (no UI freeze on long commands or large repos); the /load session picker loads asynchronously, sorts by modification time, and fuzzy-filters.
  • Lean behavioral prompt sections when tool_search is on (tools carry their own descriptions); folders-first directory tree in the context prompt.
  • Prompt caching enabled on the OpenRouter path (previously only the Anthropic cache keys were set), cutting cost on multi-turn / subagent runs.
  • Left sidebar replaced by activity panels pinned above the input; session + workspace moved to a footer; the status line carries live metrics.
  • Broad type hardening and de-duplication across the framework (pydantic models for improve insights, Literal status/action enums, typed deps/callbacks/coordinators, tightened public exports, drift guards on DeepAgentSpec and overloads); default models sourced from pydantic_deep.models.
  • Pinned pydantic-ai-backend>=0.2.15 (background processes, read output ceiling, glob mtime sort, edit staleness guard, image downscaling, Python grep build-dir skip, AsyncCompositeBackend) and subagents-pydantic-ai>=0.2.8 (dropping the local RunUsage shim); added pillow to the cli extra for image downscaling.
  • Documentation rewritten in the FastAPI tutorial style and restructured around FastAPI's Learn → Advanced → Reference model. New step-by-step Tutorial — User Guide (docs/learn/, 13 pages), a rewritten Advanced User Guide (docs/advanced/, 19 pages including new goal-loop and monitor pages), a full CLI guide (docs/cli/, 6 pages), an Applications section covering the reference apps (docs/apps/: DeepResearch, ACP/Zed, Harbor), and new API-reference pages (monitoring, goal, tool-search, message-queue). Concept/example/landing pages carry the same voice; the real Pydantic logo is used in the navbar/favicon; pages superseded by the tutorial were retired and cross-links updated. mkdocs build --strict passes clean. CLAUDE.md reflects the features/ layout.
  • Reorganized features into vertical-slice packages under pydantic_deep/features/. Each feature now lives in one folder (capability.py + toolset.py + service.py/types.py) instead of being smeared across toolsets/ and capabilities/. Top-level imports (from pydantic_deep import …) are unchanged. The old deep import paths remain as deprecation shims (emitting DeprecationWarning) and will be removed in the next minor release.
    • memory: pydantic_deep.toolsets.memory / pydantic_deep.capabilities.memorypydantic_deep.features.memory.
    • context: pydantic_deep.toolsets.context / pydantic_deep.capabilities.contextpydantic_deep.features.context.
    • browser: pydantic_deep.toolsets.browser / pydantic_deep.capabilities.browserpydantic_deep.features.browser.
    • eviction: pydantic_deep.processors.evictionpydantic_deep.features.eviction.
    • patch: pydantic_deep.processors.patchpydantic_deep.features.patch.
    • history_archive: pydantic_deep.processors.history_archivepydantic_deep.features.history_archive.
    • stuck_loop: pydantic_deep.capabilities.stuck_looppydantic_deep.features.stuck_loop.
    • periodic_reminder: pydantic_deep.capabilities.periodic_reminderpydantic_deep.features.periodic_reminder.
    • hooks: pydantic_deep.capabilities.hookspydantic_deep.features.hooks.
    • message_queue: pydantic_deep.capabilities.message_queuepydantic_deep.features.message_queue.
    • teams: pydantic_deep.toolsets.teamspydantic_deep.features.teams.
    • plan: pydantic_deep.toolsets.planpydantic_deep.features.plan.
    • checkpointing: pydantic_deep.toolsets.checkpointingpydantic_deep.features.checkpointing.
    • improve: pydantic_deep.improve / pydantic_deep.toolsets.improvepydantic_deep.features.improve.
    • skills: pydantic_deep.toolsets.skills / pydantic_deep.capabilities.skillspydantic_deep.features.skills.
    • forking: pydantic_deep.toolsets.forking / pydantic_deep.capabilities.forkingpydantic_deep.features.forking.
    • liteparse: pydantic_deep.toolsets.liteparsepydantic_deep.features.liteparse.

Fixed

  • Subagents crashing with 'RunUsage' object is not callable under pydantic-ai 2.0 (usage became a property), fixed upstream in subagents-pydantic-ai 0.2.8 and re-pinned here.
  • Context-usage warning spammed on every update — it now warns once per crossing above 90% with hysteresis (re-arms below 85%), instead of on every ContextUpdated.
  • /undo left the removed turn on screen — it now removes the turn's widgets too (MessageList.remove_last_turn), keeping the transcript in sync with history. /retry reuses the same path.
  • Status bar overflow that ghosted text beside the input.
  • Numerous edge cases: forking auto/vote merge and abort deadlocks; skills frontmatter / path containment / reserved words; eviction preview-on-write-failure and collision-safe ids; patch tool-call rebuild preserving ModelRequest fields; MCP stdio/stderr screen leaks; dropped uploads; corrupt-archive recovery; and Python warnings leaking onto the TUI.
  • CI: docs build (stale eviction.create_content_preview reference) and mypy errors.

0.3.33

Choose a tag to compare

@DEENUU1 DEENUU1 released this 25 Jun 23:08
aba4e29

[0.3.33] - 2026-06-26

Fixed

  • Agent memory injection now keeps the most recent lines, not the oldest (#157) (pydantic_deep/toolsets/memory.py). format_memory_prompt truncated an over-budget MEMORY.md by keeping the first max_lines, but write_memory appends new content to the end of the file, so the newest observations were the first to drop out. Truncation now keeps the recency tail (the dropped-line marker moves above the kept tail). Two additions from the same report: authors can pin a foundational head with a <!-- deep:pin-end --> marker (DEFAULT_PIN_END_MARKER), which is always injected in full so it survives truncation; and injection can be budgeted in approximate tokens via a new max_tokens that takes precedence over max_lines (reusing the NUM_CHARS_PER_TOKEN heuristic). AgentMemoryToolset and MemoryCapability gain max_tokens / pin_marker; subagents accept extra.memory_max_tokens / extra.memory_pin_marker.
  • Subagent delegation no longer fails with a read_memory tool name collision (#155) (pydantic_deep/agent.py). With include_memory=True and include_subagents=True (both default), the default subagent factory passed include_memory=True into each subagent's own create_deep_agent, which registered a second AgentMemoryToolset ('deep-memory', under the wrong "main" namespace) on top of the one _inject_subagent_memory_toolset already injects — a regression since 0.3.30 that made every delegation fail with AgentMemoryToolset 'deep-memory' defines a tool whose name conflicts ...: 'read_memory'. The factory no longer creates its own memory toolset; the injected one, correctly namespaced to the subagent, is the single source.