Repository navigation
bide v0.8.0
Runs that recover themselves, budgets that cover the whole tree.
v0.8.0 makes durable runs self-sustaining and fully accounted for. Recovery runs continuously, every run journals where it started, token budgets and spend reach every sub-agent and every request sent, and each library module now installs with go get.
- Continuous recovery.
agent.RecoverLoopkeeps taking over the runs of a crashed holder with no further calls, with its own interval, concurrency and error handler. Leases are held under a per-call token, failed renewals retry well before the lease expires, and a drive that loses its lease stops withErrLeaseLost. A multi-process test harness on Postgres kills, stalls and restarts workers to check it, and the Postgres stores run every write at read committed, whatever the deployment's default isolation. - Runs that know where they started. Each run journals its input and entry point (
run:start), readable withagent.RecordedStart, so aRecovercallback resumes a run with exactly what it began with. Resume decisions come from the journal: a recorded approval denial stays final, saga rollback compensates by the safety each call recorded, and aplannode re-runs only when it was retry-safe when attempted. - Sessions in their own namespace. A session's journal and turns live under
"<id>>@session"and"<id>>@turn/<n>", so no run started withRuncan share one, session ids may contain/, andagent.IsSessionRunidentifies them. Timers inside sub-agents wake under names qualified by the sub-run, so sibling sub-agents can wait on timers of the same name. - One budget for the agent tree.
WithTokenBudgeton a parent covers its sub-agents, andResult.Usageand the newResult.Spendreport the whole run, including retried, hedged and failed requests.middleware.CostMeterreports what was spent, aTurnRestartedevent marks a retried streamed turn, andWithModelCallHookandWithModeladd hooks and per-call routing around every request. - Precise model boundaries. Finish reasons are one typed, provider-neutral set (
stop,tool_use,length,filtered) with the provider's own value inFinish.Raw, and a cut-off or filtered turn is reported asErrOutputTruncatedorErrOutputFiltered. Responses are capped (WithMaxResponseBytes), adapters describe themselves throughagent.ModelInfoOf, and the provider HTTP kit has its own package,model/provider, for writing adapters. - Typed tools, exactly as declared. Tool arguments decode strictly against their schema,
schema.Fordescribes precisely whatencoding/jsondecodes, and a call whose outcome is lost mid-flight on a tool that is not retry-safe is recorded as unknown (ErrToolOutcomeUnknown). A call cancelled before its effect ran is re-attempted. - MCP with limits.
mcp.WithSafetydeclares retry safety per tool, andWithCallTimeout,WithMaxResultBytesandWithMaxDescriptionBytesbound each server, with 1 MiB and 8 KiB defaults. Tool lists are checked for malformed and duplicate names, andmodeltest.ToolNameschecks provider name rules. - Audit artifacts for tooling. Proofs and evidence use versioned formats with snake_case JSON, signed tree heads carry checked timestamps (
audit.CheckTimestamp,WithClockSkew), andbide-auditadds-jsonand-versionwith one exit-status scheme: 0 verified, 1 not verified, 2 usage, 3 no verdict, 4 input unusable. - Flows as versioned config.
planconfigs declare"version": 1with snake_case keys, blocks can be named (Arm.Named,plan.BlockName), steps and joins take acontext.Context, and a configsafetycan lower a node's retry safety, never raise it. - Evaluation you can gate on. A metric that cannot score a run leaves it unscored,
eval.Comparereturns aComparisonwith aGateand tolerances, and eval reports errors instead of panicking. - Retrieval across stores.
RetrievalNameandRetrievalDescriptionlet one agent search several stores, and retrieved context is journaled once per run and kept in every model call, including after resume. - Journaling throughput at the v0.7.0 level. Recording a step decodes each record once and tags message parts without a re-encode, with the journal bytes unchanged. On a standard 4-vCPU GitHub runner (AMD EPYC 7763, median of 21), 20,000 runs with 5,000 in flight and 50 ms model calls finish in about 1.05 s (~19,000 runs/s), and the overhead scenario runs ~23,700 runs/s (cmd/bench).
- Every module installable.
governis its own module, and the stores,mcp,trace,codec/gcf,governand the governed-event logs are tagged with each release, so they install withgo getat the same version as the core. CI checks the doc comment on every exported identifier and compiles every Go block in the README and docs against the current code.
API changes:
- Journal keys encode the tool-use id (
tool:<id>, sub-runs<parent>><id>); runs journaled by v0.7.0 do not resume. ResolveHaltresolves tool calls only; useResolveStepHaltfor aStep.- Step names with a reserved engine prefix, run and session ids containing
>, andplanstep names containing:areErrConfig, andRecoverskips sub-runs. Finish.Reasonuses the neutral valuesstop,tool_use,lengthandfiltered; a truncated or filtered turn fails withErrOutputTruncatedorErrOutputFiltered, any other reason withErrStreamProtocol.- A reply over the response cap fails with
ErrResponseTooLarge, and atool_useturn with no call fails. - Tool arguments for
Func,SubAgentandfinal_answerdecode strictly: missing required, unknown, case-variant, duplicate or trailing data isErrToolArgs. schema.Fordescribes whatencoding/jsondecodes and returnsErrUnsupportedTypefor kinds JSON cannot carry.RunTyped[T]needs an objectT, andRunTypedNativeon Anthropic returnsErrConfig.WithRetrievalsends context as a user message before the latest user turn, journaled once per run, andRetrievalToolandWithRetrievalrequire k >= 1.WithTokenBudgeton a parent covers its sub-agents, andResult.UsageandResult.Spendreport the whole run.agent.EmitMessagetakes the turn'sUsage.planstep and join functions (Builder.Step,Join2,Join3,RegisterStep,RegisterJoin2,RegisterJoin3) take acontext.Context.- Audit proof JSON is snake_case with a
formatfield (bide.audit.proof.v2,bide.audit.evidence.v4), and other formats fail withaudit.ErrFormat. plandigests arebide.plan.topology.v2(flows started under v1 do not resume), config JSON decodes strictly, and a configsafetycan lower retry safety but not raise it or clear approval.planconfigs need"version": 1and snake_case keys,TopologyJSON keys are snake_case,TopologyNode.KindisTopologyNodeKind, and parse errors wrapErrConfig.- Signed tree heads need a positive timestamp within the clock skew, empty evidence packages fail, and
bide-auditinput is capped at 256 MiB. ApprovalPolicy.Validaterefuses approver ids equal under Unicode normalization and case folding, and invalid UTF-8.middleware.RetryandToolRetrywith n < 0 andQuorumwith k above the voter count areErrConfig, andEventLog.EventsreturnsErrProtocolon a gap.eval.Judgepasses only on an exactPASS, and a failed run never passes.eval.RequiredRunsreturns(int, error), andeval.Runreturns an error for duplicate metric names.eval.Matchestakes a*regexp.Regexp,AgentRunnerreturns(RunFunc, error),Comparereturns(Comparison, error), andGovernanceHeldpredicates take a context.- The provider HTTP kit moves from
agenttomodel/provider;WithToolResultCodectakes aprovider.ToolResultCodec. Finish.Reasonis the typedagent.FinishReason.evalMetric.Fnreturns(bool, error),MetricStatreportsScoredandUnscored, and reports arebide.eval.report.v2.bide-auditexit statuses: 0 verified, 1 not verified, 2 usage, 3 no verdict, 4 input unreadable or unusable.- A session's journal and turn runs are
"<id>>@session","<id>>@turn/<n>"and"<id>>@event/<encoded key>"; sessions journaled by v0.7.0 open empty, andRecoverskips them. - Every run journals
run:start; resuming with a different input, a saga throughRun(or a run throughRunSaga), orSendOncewith a different input on an open turn isErrConfig. planattempt markers record retry safety; a node re-runs on resume only if it was retry-safe then and now, and a marker written before v0.8.0 halts.- A recorded approval denial is final even if the tool's gate is later removed, loosened or made m-of-n.
- Saga rollback treats a completed call as a write unless its result records it ran ReadOnly, and reports calls to unregistered tools as uncompensated.
plan.Retryableand the config safety"retryable"are removed; useplan.Idempotentand"idempotent".governis its own module: addgithub.com/bide-ai/bide/governwithgo get.
Install:
go get github.com/bide-ai/bide@v0.8.0
Library modules, at the same version:
go get github.com/bide-ai/bide/store/sqlite@v0.8.0
go get github.com/bide-ai/bide/store/postgres@v0.8.0
go get github.com/bide-ai/bide/mcp@v0.8.0
go get github.com/bide-ai/bide/trace@v0.8.0
go get github.com/bide-ai/bide/codec/gcf@v0.8.0
go get github.com/bide-ai/bide/govern@v0.8.0
go get github.com/bide-ai/bide/govern/sqlitelog@v0.8.0
go get github.com/bide-ai/bide/govern/redislog@v0.8.0
go get github.com/bide-ai/bide/govern/postgreslog@v0.8.0
Docs: https://bide-ai.com. The approval guide is now Human approval (human-in-the-loop).