Migration boundaries¶
The current client requires eve 0.54.2 or newer and uses eve 0.84.0 as its
compatibility reference. Eve 0.54.2 is the first published release whose agent-info
schema-v4 kernel-effect action set is exactly subagent-call, task-cancel, and
workflow-tool-call.
Earlier schema-v4 servers can still advertise the obsolete task-update action. The
payload remains version 4, so the client has no schema discriminator with which to
accept both contracts strictly. It rejects task-update in v4 while historical schema
v3 continues accepting and preserving that action through EveAgentInfo.Raw.
Moving to Eve 0.84.0 and protocol 27¶
Alpha.16 and earlier reject version-27 streams. Deploy the v27-capable client
before exposing callers to Eve 0.84.0, while retaining a qualified older server
for legacy traffic. Drain old deliveries or retain their owning deployment:
protocol-generation compatibility does not migrate existing durable sessions.
A permanent session_version_unsupported error requires a new compatible
session or its original server, not repeated stream retries.
Version 27 stores atomic commits containing several facts, not one event per
line. Persist the entire EveSessionState, including StreamEventIndex and
StreamVersion; do not manufacture a cursor from Events.Count. Response
readers drain the full commit containing their matching delivery settlement.
Raw consumers must migrate to the actual new vocabulary: content.delta,
content.completed, call.requested, call.settled, interaction.opened,
interaction.settled, child.opened, turn.paused, turn.settled and
session.ended. Owners live in Scope. The library preserves these facts rather
than rewriting them into old message.completed or subagent.called events.
An accepted message or answer carries a delivery ID. GetOutcomeAsync selects
that delivery's turn, reply and result, and can report Cancelled. An
awaiting-input outcome ends even for callback-backed sign-ins; complete the
callback and follow the session independently when more work is expected.
After consuming a v27 stream, RespondAsync translates existing
EveInputResponse values to answers[].interactionId. For a freshly attached
handle whose protocol is unknown, use AnswerAsync with EveInteractionAnswer,
or restore complete persisted state. Do not send both old and new field names.
The obsolete CancelOwnedTasks option is rejected when the handle is known v27.
Cancel, clear, compact and reset return asynchronous admission receipts.
Use their DeliveryId with GetDeliveryOutcomeAsync and inspect the durable
outcome before assuming the operation applied. EveResetStatus.Accepted does
not claim the session has already retired; the handle remains pinned to it.
For children, pass the received child.opened event to StreamSubagentAsync.
Its committed source position establishes the root-authorized descendant read.
StreamDescendantAsync follows a chain of at most eight recorded hops without
contacting event-supplied URLs or advancing the parent's cursor.
Agent-info stays at schema 5 but no longer requires resolver eventNames or
memory visibility. This client accepts both historical and current v5 shapes;
older schema versions and malformed supplied values remain validated.
Review server-side history retention independently of transport compatibility.
Eve 0.84 derives Workflow retention from resolved trace policy unless explicitly
configured: a policy that does not retain both inputs and outputs can select
zero retention. Completed child or retired-session history can therefore return
permanent HTTP 410 session_expired. Choose a retention policy consistent with
the application's data policy when post-completion history is required; the SDK
does not retry or resurrect deleted history. The synthetic compatibility fixture
explicitly uses the World's default retention to exercise completed child reads.
Historical move from Eve 0.71.0 to 0.79.1¶
Alpha.16 preserves the first input descriptor for each case-sensitive request ID.
Repeated requests no longer replace its prompt/options/action or reopen a settled
identity within an observed response. InputRequests still records every occurrence;
PendingInputRequests is the canonical unresolved projection. Completed assistant
answers now survive both input and task waits instead of becoming null.
Responses to input answers learn their guarded cancellation target from
input.resolved; ordinary message responses continue ignoring older-turn resolutions.
Bounded streams send follow=false, allowing stranded-session history recovery.
An HTTP 409 with session_stranded is permanent, and live followers complete after
yielding session.failed or session.completed.
Creation-time tool stubs are optional and require a server-side allowToolStubs
grant. Omitting them retains ordinary tool execution. Upgrade the client before
using this API, and deploy a server supporting stubs before enabling the option.
Stub declarations never replace server permission checks or execute tools locally.
Historical move from Eve 0.63.0 to 0.71.0¶
This is not a version-only server upgrade. Eve 0.64.0 changes inspection to schema
v5, 0.69.0 changes the response stream version to 26 and reshapes child descriptors,
and 0.70.0 parks human input with turn.waiting instead of ending the turn.
Alpha.14 rejects schema-v5 inspection and version-26 streams.
The newer client retains the older supported inspection and stream schemas, so upgrade the calling application first while its qualified older server remains in place. Then qualify and promote the server upgrade. If moving both under maintenance, pause traffic, deploy the already-qualified pair, and reopen only after verification. Rollback to a compatible pair rather than putting alpha.14 against a version-26 server.
Server authors must separately review the upstream workflow/task, tool and runtime API changes. C# transport qualification does not prove application tool inventories, prompts, model-backed workflows, or evaluation telemetry. Prove those on a nonproduction candidate before cutover; a production smoke of every business workflow is not required.
Eve 0.71.0 also changes the built-in bash tool: commands still running after
30 seconds return a running result and continue as sandbox jobs across turns.
Cancelling a later turn does not stop an already-detached job. Applications that
inspect bash results must handle the new completed/running discriminator and
review their cleanup policy. The C# client preserves these tool outputs as raw JSON;
it does not own sandbox processes. The just-bash provider still runs commands to
completion and does not create background processes.
Applications that consumed subagent.called directly must also recognize the newer
agent.started descriptor. StreamSubagentAsync supports both. A human-input park
returns a Waiting outcome; PendingInputRequests exposes unresolved requests while
InputRequests retains its existing complete observed history.
Historical required server-first order for Eve 0.54.2¶
This boundary is a server-first rolling upgrade:
- Pin and deploy eve
0.54.2while applications remain on their existing NexusLabs.Eve release. - Verify health and agent inspection, including the absence of
task-updateand the presence ofworkflow-tool-callwhen durable workflow tools are configured. - Upgrade the application to the client release whose minimum is eve
0.54.2. - Verify agent inspection and a multi-turn conversation against the upgraded pair.
Do not upgrade the client first. A pre-0.54.2 server can return a schema-v4 payload
that the new client correctly rejects with EveProtocolException. Existing clients
already accept the narrower 0.54.2 action set, which makes the server-first order safe.
Historical eve 0.52.3 delivery-correlation boundary¶
Eve 0.52.3 is the first release whose accepted response for a message sent to an
existing session includes a nonempty deliveryId. The client uses that identifier and
durable event meta.deliveryIds to consume stale replay events without returning an
older turn.
Accepted existing-session message responses from pre-0.52.3 servers lack
deliveryId. There is no response version negotiation and no safe fallback, so clients
using delivery correlation reject the accepted response rather than risk returning stale
durable events. That historical migration was also server-first: older clients ignore
the additive response field, while the newer client requires it.
On legacy stream protocols, the following operations do not require delivery correlation:
- The initial
SendAsynccreates a session and has no prior durable events for that session, so its accepted response does not needdeliveryId. RespondAsynccontinues a pending human-input turn rather than accepting a new message delivery, so it also remains uncorrelated.
Every SendAsync on an existing session requires the identifier. The 0.54.2 strict
agent-info cutover does not change that delivery behavior, message-stream protocol 25,
session routes, or request bodies.
Historical migration to eve 0.31.x¶
NexusLabs.Eve 0.1.0-alpha.4 requires eve 0.31.0 or newer. 0.1.0-alpha.3 is the
final release for eve 0.29.x and 0.30.x.
The boundary is hard in both directions. A mismatched client and server complete the first turn and fail the second. Upgrading either side alone breaks the conversation, so the client and the agent must move together.
Earlier clients need no migration from eve 0.32.0 through 0.52.2
For NexusLabs.Eve releases whose minimum was 0.31.0, none of these eve releases
broke the framework-neutral client protocol. The core session routes are unchanged
across 0.31.0 through 0.52.2.
0.34.0 added approval.candidate and approval.settled; later releases through
0.52.2 remove no stream event type and add only additive fields and events.
A 0.31.x deployment can move anywhere in that range without changing this package,
and those client releases treated 0.31.0 through 0.52.2 as one supported range.
Their hard boundary remained eve 0.31.0.
Two changes need no migration but are worth knowing. From eve 0.33.0, a message
that arrives while a turn is active steers instead of waiting; set
EveTurnOptions.TurnPolicy to EveTurnPolicy.Queue to keep the earlier behavior.
Eve 0.59.1 changes steering from cancel-and-replace to an in-place update at the
next committed boundary, preserving an active turn's identity and usage. From eve
0.35.0, agent inspection returns schema version 2; use
0.1.0-alpha.6 or newer, because earlier releases of this package reject it and
GetInfoAsync throws. From eve 0.37.1, active response streams remain connected
until a turn boundary by default. From eve 0.38.0, response-scoped cancellation
targets the exact observed turn. From eve 0.39.1, accepted human input emits a
durable input.resolved event. From eve 0.41.0, active responses remain attached
across interim waiting boundaries while callback-backed connection authorization is
pending. Eve 0.42.0 tightens channel input responses to their exact contract, which
the typed .NET request model already enforces. Eve 0.44.1 adds open-read idle
recovery, and eve 0.44.4 fixes replay-to-live continuation in the JavaScript store;
both behaviors are already covered by this package. Eve 0.45.0 raises agent
inspection to schema version 3 and strictly validates successful health responses;
0.1.0-alpha.8 or newer supports both. Eve 0.45.1 publishes schema version 4
memory inspection. Eve 0.46.1 adds durable streamed tool-input deltas and raises
the message-stream protocol to 24. Eve 0.48.0 adds the workflow-tool-call kernel
effect for durable workflow tools. Eve 0.50.0 raises the message-stream protocol to
25 for delta-only text streaming. Eve 0.52.x keeps transient client context
available across every model call in its turn, including after tools, then clears it
before the next turn. Client releases before the delivery-correlation cutover support
these additions. These later changes required no deployment migration until eve
0.52.3 introduced the server-first boundary described above.
Why a single smoke test will not catch this¶
The client sends no protocol version. The only headers it sets are authorization,
content-type, and the Vercel OIDC token header; the only query parameters are
startIndex, includeTailIndex, token, and bypass. Nothing negotiates a version, so
a mismatch cannot be detected at connect time.
The first turn carries no continuation token in either direction, so it succeeds against either server. The failure appears on the second turn. A health check, an info call, or a one-message test will all pass against a server the client cannot actually talk to.
Always verify a multi-turn conversation.
Route matrix¶
Taken from each release's shipped dist/src/protocol/routes.js.
| Operation | eve 0.29.x | eve 0.30.x | eve 0.31.x |
|---|---|---|---|
| create / continue / stream / cancel | unchanged | unchanged | unchanged |
| reset | POST /eve/v1/session/reset |
POST /eve/v1/session/reset |
POST /eve/v1/session/{id}/reset |
| clear | not available | POST /eve/v1/session/clear |
POST /eve/v1/session/{id}/clear |
| compact | not available | POST /eve/v1/session/compact |
POST /eve/v1/session/{id}/compact |
Session creation, follow-up turns, streaming, and cancellation use the same paths on every release. Only the control operations moved.
Clear and compact require eve 0.30.0
0.1.0-alpha.3 exposes ClearAsync and CompactAsync even though it names eve
0.29.4 as its reference. Those two routes were introduced in eve 0.30.0. Against an
eve 0.29.x agent they never worked, and they fail with HTTP 400 rather than 404
because /eve/v1/session/clear matches the continue route with a session identifier of
clear.
Observed behavior across the boundary¶
Each row was executed against a real server of the named version.
| Client | Server | First turn | Second turn | Control operations |
|---|---|---|---|---|
alpha.4 |
0.31.x |
202 accepted | 202 accepted | 202 / 200 |
alpha.4 |
0.29.x |
202 accepted | 400 Missing or empty 'continuationToken' field. |
404 no route matching |
alpha.3 |
0.31.x |
202 accepted | 400 Session-ID routes do not accept 'continuationToken'. |
400, misrouted |
alpha.3 |
0.30.x |
supported | supported | supported |
Adopting the new client while the agent stays on 0.29.x or 0.30.x¶
This breaks. alpha.4 never sends a continuation token, and an eve 0.29.x or 0.30.x
server requires one to continue a session, so the second turn is rejected with HTTP 400.
The three identifier-addressed control routes also return HTTP 404 because they do not
exist before eve 0.31.0.
Upgrading the agent to 0.31.x while the application stays on the old client¶
This also breaks, and it is the more deceptive case.
- The first turn is posted with no token and is accepted.
- eve
0.31.xstill emits acontinuationTokeninside thesession.waitingstream event, where it is now a channel-local value. alpha.3harvests that value and stores it as session state.- The next turn includes it, and the server rejects the request with HTTP 400
Session-ID routes do not accept 'continuationToken'.
The old fixed control routes do not return 404 on eve 0.31.x. /eve/v1/session/clear
matches the continue route with a session identifier of clear, so the request is
misrouted and fails with a message about missing content rather than a missing route.
Running several agent deployments on different versions¶
Mixed agent versions are fine. Serving them from one application is not.
- A .NET project can reference only one version of
NexusLabs.Eve, so a single process carries a single client version. - The client has no per-instance protocol switch.
EveClientselects the host; the protocol is fixed when the package is compiled.
To promote one agent deployment while another stays behind, give each one its own deployable pinned to the matching client version. Promote an instance only when every application that talks to it is cut over at the same time.
Order of operations¶
Because both directions break, this is a coordinated cutover for each deployable rather than a rolling upgrade of one side.
- Inventory. Record which applications talk to which agent deployments, and whether
they call
ClearAsync,CompactAsync, orResetAsync. - Pin explicitly. Set
0.1.0-alpha.3as an exact version so nothing floats forward before the agent is ready. - Migrate the code on a branch. This is compile-time work and is independent of deployment. See the table below.
- Stand up a new agent deployment on eve
0.31.xbeside the existing one. Do not upgrade in place; the old client cannot talk to it. - Deploy the
alpha.4build against the new deployment only. - Verify a multi-turn conversation, plus every control operation the application uses. A single message proves nothing.
- Move traffic, then retire the old deployment.
- Remove the
alpha.3pin once no deployment runs eve0.30.xor earlier.
Code changes required by 0.1.0-alpha.4¶
| Before | After |
|---|---|
SendAsync(new EveSendTurnRequest { Message = m }) |
SendAsync(m, options, cancellationToken) |
SendAsync carrying InputResponses |
RespondAsync(inputResponses, options, cancellationToken) |
EveSendTurnRequest for shared settings |
EveTurnOptions |
EveClient.CreateSession(continuationToken) |
EveClient.AttachSession(sessionId, streamIndex) |
EveSessionState.ContinuationToken |
removed; sessions are addressed by identifier |
EveMessageResponse.ContinuationToken |
removed |
EveClientOptions.PreserveCompletedSessions |
removed; a completed session stays streamable |
EveCancellationOutcome.SessionId non-null |
nullable; a no_active_turn result names no session |
ResetAsync clearing local state |
the handle keeps its identifier; call CreateSession for a new conversation |
A turn now carries either a message or input responses and never both. eve 0.31.0
rejects a combined body with HTTP 400, so the payload is a required argument and the
combination can no longer be expressed in code.
Reusing a retired session identifier returns HTTP 409 with the error code
session_not_active, available through EveClientException.ErrorCode.
How these results were produced¶
The route matrix comes from the published dist/src/protocol/routes.js of eve 0.29.4,
0.30.0, 0.31.0, 0.31.3, and 0.32.0.
The behavior table comes from requests issued against real servers: the pinned eve fixture
in test/fixtures/eve-agent, and eve 0.29.4 and 0.32.0 agents built from the same
agent sources. Each cell records the status code and error body that server returned. The
0.32.0 server returned the same status for every operation as 0.31.3.
The eve 0.30.x row is the supported baseline for 0.1.0-alpha.3 and is stated from the
route matrix rather than from an executed request.