Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
8bfacd8
feat(eve): run code mode as a durable workflow tool
ruiconti Sep 3, 2026
e62bfab
fix(eve): settle code mode Promise.all batches concurrently
ruiconti Sep 3, 2026
383af77
test(e2e): cover code mode end to end
ruiconti Sep 3, 2026
3c6145f
fix(eve): preserve code mode routing and nested call state
ruiconti Sep 4, 2026
cf8f6d3
fix(eve): expose every direct tool in code mode discovery
ruiconti Sep 4, 2026
80805a5
refactor(eve): replace Workflow with code mode orchestration
ruiconti Sep 4, 2026
e35d31c
test(e2e): exercise real model code mode planning
ruiconti Sep 4, 2026
84a1f39
test(e2e): require reports computed inside code mode
ruiconti Sep 4, 2026
bf34801
chore(eve): reconcile compatibility metadata after rebase
ruiconti Sep 4, 2026
9173f48
fix(e2e): configure code mode model evals
ruiconti Sep 4, 2026
d13aa7a
fix(eve): address code mode CI regressions
ruiconti Sep 4, 2026
456cc0c
fix(eve): declare code mode discovery output schemas
ruiconti Sep 4, 2026
b6447ff
feat(eve): let eager agents choose direct tools or Code Mode
ruiconti Sep 5, 2026
7e1fb0a
fix(eve): align code mode with current workflow contracts
ruiconti Sep 5, 2026
64a9dbd
fix(e2e): validate report inputs and grade task outcomes
ruiconti Sep 5, 2026
ef2fd30
feat(benchmark): trigger Code Mode tracking from PR comments
ruiconti Sep 6, 2026
54df6f9
fix(benchmark): withdraw workflow targeting the wrong repository
ruiconti Sep 6, 2026
52c698d
fix(eve): preserve optional tool arguments at provider boundary
ruiconti Sep 6, 2026
ed2c5c8
fix(eve): repair code mode suspension and program recovery
ruiconti Sep 6, 2026
ed2894a
fix(eve): reconcile code mode with current main
ruiconti Sep 6, 2026
d8d3379
refactor: build code mode stubs from the pinned catalog
ruiconti Sep 7, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/calm-code-mode-recovery.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"eve": patch
---

Fix Code Mode suspension around `try`/`catch` and `finally`, and return generated-program errors to the model without repeating the same source in workflow retries. Restore guidance to keep a task's related tool calls in one program.
5 changes: 5 additions & 0 deletions .changeset/code-mode-workflow-tool.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"eve": minor
---

Replace the experimental `Workflow` tool and `eve/tools/workflow` helper with `experimental.codeMode: { mode: "eager" | "lazy", maxSubagents?: number }`: programs discover all available tools, call eligible tools, await subagents, and enforce a subagent-call budget (100 by default). Nested calls resume durably after authorization and expose catchable failures; approval-gated tools and ordinary background tools remain direct. Eager keeps eligible direct tools available and guides the model toward programs for dependent calls and data processing; lazy exposes eligible tools through discovery.
5 changes: 5 additions & 0 deletions .changeset/optional-tool-arguments.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"eve": patch
---

Preserve optional tool arguments when calling models that implicitly normalize tool schemas into strict mode. Tools continue to validate inputs before execution, including mutually exclusive argument checks.
5 changes: 5 additions & 0 deletions .changeset/pinned-code-mode-stubs.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"eve": patch
---

