@zackbart/connecta-eve 0.35.0 → 0.36.0

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/README.md CHANGED
@@ -1,18 +1,18 @@
1
1
  # @zackbart/connecta-eve
2
2
 
3
3
  Connect an Eve agent to a Connecta agent pool and load its endpoint instructions
4
- at the start of each turn. The helper runs in the Eve app; the Connecta server
4
+ once per turn. The helper runs in the Eve app; the Connecta server
5
5
  runs separately. No `@zackbart/connecta` dependency is installed by this package.
6
6
 
7
- Requires **Node 24+** and **Eve >=0.83.0 <0.84.0**. Development and consumer
8
- checks use real Eve 0.83.0. The range covers its patch line; newer minor releases
7
+ Requires **Node 24+** and **Eve >=0.84.0 <0.85.0**. Development and consumer
8
+ checks use real Eve 0.84.0. The range covers its patch line; newer minor releases
9
9
  need a compatibility check. Helper releases share Connecta's version and tag;
10
10
  choose the helper version matching your server release.
11
11
 
12
12
  ## Install and add two files
13
13
 
14
14
  ```sh
15
- npm install @zackbart/connecta-eve eve@0.83.0
15
+ npm install @zackbart/connecta-eve eve@0.84.0
16
16
  ```
17
17
 
18
18
  The server must declare your agent, admit it to the named pool and issue its
@@ -55,9 +55,9 @@ again for each request, so rotation requires no process restart. A `getToken`
55
55
  callback can return a string or a promise of one; it overrides the environment.
56
56
  No user's identity is forwarded.
57
57
 
58
- ## Eve 0.83.0 dependency override
58
+ ## Eve 0.84.0 dependency override
59
59
 
60
- Eve 0.83.0 pins undici 8.10.2. Connecta's development/test override does not ship
60
+ Eve 0.84.0 pins undici 8.10.2. Connecta's development/test override does not ship
61
61
  with this helper, so the Eve app must apply its own override to 8.12.3 before
62
62
  installing. For an npm app, add this to its `package.json`, then reinstall and
63
63
  commit the lockfile:
@@ -66,7 +66,7 @@ commit the lockfile:
66
66
  { "overrides": { "eve": { "undici": "8.12.3" } } }
