Skip to content

v3.6.0 — DSPy 3.4, request splitting, workflow facts on classes, and a self-bounding observability store

Latest

Choose a tag to compare

@drawal1 drawal1 released this 11 Oct 19:24
· 2 commits to main since this release
d9bea5f

v3.6.0

The agent can split a request into independent sub-tasks and run them one by one, with execution guards against repeated or malformed steps. fastWorkflow moves to DSPy 3.4. The runtime manifest is retired, and workflow facts are now declared on the classes themselves. The observability store keeps itself within its size cap in long-lived servers with no setup. This release also carries the unreleased 3.5.1 work: exact prompts in the debug UI and fixes to agent tool selection. Package version is 3.6.0. This wheel is already on PyPI.

The curated list is under 3.6.0 and 3.5.1 in CHANGELOG.md. These notes cover the upgrade.

Requires Python >=3.13,<3.15 (unchanged).


Breaking changes (read before upgrading)

  1. A populated observability database from an older schema is refused and left in place. This build reads schema v9 and carries no migration. Opening a populated v8 or older observability.sqlite3 raises OlderObservabilityStore. fastWorkflow does not delete that file. Move it aside, together with its -wal and -shm files, before starting a new store.
  2. dspy is required at >=3.4.0,<3.5 with the typesafe extra. import fastworkflow imports litellm before dspy, and it repairs DSPy's lazy openai stand-in if dspy was imported first.
  3. workflow_runtime.json is retired. A context's callback class declares occupiable = False. A command's ResponseGenerator declares descends_to / descend_parameter. Workflow identity is a content hash computed by the framework.
  4. Capture profiles and context handles are gone. FW_OBS_CAPTURE_PROFILE and the manifest capture field are removed. A manifest that still declares capture or handle_projector fails validation. Recorded values get the credential scrub only.
  5. Observation handles are ReAct step indexes (O0, O1, …). Execute ordinals, ordinal_offset, forced-replan continuation segments and alias_conflict are removed.
  6. The workspace viewer and the blinded review sidecar are removed. That covers run_chatbot --workspace-manifest, /api/workspace/*, /api/select_workspace, /api/review/*, /trace and fastworkflow/review/. Comments always go to the workflow's live database. Experiment sealing is unchanged.

Highlights

  • Request splitting: the agent splits a request into independent sub-tasks and runs them one by one. Workflow skills in _skills/ serve as job types, and an optional _skills/split_instructions.md adds splitting instructions. When a sub-task hits the 25-step cap, it is handed to a fresh executor, at most twice.
  • Execution guards:
    • A call that bundles several commands is refused.
    • A command that returns the same result again is blocked for one step.
    • Unparsable replies and LLM timeouts are recovered as bad steps instead of ending the turn.
  • LLM_TIMEOUT_SECONDS bounds each LLM call (default 120). Parameter-validation hooks can declare command_text to receive the command as written.
  • Self-bounding observability store:
    • The retention prune now runs hourly, not only when the recorder starts.
    • When only turn records remain over FW_OBS_DB_MAX_BYTES, the oldest finished turns that belong to no experiment are evicted whole. The cap is now a real limit on file size.
    • No new settings: the defaults (30 days, 1 GiB) work out of the box.
    • A malformed FW_OBS_* integer now logs a warning, as does an unsealed experiment that alone holds the file over its cap.
  • Exact prompts in the debug UI: an LLM call whose messages exceed the 16 KB attribute cap is stored as deduplicated pieces in a new prompt_slots table. ObservabilityStore.prompt_as_sent rebuilds the call and checks it against the recorded digest. The debug UI shows it under "LLM input as sent".
  • Clearer observations: each observation line says where the command ran and whether it changed the context, e.g. Observation O3 (execute_workflow_query ran in Directory); and resulted in a context change.
  • Planner context: the initial planner gets every prior turn summary, not just the last trajectory. The planner and agent tools get prescriptive context-navigation guidance.
  • Observation offloading is simpler: each observation is saved once per step and offloaded when the whole executor prompt exceeds FW_TRAJECTORY_MAX_BYTES.
  • Feedback API: POST /post_feedback and GET /feedback accept a retired execution key. /post_feedback returns the turn's comments.

Fixes

  • When the model names a workflow command as its tool (for example next_tool_name: open_directory) and that command is available in the current context, the step runs as the execute_workflow_query call it meant. Previously it became an invalid-tool step, and three of those end the turn.
  • A moved or reinstalled fastworkflow no longer breaks every turn. A stale command_directory.json whose module paths no longer exist is rebuilt.

Security


What's Changed

  • Say when a command moved the context on its observation line by @dharrawal in #86
  • Agent observation and tool-selection fixes, exact prompts in the debug UI (3.5.1) by @dharrawal in #87
  • merge beads changes by @dharrawal in #88
  • DSPy 3.4, request splitting, workflow facts on classes (3.6.0) by @dharrawal in #89

Full Changelog: v3.5.0...v3.6.0


Install

uv pip install 'fastworkflow==3.6.0'
# optional extras:
uv pip install 'fastworkflow[server]==3.6.0'   # FastAPI/MCP HTTP service
uv pip install 'fastworkflow[training]==3.6.0' # HuggingFace datasets for train