Build Code Mode sandbox stubs from the tool catalog captured at dispatch, avoiding tool-context restoration on program start and resume. Actual tool calls retain authorization checks and durable execution.
1 change: 1 addition & 0 deletions .github/workflows/e2e-postgres.yml
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ jobs:
EVE_E2E_WORKFLOW_WORLD: ${{ matrix.world_package }}
EVE_EVAL_JUNIT_DIR: ${{ github.workspace }}/.junit
EVE_SANDBOX_IMAGE_TAG: latest
WORKFLOW_LOCAL_BASE_URL: http://127.0.0.1:3000
WORKFLOW_POSTGRES_MAX_POOL_SIZE: "52"
WORKFLOW_POSTGRES_URL: postgres://world:world@127.0.0.1:5432/world
WORKFLOW_POSTGRES_WORKER_CONCURRENCY: "50"
Expand Down
2 changes: 1 addition & 1 deletion apps/docs/lib/geistdocs/llms-index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Documentation links below point directly to Markdown. Remove the \`.md\` suffix
- [Execution Model and Durability](${EVE_ORIGIN}/docs/concepts/execution-model-and-durability.md): Understand sessions, checkpointed steps, and parked work.
- [Sessions, Runs, and Streaming](${EVE_ORIGIN}/docs/concepts/sessions-runs-and-streaming.md): Understand session IDs, NDJSON events, controls, and reconnecting.
- [Default Harness](${EVE_ORIGIN}/docs/concepts/default-harness.md): Understand model context and compaction in the built-in loop.
- [Built-in Tools](${EVE_ORIGIN}/docs/concepts/built-in-tools.md): Review default tools and add opt-in tools such as Workflow, glob, grep, and sleep.
- [Built-in Tools](${EVE_ORIGIN}/docs/concepts/built-in-tools.md): Review default tools and add opt-in tools such as code_mode, glob, grep, and sleep.
- [Context Control](${EVE_ORIGIN}/docs/concepts/context-control.md): Choose what the model sees and when.
- [Security Model](${EVE_ORIGIN}/docs/concepts/security-model.md): Review trust boundaries, secret handling, credentials, and fail-closed behavior.

Expand Down
89 changes: 81 additions & 8 deletions docs/agent-config.md
Original file line number Diff line number Diff line change
Expand Up @@ -251,14 +251,87 @@ installed package must stay external in hosted output, list it in

`defineAgent` takes a few more fields, all optional. For the exported types, see the [TypeScript API Reference](./reference/typescript-api).

| Field | Type | Default | Description |
| -------------- | --------------------------------------- | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `reasoning` | `AgentReasoningDefinition` | provider default | Provider-agnostic reasoning effort forwarded to the agent's turn model calls. |
| `modelOptions` | `AgentModelOptionsDefinition` | none | Provider option overrides forwarded to the model call. |
| `limits` | `AgentLimitsDefinition` | field-specific | Framework-owned runtime limits. Sessions complete after 30 days by default; usage-limit defaults and inheritance are described above. Set a limit to `false` to disable it. |
| `experimental` | `{ workflow?: { world?: string } }` | unset | Opt-in settings that can change or disappear in any release. Treat them as unstable. `workflow.world` selects the Workflow world package backing session state, queues, hooks, and streams on the root agent. |
| `outputSchema` | Standard Schema or a JSON Schema object | none | Structured return type for function-like invocations such as a subagent turn, schedule, or remote job. Ordinary interactive turns ignore it unless the client supplies a per-message schema. |
| `build` | `{ externalDependencies?: string[] }` | none | Hosted-build packaging controls. `externalDependencies` keeps listed packages external while eve compiles authored modules such as tools and channels, and traces those packages into the hosted output. |
Set `experimental.codeMode` to `{ mode: "eager" }` or `{ mode: "lazy" }` to
expose eligible tools through a framework-managed `code_mode` tool. The model writes a
JavaScript program that calls `tools.<name>(input)`; `code_mode` runs it as a
durable workflow in which every nested call is its own step, so a crash
mid-program resumes at the pending call instead of re-running earlier ones.
Tools with an approval policy other than `never()`, authored workflow tools,
ordinary `execution: "background"` tools, and framework task controls stay
direct. Subagent tools enter the program and
return their result when called, the same way an authored workflow tool's
`agent()` does.

`"eager"` keeps eligible tools directly callable and also includes their
signatures in `code_mode`. The model is guided toward programs for dependent
lookups, pagination, loops, and data processing, and toward direct calls when a
single call or native batch already provides the needed result. This is model
guidance, not a deterministic router or a performance guarantee. Schemas are
included up front even when the model chooses direct calls.

`"lazy"` hides eligible direct tools, lists the available tool names and the
discovery helpers' signatures, and lets the program discover schemas before
execution.

Each program can invoke at most 100 subagents by default. Set `maxSubagents` to
change that limit; sequential calls, parallel calls, retries, and calls that
continue an existing child all count. Excess calls reject with
`CODE_MODE_SUBAGENT_LIMIT_REACHED` before starting a child and can be caught by
the program. Ordinary tool calls do not consume this budget.

```ts title="agent/agent.ts"
import { defineAgent } from "eve";

