@anuma/agent-runtime 6.33.0 → 6.33.2
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/dist/index.cjs +0 -4
- package/dist/index.d.mts +0 -163
- package/dist/index.d.ts +0 -163
- package/dist/index.mjs +0 -4
- package/package.json +3 -3
package/dist/index.cjs
CHANGED
|
@@ -376,10 +376,6 @@ async function runAgentRequest(opts) {
|
|
|
376
376
|
model: opts.agent.model.default,
|
|
377
377
|
token: grant.bearer,
|
|
378
378
|
tools,
|
|
379
|
-
// X-Anuma-Surface drives portal auth/grant keying (OAuth client_id + first-party
|
|
380
|
-
// grant surface) — keep it. X-Anuma-Feature is the provenance header the portal
|
|
381
|
-
// records into requests.feature (#1353); without it, agent-runtime LLM traffic
|
|
382
|
-
// lands feature=null and can't be told apart from chat/background in prod.
|
|
383
379
|
headers: { "X-Anuma-Surface": "agent", "X-Anuma-Feature": "agent" },
|
|
384
380
|
...opts.portalBaseUrl ? { baseUrl: opts.portalBaseUrl } : void 0,
|
|
385
381
|
...opts.transport ? { transport: opts.transport } : void 0,
|
package/dist/index.d.mts
CHANGED
|
@@ -3,33 +3,12 @@ export { ConnectorTokenGetterOpts } from '@anuma/sdk/tools';
|
|
|
3
3
|
import { LlmapiMessage } from '@anuma/sdk';
|
|
4
4
|
import { ToolConfig, StreamingTransport, ApiType, AutoExecutedToolResult } from '@anuma/sdk/server';
|
|
5
5
|
|
|
6
|
-
/**
|
|
7
|
-
* Public types for `@anuma/agent-runtime`.
|
|
8
|
-
*
|
|
9
|
-
* Mirrors the contract in `.claude-docs/connecters/agent-runtime-spec.md`.
|
|
10
|
-
* These types are the contract between the SDK / portal vault and any
|
|
11
|
-
* server-side consumer (Haven, Sentinel, future SMS handler).
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Parsed result of an incoming bearer token. Returned by
|
|
16
|
-
* {@link extractGrantContext}.
|
|
17
|
-
*/
|
|
18
6
|
interface GrantContext {
|
|
19
|
-
/** Wallet address — primary user identifier on the portal. */
|
|
20
7
|
userAddress: string;
|
|
21
|
-
/** OAuth `client_id` that owns the bearer (e.g. `"haven_v1"`). */
|
|
22
8
|
clientId: string;
|
|
23
|
-
/** Scopes the user granted to this client. */
|
|
24
9
|
scopes: string[];
|
|
25
|
-
/** Bearer token verbatim — for relaying to the portal. */
|
|
26
10
|
bearer: string;
|
|
27
11
|
}
|
|
28
|
-
/**
|
|
29
|
-
* Discriminated result of a mint call. Failures are returned, never
|
|
30
|
-
* thrown — transport errors (5xx / network) raise from {@link PortalClient}
|
|
31
|
-
* directly.
|
|
32
|
-
*/
|
|
33
12
|
type MintResult = {
|
|
34
13
|
ok: true;
|
|
35
14
|
accessToken: string;
|
|
@@ -38,61 +17,35 @@ type MintResult = {
|
|
|
38
17
|
ok: false;
|
|
39
18
|
error: MintError;
|
|
40
19
|
};
|
|
41
|
-
/** Variants of `MintResult.error`. Re-exported from the SDK so consumers
|
|
42
|
-
* importing only `@anuma/agent-runtime` get the union without a second
|
|
43
|
-
* import. */
|
|
44
20
|
type MintError = ConnectorMintError;
|
|
45
|
-
/** Returned by {@link PortalClient.listConnectors}. */
|
|
46
21
|
interface ConnectorInfo {
|
|
47
22
|
oauthApp: string;
|
|
48
23
|
externalAccount?: string;
|
|
49
24
|
grantedScopes: string[];
|
|
50
25
|
connectedAt: number;
|
|
51
26
|
}
|
|
52
|
-
/** Argument shape for {@link PortalClient.createConnectTicket}. */
|
|
53
27
|
interface ConnectTicketOpts {
|
|
54
|
-
/** Logical provider (e.g. `"gmail"`, `"github"`) — mapped to the portal
|
|
55
|
-
* `oauth_app` internally and used to build the connect URL. */
|
|
56
28
|
provider: string;
|
|
57
|
-
/**
|
|
58
|
-
* Scopes requested for the connect flow, passed VERBATIM upstream
|
|
59
|
-
* ("upstream-flavored"): Google needs full
|
|
60
|
-
* `https://www.googleapis.com/auth/...` URLs. An empty array falls back to
|
|
61
|
-
* the provider's default scope union on the portal side.
|
|
62
|
-
*/
|
|
63
29
|
requestedScopes: string[];
|
|
64
30
|
returnTo: string;
|
|
65
31
|
}
|
|
66
|
-
/** Result of a ticket-mint call. */
|
|
67
32
|
interface ConnectTicket {
|
|
68
33
|
ticketId: string;
|
|
69
34
|
expiresAt: number;
|
|
70
35
|
connectUrl: string;
|
|
71
36
|
}
|
|
72
|
-
/** Typed wrapper over the portal HTTP API. */
|
|
73
37
|
interface PortalClient {
|
|
74
|
-
/** Mint a fresh upstream access token for a logical provider. `access`
|
|
75
|
-
* defaults to the provider's standard level (e.g. gmail `read`, github
|
|
76
|
-
* `repo`). */
|
|
77
38
|
mintConnectorToken(provider: string, access?: string): Promise<MintResult>;
|
|
78
|
-
/** List the user's currently-connected connectors. */
|
|
79
39
|
listConnectors(): Promise<ConnectorInfo[]>;
|
|
80
|
-
/** Mint a connect ticket so the user can be redirected to a connect flow. */
|
|
81
40
|
createConnectTicket(opts: ConnectTicketOpts): Promise<ConnectTicket>;
|
|
82
41
|
}
|
|
83
42
|
interface PortalClientOpts {
|
|
84
|
-
/** Defaults to `process.env.ANUMA_PORTAL_URL` then the production portal. */
|
|
85
43
|
baseUrl?: string;
|
|
86
|
-
/** Defaults to `globalThis.fetch`. */
|
|
87
44
|
fetchImpl?: typeof fetch;
|
|
88
|
-
/** Per-request timeout. @default 5000 */
|
|
89
45
|
timeoutMs?: number;
|
|
90
|
-
/** Max retry attempts on 5xx / network errors. @default 3 */
|
|
91
46
|
maxRetries?: number;
|
|
92
|
-
/** Initial backoff before the second attempt. @default 100 */
|
|
93
47
|
retryBaseMs?: number;
|
|
94
48
|
}
|
|
95
|
-
/** Structurally-typed incoming request. Any HTTP framework satisfies this. */
|
|
96
49
|
interface IncomingRequest {
|
|
97
50
|
headers: {
|
|
98
51
|
authorization?: string;
|
|
@@ -100,17 +53,6 @@ interface IncomingRequest {
|
|
|
100
53
|
[key: string]: string | string[] | undefined;
|
|
101
54
|
};
|
|
102
55
|
}
|
|
103
|
-
/**
|
|
104
|
-
* Structured tool error lifted from a tool-result message after the loop
|
|
105
|
-
* completes. Connector errors carry the canonical
|
|
106
|
-
* `__anuma_connector_error_v1` payload; other tool failures may surface
|
|
107
|
-
* here in the future.
|
|
108
|
-
*/
|
|
109
|
-
/**
|
|
110
|
-
* Open shape so future tool-execution errors can lift into the same union
|
|
111
|
-
* without breaking consumers. Connector errors populate `provider`; other
|
|
112
|
-
* errors carry a `message`.
|
|
113
|
-
*/
|
|
114
56
|
interface ToolErrorInfo {
|
|
115
57
|
code: string;
|
|
116
58
|
provider?: string;
|
|
@@ -124,152 +66,47 @@ interface ToolError {
|
|
|
124
66
|
error: ToolErrorInfo;
|
|
125
67
|
}
|
|
126
68
|
|
|
127
|
-
/**
|
|
128
|
-
* Error subclasses thrown by `@anuma/agent-runtime`.
|
|
129
|
-
*
|
|
130
|
-
* - {@link AuthError} comes out of `extractGrantContext` when the bearer is
|
|
131
|
-
* missing, malformed, expired, or already revoked.
|
|
132
|
-
*/
|
|
133
|
-
/** Discriminant for {@link AuthError}. */
|
|
134
69
|
type AuthErrorSubtype = "missing_bearer" | "invalid_bearer" | "expired" | "revoked";
|
|
135
70
|
declare class AuthError extends Error {
|
|
136
71
|
readonly subtype: AuthErrorSubtype;
|
|
137
72
|
constructor(subtype: AuthErrorSubtype, message?: string);
|
|
138
73
|
}
|
|
139
74
|
|
|
140
|
-
/**
|
|
141
|
-
* Pull the bearer off an incoming request, validate it against the portal,
|
|
142
|
-
* and return the parsed grant.
|
|
143
|
-
*
|
|
144
|
-
* In v1 the portal validates by exposing `GET /api/v1/me`, which returns
|
|
145
|
-
* `{ user_address, client_id, scopes }`. A later portal version may switch
|
|
146
|
-
* to issuing signed JWTs and let `extractGrantContext` do local decode —
|
|
147
|
-
* the consumer signature stays the same.
|
|
148
|
-
*/
|
|
149
|
-
|
|
150
75
|
type ExtractGrantContextOpts = Pick<PortalClientOpts, "baseUrl" | "fetchImpl" | "timeoutMs">;
|
|
151
76
|
declare function extractGrantContext(req: IncomingRequest, opts?: ExtractGrantContextOpts): Promise<GrantContext>;
|
|
152
77
|
|
|
153
|
-
/**
|
|
154
|
-
* Typed HTTP client over the portal API.
|
|
155
|
-
*
|
|
156
|
-
* Retries on 5xx / network errors with exponential backoff + jitter
|
|
157
|
-
* (default 3 attempts, base 100ms). Never retries 4xx — those become
|
|
158
|
-
* `MintResult.ok=false` (for mint) or thrown errors (for the bookkeeping
|
|
159
|
-
* endpoints `listConnectors` / `createConnectTicket`).
|
|
160
|
-
*
|
|
161
|
-
* Surface is duck-typed against `PortalClient` so test stubs can satisfy
|
|
162
|
-
* the same contract.
|
|
163
|
-
*/
|
|
164
|
-
|
|
165
78
|
declare function createPortalClient(bearer: string, opts?: PortalClientOpts): PortalClient;
|
|
166
79
|
|
|
167
|
-
/**
|
|
168
|
-
* Convenience wrapper that re-exports the SDK's
|
|
169
|
-
* `createConnectorTokenGetter` with the same per-instance cache semantics.
|
|
170
|
-
*
|
|
171
|
-
* The wrapper exists so consumers importing only `@anuma/agent-runtime`
|
|
172
|
-
* get the helper as part of a single import surface, without also
|
|
173
|
-
* importing `@anuma/sdk/tools` directly. The behavior is identical.
|
|
174
|
-
*/
|
|
175
|
-
|
|
176
80
|
declare function createConnectorTokenGetter(client: PortalClient, provider: string, opts?: ConnectorTokenGetterOpts): () => Promise<string | null>;
|
|
177
81
|
|
|
178
|
-
/**
|
|
179
|
-
* `runAgentRequest` — the single function a server-side agent host calls
|
|
180
|
-
* per inbound request.
|
|
181
|
-
*
|
|
182
|
-
* Wires the four pieces together:
|
|
183
|
-
* extractGrantContext → createPortalClient → toolFactories → runToolLoop
|
|
184
|
-
*
|
|
185
|
-
* After the loop returns, walks the auto-executed tool results, lifts any
|
|
186
|
-
* payload carrying the canonical `__anuma_connector_error_v1` marker into
|
|
187
|
-
* `AgentResponse.toolErrors`. The marker shape is the load-bearing contract
|
|
188
|
-
* — every connector tool factory uses `buildConnectorErrorResult` to emit
|
|
189
|
-
* it, and the parser keys solely on that marker so it can't false-positive
|
|
190
|
-
* on tools that legitimately return JSON.
|
|
191
|
-
*/
|
|
192
|
-
|
|
193
|
-
/** Minimal slice of `AgentConfig` this runtime depends on. */
|
|
194
82
|
interface AgentConfigLike {
|
|
195
|
-
/** Model selection — at least `default` must be present. */
|
|
196
83
|
model: {
|
|
197
84
|
default: string;
|
|
198
85
|
};
|
|
199
|
-
/** System prompt threaded into the loop. */
|
|
200
86
|
prompt: string;
|
|
201
87
|
}
|
|
202
88
|
interface AgentRequestOpts {
|
|
203
|
-
/** Inbound request — only `headers.authorization` is read. */
|
|
204
89
|
request: IncomingRequest;
|
|
205
|
-
/** Agent configuration (haven, sentinel, …). */
|
|
206
90
|
agent: AgentConfigLike;
|
|
207
|
-
/** Conversation history including the user turn. */
|
|
208
91
|
messages: LlmapiMessage[];
|
|
209
|
-
/** Tool factories that receive the portal client and return `ToolConfig[]`. */
|
|
210
92
|
toolFactories?: Array<(portalClient: PortalClient) => ToolConfig[]>;
|
|
211
|
-
/** Override portal client opts (test injection). */
|
|
212
93
|
portalClientOpts?: PortalClientOpts;
|
|
213
|
-
/**
|
|
214
|
-
* Override the streaming transport runToolLoop uses to talk to the
|
|
215
|
-
* portal's chat completion API. Production code never sets this — it's
|
|
216
|
-
* the injection point e2e tests use to stub LLM behavior without a real
|
|
217
|
-
* portal in the loop. Forwarded verbatim to runToolLoop's
|
|
218
|
-
* `transport` option.
|
|
219
|
-
*/
|
|
220
94
|
transport?: StreamingTransport;
|
|
221
|
-
/**
|
|
222
|
-
* Optional portal base URL forwarded to runToolLoop for chat completions.
|
|
223
|
-
* Defaults to runToolLoop's own default. Setting this without a stub
|
|
224
|
-
* `transport` will hit the real portal.
|
|
225
|
-
*/
|
|
226
95
|
portalBaseUrl?: string;
|
|
227
|
-
/**
|
|
228
|
-
* Optional override for the LLM API strategy ("responses" | "completions" | "auto").
|
|
229
|
-
* Production callers don't set this — the default ("auto") picks the right
|
|
230
|
-
* endpoint for the model. Tests use "completions" with the stub transport
|
|
231
|
-
* to feed OpenAI-style streaming chunks.
|
|
232
|
-
*/
|
|
233
96
|
apiType?: ApiType;
|
|
234
97
|
}
|
|
235
|
-
/** Minimal usage summary lifted off the LLM response. */
|
|
236
98
|
interface UsageSummary {
|
|
237
99
|
inputTokens?: number;
|
|
238
100
|
outputTokens?: number;
|
|
239
101
|
totalTokens?: number;
|
|
240
102
|
}
|
|
241
103
|
interface AgentResponse {
|
|
242
|
-
/**
|
|
243
|
-
* Conversation messages after the loop completes: the input messages,
|
|
244
|
-
* followed by tool-result messages for each auto-executed tool, followed
|
|
245
|
-
* by the final assistant message. Synthesized — `runToolLoop` doesn't
|
|
246
|
-
* expose the full message history directly.
|
|
247
|
-
*/
|
|
248
104
|
messages: LlmapiMessage[];
|
|
249
|
-
/** Structured tool errors lifted from the post-loop parser. */
|
|
250
105
|
toolErrors: ToolError[];
|
|
251
|
-
/** Token usage summary if the response carried one. */
|
|
252
106
|
usage?: UsageSummary;
|
|
253
|
-
/** Grant context, surfaced for logging / multi-tenant context propagation. */
|
|
254
107
|
grant: GrantContext;
|
|
255
108
|
}
|
|
256
|
-
/**
|
|
257
|
-
* Walk the loop's tool results, lift entries that carry the
|
|
258
|
-
* `__anuma_connector_error_v1` marker into structured `ToolError`s.
|
|
259
|
-
*
|
|
260
|
-
* Each `AutoExecutedToolResult.result` is what the executor returned.
|
|
261
|
-
* Connector tool factories return the JSON string produced by
|
|
262
|
-
* `buildConnectorErrorResult`, so we JSON.parse strings and inspect for
|
|
263
|
-
* the marker. Non-string results (objects, arrays, errors) skip the
|
|
264
|
-
* parser entirely — they can't be connector errors.
|
|
265
|
-
*/
|
|
266
109
|
declare function extractConnectorToolErrors(toolResults: AutoExecutedToolResult[] | undefined): ToolError[];
|
|
267
|
-
/**
|
|
268
|
-
* Default `requestAccess` passed to connector tool factories from inside
|
|
269
|
-
* `runAgentRequest`. Server agents cannot drive interactive OAuth — they
|
|
270
|
-
* have no surface to bounce the user through. The factory falls back to
|
|
271
|
-
* emitting the canonical connector error JSON when this throws.
|
|
272
|
-
*/
|
|
273
110
|
declare function denyInteractive(): Promise<string | null>;
|
|
274
111
|
declare function runAgentRequest(opts: AgentRequestOpts): Promise<AgentResponse>;
|
|
275
112
|
|
package/dist/index.d.ts
CHANGED
|
@@ -3,33 +3,12 @@ export { ConnectorTokenGetterOpts } from '@anuma/sdk/tools';
|
|
|
3
3
|
import { LlmapiMessage } from '@anuma/sdk';
|
|
4
4
|
import { ToolConfig, StreamingTransport, ApiType, AutoExecutedToolResult } from '@anuma/sdk/server';
|
|
5
5
|
|
|
6
|
-
/**
|
|
7
|
-
* Public types for `@anuma/agent-runtime`.
|
|
8
|
-
*
|
|
9
|
-
* Mirrors the contract in `.claude-docs/connecters/agent-runtime-spec.md`.
|
|
10
|
-
* These types are the contract between the SDK / portal vault and any
|
|
11
|
-
* server-side consumer (Haven, Sentinel, future SMS handler).
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Parsed result of an incoming bearer token. Returned by
|
|
16
|
-
* {@link extractGrantContext}.
|
|
17
|
-
*/
|
|
18
6
|
interface GrantContext {
|
|
19
|
-
/** Wallet address — primary user identifier on the portal. */
|
|
20
7
|
userAddress: string;
|
|
21
|
-
/** OAuth `client_id` that owns the bearer (e.g. `"haven_v1"`). */
|
|
22
8
|
clientId: string;
|
|
23
|
-
/** Scopes the user granted to this client. */
|
|
24
9
|
scopes: string[];
|
|
25
|
-
/** Bearer token verbatim — for relaying to the portal. */
|
|
26
10
|
bearer: string;
|
|
27
11
|
}
|
|
28
|
-
/**
|
|
29
|
-
* Discriminated result of a mint call. Failures are returned, never
|
|
30
|
-
* thrown — transport errors (5xx / network) raise from {@link PortalClient}
|
|
31
|
-
* directly.
|
|
32
|
-
*/
|
|
33
12
|
type MintResult = {
|
|
34
13
|
ok: true;
|
|
35
14
|
accessToken: string;
|
|
@@ -38,61 +17,35 @@ type MintResult = {
|
|
|
38
17
|
ok: false;
|
|
39
18
|
error: MintError;
|
|
40
19
|
};
|
|
41
|
-
/** Variants of `MintResult.error`. Re-exported from the SDK so consumers
|
|
42
|
-
* importing only `@anuma/agent-runtime` get the union without a second
|
|
43
|
-
* import. */
|
|
44
20
|
type MintError = ConnectorMintError;
|
|
45
|
-
/** Returned by {@link PortalClient.listConnectors}. */
|
|
46
21
|
interface ConnectorInfo {
|
|
47
22
|
oauthApp: string;
|
|
48
23
|
externalAccount?: string;
|
|
49
24
|
grantedScopes: string[];
|
|
50
25
|
connectedAt: number;
|
|
51
26
|
}
|
|
52
|
-
/** Argument shape for {@link PortalClient.createConnectTicket}. */
|
|
53
27
|
interface ConnectTicketOpts {
|
|
54
|
-
/** Logical provider (e.g. `"gmail"`, `"github"`) — mapped to the portal
|
|
55
|
-
* `oauth_app` internally and used to build the connect URL. */
|
|
56
28
|
provider: string;
|
|
57
|
-
/**
|
|
58
|
-
* Scopes requested for the connect flow, passed VERBATIM upstream
|
|
59
|
-
* ("upstream-flavored"): Google needs full
|
|
60
|
-
* `https://www.googleapis.com/auth/...` URLs. An empty array falls back to
|
|
61
|
-
* the provider's default scope union on the portal side.
|
|
62
|
-
*/
|
|
63
29
|
requestedScopes: string[];
|
|
64
30
|
returnTo: string;
|
|
65
31
|
}
|
|
66
|
-
/** Result of a ticket-mint call. */
|
|
67
32
|
interface ConnectTicket {
|
|
68
33
|
ticketId: string;
|
|
69
34
|
expiresAt: number;
|
|
70
35
|
connectUrl: string;
|
|
71
36
|
}
|
|
72
|
-
/** Typed wrapper over the portal HTTP API. */
|
|
73
37
|
interface PortalClient {
|
|
74
|
-
/** Mint a fresh upstream access token for a logical provider. `access`
|
|
75
|
-
* defaults to the provider's standard level (e.g. gmail `read`, github
|
|
76
|
-
* `repo`). */
|
|
77
38
|
mintConnectorToken(provider: string, access?: string): Promise<MintResult>;
|
|
78
|
-
/** List the user's currently-connected connectors. */
|
|
79
39
|
listConnectors(): Promise<ConnectorInfo[]>;
|
|
80
|
-
/** Mint a connect ticket so the user can be redirected to a connect flow. */
|
|
81
40
|
createConnectTicket(opts: ConnectTicketOpts): Promise<ConnectTicket>;
|
|
82
41
|
}
|
|
83
42
|
interface PortalClientOpts {
|
|
84
|
-
/** Defaults to `process.env.ANUMA_PORTAL_URL` then the production portal. */
|
|
85
43
|
baseUrl?: string;
|
|
86
|
-
/** Defaults to `globalThis.fetch`. */
|
|
87
44
|
fetchImpl?: typeof fetch;
|
|
88
|
-
/** Per-request timeout. @default 5000 */
|
|
89
45
|
timeoutMs?: number;
|
|
90
|
-
/** Max retry attempts on 5xx / network errors. @default 3 */
|
|
91
46
|
maxRetries?: number;
|
|
92
|
-
/** Initial backoff before the second attempt. @default 100 */
|
|
93
47
|
retryBaseMs?: number;
|
|
94
48
|
}
|
|
95
|
-
/** Structurally-typed incoming request. Any HTTP framework satisfies this. */
|
|
96
49
|
interface IncomingRequest {
|
|
97
50
|
headers: {
|
|
98
51
|
authorization?: string;
|
|
@@ -100,17 +53,6 @@ interface IncomingRequest {
|
|
|
100
53
|
[key: string]: string | string[] | undefined;
|
|
101
54
|
};
|
|
102
55
|
}
|
|
103
|
-
/**
|
|
104
|
-
* Structured tool error lifted from a tool-result message after the loop
|
|
105
|
-
* completes. Connector errors carry the canonical
|
|
106
|
-
* `__anuma_connector_error_v1` payload; other tool failures may surface
|
|
107
|
-
* here in the future.
|
|
108
|
-
*/
|
|
109
|
-
/**
|
|
110
|
-
* Open shape so future tool-execution errors can lift into the same union
|
|
111
|
-
* without breaking consumers. Connector errors populate `provider`; other
|
|
112
|
-
* errors carry a `message`.
|
|
113
|
-
*/
|
|
114
56
|
interface ToolErrorInfo {
|
|
115
57
|
code: string;
|
|
116
58
|
provider?: string;
|
|
@@ -124,152 +66,47 @@ interface ToolError {
|
|
|
124
66
|
error: ToolErrorInfo;
|
|
125
67
|
}
|
|
126
68
|
|
|
127
|
-
/**
|
|
128
|
-
* Error subclasses thrown by `@anuma/agent-runtime`.
|
|
129
|
-
*
|
|
130
|
-
* - {@link AuthError} comes out of `extractGrantContext` when the bearer is
|
|
131
|
-
* missing, malformed, expired, or already revoked.
|
|
132
|
-
*/
|
|
133
|
-
/** Discriminant for {@link AuthError}. */
|
|
134
69
|
type AuthErrorSubtype = "missing_bearer" | "invalid_bearer" | "expired" | "revoked";
|
|
135
70
|
declare class AuthError extends Error {
|
|
136
71
|
readonly subtype: AuthErrorSubtype;
|
|
137
72
|
constructor(subtype: AuthErrorSubtype, message?: string);
|
|
138
73
|
}
|
|
139
74
|
|
|
140
|
-
/**
|
|
141
|
-
* Pull the bearer off an incoming request, validate it against the portal,
|
|
142
|
-
* and return the parsed grant.
|
|
143
|
-
*
|
|
144
|
-
* In v1 the portal validates by exposing `GET /api/v1/me`, which returns
|
|
145
|
-
* `{ user_address, client_id, scopes }`. A later portal version may switch
|
|
146
|
-
* to issuing signed JWTs and let `extractGrantContext` do local decode —
|
|
147
|
-
* the consumer signature stays the same.
|
|
148
|
-
*/
|
|
149
|
-
|
|
150
75
|
type ExtractGrantContextOpts = Pick<PortalClientOpts, "baseUrl" | "fetchImpl" | "timeoutMs">;
|
|
151
76
|
declare function extractGrantContext(req: IncomingRequest, opts?: ExtractGrantContextOpts): Promise<GrantContext>;
|
|
152
77
|
|
|
153
|
-
/**
|
|
154
|
-
* Typed HTTP client over the portal API.
|
|
155
|
-
*
|
|
156
|
-
* Retries on 5xx / network errors with exponential backoff + jitter
|
|
157
|
-
* (default 3 attempts, base 100ms). Never retries 4xx — those become
|
|
158
|
-
* `MintResult.ok=false` (for mint) or thrown errors (for the bookkeeping
|
|
159
|
-
* endpoints `listConnectors` / `createConnectTicket`).
|
|
160
|
-
*
|
|
161
|
-
* Surface is duck-typed against `PortalClient` so test stubs can satisfy
|
|
162
|
-
* the same contract.
|
|
163
|
-
*/
|
|
164
|
-
|
|
165
78
|
declare function createPortalClient(bearer: string, opts?: PortalClientOpts): PortalClient;
|
|
166
79
|
|
|
167
|
-
/**
|
|
168
|
-
* Convenience wrapper that re-exports the SDK's
|
|
169
|
-
* `createConnectorTokenGetter` with the same per-instance cache semantics.
|
|
170
|
-
*
|
|
171
|
-
* The wrapper exists so consumers importing only `@anuma/agent-runtime`
|
|
172
|
-
* get the helper as part of a single import surface, without also
|
|
173
|
-
* importing `@anuma/sdk/tools` directly. The behavior is identical.
|
|
174
|
-
*/
|
|
175
|
-
|
|
176
80
|
declare function createConnectorTokenGetter(client: PortalClient, provider: string, opts?: ConnectorTokenGetterOpts): () => Promise<string | null>;
|
|
177
81
|
|
|
178
|
-
/**
|
|
179
|
-
* `runAgentRequest` — the single function a server-side agent host calls
|
|
180
|
-
* per inbound request.
|
|
181
|
-
*
|
|
182
|
-
* Wires the four pieces together:
|
|
183
|
-
* extractGrantContext → createPortalClient → toolFactories → runToolLoop
|
|
184
|
-
*
|
|
185
|
-
* After the loop returns, walks the auto-executed tool results, lifts any
|
|
186
|
-
* payload carrying the canonical `__anuma_connector_error_v1` marker into
|
|
187
|
-
* `AgentResponse.toolErrors`. The marker shape is the load-bearing contract
|
|
188
|
-
* — every connector tool factory uses `buildConnectorErrorResult` to emit
|
|
189
|
-
* it, and the parser keys solely on that marker so it can't false-positive
|
|
190
|
-
* on tools that legitimately return JSON.
|
|
191
|
-
*/
|
|
192
|
-
|
|
193
|
-
/** Minimal slice of `AgentConfig` this runtime depends on. */
|
|
194
82
|
interface AgentConfigLike {
|
|
195
|
-
/** Model selection — at least `default` must be present. */
|
|
196
83
|
model: {
|
|
197
84
|
default: string;
|
|
198
85
|
};
|
|
199
|
-
/** System prompt threaded into the loop. */
|
|
200
86
|
prompt: string;
|
|
201
87
|
}
|
|
202
88
|
interface AgentRequestOpts {
|
|
203
|
-
/** Inbound request — only `headers.authorization` is read. */
|
|
204
89
|
request: IncomingRequest;
|
|
205
|
-
/** Agent configuration (haven, sentinel, …). */
|
|
206
90
|
agent: AgentConfigLike;
|
|
207
|
-
/** Conversation history including the user turn. */
|
|
208
91
|
messages: LlmapiMessage[];
|
|
209
|
-
/** Tool factories that receive the portal client and return `ToolConfig[]`. */
|
|
210
92
|
toolFactories?: Array<(portalClient: PortalClient) => ToolConfig[]>;
|
|
211
|
-
/** Override portal client opts (test injection). */
|
|
212
93
|
portalClientOpts?: PortalClientOpts;
|
|
213
|
-
/**
|
|
214
|
-
* Override the streaming transport runToolLoop uses to talk to the
|
|
215
|
-
* portal's chat completion API. Production code never sets this — it's
|
|
216
|
-
* the injection point e2e tests use to stub LLM behavior without a real
|
|
217
|
-
* portal in the loop. Forwarded verbatim to runToolLoop's
|
|
218
|
-
* `transport` option.
|
|
219
|
-
*/
|
|
220
94
|
transport?: StreamingTransport;
|
|
221
|
-
/**
|
|
222
|
-
* Optional portal base URL forwarded to runToolLoop for chat completions.
|
|
223
|
-
* Defaults to runToolLoop's own default. Setting this without a stub
|
|
224
|
-
* `transport` will hit the real portal.
|
|
225
|
-
*/
|
|
226
95
|
portalBaseUrl?: string;
|
|
227
|
-
/**
|
|
228
|
-
* Optional override for the LLM API strategy ("responses" | "completions" | "auto").
|
|
229
|
-
* Production callers don't set this — the default ("auto") picks the right
|
|
230
|
-
* endpoint for the model. Tests use "completions" with the stub transport
|
|
231
|
-
* to feed OpenAI-style streaming chunks.
|
|
232
|
-
*/
|
|
233
96
|
apiType?: ApiType;
|
|
234
97
|
}
|
|
235
|
-
/** Minimal usage summary lifted off the LLM response. */
|
|
236
98
|
interface UsageSummary {
|
|
237
99
|
inputTokens?: number;
|
|
238
100
|
outputTokens?: number;
|
|
239
101
|
totalTokens?: number;
|
|
240
102
|
}
|
|
241
103
|
interface AgentResponse {
|
|
242
|
-
/**
|
|
243
|
-
* Conversation messages after the loop completes: the input messages,
|
|
244
|
-
* followed by tool-result messages for each auto-executed tool, followed
|
|
245
|
-
* by the final assistant message. Synthesized — `runToolLoop` doesn't
|
|
246
|
-
* expose the full message history directly.
|
|
247
|
-
*/
|
|
248
104
|
messages: LlmapiMessage[];
|
|
249
|
-
/** Structured tool errors lifted from the post-loop parser. */
|
|
250
105
|
toolErrors: ToolError[];
|
|
251
|
-
/** Token usage summary if the response carried one. */
|
|
252
106
|
usage?: UsageSummary;
|
|
253
|
-
/** Grant context, surfaced for logging / multi-tenant context propagation. */
|
|
254
107
|
grant: GrantContext;
|
|
255
108
|
}
|
|
256
|
-
/**
|
|
257
|
-
* Walk the loop's tool results, lift entries that carry the
|
|
258
|
-
* `__anuma_connector_error_v1` marker into structured `ToolError`s.
|
|
259
|
-
*
|
|
260
|
-
* Each `AutoExecutedToolResult.result` is what the executor returned.
|
|
261
|
-
* Connector tool factories return the JSON string produced by
|
|
262
|
-
* `buildConnectorErrorResult`, so we JSON.parse strings and inspect for
|
|
263
|
-
* the marker. Non-string results (objects, arrays, errors) skip the
|
|
264
|
-
* parser entirely — they can't be connector errors.
|
|
265
|
-
*/
|
|
266
109
|
declare function extractConnectorToolErrors(toolResults: AutoExecutedToolResult[] | undefined): ToolError[];
|
|
267
|
-
/**
|
|
268
|
-
* Default `requestAccess` passed to connector tool factories from inside
|
|
269
|
-
* `runAgentRequest`. Server agents cannot drive interactive OAuth — they
|
|
270
|
-
* have no surface to bounce the user through. The factory falls back to
|
|
271
|
-
* emitting the canonical connector error JSON when this throws.
|
|
272
|
-
*/
|
|
273
110
|
declare function denyInteractive(): Promise<string | null>;
|
|
274
111
|
declare function runAgentRequest(opts: AgentRequestOpts): Promise<AgentResponse>;
|
|
275
112
|
|
package/dist/index.mjs
CHANGED
|
@@ -348,10 +348,6 @@ async function runAgentRequest(opts) {
|
|
|
348
348
|
model: opts.agent.model.default,
|
|
349
349
|
token: grant.bearer,
|
|
350
350
|
tools,
|
|
351
|
-
// X-Anuma-Surface drives portal auth/grant keying (OAuth client_id + first-party
|
|
352
|
-
// grant surface) — keep it. X-Anuma-Feature is the provenance header the portal
|
|
353
|
-
// records into requests.feature (#1353); without it, agent-runtime LLM traffic
|
|
354
|
-
// lands feature=null and can't be told apart from chat/background in prod.
|
|
355
351
|
headers: { "X-Anuma-Surface": "agent", "X-Anuma-Feature": "agent" },
|
|
356
352
|
...opts.portalBaseUrl ? { baseUrl: opts.portalBaseUrl } : void 0,
|
|
357
353
|
...opts.transport ? { transport: opts.transport } : void 0,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@anuma/agent-runtime",
|
|
3
|
-
"version": "6.33.
|
|
3
|
+
"version": "6.33.2",
|
|
4
4
|
"description": "Server-side runtime contract for Anuma agents — extractGrantContext, PortalClient, runAgentRequest.",
|
|
5
5
|
"main": "./dist/index.cjs",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
@@ -30,13 +30,13 @@
|
|
|
30
30
|
"access": "public"
|
|
31
31
|
},
|
|
32
32
|
"peerDependencies": {
|
|
33
|
-
"@anuma/sdk": "6.33.
|
|
33
|
+
"@anuma/sdk": "6.33.2"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
36
|
"tsup": "^8.5.1",
|
|
37
37
|
"typescript": "^5.9.3",
|
|
38
38
|
"vitest": "^4.1.11",
|
|
39
|
-
"@anuma/sdk": "6.33.
|
|
39
|
+
"@anuma/sdk": "6.33.2"
|
|
40
40
|
},
|
|
41
41
|
"scripts": {
|
|
42
42
|
"build": "tsup",
|