eve
Connect an Eve application to Keiki's external harness with signed push turns and turn-scoped tools.
Use @onkeiki/eve to run an Eve
application as an external Keiki harness. Keiki continues to receive channel
messages, manage turn scheduling and delivery, and record the Keiki trace.
Install and mount
The integration requires Node.js 24 or later. Use @onkeiki/eve 0.1.6 or later
with Eve 0.91.0; older extension releases use an incompatible manifest. Rebuild
your Eve app after upgrading:
npm install @onkeiki/eveOr run npx @onkeiki/cli init in your app to do this setup for you (see CLI).
Mount the extension in your Eve app:
import from '@onkeiki/eve'
export default ({})The extension accepts signingSecret and instructions settings. Instructions
are enabled by default; disable them with keiki({ instructions: false }).
Configure Keiki push
The extension mounts this custom-channel route:
POST /keiki/v1/dispatchUse the route's full, externally reachable URL as the SDK dispatchUrl:
import { } from '@onkeiki/agents'
const = .({
// ...
: {
: 'external',
: 'push',
: 'https://your-eve-app.example/keiki/v1/dispatch',
: '10 minutes',
},
})Keiki signs each push with its Ed25519 platform key, and the extension verifies
it against Keiki's published turn keys, so no secret is needed. To verify with a
per-agent secret instead, create it once with
POST /api/v1/developer/agents/:agentId/harness/signing-secret; the returned
secret is shown once. kit.sync() does not create it. Store it in your Eve
application's secret manager as KEIKI_SIGNING_SECRET, or provide it in the
extension configuration:
export default ({ : .. })See the external harness contract for payload verification, turn API responses, and signing details.
Serving several agents
Resolve the signing secret by the dispatch's agent ID:
const : <string, string> = { : , : }
export default ({
: ({ }) => [],
})Returning nothing rejects the push with 401 unknown_agent. The resolver runs
before the signature is verified, so use a local map or cache rather than making
a network call on every request. Eve calls it on every push.
Turns, tools, and delivery
Each Keiki agent and conversation pair has its own Eve channel-local session.
New deliveries create a session; later turns for that pair are queued in the
same session. Each inbound message's content is joined with blank lines; on
threaded channels it starts with the [Message; message_id=…] annotation the Keiki
instructions refer to, and a message prompt screening flagged starts with a warning. The extension passes Keiki instructions through
Eve's channel context option by default; Eve appends channel context to session
history. Set instructions: false to omit it.
Retried push dispatches are deduplicated per session using the most recent 20 Keiki turn IDs.
Eve's turn.started event requests Keiki typing. Each non-empty
content.completed event with text in the reply phase is sent through the
turn-scoped /messages endpoint. Reasoning, narration, interrupted content, and
non-text content are not delivered. Eve's turn.settled event reports completion,
failure, or cancellation; a failed session.ended event also settles the Keiki
turn. The extension does not stream content.delta events; Keiki receives
completed replies rather than live token streaming.
The extension adds a dynamic Keiki MCP connection for each turn. Eve's
eve__search and eve__tool tools can discover and call Keiki
tools, including reply, files, reactions, and channel integrations. Keiki
controls whether completed answers are delivered; it captures held-back or
steered turns without delivering their answers to the contact.
A keiki.reaction push is accepted with 202 and does not start an Eve turn.
Inbound files arrive on each message's attachments, with a short-lived download url.
The send_file tool sends a sandbox path or a stored attachment_id. To send a file from
your own server, upload it with the channels TurnClient.sendFile (see
External harness).
Mid-turn messages
With midTurnStrategy: 'append', push-mode Eve deliveries that arrive while a turn is
running are steered into the existing Eve session. Eve reports the arrival sequence numbers
it accepted when completing the matching Keiki turn; messages it did not consume are
returned to Keiki's queue and answered by a later turn. An arrival that reaches Eve after
the session run ends can be forwarded to a new framework run while the Keiki turn is
closing; turn API calls then receive 409 turn_closed, and Keiki requeues the unconsumed
message.
Eve 0.91 applies steering before assistant answer output starts; reasoning and search progress do not count as answer output. If output has started, steering waits for the next committed workflow boundary. An executing tool is allowed to finish and checkpoint before the correction is applied. These are Eve's documented steering semantics.
Eve approval prompts and input requests are not bridged to Keiki. Keiki owns the
channel and delivery credentials. Keiki's provider credentials and platform API
keys are not sent to Eve; the Eve app may use its own model-provider
credentials. The app does receive a short-lived ht_ turn token so it can call
that turn's API. Never log or reuse this token.
Relay mode
Relay mode requires a connected Keiki development relay (keiki dev); it is
not shipped yet. For this extension, use push mode with a dispatch URL Keiki
can reach.