export default defineAgent({
model: "openai/gpt-5.5",
experimental: { codeMode: { mode: "eager", maxSubagents: 25 } },
});
```

`code_mode` replaces the former `Workflow` tool. Remove the file that exports
`experimental_workflow()` from `eve/tools/workflow` and enable code mode in
`agent.ts`. Authored [workflow tools](./tools/workflows) continue to work.

In both modes, `tools.search_tools` and `tools.describe_tools` discover the
complete advertised tool catalog, including tools that remain available for
direct calls. Results include `requiresDirectCall: true` when the program
cannot execute a tool. Discovery does not run the tool or bypass its approval
policy. `code_mode` remains available for discovery even when all other tools
require direct calls.

`tools.search_tools({ query })` returns an array of matching tools; `query` is a
case-insensitive substring of the name or description. Omit it to list every
tool. `tools.describe_tools({ names })` returns an array of descriptions and
input schemas for the requested tool names.

Dynamic tools, including discovered connection tools, use the same eligibility
rules. `connection_search` stays direct so its discoveries reach the next model
step's catalog; eligible discovered tools become callable through `code_mode`, and remain
directly callable in eager mode. When names overlap, step-scoped definitions override turn-scoped,
session-scoped, and static definitions, in that order. Each program keeps the
tool catalog and captured values from the model step that dispatched it.

If a nested tool requires authorization, eve displays its authorization
request and waits for the matching callback before retrying that call. Earlier
completed calls retain their results. Tool and subagent failures reject the
corresponding JavaScript call, so programs can use `try`/`catch` or
`Promise.allSettled`. Parking a call for durable execution does not run the
program's `catch` or `finally` handlers. After the call settles, the program
resumes with its result or failure and follows normal JavaScript control flow.
Cancelling code mode stops the workflow.

Invalid JavaScript, uncaught program or nested-tool errors, and source, bridge,
or Code Mode serialization limit failures return to the model without retrying
the unchanged program. Sandbox infrastructure failures retain workflow step retries.

| Field | Type | Default | Description |
| -------------- | ----------------------------------------------------------------------------------------------------------- | ---------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `reasoning` | `AgentReasoningDefinition` | provider default | Provider-agnostic reasoning effort forwarded to the agent's turn model calls. |
| `modelOptions` | `AgentModelOptionsDefinition` | none | Provider option overrides forwarded to the model call. |
| `limits` | `AgentLimitsDefinition` | field-specific | Framework-owned runtime limits. Sessions complete after 30 days by default; usage-limit defaults and inheritance are described above. Set a limit to `false` to disable it. |
| `experimental` | `{ codeMode?: false \| { mode: "eager" \| "lazy"; maxSubagents?: number }; workflow?: { world?: string } }` | unset | Opt-in settings that can change or disappear in any release. `codeMode` groups eligible tools behind a JavaScript program; `workflow.world` selects the Workflow world package on the root agent. |
| `outputSchema` | Standard Schema or a JSON Schema object | none | Structured return type for function-like invocations such as a subagent turn, schedule, or remote job. Ordinary interactive turns ignore it unless the client supplies a per-message schema. |
| `build` | `{ externalDependencies?: string[] }` | none | Hosted-build packaging controls. `externalDependencies` keeps listed packages external while eve compiles authored modules such as tools and channels, and traces those packages into the hosted output. |

`externalDependencies` is a packaging control only. It keeps selected packages as runtime dependencies in the hosted output; it does not authorize, configure, or review any third-party service those packages may call.

Expand Down
11 changes: 9 additions & 2 deletions docs/concepts/built-in-tools.md
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ export default disableTool();

### `agent`

`agent` delegates a subtask to a fresh copy of the root agent. It is root-only, always runs in the background, and returns a task receipt immediately. The child receives the root's instructions, tools, connections, and sandbox, but starts with fresh conversation history and [state](./state). See [Subagents](../subagents).
`agent` delegates a subtask to a fresh copy of the root agent. It is root-only, runs in the background when called directly, and returns a task receipt immediately. The child receives the root's instructions, tools, connections, and sandbox, but starts with fresh conversation history and [state](./state). See [Subagents](../subagents).

```sh
eve add tool/agent
Expand Down Expand Up @@ -373,14 +373,21 @@ export default disableTool();

### `connection_search`

`connection_search` discovers tools across declared [connections](../connections) and makes matches directly callable by qualified name, such as `linear__list_issues`. eve adds it automatically when connections exist, even when `defaultTools` is `false`, so there is no add command.
`connection_search` discovers tools across declared [connections](../connections) and makes matches available by qualified name, such as `linear__list_issues`. Eligible matches can be called through `code_mode`, and remain directly callable in eager mode. eve adds it automatically when connections exist, even when `defaultTools` is `false`, so there is no add command.

An authored `agent/tools/connection_search.ts` replaces the framework behavior. Import the framework definition from `eve/tools/connection_search` when you need to reference it directly. Exporting `disableTool()` from this slot is an error because agents with connections require connection discovery.

Review these tools before production use. Disable, wrap, restrict, or require approval for any tool that can access the filesystem, network, shell, or sensitive data.

You can also add the opt-in framework tools described below.

## Programmatic orchestration

Enable [`experimental.codeMode`](../agent-config#other-defineagent-fields) to
coordinate tools and subagents in one JavaScript program. `code_mode` is
available only in the root session. Subagent calls inside its program await the
child result; direct subagent calls return background task receipts.

## Opt-in framework tools

These framework-provided tools are not added by default. Add only the ones the agent needs.
Expand Down
5 changes: 3 additions & 2 deletions docs/guides/dynamic-capabilities.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,9 @@ shadows the session selection for that turn, including when the turn handler
returns `null`. If a resolver throws or returns an invalid definition, eve logs the
failure and omits the subagent.

The resolved set applies to local and remote direct delegation. Background subagents are not
exposed inside the model-authored `Workflow` tool. eve
The resolved set applies to local and remote direct delegation and to subagent
calls inside `code_mode` programs. Direct calls return a background task receipt;
calls inside the program await the child result. eve
also checks availability again before starting the child, so a stale or
manually constructed call fails with `SUBAGENT_UNAVAILABLE`. Treat conditional
availability as capability composition, not as the only authorization
Expand Down
Loading
Loading