eve 0.22.2 → 0.22.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +36 -0
- package/dist/src/chunks/{use-eve-agent-CM24ZUEI.js → use-eve-agent-CFBTHlPx.js} +43 -14
- package/dist/src/chunks/{use-eve-agent-CxcKypLZ.js → use-eve-agent-dEGV09g_.js} +43 -14
- package/dist/src/cli/dev/url.js +1 -1
- package/dist/src/client/agent-host.d.ts +4 -0
- package/dist/src/client/agent-host.js +1 -0
- package/dist/src/client/client-error.d.ts +5 -1
- package/dist/src/client/client-error.js +1 -1
- package/dist/src/client/client.js +1 -1
- package/dist/src/client/open-stream.js +1 -1
- package/dist/src/client/session.js +1 -1
- package/dist/src/client/types.d.ts +2 -1
- package/dist/src/client/url.js +1 -1
- package/dist/src/compiler/manifest.d.ts +44 -6
- package/dist/src/compiler/manifest.js +1 -1
- package/dist/src/compiler/module-map.js +2 -2
- package/dist/src/compiler/normalize-extension.d.ts +68 -0
- package/dist/src/compiler/normalize-extension.js +1 -0
- package/dist/src/compiler/normalize-manifest.js +2 -2
- package/dist/src/compiler/normalize-subagent.js +1 -1
- package/dist/src/compiler/remote-agent-node.d.ts +1 -1
- package/dist/src/compiler/remote-agent-node.js +1 -1
- package/dist/src/compiler/workspace-resources.js +1 -1
- package/dist/src/context/dynamic-skill-lifecycle.js +1 -1
- package/dist/src/context/dynamic-tool-lifecycle.js +1 -1
- package/dist/src/discover/discover-agent.d.ts +14 -1
- package/dist/src/discover/discover-agent.js +1 -1
- package/dist/src/discover/extension-specifier.d.ts +15 -0
- package/dist/src/discover/extension-specifier.js +1 -0
- package/dist/src/discover/extensions.d.ts +109 -0
- package/dist/src/discover/extensions.js +1 -0
- package/dist/src/discover/filesystem.d.ts +2 -2
- package/dist/src/discover/filesystem.js +1 -1
- package/dist/src/discover/grammar.d.ts +27 -0
- package/dist/src/discover/grammar.js +1 -1
- package/dist/src/discover/manifest.d.ts +46 -0
- package/dist/src/discover/manifest.js +1 -1
- package/dist/src/discover/project.js +1 -1
- package/dist/src/evals/assertions/run.d.ts +3 -2
- package/dist/src/evals/assertions/run.js +2 -2
- package/dist/src/evals/index.d.ts +1 -1
- package/dist/src/evals/loaders/yaml.js +1 -1
- package/dist/src/evals/match.d.ts +11 -6
- package/dist/src/execution/sandbox/bindings/microsandbox-network.js +1 -1
- package/dist/src/internal/application/package.js +1 -1
- package/dist/src/internal/authored-module-loader.d.ts +14 -0
- package/dist/src/internal/authored-module-loader.js +2 -2
- package/dist/src/internal/authored-module-map-loader.js +1 -1
- package/dist/src/internal/bundler/extension-scope-plugin.d.ts +37 -0
- package/dist/src/internal/bundler/extension-scope-plugin.js +3 -0
- package/dist/src/internal/helpers/gray-matter.d.ts +25 -0
- package/dist/src/internal/helpers/gray-matter.js +1 -0
- package/dist/src/internal/helpers/markdown.js +1 -1
- package/dist/src/internal/nitro/dev-runtime-source-snapshot-copy.js +1 -1
- package/dist/src/internal/nitro/host/build-application.js +1 -1
- package/dist/src/internal/nitro/host/build-extension.d.ts +24 -0
- package/dist/src/internal/nitro/host/build-extension.js +4 -0
- package/dist/src/internal/nitro/host/create-application-nitro.js +1 -1
- package/dist/src/internal/workflow-bundle/eve-service-route-output.d.ts +1 -2
- package/dist/src/internal/workflow-bundle/eve-service-route-output.js +1 -54
- package/dist/src/internal/workflow-bundle/vercel-workflow-output.js +1 -1
- package/dist/src/packages/eve-catalog/src/index.js +1 -1
- package/dist/src/public/channels/discord/discordChannel.js +1 -1
- package/dist/src/public/channels/slack/api.js +1 -1
- package/dist/src/public/channels/slack/mrkdwn.d.ts +0 -2
- package/dist/src/public/channels/slack/mrkdwn.js +1 -1
- package/dist/src/public/definitions/extension.d.ts +68 -0
- package/dist/src/public/definitions/extension.js +1 -0
- package/dist/src/public/definitions/remote-agent.d.ts +11 -2
- package/dist/src/public/extension/index.d.ts +10 -0
- package/dist/src/public/extension/index.js +1 -0
- package/dist/src/public/index.d.ts +1 -1
- package/dist/src/public/next/index.d.ts +38 -3
- package/dist/src/public/next/index.js +1 -1
- package/dist/src/public/next/server.d.ts +1 -0
- package/dist/src/public/next/server.js +2 -1
- package/dist/src/public/next/vercel-output-config.d.ts +12 -3
- package/dist/src/public/next/vercel-output-config.js +1 -1
- package/dist/src/react/use-eve-agent.d.ts +8 -1
- package/dist/src/react/use-eve-agent.js +1 -1
- package/dist/src/runtime/connections/openapi-client.js +1 -1
- package/dist/src/runtime/connections/openapi-spec.js +1 -1
- package/dist/src/runtime/resolve-agent-graph.js +1 -1
- package/dist/src/runtime/resolve-dynamic-skill.js +1 -1
- package/dist/src/runtime/resolve-dynamic-tool.js +1 -1
- package/dist/src/runtime/types.d.ts +10 -0
- package/dist/src/services/dev-client/vercel-auth-error.d.ts +2 -2
- package/dist/src/services/dev-client/vercel-auth-error.js +3 -3
- package/dist/src/setup/scaffold/connections/catalog.js +1 -1
- package/dist/src/setup/scaffold/create/project.js +3 -3
- package/dist/src/svelte/index.js +1 -1
- package/dist/src/svelte/use-eve-agent.d.ts +8 -1
- package/dist/src/svelte/use-eve-agent.js +1 -1
- package/dist/src/vue/index.js +1 -1
- package/dist/src/vue/use-eve-agent.d.ts +8 -1
- package/dist/src/vue/use-eve-agent.js +1 -1
- package/docs/channels/custom.mdx +2 -2
- package/docs/channels/linear.mdx +1 -1
- package/docs/channels/slack.mdx +2 -0
- package/docs/concepts/context-control.md +1 -1
- package/docs/connections/openapi.mdx +3 -1
- package/docs/evals/assertions.mdx +4 -2
- package/docs/extensions.md +176 -0
- package/docs/guides/client/overview.mdx +1 -1
- package/docs/guides/dev-tui.md +4 -0
- package/docs/guides/dynamic-capabilities.md +3 -3
- package/docs/guides/frontend/nextjs.mdx +32 -7
- package/docs/guides/frontend/overview.mdx +7 -1
- package/docs/guides/hooks.md +9 -0
- package/docs/guides/instrumentation.md +1 -1
- package/docs/guides/remote-agents.md +23 -8
- package/docs/guides/state.md +3 -3
- package/docs/instructions.mdx +1 -1
- package/docs/patterns/dynamic-scheduling.md +11 -11
- package/docs/patterns/multi-tenant-approvals.md +6 -6
- package/docs/patterns/multi-tenant-auth.md +13 -13
- package/docs/patterns/multi-tenant-memory.md +9 -9
- package/docs/schedules.mdx +1 -1
- package/docs/tutorial/guard-the-spend.mdx +2 -2
- package/docs/tutorial/query-sample-data.mdx +1 -1
- package/docs/tutorial/remember-definitions.mdx +2 -2
- package/docs/tutorial/ship-it.mdx +1 -1
- package/package.json +6 -1
|
@@ -19,7 +19,7 @@ const client = new Client({
|
|
|
19
19
|
});
|
|
20
20
|
```
|
|
21
21
|
|
|
22
|
-
`host` is the
|
|
22
|
+
`host` is the URL where the eve routes are mounted. In a same-origin browser integration this is often `""`; scripts and backend services usually name the full URL. Any query parameters on `host` are included on every request, including session POSTs and event streams. Request-specific parameters, such as a stream cursor, take precedence when names overlap.
|
|
23
23
|
|
|
24
24
|
## Check health
|
|
25
25
|
|
package/docs/guides/dev-tui.md
CHANGED
|
@@ -136,6 +136,10 @@ eve dev https://user:pass@<your-app>
|
|
|
136
136
|
|
|
137
137
|
For bearer tokens or custom schemes, repeat `-H, --header` to attach request headers.
|
|
138
138
|
|
|
139
|
+
Query parameters in the target URL are preserved on every request, including
|
|
140
|
+
session POSTs and event streams. This also supports deployment-protection URLs
|
|
141
|
+
that carry their bypass credential in the query string.
|
|
142
|
+
|
|
139
143
|
At startup the TUI asks Vercel to resolve the remote origin under the active scope. A resolved response is the authority for a project-scoped OIDC token—refreshing an expired development token when refresh credentials exist—or an automation-bypass secret. An unresolved host is probed anonymously. The TUI then requests `/eve/v1/info`, with a ten-second timeout. A successful response marks the remote ready. An eve OIDC challenge, Vercel Deployment Protection challenge, or `TRUSTED_SOURCES_ENVIRONMENT_MISMATCH` opens `/vc:login` automatically; ordinary network failures and server errors remain remote-availability errors and do not start an authentication flow. Esc or Ctrl-C cancels the authentication flow.
|
|
140
144
|
|
|
141
145
|
In a remote session, `/vc:login` first resolves the deployment's Vercel project from its URL. If the active Vercel scope cannot resolve it, the flow asks for another team and reruns the lookup in that team's scope. If the CLI is logged out, the same panel runs the browser login first. The flow asks before adding any required Trusted Sources rule and requests a project-scoped token through `@vercel/oidc`. It does not relink the directory or modify `.env.local`. Finally, it retries `/eve/v1/info` to prove the credential works. A failure reports any login or Trusted Sources update that completed before it stopped.
|
|
@@ -30,7 +30,7 @@ The example below builds one tool per warehouse table. A map return names each t
|
|
|
30
30
|
```ts title="agent/tools/query.ts"
|
|
31
31
|
import { defineDynamic, defineTool } from "eve/tools";
|
|
32
32
|
import { z } from "zod";
|
|
33
|
-
import { listTables, runReadOnly } from "../lib/warehouse
|
|
33
|
+
import { listTables, runReadOnly } from "../lib/warehouse";
|
|
34
34
|
|
|
35
35
|
export default defineDynamic({
|
|
36
36
|
events: {
|
|
@@ -89,7 +89,7 @@ A single file can declare handlers for several events, and the most recently fir
|
|
|
89
89
|
```ts title="agent/tools/catalog.ts"
|
|
90
90
|
import { defineDynamic, defineTool } from "eve/tools";
|
|
91
91
|
import { z } from "zod";
|
|
92
|
-
import { runReadOnly, searchCatalog } from "../lib/catalog
|
|
92
|
+
import { runReadOnly, searchCatalog } from "../lib/catalog";
|
|
93
93
|
|
|
94
94
|
export default defineDynamic({
|
|
95
95
|
events: {
|
|
@@ -120,7 +120,7 @@ A dynamic skills file resolves which [skill](../skills) a caller can load, keyed
|
|
|
120
120
|
|
|
121
121
|
```ts title="agent/skills/team_playbook.ts"
|
|
122
122
|
import { defineDynamic, defineSkill } from "eve/skills";
|
|
123
|
-
import { PLAYBOOKS } from "../lib/playbooks
|
|
123
|
+
import { PLAYBOOKS } from "../lib/playbooks";
|
|
124
124
|
|
|
125
125
|
export default defineDynamic({
|
|
126
126
|
events: {
|
|
@@ -30,16 +30,41 @@ export default withEve(nextConfig, {
|
|
|
30
30
|
});
|
|
31
31
|
```
|
|
32
32
|
|
|
33
|
+
For multiple agents, use `agents`. String values are agent roots; object values can override the build command or private production service prefix for that agent:
|
|
34
|
+
|
|
35
|
+
```ts
|
|
36
|
+
export default withEve(nextConfig, {
|
|
37
|
+
agents: {
|
|
38
|
+
support: "./agents/support",
|
|
39
|
+
billing: {
|
|
40
|
+
root: "./agents/billing",
|
|
41
|
+
buildCommand: "pnpm build:billing-agent",
|
|
42
|
+
servicePrefix: "/_eve_internal/billing",
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Named agents mount under `/eve/agents/<name>/eve/v1/*`. Call the matching agent from React with `agent`:
|
|
49
|
+
|
|
50
|
+
```tsx
|
|
51
|
+
const support = useEveAgent({ agent: "support" });
|
|
52
|
+
const billing = useEveAgent({ agent: "billing" });
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Use either `eveRoot` or `agents`, not both. `eveRoot` remains the shorthand for a single unnamed agent mounted at `/eve/v1/*`.
|
|
56
|
+
|
|
33
57
|
### `withEve` options
|
|
34
58
|
|
|
35
59
|
All fields are optional.
|
|
36
60
|
|
|
37
|
-
| Option | Type
|
|
38
|
-
| -------------------- |
|
|
39
|
-
| `eveRoot` | `string`
|
|
40
|
-
| `
|
|
41
|
-
| `
|
|
42
|
-
| `
|
|
61
|
+
| Option | Type | Default | Purpose |
|
|
62
|
+
| -------------------- | --------------------- | ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
63
|
+
| `eveRoot` | `string` | Next.js app root | Path to one unnamed eve app root, relative to `process.cwd()` unless absolute. Do not combine with `agents`. |
|
|
64
|
+
| `agents` | `Record<string, ...>` | unset | Named eve agents to mount under `/eve/agents/<name>/eve/v1/*`. Each value is a root string or `{ root, buildCommand?, servicePrefix? }`. |
|
|
65
|
+
| `eveBuildCommand` | `string` | generated | Build command for generated eve Vercel services. In multi-agent mode this is the default for agents without their own `buildCommand`. |
|
|
66
|
+
| `servicePrefix` | `string` | `"/_eve_internal/eve"` | Private route namespace for legacy manual Vercel service configs and non-Vercel production proxying. Named agents derive unique defaults from this prefix. |
|
|
67
|
+
| `devServerTimeoutMs` | `number` | `180000` | Maximum time to wait for each eve development server to become available. |
|
|
43
68
|
|
|
44
69
|
For slow cold starts, increase the development timeout:
|
|
45
70
|
|
|
@@ -75,7 +100,7 @@ For a public demo, use `none()` (also from `eve/channels/auth`) to skip authenti
|
|
|
75
100
|
## Dev vs deploy topology
|
|
76
101
|
|
|
77
102
|
- **Local dev.** `npm run dev` boots the eve dev server next to `next dev` and rewrites the eve routes over to it. The browser only ever talks to the Next.js origin.
|
|
78
|
-
- **Vercel.** The web app and the eve runtime deploy as a single project. `withEve()` writes Build Output `services` for eve and `routes` that send `/eve/v1/**` to that service before filesystem routing; the Next.js app itself remains the default app. When the agent needs its own build step, set `eveBuildCommand`:
|
|
103
|
+
- **Vercel.** The web app and the eve runtime deploy as a single project. `withEve()` writes Build Output `services` for eve and `routes` that send `/eve/v1/**` to that service before filesystem routing; the Next.js app itself remains the default app. By default, generated services run the installed eve binary from the agent root, so the agent directory does not need its own `package.json`. When the agent needs its own build step, set `eveBuildCommand`:
|
|
79
104
|
|
|
80
105
|
```ts
|
|
81
106
|
export default withEve(nextConfig, {
|
|
@@ -254,7 +254,7 @@ const agent = useEveAgent({
|
|
|
254
254
|
|
|
255
255
|
Store the full `session` object (`sessionId`, `continuationToken`, `streamIndex`), not a single field. The session cursor lets eve continue the durable conversation; the event log lets your UI render historical messages without replaying the whole stream. A database-backed chat app should usually persist stream events as they arrive with `onEvent` and then save a final snapshot in `onFinish`.
|
|
256
256
|
|
|
257
|
-
For multiple chat threads, keep one saved event log and session cursor per thread. `host`, `reducer`, `session`, `initialEvents`, `initialSession`, `auth`, `headers`, `maxReconnectAttempts`, and `optimistic` are read when the hook creates its store, so remount the chat component when switching threads, for example with `key={chat.id}`.
|
|
257
|
+
For multiple chat threads, keep one saved event log and session cursor per thread. `agent`, `host`, `reducer`, `session`, `initialEvents`, `initialSession`, `auth`, `headers`, `maxReconnectAttempts`, and `optimistic` are read when the hook creates its store, so remount the chat component when switching threads, for example with `key={chat.id}`.
|
|
258
258
|
|
|
259
259
|
If the user can refresh or navigate immediately after pressing send, create your app-level chat row and store the pending user message before calling `send()`. After the request starts, persist the session state as soon as it contains a `sessionId`, then reconnect an interrupted in-flight turn with `session.stream({ startIndex: savedEvents.length })` from the lower-level client.
|
|
260
260
|
|
|
@@ -271,6 +271,12 @@ const agent = useEveAgent({
|
|
|
271
271
|
});
|
|
272
272
|
```
|
|
273
273
|
|
|
274
|
+
When a framework integration mounts multiple named agents, pass `agent` instead of `host`:
|
|
275
|
+
|
|
276
|
+
```tsx
|
|
277
|
+
const support = useEveAgent({ agent: "support" });
|
|
278
|
+
```
|
|
279
|
+
|
|
274
280
|
## Per-framework integration
|
|
275
281
|
|
|
276
282
|
| Framework | Integration | Hook |
|
package/docs/guides/hooks.md
CHANGED
|
@@ -71,6 +71,15 @@ export default defineHook({
|
|
|
71
71
|
|
|
72
72
|
Returns `undefined` when the result doesn't match, or when `isError` is `true`. For authored tools the return includes `{ output, toolName, callId }` with `output` typed as the tool's `TOutput`. For connections it includes `{ output, toolName, connectionToolName, callId }` with `output` as `unknown`.
|
|
73
73
|
|
|
74
|
+
This works for a mounted extension's tools too — import the tool from the extension's `./tools` export and pass it. `toolResultFrom` matches the namespaced result (`crm__search`) because it keys off the tool definition, not the name:
|
|
75
|
+
|
|
76
|
+
```ts
|
|
77
|
+
import { search } from "@acme/crm/tools";
|
|
78
|
+
|
|
79
|
+
// inside "action.result":
|
|
80
|
+
const crmSearch = toolResultFrom(event.data.result, search); // typed; matches crm__search
|
|
81
|
+
```
|
|
82
|
+
|
|
74
83
|
## Execution order
|
|
75
84
|
|
|
76
85
|
When a stream event fires, three things happen in order:
|
|
@@ -66,7 +66,7 @@ Use it when the values depend on the current session, turn, step, channel, or mo
|
|
|
66
66
|
|
|
67
67
|
```ts
|
|
68
68
|
import { defineInstrumentation, isChannel } from "eve/instrumentation";
|
|
69
|
-
import supportChannel from "./channels/support
|
|
69
|
+
import supportChannel from "./channels/support";
|
|
70
70
|
|
|
71
71
|
export default defineInstrumentation({
|
|
72
72
|
events: {
|
|
@@ -20,14 +20,29 @@ export default defineRemoteAgent({
|
|
|
20
20
|
|
|
21
21
|
`defineRemoteAgent` accepts:
|
|
22
22
|
|
|
23
|
-
| Parameter | Type
|
|
24
|
-
| -------------- |
|
|
25
|
-
| `url` | `string`
|
|
26
|
-
| `description` | `string`
|
|
27
|
-
| `auth` | `OutboundAuthFn`
|
|
28
|
-
| `headers` | `HeadersValue`
|
|
29
|
-
| `path` | `string`
|
|
30
|
-
| `outputSchema` | `StandardSchema \| JSON Schema`
|
|
23
|
+
| Parameter | Type | Required | Default | Description |
|
|
24
|
+
| -------------- | --------------------------------------------- | -------- | ----------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
25
|
+
| `url` | `string \| (() => string \| Promise<string>)` | Yes | n/a | Base URL of the remote eve deployment to call. A string is baked at compile time; a function is resolved at runtime (see [Runtime URLs](#runtime-urls)). |
|
|
26
|
+
| `description` | `string` | Yes | n/a | Model-visible delegation description. |
|
|
27
|
+
| `auth` | `OutboundAuthFn` | No | none | Outbound auth hook from `eve/agents/auth`. |
|
|
28
|
+
| `headers` | `HeadersValue` | No | none | Static or lazily resolved request headers. |
|
|
29
|
+
| `path` | `string` | No | `/eve/v1/session` | Route appended to `url` for the create-session request. |
|
|
30
|
+
| `outputSchema` | `StandardSchema \| JSON Schema` | No | none | Structured return type the caller requires. Lowered to JSON Schema at compile time and enforced by the remote like any task-mode output schema. |
|
|
31
|
+
|
|
32
|
+
## Runtime URLs
|
|
33
|
+
|
|
34
|
+
A string `url` is read at compile time and frozen into the build. When the target comes from a runtime env var — known only once the deployment runs — pass a function instead. eve calls it when it resolves the agent graph at runtime, so it can read `process.env`:
|
|
35
|
+
|
|
36
|
+
```ts title="agent/subagents/weather.ts"
|
|
37
|
+
import { defineRemoteAgent } from "eve";
|
|
38
|
+
|
|
39
|
+
export default defineRemoteAgent({
|
|
40
|
+
url: () => process.env.WEATHER_AGENT_URL ?? "https://weather-agent.example.com",
|
|
41
|
+
description: "Answers weather, temperature, forecast, wind, rain, and snow questions.",
|
|
42
|
+
});
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
The function may be async and must return a non-empty string. `auth` and `headers` are resolved at runtime the same way.
|
|
31
46
|
|
|
32
47
|
## The lowered tool
|
|
33
48
|
|
package/docs/guides/state.md
CHANGED
|
@@ -27,8 +27,8 @@ export const budget = defineState("my-agent.budget", () => ({ count: 0, cap: 25
|
|
|
27
27
|
```ts title="agent/tools/spend.ts"
|
|
28
28
|
import { defineTool } from "eve/tools";
|
|
29
29
|
import { z } from "zod";
|
|
30
|
-
import { budget } from "../lib/budget
|
|
31
|
-
import { runQuery } from "../lib/warehouse
|
|
30
|
+
import { budget } from "../lib/budget";
|
|
31
|
+
import { runQuery } from "../lib/warehouse";
|
|
32
32
|
|
|
33
33
|
export default defineTool({
|
|
34
34
|
description: "Run a query, counting it against the session budget.",
|
|
@@ -50,7 +50,7 @@ State is durable by default and does not reset between turns. If you want a clea
|
|
|
50
50
|
|
|
51
51
|
```ts title="agent/hooks/reset-budget.ts"
|
|
52
52
|
import { defineHook } from "eve/hooks";
|
|
53
|
-
import { budget } from "../lib/budget
|
|
53
|
+
import { budget } from "../lib/budget";
|
|
54
54
|
|
|
55
55
|
export default defineHook({
|
|
56
56
|
events: {
|
package/docs/instructions.mdx
CHANGED
|
@@ -21,7 +21,7 @@ A static prompt belongs in markdown (`agent/instructions.md`). Switch to a TypeS
|
|
|
21
21
|
|
|
22
22
|
```ts title="agent/instructions.ts"
|
|
23
23
|
import { defineInstructions } from "eve/instructions";
|
|
24
|
-
import { buildInstructionsPrompt } from "./lib/prompts
|
|
24
|
+
import { buildInstructionsPrompt } from "./lib/prompts";
|
|
25
25
|
|
|
26
26
|
export default defineInstructions({
|
|
27
27
|
markdown: buildInstructionsPrompt(),
|
|
@@ -30,8 +30,8 @@ This is the only authored schedule. It looks up due application-managed rows and
|
|
|
30
30
|
|
|
31
31
|
```ts title="agent/schedules/dynamic.ts"
|
|
32
32
|
import { defineSchedule } from "eve/schedules";
|
|
33
|
-
import slack from "../channels/slack
|
|
34
|
-
import { scheduleStore } from "../lib/schedule-store
|
|
33
|
+
import slack from "../channels/slack";
|
|
34
|
+
import { scheduleStore } from "../lib/schedule-store";
|
|
35
35
|
|
|
36
36
|
export default defineSchedule({
|
|
37
37
|
cron: "* * * * *",
|
|
@@ -119,8 +119,8 @@ Create a one-time schedule with `everyMinutes: null`, or a recurring one with an
|
|
|
119
119
|
```ts title="agent/tools/create_schedule.ts"
|
|
120
120
|
import { defineTool } from "eve/tools";
|
|
121
121
|
import { z } from "zod";
|
|
122
|
-
import { scheduleStore } from "../lib/schedule-store
|
|
123
|
-
import { requireScheduleOwner } from "../lib/tenant
|
|
122
|
+
import { scheduleStore } from "../lib/schedule-store";
|
|
123
|
+
import { requireScheduleOwner } from "../lib/tenant";
|
|
124
124
|
|
|
125
125
|
export default defineTool({
|
|
126
126
|
description: "Create a one-time or repeating scheduled agent run for this tenant.",
|
|
@@ -142,8 +142,8 @@ export default defineTool({
|
|
|
142
142
|
```ts title="agent/tools/list_schedules.ts"
|
|
143
143
|
import { defineTool } from "eve/tools";
|
|
144
144
|
import { z } from "zod";
|
|
145
|
-
import { scheduleStore } from "../lib/schedule-store
|
|
146
|
-
import { requireScheduleOwner } from "../lib/tenant
|
|
145
|
+
import { scheduleStore } from "../lib/schedule-store";
|
|
146
|
+
import { requireScheduleOwner } from "../lib/tenant";
|
|
147
147
|
|
|
148
148
|
export default defineTool({
|
|
149
149
|
description: "List this tenant's dynamic schedules and their latest status.",
|
|
@@ -157,8 +157,8 @@ export default defineTool({
|
|
|
157
157
|
```ts title="agent/tools/update_schedule.ts"
|
|
158
158
|
import { defineTool } from "eve/tools";
|
|
159
159
|
import { z } from "zod";
|
|
160
|
-
import { scheduleStore } from "../lib/schedule-store
|
|
161
|
-
import { requireScheduleOwner } from "../lib/tenant
|
|
160
|
+
import { scheduleStore } from "../lib/schedule-store";
|
|
161
|
+
import { requireScheduleOwner } from "../lib/tenant";
|
|
162
162
|
|
|
163
163
|
export default defineTool({
|
|
164
164
|
description: "Change, pause, or resume one of this tenant's schedules.",
|
|
@@ -183,8 +183,8 @@ export default defineTool({
|
|
|
183
183
|
import { defineTool } from "eve/tools";
|
|
184
184
|
import { always } from "eve/tools/approval";
|
|
185
185
|
import { z } from "zod";
|
|
186
|
-
import { scheduleStore } from "../lib/schedule-store
|
|
187
|
-
import { requireScheduleOwner } from "../lib/tenant
|
|
186
|
+
import { scheduleStore } from "../lib/schedule-store";
|
|
187
|
+
import { requireScheduleOwner } from "../lib/tenant";
|
|
188
188
|
|
|
189
189
|
export default defineTool({
|
|
190
190
|
description: "Permanently delete one of this tenant's schedules.",
|
|
@@ -232,7 +232,7 @@ export interface ScheduleStore {
|
|
|
232
232
|
release(job: ClaimedSchedule, failure: { error: unknown; retryAt: Date }): Promise<void>;
|
|
233
233
|
}
|
|
234
234
|
|
|
235
|
-
export { scheduleStore } from "../../lib/schedule-store
|
|
235
|
+
export { scheduleStore } from "../../lib/schedule-store";
|
|
236
236
|
```
|
|
237
237
|
|
|
238
238
|
Implement that adapter with whichever durable store already belongs to your application. It must preserve a few semantics:
|
|
@@ -22,7 +22,7 @@ The current caller and initiating caller are both available on the session. This
|
|
|
22
22
|
|
|
23
23
|
```ts title="agent/lib/tenant-approval.ts"
|
|
24
24
|
import type { ApprovalContext, ApprovalStatus } from "eve/tools";
|
|
25
|
-
import { approvalPolicies } from "./approval-policies
|
|
25
|
+
import { approvalPolicies } from "./approval-policies";
|
|
26
26
|
|
|
27
27
|
type Surface = "connection" | "tool";
|
|
28
28
|
|
|
@@ -77,8 +77,8 @@ Approval runs before `execute`. The executor must still derive and enforce tenan
|
|
|
77
77
|
```ts title="agent/tools/transfer_funds.ts"
|
|
78
78
|
import { defineTool } from "eve/tools";
|
|
79
79
|
import { z } from "zod";
|
|
80
|
-
import { transferFunds } from "../../lib/payments
|
|
81
|
-
import { decideTenantApproval } from "../lib/tenant-approval
|
|
80
|
+
import { transferFunds } from "../../lib/payments";
|
|
81
|
+
import { decideTenantApproval } from "../lib/tenant-approval";
|
|
82
82
|
|
|
83
83
|
export default defineTool({
|
|
84
84
|
description: "Transfer funds from the current tenant's account.",
|
|
@@ -111,7 +111,7 @@ The same callback gates every generated operation. The qualified operation name
|
|
|
111
111
|
|
|
112
112
|
```ts title="agent/connections/billing.ts"
|
|
113
113
|
import { defineOpenAPIConnection } from "eve/connections";
|
|
114
|
-
import { decideTenantApproval } from "../lib/tenant-approval
|
|
114
|
+
import { decideTenantApproval } from "../lib/tenant-approval";
|
|
115
115
|
|
|
116
116
|
export default defineOpenAPIConnection({
|
|
117
117
|
spec: "https://billing.example.com/openapi.json",
|
|
@@ -135,7 +135,7 @@ The allow-list limits what the model can discover. Approval independently decide
|
|
|
135
135
|
|
|
136
136
|
```ts title="agent/connections/support.ts"
|
|
137
137
|
import { defineMcpClientConnection } from "eve/connections";
|
|
138
|
-
import { decideTenantApproval } from "../lib/tenant-approval
|
|
138
|
+
import { decideTenantApproval } from "../lib/tenant-approval";
|
|
139
139
|
|
|
140
140
|
export default defineMcpClientConnection({
|
|
141
141
|
url: "https://support.example.com/mcp",
|
|
@@ -176,7 +176,7 @@ export interface ApprovalPolicyProvider {
|
|
|
176
176
|
decide(request: ApprovalPolicyRequest): Promise<ApprovalPolicyDecision>;
|
|
177
177
|
}
|
|
178
178
|
|
|
179
|
-
export { approvalPolicies } from "../../lib/approval-policies
|
|
179
|
+
export { approvalPolicies } from "../../lib/approval-policies";
|
|
180
180
|
```
|
|
181
181
|
|
|
182
182
|
Your provider decides the policy model. A common implementation checks active tenant membership, finds an exact resource rule before a connection-wide fallback, evaluates role and input thresholds, and defaults to deny. Keep those choices in application code rather than encoding a database design into the agent.
|
|
@@ -44,7 +44,7 @@ the caller before eve starts a run, then stamp the tenant onto the session:
|
|
|
44
44
|
```ts title="agent/channels/eve.ts"
|
|
45
45
|
import { eveChannel } from "eve/channels/eve";
|
|
46
46
|
import { localDev, type AuthFn } from "eve/channels/auth";
|
|
47
|
-
import { verifyAgentCaller } from "../../lib/app-auth
|
|
47
|
+
import { verifyAgentCaller } from "../../lib/app-auth";
|
|
48
48
|
|
|
49
49
|
function tenantAppAuth(): AuthFn<Request> {
|
|
50
50
|
return async (request) => {
|
|
@@ -92,7 +92,7 @@ cache by that user, and pass the projected principal into `getToken`:
|
|
|
92
92
|
|
|
93
93
|
```ts title="agent/lib/tenant-connection-auth.ts"
|
|
94
94
|
import type { ConnectionPrincipal, NonInteractiveAuthorizationDefinition } from "eve/connections";
|
|
95
|
-
import { tenantCredentials, type TenantService } from "./tenant-credentials
|
|
95
|
+
import { tenantCredentials, type TenantService } from "./tenant-credentials";
|
|
96
96
|
|
|
97
97
|
function requireTenantPrincipal(principal: ConnectionPrincipal): {
|
|
98
98
|
tenantId: string;
|
|
@@ -136,8 +136,8 @@ Derive the tenant inside `execute`, fetch its credential from your application p
|
|
|
136
136
|
```ts title="agent/tools/list_invoices.ts"
|
|
137
137
|
import { defineTool } from "eve/tools";
|
|
138
138
|
import { z } from "zod";
|
|
139
|
-
import { tenantCredentials } from "../lib/tenant-credentials
|
|
140
|
-
import { requireTenantCaller } from "../lib/tenant
|
|
139
|
+
import { tenantCredentials } from "../lib/tenant-credentials";
|
|
140
|
+
import { requireTenantCaller } from "../lib/tenant";
|
|
141
141
|
|
|
142
142
|
export default defineTool({
|
|
143
143
|
description: "List recent invoices from the current tenant's billing account.",
|
|
@@ -167,9 +167,9 @@ receive the token at call time without exposing it to the model:
|
|
|
167
167
|
|
|
168
168
|
```ts title="agent/connections/billing.ts"
|
|
169
169
|
import { defineOpenAPIConnection } from "eve/connections";
|
|
170
|
-
import { tenantCredentials } from "../lib/tenant-credentials
|
|
171
|
-
import { tenantBearerAuth } from "../lib/tenant-connection-auth
|
|
172
|
-
import { requireTenantCaller } from "../lib/tenant
|
|
170
|
+
import { tenantCredentials } from "../lib/tenant-credentials";
|
|
171
|
+
import { tenantBearerAuth } from "../lib/tenant-connection-auth";
|
|
172
|
+
import { requireTenantCaller } from "../lib/tenant";
|
|
173
173
|
|
|
174
174
|
export default defineOpenAPIConnection({
|
|
175
175
|
spec: "https://billing.example.com/openapi.json",
|
|
@@ -193,9 +193,9 @@ MCP connections accept the same callbacks:
|
|
|
193
193
|
|
|
194
194
|
```ts title="agent/connections/support.ts"
|
|
195
195
|
import { defineMcpClientConnection } from "eve/connections";
|
|
196
|
-
import { tenantCredentials } from "../lib/tenant-credentials
|
|
197
|
-
import { tenantBearerAuth } from "../lib/tenant-connection-auth
|
|
198
|
-
import { requireTenantCaller } from "../lib/tenant
|
|
196
|
+
import { tenantCredentials } from "../lib/tenant-credentials";
|
|
197
|
+
import { tenantBearerAuth } from "../lib/tenant-connection-auth";
|
|
198
|
+
import { requireTenantCaller } from "../lib/tenant";
|
|
199
199
|
|
|
200
200
|
export default defineMcpClientConnection({
|
|
201
201
|
url: "https://support.example.com/mcp",
|
|
@@ -220,8 +220,8 @@ tenant API key from `headers` instead:
|
|
|
220
220
|
|
|
221
221
|
```ts title="agent/connections/support.ts"
|
|
222
222
|
import { defineMcpClientConnection } from "eve/connections";
|
|
223
|
-
import { tenantCredentials } from "../lib/tenant-credentials
|
|
224
|
-
import { requireTenantCaller } from "../lib/tenant
|
|
223
|
+
import { tenantCredentials } from "../lib/tenant-credentials";
|
|
224
|
+
import { requireTenantCaller } from "../lib/tenant";
|
|
225
225
|
|
|
226
226
|
export default defineMcpClientConnection({
|
|
227
227
|
url: "https://support.example.com/mcp",
|
|
@@ -274,7 +274,7 @@ export interface TenantCredentialProvider {
|
|
|
274
274
|
): Promise<TenantApiKeyCredential>;
|
|
275
275
|
}
|
|
276
276
|
|
|
277
|
-
export { tenantCredentials } from "../../lib/tenant-credentials
|
|
277
|
+
export { tenantCredentials } from "../../lib/tenant-credentials";
|
|
278
278
|
```
|
|
279
279
|
|
|
280
280
|
Implement the provider with the secret system your application already trusts:
|
|
@@ -53,8 +53,8 @@ Resolve on `turn.started` so later turns in the same session see memories writte
|
|
|
53
53
|
|
|
54
54
|
```ts title="agent/instructions/memory.ts"
|
|
55
55
|
import { defineDynamic, defineInstructions } from "eve/instructions";
|
|
56
|
-
import { memoryStore } from "../lib/memory-store
|
|
57
|
-
import { requireTenantCaller } from "../lib/tenant
|
|
56
|
+
import { memoryStore } from "../lib/memory-store";
|
|
57
|
+
import { requireTenantCaller } from "../lib/tenant";
|
|
58
58
|
|
|
59
59
|
export default defineDynamic({
|
|
60
60
|
events: {
|
|
@@ -88,8 +88,8 @@ The model chooses the memory key and value. The executor chooses the tenant and
|
|
|
88
88
|
```ts title="agent/tools/remember.ts"
|
|
89
89
|
import { defineTool } from "eve/tools";
|
|
90
90
|
import { z } from "zod";
|
|
91
|
-
import { memoryStore } from "../lib/memory-store
|
|
92
|
-
import { requireTenantCaller } from "../lib/tenant
|
|
91
|
+
import { memoryStore } from "../lib/memory-store";
|
|
92
|
+
import { requireTenantCaller } from "../lib/tenant";
|
|
93
93
|
|
|
94
94
|
export default defineTool({
|
|
95
95
|
description: "Remember one stable fact or preference for the current user.",
|
|
@@ -110,8 +110,8 @@ export default defineTool({
|
|
|
110
110
|
```ts title="agent/tools/list_memories.ts"
|
|
111
111
|
import { defineTool } from "eve/tools";
|
|
112
112
|
import { z } from "zod";
|
|
113
|
-
import { memoryStore } from "../lib/memory-store
|
|
114
|
-
import { requireTenantCaller } from "../lib/tenant
|
|
113
|
+
import { memoryStore } from "../lib/memory-store";
|
|
114
|
+
import { requireTenantCaller } from "../lib/tenant";
|
|
115
115
|
|
|
116
116
|
export default defineTool({
|
|
117
117
|
description: "List long-term memories saved for the current user.",
|
|
@@ -126,8 +126,8 @@ export default defineTool({
|
|
|
126
126
|
import { defineTool } from "eve/tools";
|
|
127
127
|
import { always } from "eve/tools/approval";
|
|
128
128
|
import { z } from "zod";
|
|
129
|
-
import { memoryStore } from "../lib/memory-store
|
|
130
|
-
import { requireTenantCaller } from "../lib/tenant
|
|
129
|
+
import { memoryStore } from "../lib/memory-store";
|
|
130
|
+
import { requireTenantCaller } from "../lib/tenant";
|
|
131
131
|
|
|
132
132
|
export default defineTool({
|
|
133
133
|
description: "Delete one long-term memory belonging to the current user.",
|
|
@@ -165,7 +165,7 @@ export interface MemoryStore {
|
|
|
165
165
|
}
|
|
166
166
|
|
|
167
167
|
// Implement this with your application's PostgreSQL, KV, or vector-store client.
|
|
168
|
-
export { memoryStore } from "../../lib/memory-store
|
|
168
|
+
export { memoryStore } from "../../lib/memory-store";
|
|
169
169
|
```
|
|
170
170
|
|
|
171
171
|
Whatever backend you choose, preserve these invariants:
|
package/docs/schedules.mdx
CHANGED
|
@@ -61,7 +61,7 @@ Use a handler when the schedule needs to deliver to a channel, branch on conditi
|
|
|
61
61
|
```ts title="agent/schedules/critical-alerts.ts"
|
|
62
62
|
import { defineSchedule } from "eve/schedules";
|
|
63
63
|
|
|
64
|
-
import slack from "../channels/slack
|
|
64
|
+
import slack from "../channels/slack";
|
|
65
65
|
|
|
66
66
|
export default defineSchedule({
|
|
67
67
|
cron: "* * * * *",
|
|
@@ -23,8 +23,8 @@ export function estimateScanGb(sql: string): number {
|
|
|
23
23
|
```ts title="agent/tools/run_sql.ts"
|
|
24
24
|
import { defineTool } from "eve/tools";
|
|
25
25
|
import { z } from "zod";
|
|
26
|
-
import { runReadOnlySql } from "../lib/sample-db
|
|
27
|
-
import { estimateScanGb } from "../lib/cost
|
|
26
|
+
import { runReadOnlySql } from "../lib/sample-db";
|
|
27
|
+
import { estimateScanGb } from "../lib/cost";
|
|
28
28
|
|
|
29
29
|
const THRESHOLD_GB = 50;
|
|
30
30
|
|
|
@@ -47,7 +47,7 @@ export async function runReadOnlySql(sql: string) {
|
|
|
47
47
|
```ts title="agent/tools/run_sql.ts"
|
|
48
48
|
import { defineTool } from "eve/tools";
|
|
49
49
|
import { z } from "zod";
|
|
50
|
-
import { runReadOnlySql } from "../lib/sample-db
|
|
50
|
+
import { runReadOnlySql } from "../lib/sample-db";
|
|
51
51
|
|
|
52
52
|
export default defineTool({
|
|
53
53
|
description:
|
|
@@ -26,7 +26,7 @@ export const glossary = defineState<Glossary>("analytics.glossary", () => ({
|
|
|
26
26
|
```ts title="agent/tools/define_metric.ts"
|
|
27
27
|
import { defineTool } from "eve/tools";
|
|
28
28
|
import { z } from "zod";
|
|
29
|
-
import { glossary } from "../lib/glossary
|
|
29
|
+
import { glossary } from "../lib/glossary";
|
|
30
30
|
|
|
31
31
|
export default defineTool({
|
|
32
32
|
description: "Record the team's definition of a metric so it persists across turns.",
|
|
@@ -41,7 +41,7 @@ export default defineTool({
|
|
|
41
41
|
```ts title="agent/tools/recall_metrics.ts"
|
|
42
42
|
import { defineTool } from "eve/tools";
|
|
43
43
|
import { z } from "zod";
|
|
44
|
-
import { glossary } from "../lib/glossary
|
|
44
|
+
import { glossary } from "../lib/glossary";
|
|
45
45
|
|
|
46
46
|
export default defineTool({
|
|
47
47
|
description: "Read the team's recorded metric definitions.",
|
|
@@ -98,7 +98,7 @@ Now point the channel at it. Replace the contents of `agent/channels/eve.ts`, wh
|
|
|
98
98
|
```ts title="agent/channels/eve.ts"
|
|
99
99
|
import { eveChannel } from "eve/channels/eve";
|
|
100
100
|
import { localDev, vercelOidc, type AuthFn } from "eve/channels/auth";
|
|
101
|
-
import { authenticate } from "../lib/auth
|
|
101
|
+
import { authenticate } from "../lib/auth";
|
|
102
102
|
|
|
103
103
|
const appAuth: AuthFn<Request> = async (request) => {
|
|
104
104
|
const user = await authenticate(request); // your cookie/session/provider
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eve",
|
|
3
|
-
"version": "0.22.
|
|
3
|
+
"version": "0.22.4",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Filesystem-first framework for durable backend AI agents that run anywhere.",
|
|
6
6
|
"keywords": [
|
|
@@ -186,6 +186,11 @@
|
|
|
186
186
|
"import": "./dist/src/public/context/index.js",
|
|
187
187
|
"default": "./dist/src/public/context/index.js"
|
|
188
188
|
},
|
|
189
|
+
"./extension": {
|
|
190
|
+
"types": "./dist/src/public/extension/index.d.ts",
|
|
191
|
+
"import": "./dist/src/public/extension/index.js",
|
|
192
|
+
"default": "./dist/src/public/extension/index.js"
|
|
193
|
+
},
|
|
189
194
|
"./instrumentation": {
|
|
190
195
|
"types": "./dist/src/public/instrumentation/index.d.ts",
|
|
191
196
|
"import": "./dist/src/public/instrumentation/index.js",
|