eve
@ingram-tech/eve-ingram-cloud wires a smith into a
eve agent — the eve-ecosystem sibling of the
Vercel AI SDK adapter and Flue. It is three thin
seams, each over a surface you already know: a smith becomes the agent's
model, Ingram-hosted tools attach as an MCP connection, and approvals ride
the standard tool-call channel. No bespoke protocol.
eve's model field takes a plain AI SDK LanguageModel, so the model seam stands
on the OpenAI-compatible API directly — a smith looks like
any model to eve while it runs the agent loop server-side: memory, tools,
approvals, isolation.
npm install @ingram-tech/eve-ingram-cloud
eve and ai are peer dependencies — you already have them in an eve project.
The model
Author it in agent/agent.ts. The token names the smith (the end-user's
instance); the agent is the one that smith runs.
// agent/agent.ts
import { defineAgent } from "eve";
import { ingramCloudModel } from "@ingram-tech/eve-ingram-cloud";
// A per-smith token already names one smith — browser-safe.
export default defineAgent({
model: ingramCloudModel({ apiKey: process.env.IC_SMITH_TOKEN! }),
});
eve routes this as an external provider — it bypasses the AI Gateway and talks to Ingram Cloud directly.
The model id is the LLM, not the agent
The agent a smith runs — its instructions, tools, and memory — is
resolved from the smith, never from the model id. modelId is the upstream
inference LLM for the turn: omit it to use the smith's configured model, or name
one to override it (ingramCloudModel({ apiKey, modelId: "gpt-5.5" })). Opt into
server-side memory by passing a threadId.
Server-side with a tenant-admin token instead of a smith token? Name the smith:
ingramCloudModel({
apiKey: process.env.IC_TENANT_TOKEN!, // server-side only
smithId: "smt_…", // sent as IC-Smith-Id
});
Tools over MCP
Expose an Ingram Cloud deployment of kind: "mcp" as an eve
connection. The filename is the connection name; Ingram runs the tools for you,
with approval gating.
// agent/connections/ingram.ts
import { defineIngramMcpConnection } from "@ingram-tech/eve-ingram-cloud";
export default defineIngramMcpConnection({
apiKey: process.env.IC_SMITH_TOKEN!,
deploymentId: "dep_…",
description: "Ingram-hosted tools for this smith.",
});
eve discovers the deployment's tools, brokers auth, and hands them to the model —
the token never reaches the model. Gate them with eve's own per-connection
approval (never() / once() / always() from eve/tools/approval), or
narrow them with tools: { allow: [...] }.
This is distinct from the model seam: there a smith runs its own server-side tools as the model; here an eve agent calls Ingram-hosted tools directly over MCP.
Approvals
A tool the agent marks destructiveHint pauses the run for a human decision. On
this surface the pause is a tool call whose id is "<run_id>::<tool_call_id>"
and the turn ends with finish_reason: "tool_calls". The helpers are pure and
also live at @ingram-tech/eve-ingram-cloud/approvals:
import { getApprovalRequests, approvalToolResult } from "@ingram-tech/eve-ingram-cloud";
// `toolCalls` from the model result — composite ids are Ingram approvals.
const approvals = getApprovalRequests(toolCalls);
for (const a of approvals) {
const decision = (await askTheHuman(a)) ? "approve" : "reject";
// Append this tool message and run the next turn to resume the paused run:
messages.push(approvalToolResult(a, decision));
}
On approve, Ingram Cloud runs the tool itself and continues; on reject, the
run completes with stop_reason: "approval_rejected" and nothing executes. These
are the smith's server-side approvals — distinct from eve's per-connection
approval gate above.
Identity & tokens
| Token | Use | How the smith is chosen |
|---|---|---|
Smith token (sub = "<tenant>:<smith>") | browser-safe; the default | the token is the smith |
| Tenant-admin token | server-side only | pass smithId (sent as IC-Smith-Id) |
The agent is the one the smith runs — chosen by the smith, never by an argument.
When you need more
- Raw wire format or the
openaiSDK → OpenAI-compatible API. - The same product over the raw Vercel AI SDK → Vercel AI SDK.
- The same product over Flue → Flue.
- Where every surface fits → Ecosystem & compatibility.