import { Redis } from '@upstash/redis'; import { ToolContext, ToolDefinition } from 'eve/tools'; import { SearchToolDefsConfig, RateLimitConfig } from '@upstash/agentkit-sdk'; export { Duration, RateLimitConfig, Ratelimit, createRateLimit } from '@upstash/agentkit-sdk'; import { AuthFn } from 'eve/channels/auth'; /** The user a cache entry is scoped to: a fixed string, or a function of the tool input + context. */ type CacheUserId = string | ((input: TInput, ctx: ToolContext) => string); /** * A value that is not an `AsyncIterable`. Without the `[Symbol.asyncIterator]: never` block, an * async-generator executor would satisfy a plain `Promise | TOutput` union by inferring * `TOutput` *as* the generator object itself. */ type NonStreaming = T & { [Symbol.asyncIterator]?: never; }; type DefineCachedToolConfig = Omit, "execute"> & { /** * The tool body to memoize. Must resolve to a value — a cached tool cannot stream, so eve ≥0.31 * async-generator executors (preliminary output snapshots) are rejected at the type level: a cache * hit could never replay the snapshots, it can only return the stored final value. */ execute(input: TInput, ctx: ToolContext): Promise | NonStreaming; /** Upstash Redis client. Defaults to `Redis.fromEnv()`. */ redis?: Redis; /** The tool name — the `toolName` segment of the cache key. */ toolName: string; /** The user the cache entry is scoped to — a string, or a per-call function of input + ctx. */ userId: CacheUserId; /** Per-result TTL (seconds). */ ttlSeconds?: number; /** * Report the sdk name + version to Upstash as a header on the requests made by your redis client. * Can also be disabled with the `UPSTASH_DISABLE_TELEMETRY` env var. Defaults to `true`. */ enableTelemetry?: boolean; }; /** * Like Eve's `defineTool`, but the tool's `execute` is memoized in an Upstash {@link ToolCache}. * Takes the same fields as `defineTool` plus `toolName` and `userId` (and an optional `redis`), calls * `defineTool` for you, and returns the branded `ToolDefinition` — export it directly. Cache keys are * `agentkit:toolCache:::`. * * ```ts * // agent/tools/get_weather.ts * import { z } from "zod"; * import { defineCachedTool } from "@upstash/agentkit-eve"; * * export default defineCachedTool({ * description: "Get the current weather for a city.", * inputSchema: z.object({ city: z.string() }), * toolName: "get_weather", * userId: (_, ctx) => ctx.session.auth.current?.principalId ?? ctx.session.id, // scope per user * execute: async ({ city }) => fetchWeather(city), * }); * ``` */ declare function defineCachedTool(config: DefineCachedToolConfig): ToolDefinition; /** * The user the memory is read/written under. A string shares all memory across callers (fine for a * single-user agent — avoid in multi-tenant production unless intentional). A function derives the * user per call from the tool input and Eve context (e.g. `(_, ctx) => ctx.session.auth.current.id`). */ type MemoryUserId = string | ((input: Record, ctx: ToolContext) => string); interface MemoryToolConfig { /** Required user — a shared string, or a per-call function deriving it from the context. */ userId: MemoryUserId; /** Upstash Redis client. Defaults to `Redis.fromEnv()`. */ redis?: Redis; /** Max memories returned by the recall tool. */ topK?: number; /** Minimum relevance score for recall. */ minScore?: number; /** * Report the sdk name + version to Upstash as a header on the requests made by your redis client. * Can also be disabled with the `UPSTASH_DISABLE_TELEMETRY` env var. Defaults to `true`. */ enableTelemetry?: boolean; } /** * A ready eve tool (already `defineTool`-branded) that lets the agent recall long-term memories. One * import, drop into a file — export it directly, no extra wrapping: * * ```ts * // agent/tools/recall_memory.ts * import { defineMemoryRecallTool } from "@upstash/agentkit-eve"; * * export default defineMemoryRecallTool({ userId: (_, ctx) => ctx.session.id }); * ``` */ declare function defineMemoryRecallTool(config: MemoryToolConfig): ToolDefinition<{ query?: string; }, { text: string; score: number; }[]>; /** * A ready eve tool (already `defineTool`-branded) that lets the agent save a durable fact to * long-term memory. Export it directly, no extra wrapping. * * ```ts * // agent/tools/save_memory.ts * export default defineMemorySaveTool({ userId: (_, ctx) => ctx.session.id }); * ``` */ declare function defineMemorySaveTool(config: MemoryToolConfig): ToolDefinition<{ text: string; }, { id: string; saved: boolean; }>; interface DefineSearchToolsConfig extends Omit { /** Upstash Redis client. Defaults to `Redis.fromEnv()`. */ redis?: Redis; } /** The three eve search tools over one index, each already `defineTool`-branded. */ interface SearchToolSet { search: ToolDefinition; aggregate: ToolDefinition; count: ToolDefinition; } /** * Build eve `search` / `aggregate` / `count` tools over an Upstash Redis Search index, the eve * counterpart to the AI SDK adapter's `createSearchTools`. Returns a record of ready (already * `defineTool`-branded) tools; the index is created on first use (reactively). `redis` defaults to env. * * eve snapshots each tool file and resolves only **package** imports, so every `agent/tools/*.ts` file * must be self-contained: call `defineSearchTools` in each file and export the member you want, repeating * the same `schema` + `indexName` across them. Don't import a shared `agent/` module (e.g. a * `../redis.js` or `../lib/book-search.js`) — it fails at the turn step with `Cannot find module`. Omit * `redis` so it defaults to `Redis.fromEnv()`. * * ```ts * // agent/tools/search_books.ts * import { s } from "@upstash/redis"; * import { defineSearchTools } from "@upstash/agentkit-eve"; * * export default defineSearchTools({ * schema: s.object({ title: s.string(), author: s.string().noTokenize(), year: s.number() }), * indexName: "books", * }).search; // aggregate_books.ts → .aggregate, count_books.ts → .count (repeat schema + indexName) * ``` */ declare function defineSearchTools(config: DefineSearchToolsConfig): SearchToolSet; /** Configuration for {@link createRateLimitAuth}. */ interface RateLimitAuthConfig extends Omit { /** Upstash Redis client backing the limiter. Defaults to `Redis.fromEnv()`. */ redis?: Redis; /** * The rate-limit identifier — **required**. A static string (e.g. a tenant id) shares one bucket, so * for per-user limiting pass a function deriving the id from the inbound `Request` (an authenticated * user id, an API key, or `x-forwarded-for` for per-IP). There is intentionally **no** default: a * single global bucket means one abusive caller can exhaust the window for everyone. */ identifier: string | ((request: Request) => string | Promise); /** Message returned in the 403 body when the caller is over the limit. */ message?: string; } /** * Build an eve route-auth `AuthFn` that rate-limits inbound requests. Drop it into your channel's * `auth` walk ahead of your real authenticators: it throttles the request and, when under the limit, * returns `null` so the walk falls through to the next entry (it is a gate, not an identity provider). * Over the limit it throws a `ForbiddenError` (HTTP 403). Backed by {@link createRateLimit}; keys are * `agentkit:rateLimit:`. * * **Only `POST` requests are counted** (the message-submitting routes that actually invoke the model: * `POST /eve/v1/session` and `POST /eve/v1/session/:id`). eve drives each turn as two authenticated * requests — the message `POST` **and** a follow-up `GET …/stream` that opens the reply stream — and * the auth walk runs on both. Counting both would charge every turn twice; gating only the `POST` * makes one turn cost exactly one token, while the session-read `GET`s fall through unthrottled. * * ```ts * // agent/channels/eve.ts * import { createRateLimitAuth, Ratelimit } from "@upstash/agentkit-eve"; * import { localDev, vercelOidc } from "eve/channels/auth"; * import { eveChannel } from "eve/channels/eve"; * * export default eveChannel({ * auth: [ * createRateLimitAuth({ * limiter: Ratelimit.slidingWindow(20, "1 m"), * identifier: (req) => req.headers.get("x-forwarded-for") ?? "anonymous", // required * }), * localDev(), * vercelOidc(), * ], * }); * ``` */ declare function createRateLimitAuth(config: RateLimitAuthConfig): AuthFn; export { type CacheUserId, type DefineCachedToolConfig, type DefineSearchToolsConfig, type MemoryToolConfig, type MemoryUserId, type RateLimitAuthConfig, type SearchToolSet, createRateLimitAuth, defineCachedTool, defineMemoryRecallTool, defineMemorySaveTool, defineSearchTools };