Skip to documentation
Documentation

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:

Terminal
npm install @onkeiki/eve

Or run npx @onkeiki/cli init in your app to do this setup for you (see CLI).

Mount the extension in your Eve app:

agent/extensions/keiki.ts
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:

text
POST /keiki/v1/dispatch

Use the route's full, externally reachable URL as the SDK dispatchUrl:

TypeScript
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:

TypeScript
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:

TypeScript
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.