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.
Files changed (123) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/dist/src/chunks/{use-eve-agent-CM24ZUEI.js → use-eve-agent-CFBTHlPx.js} +43 -14
  3. package/dist/src/chunks/{use-eve-agent-CxcKypLZ.js → use-eve-agent-dEGV09g_.js} +43 -14
  4. package/dist/src/cli/dev/url.js +1 -1
  5. package/dist/src/client/agent-host.d.ts +4 -0
  6. package/dist/src/client/agent-host.js +1 -0
  7. package/dist/src/client/client-error.d.ts +5 -1
  8. package/dist/src/client/client-error.js +1 -1
  9. package/dist/src/client/client.js +1 -1
  10. package/dist/src/client/open-stream.js +1 -1
  11. package/dist/src/client/session.js +1 -1
  12. package/dist/src/client/types.d.ts +2 -1
  13. package/dist/src/client/url.js +1 -1
  14. package/dist/src/compiler/manifest.d.ts +44 -6
  15. package/dist/src/compiler/manifest.js +1 -1
  16. package/dist/src/compiler/module-map.js +2 -2
  17. package/dist/src/compiler/normalize-extension.d.ts +68 -0
  18. package/dist/src/compiler/normalize-extension.js +1 -0
  19. package/dist/src/compiler/normalize-manifest.js +2 -2
  20. package/dist/src/compiler/normalize-subagent.js +1 -1
  21. package/dist/src/compiler/remote-agent-node.d.ts +1 -1
  22. package/dist/src/compiler/remote-agent-node.js +1 -1
  23. package/dist/src/compiler/workspace-resources.js +1 -1
  24. package/dist/src/context/dynamic-skill-lifecycle.js +1 -1
  25. package/dist/src/context/dynamic-tool-lifecycle.js +1 -1
  26. package/dist/src/discover/discover-agent.d.ts +14 -1
  27. package/dist/src/discover/discover-agent.js +1 -1
  28. package/dist/src/discover/extension-specifier.d.ts +15 -0
  29. package/dist/src/discover/extension-specifier.js +1 -0
  30. package/dist/src/discover/extensions.d.ts +109 -0
  31. package/dist/src/discover/extensions.js +1 -0
  32. package/dist/src/discover/filesystem.d.ts +2 -2
  33. package/dist/src/discover/filesystem.js +1 -1
  34. package/dist/src/discover/grammar.d.ts +27 -0
  35. package/dist/src/discover/grammar.js +1 -1
  36. package/dist/src/discover/manifest.d.ts +46 -0
  37. package/dist/src/discover/manifest.js +1 -1
  38. package/dist/src/discover/project.js +1 -1
  39. package/dist/src/evals/assertions/run.d.ts +3 -2
  40. package/dist/src/evals/assertions/run.js +2 -2
  41. package/dist/src/evals/index.d.ts +1 -1
  42. package/dist/src/evals/loaders/yaml.js +1 -1
  43. package/dist/src/evals/match.d.ts +11 -6
  44. package/dist/src/execution/sandbox/bindings/microsandbox-network.js +1 -1
  45. package/dist/src/internal/application/package.js +1 -1
  46. package/dist/src/internal/authored-module-loader.d.ts +14 -0
  47. package/dist/src/internal/authored-module-loader.js +2 -2
  48. package/dist/src/internal/authored-module-map-loader.js +1 -1
  49. package/dist/src/internal/bundler/extension-scope-plugin.d.ts +37 -0
  50. package/dist/src/internal/bundler/extension-scope-plugin.js +3 -0
  51. package/dist/src/internal/helpers/gray-matter.d.ts +25 -0
  52. package/dist/src/internal/helpers/gray-matter.js +1 -0
  53. package/dist/src/internal/helpers/markdown.js +1 -1
  54. package/dist/src/internal/nitro/dev-runtime-source-snapshot-copy.js +1 -1
  55. package/dist/src/internal/nitro/host/build-application.js +1 -1
  56. package/dist/src/internal/nitro/host/build-extension.d.ts +24 -0
  57. package/dist/src/internal/nitro/host/build-extension.js +4 -0
  58. package/dist/src/internal/nitro/host/create-application-nitro.js +1 -1
  59. package/dist/src/internal/workflow-bundle/eve-service-route-output.d.ts +1 -2
  60. package/dist/src/internal/workflow-bundle/eve-service-route-output.js +1 -54
  61. package/dist/src/internal/workflow-bundle/vercel-workflow-output.js +1 -1
  62. package/dist/src/packages/eve-catalog/src/index.js +1 -1
  63. package/dist/src/public/channels/discord/discordChannel.js +1 -1
  64. package/dist/src/public/channels/slack/api.js +1 -1
  65. package/dist/src/public/channels/slack/mrkdwn.d.ts +0 -2
  66. package/dist/src/public/channels/slack/mrkdwn.js +1 -1
  67. package/dist/src/public/definitions/extension.d.ts +68 -0
  68. package/dist/src/public/definitions/extension.js +1 -0
  69. package/dist/src/public/definitions/remote-agent.d.ts +11 -2
  70. package/dist/src/public/extension/index.d.ts +10 -0
  71. package/dist/src/public/extension/index.js +1 -0
  72. package/dist/src/public/index.d.ts +1 -1
  73. package/dist/src/public/next/index.d.ts +38 -3
  74. package/dist/src/public/next/index.js +1 -1
  75. package/dist/src/public/next/server.d.ts +1 -0
  76. package/dist/src/public/next/server.js +2 -1
  77. package/dist/src/public/next/vercel-output-config.d.ts +12 -3
  78. package/dist/src/public/next/vercel-output-config.js +1 -1
  79. package/dist/src/react/use-eve-agent.d.ts +8 -1
  80. package/dist/src/react/use-eve-agent.js +1 -1
  81. package/dist/src/runtime/connections/openapi-client.js +1 -1
  82. package/dist/src/runtime/connections/openapi-spec.js +1 -1
  83. package/dist/src/runtime/resolve-agent-graph.js +1 -1
  84. package/dist/src/runtime/resolve-dynamic-skill.js +1 -1
  85. package/dist/src/runtime/resolve-dynamic-tool.js +1 -1
  86. package/dist/src/runtime/types.d.ts +10 -0
  87. package/dist/src/services/dev-client/vercel-auth-error.d.ts +2 -2
  88. package/dist/src/services/dev-client/vercel-auth-error.js +3 -3
  89. package/dist/src/setup/scaffold/connections/catalog.js +1 -1
  90. package/dist/src/setup/scaffold/create/project.js +3 -3
  91. package/dist/src/svelte/index.js +1 -1
  92. package/dist/src/svelte/use-eve-agent.d.ts +8 -1
  93. package/dist/src/svelte/use-eve-agent.js +1 -1
  94. package/dist/src/vue/index.js +1 -1
  95. package/dist/src/vue/use-eve-agent.d.ts +8 -1
  96. package/dist/src/vue/use-eve-agent.js +1 -1
  97. package/docs/channels/custom.mdx +2 -2
  98. package/docs/channels/linear.mdx +1 -1
  99. package/docs/channels/slack.mdx +2 -0
  100. package/docs/concepts/context-control.md +1 -1
  101. package/docs/connections/openapi.mdx +3 -1
  102. package/docs/evals/assertions.mdx +4 -2
  103. package/docs/extensions.md +176 -0
  104. package/docs/guides/client/overview.mdx +1 -1
  105. package/docs/guides/dev-tui.md +4 -0
  106. package/docs/guides/dynamic-capabilities.md +3 -3
  107. package/docs/guides/frontend/nextjs.mdx +32 -7
  108. package/docs/guides/frontend/overview.mdx +7 -1
  109. package/docs/guides/hooks.md +9 -0
  110. package/docs/guides/instrumentation.md +1 -1
  111. package/docs/guides/remote-agents.md +23 -8
  112. package/docs/guides/state.md +3 -3
  113. package/docs/instructions.mdx +1 -1
  114. package/docs/patterns/dynamic-scheduling.md +11 -11
  115. package/docs/patterns/multi-tenant-approvals.md +6 -6
  116. package/docs/patterns/multi-tenant-auth.md +13 -13
  117. package/docs/patterns/multi-tenant-memory.md +9 -9
  118. package/docs/schedules.mdx +1 -1
  119. package/docs/tutorial/guard-the-spend.mdx +2 -2
  120. package/docs/tutorial/query-sample-data.mdx +1 -1
  121. package/docs/tutorial/remember-definitions.mdx +2 -2
  122. package/docs/tutorial/ship-it.mdx +1 -1
  123. package/package.json +6 -1