67
67
  ```
68
68
 
69
- For a pnpm app, add `overrides: { "eve@0.83.0>undici": "8.12.3" }` to its
69
+ For a pnpm app, add `overrides: { "eve@0.84.0>undici": "8.12.3" }` to its
70
70
  `pnpm-workspace.yaml`. Check the resolved dependency graph and audit the app.
71
71
  Remove this override after upgrading to an Eve release that pins a fixed version
72
72
  and validating compatibility. The server's optional undici 6.29.1 peer is a
@@ -79,7 +79,8 @@ read-only Connecta pool when the agent must never write. For an interactive
79
79
  agent, add `gateWrites: true` to the connection to request user approval before
80
80
  any tool whose `readOnlyHint` is not `true`, including writable `execute_code`.
81
81
  `gateConnectaWrites` exports that policy for composition. An explicit Eve
82
- `approval` policy takes precedence over `gateWrites`.
82
+ `approval`, either a policy or an approval configuration, takes precedence over
83
+ `gateWrites`.
83
84
 
84
85
  The gate uses the host's cached annotations. If a read becomes a write before
85
86
  dispatch, Connecta applies its current classification; a writable pool can
@@ -92,8 +93,13 @@ Instructions use `server/discover` (MCP 2026-07-28), falling back to legacy
92
93
  non-OK status or an unsupported-method response. Network errors and timeouts
93
94
  never trigger initialize. Both JSON and SSE replies are accepted. Each request
94
95
  has a five-second timeout. Successful guidance is cached for ten minutes per
95
- resolver; `ttlMs` overrides that duration. A failed refresh keeps the last copy,
96
- or adds nothing if no fetch has succeeded, and waits 30 seconds before retrying.
96
+ resolver; `ttlMs` overrides that duration. Eve evaluates instructions before
97
+ every model call; the helper keeps one result per turn in Eve's memo, so a turn
98
+ sees the same guidance throughout and at most one refresh. A failed refresh
99
+ keeps the last copy, or adds nothing if no fetch has succeeded, and waits 30
100
+ seconds before retrying.
101
+ When Eve cancels an evaluation, the helper rethrows the cancellation instead of
102
+ counting it as a failure: nothing is kept for that turn and no wait starts.
97
103
  Tools remain usable. Instructions do not grant access.
98
104
 
99
105
  ## Vercel OIDC token source
@@ -129,7 +135,7 @@ dependency on it and never switches credential types automatically.
129
135
 
130
136
  In a source checkout with dependencies installed and both packages built, run
131
137
  `pnpm --filter @zackbart/connecta-eve run probe:catalog --output /absolute/path/outside/checkout`
132
- on Node 24. This boots real Eve 0.83.0 with a packed, installed helper against
138
+ on Node 24. This boots real Eve 0.84.0 with a packed, installed helper against
133
139
  seeded local catalogs of 40, 100, 250, 500, and 1,000 downstream tools on the
134
140
  meta, native, and native-plus-code surfaces. Native listings include two
135
141
  Connecta tools beyond the downstream count. A 1,001-tool native catalog must
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { type McpClientConnectionDefinition } from "eve/connections";
2
- import { type ApprovalPolicy } from "eve/tools/approval";
2
+ import { type Approval, type ApprovalPolicy } from "eve/tools/approval";
3
3
  /** Where an Eve agent reaches Connecta and how it proves who it is. */
4
4
  export interface ConnectaEndpointOptions {
5
5
  /**
@@ -18,8 +18,8 @@ export interface ConnectaEndpointOptions {
18
18
  export interface ConnectaConnectionOptions extends ConnectaEndpointOptions {
19
19
  /** What the connection offers, for the model choosing which connection to search. */
20
20
  description: string;
21
- /** Eve's approval policy for every Connecta tool. Defaults to `never()`. */
22
- approval?: ApprovalPolicy;
21
+ /** Eve's approval for every Connecta tool: a policy or configuration. Defaults to `never()`. */
22
+ approval?: Approval;
23
23
  /**
24
24
  * Ask a person before every tool not annotated read-only: each write tool
25
25
  * on a native endpoint, and `execute_code` on a writable one. Ignored when
@@ -46,9 +46,10 @@ export declare const gateConnectaWrites: ApprovalPolicy;
46
46
  */
47
47
  export declare function connectaConnection(options: ConnectaConnectionOptions): McpClientConnectionDefinition;
48
48
  /**
49
- * Connecta's instructions as Eve system instructions, refreshed at turn start.
49
+ * Connecta's instructions as Eve system instructions, refreshed once per turn.
50
50
  * Eve does not pass an MCP server's `instructions` to the model, so this
51
51
  * fetches them and caches each success; a failure keeps the last copy, or adds
52
- * nothing, and the tools still work.
52
+ * nothing, and the tools still work. Eve evaluates the resolver before every
53
+ * model call; a memo keyed on the turn keeps one result for the whole turn.
53
54
  */
54
- export declare function connectaInstructions(options?: ConnectaInstructionsOptions): import("eve/connections").DynamicSentinel<import("eve/instructions").DynamicInstructionsResult>;
55
+ export declare function connectaInstructions(options?: ConnectaInstructionsOptions): import("eve/connections").DynamicSentinel<import("eve/instructions").DynamicInstructionsResult, import("eve/connections").DynamicContext>;
package/dist/index.js CHANGED
@@ -36,14 +36,14 @@ export function connectaConnection(options) {
36
36
  url: connectaEndpoint(options),
37
37
  description: options.description,
38
38
  auth: {
39
- credentialOwner: "app",
39
+ principalType: "app",
40
40
  getToken: async () => ({ token: await tokenFor(options) }),
41
41
  },
42
42
  approval: options.approval ?? (options.gateWrites ? gateConnectaWrites : never()),
43
43
  });
44
44
  }
45
45
  /** Connecta's MCP `instructions` for one endpoint, or null when unavailable. */
46
- async function instructionRequest(options, method) {
46
+ async function instructionRequest(options, method, signal) {
47
47
  const modern = method === "server/discover";
48
48
  const response = await (options.fetch ?? fetch)(connectaEndpoint(options), {
49
49
  method: "POST",
@@ -71,7 +71,7 @@ async function instructionRequest(options, method) {
71
71
  clientInfo: { name: "connecta-eve-instructions", version: "1" },
72
72
  },
73
73
  }),
74
- signal: AbortSignal.timeout(5_000),
74
+ signal: AbortSignal.any([signal, AbortSignal.timeout(5_000)]),
75
75
  });
76
76
  if (!response.ok)
77
77
  return null;
@@ -88,39 +88,46 @@ async function instructionRequest(options, method) {
88
88
  const instructions = JSON.parse(json).result?.instructions;
89
89
  return typeof instructions === "string" && instructions.trim() ? instructions.trim() : null;
90
90
  }
91
- async function fetchConnectaInstructions(options) {
91
+ async function fetchConnectaInstructions(options, signal) {
92
92
  // Only a completed discovery response can justify legacy negotiation.
93
93
  // Network failures and timeouts propagate to the resolver's fail-open path.
94
- const discovered = await instructionRequest(options, "server/discover");
95
- return discovered ?? instructionRequest(options, "initialize");
94
+ const discovered = await instructionRequest(options, "server/discover", signal);
95
+ return discovered ?? instructionRequest(options, "initialize", signal);
96
96
  }
97
97
  /**
98
- * Connecta's instructions as Eve system instructions, refreshed at turn start.
98
+ * Connecta's instructions as Eve system instructions, refreshed once per turn.
99
99
  * Eve does not pass an MCP server's `instructions` to the model, so this
100
100
  * fetches them and caches each success; a failure keeps the last copy, or adds
101
- * nothing, and the tools still work.
101
+ * nothing, and the tools still work. Eve evaluates the resolver before every
102
+ * model call; a memo keyed on the turn keeps one result for the whole turn.
102
103
  */
103
104
  export function connectaInstructions(options = {}) {
104
105
  const ttlMs = options.ttlMs ?? 600_000;
105
106
  let cached;
106
107
  let retryAfter = 0;
107
- const current = async () => {
108
+ const current = async (signal) => {
109
+ signal.throwIfAborted();
108
110
  if (cached && Date.now() - cached.at <= ttlMs)
109
111
  return cached.content;
110
112
  if (Date.now() < retryAfter)
111
113
  return cached?.content ?? null;
112
- const fresh = await fetchConnectaInstructions(options).catch(() => null);
114
+ let fresh;
115
+ try {
116
+ fresh = await fetchConnectaInstructions(options, signal);
117
+ }
118
+ catch {
119
+ // Eve's cancellation is not an endpoint failure: rethrowing keeps it out
120
+ // of the memo and the backoff, which every session of this resolver shares.
121
+ signal.throwIfAborted();
122
+ fresh = null;
123
+ }
113
124
  if (fresh)
114
125
  cached = { at: Date.now(), content: fresh };
115
126
  retryAfter = fresh ? 0 : Date.now() + 30_000;
116
127
  return fresh ?? cached?.content ?? null;
117
128
  };
118
- return defineDynamic({
119
- events: {
120
- "turn.started": async () => {
121
- const content = await current();
122
- return content ? defineInstructions({ content: `Connecta guidance:\n${content}` }) : null;
123
- },
124
- },
129
+ return defineDynamic(async (ctx) => {
130
+ const content = await ctx.memo(["connecta-instructions", ctx.turn?.id ?? null], ({ abortSignal }) => current(abortSignal));
131
+ return content ? defineInstructions({ content: `Connecta guidance:\n${content}` }) : null;
125
132
  });
126
133
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zackbart/connecta-eve",
3
- "version": "0.35.0",
3
+ "version": "0.36.0",
4
4
  "type": "module",
5
5
  "sideEffects": false,
6
6
  "description": "Eve connection and instructions helpers for Connecta agent endpoints.",
@@ -28,11 +28,11 @@
28
28
  }
29
29
  },
30
30
  "peerDependencies": {
31
- "eve": ">=0.83.0 <0.84.0"
31
+ "eve": ">=0.84.0 <0.85.0"
32
32
  },
33
33
  "devDependencies": {
34
34
  "@types/node": "^24.0.0",
35
- "eve": "0.83.0",
35
+ "eve": "0.84.0",
36
36
  "typescript": "^5.9.3",
37
37
  "vitest": "^4.1.6"
38
38
  },