@@ -19,7 +19,7 @@ const client = new Client({
19
19
  });
20
20
  ```
21
21
 
22
- `host` is the origin where the eve routes are mounted. In a same-origin browser integration this is often `""`; scripts and backend services usually name the full URL.
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
 
@@ -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.js";
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.js";
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.js";
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 | Default | Purpose |
38
- | -------------------- | -------- | ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
39
- | `eveRoot` | `string` | Next.js app root | Path to the eve app root, relative to `process.cwd()` unless absolute. Set it when the agent lives outside the Next.js project. |
40
- | `eveBuildCommand` | `string` | `"eve build"` | Build command for the generated eve Vercel service. Use it when the eve service needs project-specific prework, without changing the Next.js build. |
41
- | `servicePrefix` | `string` | `"/_eve_internal/eve"` | Private route namespace for legacy manual Vercel service configs and non-Vercel production proxying. Generated Vercel configs use service routes instead. |
42
- | `devServerTimeoutMs` | `number` | `180000` | Maximum time to wait for the eve development server to become available. |
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 |
@@ -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.js";
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 | Required | Default | Description |
24
- | -------------- | ------------------------------- | -------- | ----------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
25
- | `url` | `string` | Yes | n/a | Base URL of the remote eve deployment to call. |
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. |
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
 
@@ -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.js";
31
- import { runQuery } from "../lib/warehouse.js";
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.js";
53
+ import { budget } from "../lib/budget";
54
54
 
55
55
  export default defineHook({
56
56
  events: {
@@ -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.js";
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.js";
34
- import { scheduleStore } from "../lib/schedule-store.js";
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.js";
123
- import { requireScheduleOwner } from "../lib/tenant.js";
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.js";
146
- import { requireScheduleOwner } from "../lib/tenant.js";
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.js";
161
- import { requireScheduleOwner } from "../lib/tenant.js";
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.js";
187
- import { requireScheduleOwner } from "../lib/tenant.js";
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.js";
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.js";
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.js";
81
- import { decideTenantApproval } from "../lib/tenant-approval.js";
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.js";
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.js";
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.js";
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.js";
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.js";
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.js";
140
- import { requireTenantCaller } from "../lib/tenant.js";
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.js";
171
- import { tenantBearerAuth } from "../lib/tenant-connection-auth.js";
172
- import { requireTenantCaller } from "../lib/tenant.js";
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.js";
197
- import { tenantBearerAuth } from "../lib/tenant-connection-auth.js";
198
- import { requireTenantCaller } from "../lib/tenant.js";
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.js";
224
- import { requireTenantCaller } from "../lib/tenant.js";
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.js";
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.js";
57
- import { requireTenantCaller } from "../lib/tenant.js";
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.js";
92
- import { requireTenantCaller } from "../lib/tenant.js";
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.js";
114
- import { requireTenantCaller } from "../lib/tenant.js";
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.js";
130
- import { requireTenantCaller } from "../lib/tenant.js";
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.js";
168
+ export { memoryStore } from "../../lib/memory-store";
169
169
  ```
170
170
 
171
171
  Whatever backend you choose, preserve these invariants:
@@ -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.js";
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.js";
27
- import { estimateScanGb } from "../lib/cost.js";
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.js";
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.js";
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.js";
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.js";
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.2",
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",