agentfootprint 9.114.2 → 9.115.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/AGENTS.md +1 -1
- package/CAPABILITIES.md +3 -0
- package/ai-instructions/claude-code/SKILL.md +1 -1
- package/dist/adapters/hosting/agentCoreA2A.js +5 -0
- package/dist/adapters/hosting/agentCoreA2A.js.map +1 -1
- package/dist/adapters/hosting/agentcore.js +5 -0
- package/dist/adapters/hosting/agentcore.js.map +1 -1
- package/dist/adapters/hosting/foundryResponses.js +5 -0
- package/dist/adapters/hosting/foundryResponses.js.map +1 -1
- package/dist/adapters/observability/agentcore.js +18 -5
- package/dist/adapters/observability/agentcore.js.map +1 -1
- package/dist/adapters/observability/audit.js +17 -4
- package/dist/adapters/observability/audit.js.map +1 -1
- package/dist/adapters/observability/otel.js +890 -33
- package/dist/adapters/observability/otel.js.map +1 -1
- package/dist/artifacts/capability.js +9 -3
- package/dist/artifacts/capability.js.map +1 -1
- package/dist/bridge/eventMeta.js +40 -1
- package/dist/bridge/eventMeta.js.map +1 -1
- package/dist/core/Agent.js +40 -6
- package/dist/core/Agent.js.map +1 -1
- package/dist/core/RunnerBase.js +32 -1
- package/dist/core/RunnerBase.js.map +1 -1
- package/dist/core/agent/AgentBuilder.js +13 -1
- package/dist/core/agent/AgentBuilder.js.map +1 -1
- package/dist/core/agent/stages/toolCalls.js +64 -7
- package/dist/core/agent/stages/toolCalls.js.map +1 -1
- package/dist/core/flowchartAsTool.js +8 -2
- package/dist/core/flowchartAsTool.js.map +1 -1
- package/dist/core/runbook/runbookAsTool.js +7 -2
- package/dist/core/runbook/runbookAsTool.js.map +1 -1
- package/dist/core/toolShownArgs.js +55 -0
- package/dist/core/toolShownArgs.js.map +1 -0
- package/dist/esm/adapters/hosting/agentCoreA2A.d.ts +14 -1
- package/dist/esm/adapters/hosting/agentCoreA2A.js +5 -0
- package/dist/esm/adapters/hosting/agentCoreA2A.js.map +1 -1
- package/dist/esm/adapters/hosting/agentcore.d.ts +18 -2
- package/dist/esm/adapters/hosting/agentcore.js +5 -0
- package/dist/esm/adapters/hosting/agentcore.js.map +1 -1
- package/dist/esm/adapters/hosting/foundryResponses.d.ts +15 -1
- package/dist/esm/adapters/hosting/foundryResponses.js +5 -0
- package/dist/esm/adapters/hosting/foundryResponses.js.map +1 -1
- package/dist/esm/adapters/observability/agentcore.d.ts +17 -5
- package/dist/esm/adapters/observability/agentcore.js +18 -5
- package/dist/esm/adapters/observability/agentcore.js.map +1 -1
- package/dist/esm/adapters/observability/audit.d.ts +6 -2
- package/dist/esm/adapters/observability/audit.js +17 -4
- package/dist/esm/adapters/observability/audit.js.map +1 -1
- package/dist/esm/adapters/observability/otel.d.ts +240 -11
- package/dist/esm/adapters/observability/otel.js +890 -33
- package/dist/esm/adapters/observability/otel.js.map +1 -1
- package/dist/esm/artifacts/capability.d.ts +3 -1
- package/dist/esm/artifacts/capability.js +9 -3
- package/dist/esm/artifacts/capability.js.map +1 -1
- package/dist/esm/bridge/eventMeta.d.ts +32 -0
- package/dist/esm/bridge/eventMeta.js +38 -0
- package/dist/esm/bridge/eventMeta.js.map +1 -1
- package/dist/esm/core/Agent.d.ts +18 -5
- package/dist/esm/core/Agent.js +42 -8
- package/dist/esm/core/Agent.js.map +1 -1
- package/dist/esm/core/RunnerBase.d.ts +20 -0
- package/dist/esm/core/RunnerBase.js +32 -1
- package/dist/esm/core/RunnerBase.js.map +1 -1
- package/dist/esm/core/agent/AgentBuilder.js +13 -1
- package/dist/esm/core/agent/AgentBuilder.js.map +1 -1
- package/dist/esm/core/agent/stages/toolCalls.d.ts +11 -0
- package/dist/esm/core/agent/stages/toolCalls.js +64 -7
- package/dist/esm/core/agent/stages/toolCalls.js.map +1 -1
- package/dist/esm/core/flowchartAsTool.js +8 -2
- package/dist/esm/core/flowchartAsTool.js.map +1 -1
- package/dist/esm/core/runbook/runbookAsTool.js +7 -2
- package/dist/esm/core/runbook/runbookAsTool.js.map +1 -1
- package/dist/esm/core/toolShownArgs.d.ts +62 -0
- package/dist/esm/core/toolShownArgs.js +49 -0
- package/dist/esm/core/toolShownArgs.js.map +1 -0
- package/dist/esm/events/payloads.d.ts +122 -6
- package/dist/esm/events/registry.d.ts +3 -1
- package/dist/esm/events/registry.js +2 -0
- package/dist/esm/events/registry.js.map +1 -1
- package/dist/esm/events/types.d.ts +7 -0
- package/dist/esm/hosting/artifactWire.d.ts +10 -2
- package/dist/esm/hosting/artifactWire.js +20 -2
- package/dist/esm/hosting/artifactWire.js.map +1 -1
- package/dist/esm/hosting/doorGuard.d.ts +280 -0
- package/dist/esm/hosting/doorGuard.js +499 -0
- package/dist/esm/hosting/doorGuard.js.map +1 -0
- package/dist/esm/hosting/errors.d.ts +113 -0
- package/dist/esm/hosting/errors.js +177 -0
- package/dist/esm/hosting/errors.js.map +1 -1
- package/dist/esm/hosting/httpHost.d.ts +32 -3
- package/dist/esm/hosting/httpHost.js +218 -4
- package/dist/esm/hosting/httpHost.js.map +1 -1
- package/dist/esm/hosting/index.d.ts +7 -5
- package/dist/esm/hosting/index.js +10 -3
- package/dist/esm/hosting/index.js.map +1 -1
- package/dist/esm/hosting/ingressRecord.d.ts +64 -10
- package/dist/esm/hosting/ingressRecord.js +65 -6
- package/dist/esm/hosting/ingressRecord.js.map +1 -1
- package/dist/esm/hosting/nodeHost.d.ts +32 -2
- package/dist/esm/hosting/nodeHost.js +10 -0
- package/dist/esm/hosting/nodeHost.js.map +1 -1
- package/dist/esm/hosting/standingAgent.js +362 -51
- package/dist/esm/hosting/standingAgent.js.map +1 -1
- package/dist/esm/hosting/turnArtifacts.d.ts +93 -0
- package/dist/esm/hosting/turnArtifacts.js +126 -0
- package/dist/esm/hosting/turnArtifacts.js.map +1 -0
- package/dist/esm/hosting/types.d.ts +196 -3
- package/dist/esm/hosting/types.js +10 -0
- package/dist/esm/hosting/types.js.map +1 -1
- package/dist/esm/hosting/webSocketConversation.d.ts +15 -1
- package/dist/esm/hosting/webSocketConversation.js +54 -2
- package/dist/esm/hosting/webSocketConversation.js.map +1 -1
- package/dist/esm/integrity/disposition/ledger.d.ts +8 -0
- package/dist/esm/integrity/disposition/ledger.js +0 -0
- package/dist/esm/integrity/disposition/ledger.js.map +1 -1
- package/dist/esm/lib/mcp/mcpServe.js +39 -2
- package/dist/esm/lib/mcp/mcpServe.js.map +1 -1
- package/dist/esm/lib/mcp/types.d.ts +30 -0
- package/dist/esm/recorders/observability/commentary/artifactPhrases.d.ts +4 -0
- package/dist/esm/recorders/observability/commentary/artifactPhrases.js +9 -0
- package/dist/esm/recorders/observability/commentary/artifactPhrases.js.map +1 -1
- package/dist/esm/recorders/observability/commentary/commentaryTemplates.js +30 -3
- package/dist/esm/recorders/observability/commentary/commentaryTemplates.js.map +1 -1
- package/dist/esm/recorders/observability/recordRun.d.ts +12 -0
- package/dist/esm/recorders/observability/recordRun.js +17 -1
- package/dist/esm/recorders/observability/recordRun.js.map +1 -1
- package/dist/esm/strategies/attach.js +87 -1
- package/dist/esm/strategies/attach.js.map +1 -1
- package/dist/events/registry.js +2 -0
- package/dist/events/registry.js.map +1 -1
- package/dist/hosting/artifactWire.js +21 -3
- package/dist/hosting/artifactWire.js.map +1 -1
- package/dist/hosting/doorGuard.js +509 -0
- package/dist/hosting/doorGuard.js.map +1 -0
- package/dist/hosting/errors.js +183 -1
- package/dist/hosting/errors.js.map +1 -1
- package/dist/hosting/httpHost.js +218 -4
- package/dist/hosting/httpHost.js.map +1 -1
- package/dist/hosting/index.js +19 -2
- package/dist/hosting/index.js.map +1 -1
- package/dist/hosting/ingressRecord.js +66 -6
- package/dist/hosting/ingressRecord.js.map +1 -1
- package/dist/hosting/nodeHost.js +11 -1
- package/dist/hosting/nodeHost.js.map +1 -1
- package/dist/hosting/standingAgent.js +359 -48
- package/dist/hosting/standingAgent.js.map +1 -1
- package/dist/hosting/turnArtifacts.js +130 -0
- package/dist/hosting/turnArtifacts.js.map +1 -0
- package/dist/hosting/types.js +11 -1
- package/dist/hosting/types.js.map +1 -1
- package/dist/hosting/webSocketConversation.js +54 -2
- package/dist/hosting/webSocketConversation.js.map +1 -1
- package/dist/integrity/disposition/ledger.js +0 -0
- package/dist/integrity/disposition/ledger.js.map +1 -1
- package/dist/lib/mcp/mcpServe.js +39 -2
- package/dist/lib/mcp/mcpServe.js.map +1 -1
- package/dist/recorders/observability/commentary/artifactPhrases.js +10 -1
- package/dist/recorders/observability/commentary/artifactPhrases.js.map +1 -1
- package/dist/recorders/observability/commentary/commentaryTemplates.js +29 -2
- package/dist/recorders/observability/commentary/commentaryTemplates.js.map +1 -1
- package/dist/recorders/observability/recordRun.js +20 -3
- package/dist/recorders/observability/recordRun.js.map +1 -1
- package/dist/strategies/attach.js +87 -1
- package/dist/strategies/attach.js.map +1 -1
- package/dist/types/adapters/hosting/agentCoreA2A.d.ts +14 -1
- package/dist/types/adapters/hosting/agentCoreA2A.d.ts.map +1 -1
- package/dist/types/adapters/hosting/agentcore.d.ts +18 -2
- package/dist/types/adapters/hosting/agentcore.d.ts.map +1 -1
- package/dist/types/adapters/hosting/foundryResponses.d.ts +15 -1
- package/dist/types/adapters/hosting/foundryResponses.d.ts.map +1 -1
- package/dist/types/adapters/observability/agentcore.d.ts +17 -5
- package/dist/types/adapters/observability/agentcore.d.ts.map +1 -1
- package/dist/types/adapters/observability/audit.d.ts +6 -2
- package/dist/types/adapters/observability/audit.d.ts.map +1 -1
- package/dist/types/adapters/observability/otel.d.ts +240 -11
- package/dist/types/adapters/observability/otel.d.ts.map +1 -1
- package/dist/types/artifacts/capability.d.ts +3 -1
- package/dist/types/artifacts/capability.d.ts.map +1 -1
- package/dist/types/bridge/eventMeta.d.ts +32 -0
- package/dist/types/bridge/eventMeta.d.ts.map +1 -1
- package/dist/types/core/Agent.d.ts +18 -5
- package/dist/types/core/Agent.d.ts.map +1 -1
- package/dist/types/core/RunnerBase.d.ts +20 -0
- package/dist/types/core/RunnerBase.d.ts.map +1 -1
- package/dist/types/core/agent/AgentBuilder.d.ts.map +1 -1
- package/dist/types/core/agent/stages/toolCalls.d.ts +11 -0
- package/dist/types/core/agent/stages/toolCalls.d.ts.map +1 -1
- package/dist/types/core/flowchartAsTool.d.ts.map +1 -1
- package/dist/types/core/runbook/runbookAsTool.d.ts.map +1 -1
- package/dist/types/core/toolShownArgs.d.ts +63 -0
- package/dist/types/core/toolShownArgs.d.ts.map +1 -0
- package/dist/types/events/payloads.d.ts +122 -6
- package/dist/types/events/payloads.d.ts.map +1 -1
- package/dist/types/events/registry.d.ts +3 -1
- package/dist/types/events/registry.d.ts.map +1 -1
- package/dist/types/events/types.d.ts +7 -0
- package/dist/types/events/types.d.ts.map +1 -1
- package/dist/types/hosting/artifactWire.d.ts +10 -2
- package/dist/types/hosting/artifactWire.d.ts.map +1 -1
- package/dist/types/hosting/doorGuard.d.ts +281 -0
- package/dist/types/hosting/doorGuard.d.ts.map +1 -0
- package/dist/types/hosting/errors.d.ts +113 -0
- package/dist/types/hosting/errors.d.ts.map +1 -1
- package/dist/types/hosting/httpHost.d.ts +32 -3
- package/dist/types/hosting/httpHost.d.ts.map +1 -1
- package/dist/types/hosting/index.d.ts +7 -5
- package/dist/types/hosting/index.d.ts.map +1 -1
- package/dist/types/hosting/ingressRecord.d.ts +64 -10
- package/dist/types/hosting/ingressRecord.d.ts.map +1 -1
- package/dist/types/hosting/nodeHost.d.ts +32 -2
- package/dist/types/hosting/nodeHost.d.ts.map +1 -1
- package/dist/types/hosting/standingAgent.d.ts.map +1 -1
- package/dist/types/hosting/turnArtifacts.d.ts +94 -0
- package/dist/types/hosting/turnArtifacts.d.ts.map +1 -0
- package/dist/types/hosting/types.d.ts +196 -3
- package/dist/types/hosting/types.d.ts.map +1 -1
- package/dist/types/hosting/webSocketConversation.d.ts +15 -1
- package/dist/types/hosting/webSocketConversation.d.ts.map +1 -1
- package/dist/types/integrity/disposition/ledger.d.ts +8 -0
- package/dist/types/integrity/disposition/ledger.d.ts.map +1 -1
- package/dist/types/lib/mcp/mcpServe.d.ts.map +1 -1
- package/dist/types/lib/mcp/types.d.ts +30 -0
- package/dist/types/lib/mcp/types.d.ts.map +1 -1
- package/dist/types/recorders/observability/commentary/artifactPhrases.d.ts +4 -0
- package/dist/types/recorders/observability/commentary/artifactPhrases.d.ts.map +1 -1
- package/dist/types/recorders/observability/commentary/commentaryTemplates.d.ts.map +1 -1
- package/dist/types/recorders/observability/recordRun.d.ts +12 -0
- package/dist/types/recorders/observability/recordRun.d.ts.map +1 -1
- package/dist/types/strategies/attach.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -55,12 +55,22 @@
|
|
|
55
55
|
* concurrent-run refusal, an artifact ref that did not resolve;
|
|
56
56
|
* - and a request that was SERVED.
|
|
57
57
|
*
|
|
58
|
+
* The HOST's own decisions land here too, though no handler ever saw them: a
|
|
59
|
+
* request its door guard turned away (a content type any page can send, a
|
|
60
|
+
* foreign Origin, a Host it was not configured for — `'cross-site-refused'`)
|
|
61
|
+
* and a session id over the bound (`'refused'`), at the request door and the
|
|
62
|
+
* conversation door alike. They arrive through the host's `onRefusal`, which
|
|
63
|
+
* the composer subscribes to whenever a sink is set, and they carry the same
|
|
64
|
+
* classes and nothing more — door `'request'` or `'conversation'`, because a
|
|
65
|
+
* forged request is refused before its body says which of the three doors it
|
|
66
|
+
* wanted.
|
|
67
|
+
*
|
|
58
68
|
* What it does not carry, stated rather than implied: a body the TRANSPORT
|
|
59
|
-
* refused
|
|
60
|
-
* host's wire grammar does not speak (`InvalidWireOpError`, answered
|
|
61
|
-
* `httpHost` inside its own request reader). That is a
|
|
62
|
-
* than a decision about a caller, and the composer does not claim it.
|
|
63
|
-
* access log has it.
|
|
69
|
+
* refused as MALFORMED — unparseable JSON, a body over `maxBodyBytes`, or an
|
|
70
|
+
* `op` this host's wire grammar does not speak (`InvalidWireOpError`, answered
|
|
71
|
+
* 400 by `httpHost` inside its own request reader). That is a broken request
|
|
72
|
+
* rather than a decision about a caller, and the composer does not claim it.
|
|
73
|
+
* Your HTTP access log has it.
|
|
64
74
|
*
|
|
65
75
|
* Pattern: Observer at a composition boundary. Zero-cost when unset — with no
|
|
66
76
|
* sink configured nothing is built, nothing is wrapped, and the reply object the
|
|
@@ -68,9 +78,22 @@
|
|
|
68
78
|
*/
|
|
69
79
|
import { type VerifiedIdentity } from './identityVerification.js';
|
|
70
80
|
import { type IdentityFailureClass } from './errors.js';
|
|
71
|
-
import type {
|
|
72
|
-
|
|
73
|
-
|
|
81
|
+
import type { ArtifactHandOverFailedPayload } from '../events/payloads.js';
|
|
82
|
+
import type { HostRefusal, HostReply, HostRequest } from './types.js';
|
|
83
|
+
/**
|
|
84
|
+
* Which door this request knocked at.
|
|
85
|
+
*
|
|
86
|
+
* - `'turn'`, `'session-op'`, `'artifact'` — the composer's three doors, for
|
|
87
|
+
* every request the host handed on.
|
|
88
|
+
* - `'request'` — the host's one-exchange door, for a request the HOST refused
|
|
89
|
+
* before the composer saw it (the door guard; the session-id bound). Which
|
|
90
|
+
* of the three it was headed for is deliberately not recorded: a forged
|
|
91
|
+
* request is refused on its headers, and its body is never parsed.
|
|
92
|
+
* - `'conversation'` — a conversation upgrade the host refused before the 101.
|
|
93
|
+
* Recorded here because it is the same host's door and the same census,
|
|
94
|
+
* though the composer itself never serves conversations.
|
|
95
|
+
*/
|
|
96
|
+
export type IngressDoor = 'turn' | 'session-op' | 'artifact' | 'request' | 'conversation';
|
|
74
97
|
/**
|
|
75
98
|
* How the door answered — coarse on purpose, because this is the field a
|
|
76
99
|
* dashboard groups by. `errorCode` carries the precision beside it.
|
|
@@ -95,14 +118,21 @@ export type IngressDoor = 'turn' | 'session-op' | 'artifact';
|
|
|
95
118
|
* - `'admission-refused'` — 429. A policy said no before any work started.
|
|
96
119
|
* - `'session-refused'` — the one indistinguishable not-found: a session that
|
|
97
120
|
* does not exist, belongs to somebody else, or names no owner.
|
|
121
|
+
* - `'cross-site-refused'` — the host's door guard turned it away before any
|
|
122
|
+
* handler saw it: a content type a page on any site can send (415), a
|
|
123
|
+
* browser Origin this door does not allow (403), a Host it was not
|
|
124
|
+
* configured for (421). `errorCode` says which. Not proof of an attack — a
|
|
125
|
+
* script that forgot `content-type: application/json` lands here too — but
|
|
126
|
+
* the shape every forged request has, counted where it can be seen.
|
|
98
127
|
* - `'refused'` — every other refusal the door made by name (a session op with
|
|
99
128
|
* no verifier configured, a store with no owner index, a concurrent run, an
|
|
100
|
-
* artifact ref that did not resolve, a pause the wire could not carry
|
|
129
|
+
* artifact ref that did not resolve, a pause the wire could not carry, a
|
|
130
|
+
* session id over the ceiling).
|
|
101
131
|
* - `'failed'` — the request ended in an error that is not one of the door's
|
|
102
132
|
* own refusals. Usually the run, the store or the provider — which is why
|
|
103
133
|
* an admitted request that then broke lands HERE and not in `'served'`.
|
|
104
134
|
*/
|
|
105
|
-
export type IngressOutcome = 'served' | 'identity-refused' | 'verifier-unavailable' | 'admission-refused' | 'session-refused' | 'refused' | 'failed';
|
|
135
|
+
export type IngressOutcome = 'served' | 'identity-refused' | 'verifier-unavailable' | 'admission-refused' | 'session-refused' | 'cross-site-refused' | 'refused' | 'failed';
|
|
106
136
|
/** What an admission policy answered, when one was consulted. */
|
|
107
137
|
export type IngressAdmissionVerdict = 'allow' | 'queue' | 'refuse';
|
|
108
138
|
/**
|
|
@@ -138,6 +168,16 @@ export interface IngressRecord {
|
|
|
138
168
|
readonly bearerPresent: boolean;
|
|
139
169
|
/** What the admission policy answered, when one was consulted. */
|
|
140
170
|
readonly admission?: IngressAdmissionVerdict;
|
|
171
|
+
/**
|
|
172
|
+
* This turn's artifact hand-over (`HostReply.turnArtifacts`) did not go
|
|
173
|
+
* cleanly — the FIRST failure of it: the host's hook threw, an operation it
|
|
174
|
+
* started failed, it outran `turnArtifactsTimeoutMs`, or the caller hung up
|
|
175
|
+
* first. The reply was delivered regardless — the hand-over never decides the
|
|
176
|
+
* terminal, so `outcome` still says what the caller got. The per-request
|
|
177
|
+
* census of what `agentfootprint.artifacts.hand_over_failed` reports on the
|
|
178
|
+
* serving agent's stream, in the same shape: class only, never the message.
|
|
179
|
+
*/
|
|
180
|
+
readonly turnArtifactsFailure?: ArtifactHandOverFailedPayload;
|
|
141
181
|
}
|
|
142
182
|
/**
|
|
143
183
|
* Where records go — {@link StandingAgentBaseOptions.onIngressDecision}.
|
|
@@ -166,9 +206,23 @@ export interface IngressNote {
|
|
|
166
206
|
identified(verified: VerifiedIdentity | undefined): void;
|
|
167
207
|
/** An admission policy answered. */
|
|
168
208
|
admitted(verdict: IngressAdmissionVerdict): void;
|
|
209
|
+
/** The turn's artifact hand-over failed — the first failure is recorded. */
|
|
210
|
+
turnArtifactsFailed(failure: ArtifactHandOverFailedPayload): void;
|
|
169
211
|
/** File the record for a request that left without any terminal at all. */
|
|
170
212
|
settle(): void;
|
|
171
213
|
}
|
|
214
|
+
/**
|
|
215
|
+
* File the record for a request the HOST refused before the composer saw it —
|
|
216
|
+
* what `standingAgent` hands to the host's `onRefusal` when a sink is set.
|
|
217
|
+
*
|
|
218
|
+
* Built from the refusal's class and the fact of a credential, exactly as a
|
|
219
|
+
* composer refusal is: no message, no header, no session id (a session id the
|
|
220
|
+
* bound refused is the one thing this record must never carry), no user —
|
|
221
|
+
* nothing was verified, because nothing got that far.
|
|
222
|
+
*
|
|
223
|
+
* @internal — the option is public, this bookkeeping is not.
|
|
224
|
+
*/
|
|
225
|
+
export declare function recordHostRefusal(refusal: HostRefusal, sink: IngressSink): void;
|
|
172
226
|
/**
|
|
173
227
|
* Begin one request's ingress record.
|
|
174
228
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ingressRecord.d.ts","sourceRoot":"","sources":["../../../src/hosting/ingressRecord.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"ingressRecord.d.ts","sourceRoot":"","sources":["../../../src/hosting/ingressRecord.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6EG;AAEH,OAAO,EAAe,KAAK,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAC/E,OAAO,EAQL,KAAK,oBAAoB,EAC1B,MAAM,aAAa,CAAC;AAGrB,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,uBAAuB,CAAC;AAC3E,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,WAAW,EAAiB,MAAM,YAAY,CAAC;AAErF;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,YAAY,GAAG,UAAU,GAAG,SAAS,GAAG,cAAc,CAAC;AAE1F;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,MAAM,MAAM,cAAc,GACtB,QAAQ,GACR,kBAAkB,GAClB,sBAAsB,GACtB,mBAAmB,GACnB,iBAAiB,GACjB,oBAAoB,GACpB,SAAS,GACT,QAAQ,CAAC;AAEb,iEAAiE;AACjE,MAAM,MAAM,uBAAuB,GAAG,OAAO,GAAG,OAAO,GAAG,QAAQ,CAAC;AAEnE;;;;;GAKG;AACH,MAAM,WAAW,aAAa;IAC5B,oDAAoD;IACpD,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,gCAAgC;IAChC,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC;IACrB,6BAA6B;IAC7B,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAC;IACjC,oFAAoF;IACpF,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,yEAAyE;IACzE,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B;iEAC6D;IAC7D,QAAQ,CAAC,eAAe,CAAC,EAAE,oBAAoB,CAAC;IAChD;yEACqE;IACrE,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAC/B,yEAAyE;IACzE,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,8DAA8D;IAC9D,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,gEAAgE;IAChE,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;IAChC,kEAAkE;IAClE,QAAQ,CAAC,SAAS,CAAC,EAAE,uBAAuB,CAAC;IAC7C;;;;;;;;OAQG;IACH,QAAQ,CAAC,oBAAoB,CAAC,EAAE,6BAA6B,CAAC;CAC/D;AAED;;;;;;;;;GASG;AACH,MAAM,MAAM,WAAW,GAAG,CAAC,MAAM,EAAE,aAAa,KAAK,IAAI,CAAC;AAsD1D;;;;;;;;GAQG;AACH,MAAM,WAAW,WAAW;IAC1B,oEAAoE;IACpE,KAAK,CAAC,KAAK,EAAE,SAAS,GAAG,SAAS,CAAC;IACnC,gFAAgF;IAChF,UAAU,CAAC,QAAQ,EAAE,gBAAgB,GAAG,SAAS,GAAG,IAAI,CAAC;IACzD,oCAAoC;IACpC,QAAQ,CAAC,OAAO,EAAE,uBAAuB,GAAG,IAAI,CAAC;IACjD,4EAA4E;IAC5E,mBAAmB,CAAC,OAAO,EAAE,6BAA6B,GAAG,IAAI,CAAC;IAClE,2EAA2E;IAC3E,MAAM,IAAI,IAAI,CAAC;CAChB;AAuDD;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,WAAW,GAAG,IAAI,CAe/E;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,WAAW,GAAG,WAAW,CAsGjF"}
|
|
@@ -51,10 +51,24 @@
|
|
|
51
51
|
* throws does. `types.ts` knows none of it either way.
|
|
52
52
|
*/
|
|
53
53
|
/// <reference types="node" />
|
|
54
|
+
import type { CrossSiteOptions } from './doorGuard.js';
|
|
54
55
|
import { type HttpHost, type HttpHostHandle, type HttpWire } from './httpHost.js';
|
|
55
56
|
import type { ConversationLimits } from './types.js';
|
|
56
|
-
/**
|
|
57
|
-
|
|
57
|
+
/**
|
|
58
|
+
* Options for {@link nodeHost}.
|
|
59
|
+
*
|
|
60
|
+
* The three cross-site fields — `allowedOrigins`, `allowedHosts`,
|
|
61
|
+
* `requireJsonContentType` — are `httpHost`'s own door guard, on both of this
|
|
62
|
+
* adapter's doors, with the safe defaults: a request that changes something
|
|
63
|
+
* must say it is JSON, a browser may drive the door only from its own host,
|
|
64
|
+
* and with `allowedHosts` unset the host says once at boot that it answers any
|
|
65
|
+
* name. Behind a proxy, list every name the door is reached by — the library
|
|
66
|
+
* never redirects a short name to a canonical one; that is the proxy's job.
|
|
67
|
+
*
|
|
68
|
+
* @example A door on a company network, reached by one name
|
|
69
|
+
* nodeHost({ port: 8080, allowedHosts: ['neo.corp.example'] });
|
|
70
|
+
*/
|
|
71
|
+
export interface NodeHostOptions extends CrossSiteOptions {
|
|
58
72
|
/** Port to bind. Default `8080`. Pass `0` for an ephemeral port. Refused alongside `server`. */
|
|
59
73
|
readonly port?: number;
|
|
60
74
|
/** Interface to bind. Default `'0.0.0.0'`. Refused alongside `server`. */
|
|
@@ -138,7 +152,23 @@ export interface NodeHostOptions {
|
|
|
138
152
|
* is behind TLS.
|
|
139
153
|
*/
|
|
140
154
|
readonly sessionCookie?: string;
|
|
155
|
+
/**
|
|
156
|
+
* Ceiling on a request body, in bytes. Default {@link DEFAULT_NODE_MAX_BODY_BYTES}
|
|
157
|
+
* (one mebibyte) — the same number the hosted-runtime adapters default to.
|
|
158
|
+
*
|
|
159
|
+
* `httpHost` itself keeps no default (a number chosen there would be
|
|
160
|
+
* inherited by every adapter built on it); this adapter chooses one, because
|
|
161
|
+
* without it a caller with no credentials could make the door buffer and
|
|
162
|
+
* parse a body of any size before a single rule about it — the session-id
|
|
163
|
+
* bound included — could say no. A body over the line is refused with
|
|
164
|
+
* `ERR_REQUEST_TOO_LARGE` (413) at the byte that crossed it. One mebibyte is
|
|
165
|
+
* about a quarter of a million tokens of input, more than any context window
|
|
166
|
+
* serves in one message; raise it if this deployment genuinely carries more.
|
|
167
|
+
*/
|
|
168
|
+
readonly maxBodyBytes?: number;
|
|
141
169
|
}
|
|
170
|
+
/** {@link NodeHostOptions.maxBodyBytes}'s default: one mebibyte. */
|
|
171
|
+
export declare const DEFAULT_NODE_MAX_BODY_BYTES = 1048576;
|
|
142
172
|
/**
|
|
143
173
|
* What {@link nodeHost}'s `serve()` resolves to — a `HostHandle` that also
|
|
144
174
|
* reports the `url` and `port` it actually bound, which is the only way to find
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nodeHost.d.ts","sourceRoot":"","sources":["../../../src/hosting/nodeHost.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmDG;;
|
|
1
|
+
{"version":3,"file":"nodeHost.d.ts","sourceRoot":"","sources":["../../../src/hosting/nodeHost.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmDG;;AAGH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAEvD,OAAO,EAGL,KAAK,QAAQ,EACb,KAAK,cAAc,EACnB,KAAK,QAAQ,EACd,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAErD;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,eAAgB,SAAQ,gBAAgB;IACvD,gGAAgG;IAChG,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,0EAA0E;IAC1E,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,sDAAsD;IACtD,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,6DAA6D;IAC7D,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B;;;;OAIG;IACH,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC;;;;;;;OAOG;IACH,QAAQ,CAAC,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;IACjD;;;;;;;;;;;OAWG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,WAAW,EAAE,MAAM,CAAC;IAC7C;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,CACrB,GAAG,EAAE,OAAO,WAAW,EAAE,eAAe,EACxC,GAAG,EAAE,OAAO,WAAW,EAAE,cAAc,KACpC,IAAI,CAAC;IACV;;;;;;;OAOG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC;;;;;;;;;;;;OAYG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;CAChC;AAED,oEAAoE;AACpE,eAAO,MAAM,2BAA2B,UAAY,CAAC;AAErD;;;;GAIG;AACH,MAAM,MAAM,cAAc,GAAG,cAAc,CAAC;AAE5C,qDAAqD;AACrD,MAAM,MAAM,QAAQ,GAAG,QAAQ,CAAC;AAIhC,kFAAkF;AAClF,eAAO,MAAM,sBAAsB,iBAAiB,CAAC;AAErD,4EAA4E;AAC5E,MAAM,WAAW,eAAe;IAC9B;;;;;;;OAOG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA4BG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;CACjC;AAED;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,OAAO,GAAE,eAAoB,GAAG,QAAQ,CAgFpE;AAED;;;GAGG;AACH,eAAO,MAAM,QAAQ,EAAE,QAAyB,CAAC;AAgCjD;;;;;;;;;;;GAWG;AACH,wBAAgB,QAAQ,CAAC,OAAO,GAAE,eAAoB,GAAG,QAAQ,CAyChE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"standingAgent.d.ts","sourceRoot":"","sources":["../../../src/hosting/standingAgent.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkGG;
|
|
1
|
+
{"version":3,"file":"standingAgent.d.ts","sourceRoot":"","sources":["../../../src/hosting/standingAgent.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkGG;AA4CH,OAAO,KAAK,EAEV,UAAU,EAKV,oBAAoB,EAErB,MAAM,YAAY,CAAC;AAqEpB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,wBAAsB,aAAa,CAAC,EAAE,SAAS,UAAU,EACvD,OAAO,EAAE,oBAAoB,CAAC,EAAE,CAAC,GAChC,OAAO,CAAC,EAAE,CAAC,CA2sCb"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* hosting/turnArtifacts — the artifact hand-over a turn gives its host, and
|
|
3
|
+
* how long it lives.
|
|
4
|
+
*
|
|
5
|
+
* turnArtifacts: async (turn) => {
|
|
6
|
+
* if (turn.bound) story = await turn.artifacts.put({ kind: 'story/turn', mediaType, data });
|
|
7
|
+
* },
|
|
8
|
+
*
|
|
9
|
+
* `standingAgent` opens one per turn (`openTurnArtifacts`), awaits the host's
|
|
10
|
+
* `HostReply.turnArtifacts` hook with it and then `drain()` — both BOUNDED by
|
|
11
|
+
* the composer (`turnArtifactsTimeoutMs`, the request's signal) — and finally
|
|
12
|
+
* `revoke()`s it before the reply's terminal. This module owns that lifetime
|
|
13
|
+
* and the failures it can see; the scope, the bound and the record are the
|
|
14
|
+
* composer's.
|
|
15
|
+
*
|
|
16
|
+
* ── Why the hand-over has a lifetime at all ──────────────────────────────────
|
|
17
|
+
* The scope never widens — the binding closes over one tuple — so a late write
|
|
18
|
+
* can only ever land in the same person's scope. What a late write breaks is
|
|
19
|
+
* the RECORD: the binding's facts are delivered on the serving agent's
|
|
20
|
+
* dispatcher, and by then the agent may be running somebody else's turn (the
|
|
21
|
+
* shared shape), a stopped instance (the pool evicted the lane), or the next
|
|
22
|
+
* turn of the same conversation. So the binding is live only while its turn
|
|
23
|
+
* is — the footprintjs `ScopeFacade · assertLive` law, "a handle held past its
|
|
24
|
+
* stage is refused", applied to the turn.
|
|
25
|
+
*
|
|
26
|
+
* ── Drain, then revoke — and nothing here can crash the process ──────────────
|
|
27
|
+
* `drain()` waits for every operation started through the binding — a `put`
|
|
28
|
+
* the hook never awaited included, and one an earlier operation's
|
|
29
|
+
* continuation starts while it waits. `revoke()` then refuses every later call
|
|
30
|
+
* by name (`TurnArtifactsExpiredError`). Every promise this module hands out
|
|
31
|
+
* is handled the moment it is created — an operation's, and a revoked call's
|
|
32
|
+
* refusal alike — so none of them can become an unhandled rejection that ends
|
|
33
|
+
* the process; a host that awaits one still receives its error. (A promise the
|
|
34
|
+
* HOST derives from one — `put(...).then(f)` — is the host's own.)
|
|
35
|
+
*
|
|
36
|
+
* ── Failures are reported, never swallowed silently ──────────────────────────
|
|
37
|
+
* Every failed operation (`'operation'`, with its verb and error class) and
|
|
38
|
+
* every refused late call (`'expired'`) goes to `onFailure`, which the
|
|
39
|
+
* composer puts on the serving agent's stream. `reported(err)` lets the
|
|
40
|
+
* composer tell a hook that merely re-threw an operation's own failure from a
|
|
41
|
+
* hook that failed for a reason of its own — one failure, counted once.
|
|
42
|
+
*
|
|
43
|
+
* Pattern: Proxy (a lifetime-bounded view over the `ctx.artifacts` capability).
|
|
44
|
+
*/
|
|
45
|
+
import { type ArtifactEventSink } from '../artifacts/capability.js';
|
|
46
|
+
import type { ArtifactScope, ArtifactStore } from '../artifacts/types.js';
|
|
47
|
+
import { TurnArtifactsExpiredError } from './errors.js';
|
|
48
|
+
import type { TurnArtifacts } from './types.js';
|
|
49
|
+
/** The five verbs of the capability, by name — what a refusal names. */
|
|
50
|
+
type TurnVerb = TurnArtifactsExpiredError['op'];
|
|
51
|
+
/** One failure of the hand-over this module can see. */
|
|
52
|
+
export type TurnArtifactsFailure = {
|
|
53
|
+
readonly cause: 'operation';
|
|
54
|
+
readonly op: TurnVerb;
|
|
55
|
+
readonly error: unknown;
|
|
56
|
+
} | {
|
|
57
|
+
readonly cause: 'expired';
|
|
58
|
+
readonly op: TurnVerb;
|
|
59
|
+
};
|
|
60
|
+
/** What one turn's hand-over is built from. */
|
|
61
|
+
export interface TurnArtifactsSource {
|
|
62
|
+
/** The serving agent's store. Absent ⇒ `{ bound: false, reason: 'no-store' }`. */
|
|
63
|
+
readonly store: ArtifactStore | undefined;
|
|
64
|
+
/** This request's redemption scope. Absent ⇒ `{ bound: false, reason: 'no-session' }`. */
|
|
65
|
+
readonly scope: ArtifactScope | undefined;
|
|
66
|
+
/** The run this turn executed, captured when the binding is built — its `origin`. */
|
|
67
|
+
readonly runId: string | undefined;
|
|
68
|
+
/** Where the binding's facts go (the hosting door's adapter onto the record). */
|
|
69
|
+
readonly onEvent: ArtifactEventSink;
|
|
70
|
+
/** Where a failed operation or a refused late call is reported. */
|
|
71
|
+
readonly onFailure: (failure: TurnArtifactsFailure) => void;
|
|
72
|
+
}
|
|
73
|
+
/** One turn's hand-over: the value the host is given, and the ways to end it. */
|
|
74
|
+
export interface OpenTurnArtifacts {
|
|
75
|
+
readonly turn: TurnArtifacts;
|
|
76
|
+
/** Wait for every operation started through the binding — including one
|
|
77
|
+
* started while this waits. Never rejects; resolves at once when nothing
|
|
78
|
+
* was bound. The composer races it against its bound. */
|
|
79
|
+
drain(): Promise<void>;
|
|
80
|
+
/** Refuse every later call by name. Idempotent. */
|
|
81
|
+
revoke(): void;
|
|
82
|
+
/** Was this error already reported as a failed operation? */
|
|
83
|
+
reported(err: unknown): boolean;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Open this turn's hand-over — bound to `scope`, or the stated reason there is
|
|
87
|
+
* nothing to bind. `'no-session'` is checked first: with no session there is no
|
|
88
|
+
* scope to name at all, whatever the store.
|
|
89
|
+
*
|
|
90
|
+
* @internal — the composer's; hosts receive the `TurnArtifacts` value only.
|
|
91
|
+
*/
|
|
92
|
+
export declare function openTurnArtifacts(source: TurnArtifactsSource): OpenTurnArtifacts;
|
|
93
|
+
export {};
|
|
94
|
+
//# sourceMappingURL=turnArtifacts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"turnArtifacts.d.ts","sourceRoot":"","sources":["../../../src/hosting/turnArtifacts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AAEH,OAAO,EAEL,KAAK,iBAAiB,EAEvB,MAAM,4BAA4B,CAAC;AACpC,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC1E,OAAO,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD,wEAAwE;AACxE,KAAK,QAAQ,GAAG,yBAAyB,CAAC,IAAI,CAAC,CAAC;AAEhD,wDAAwD;AACxD,MAAM,MAAM,oBAAoB,GAC5B;IAAE,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC;IAAC,QAAQ,CAAC,EAAE,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;CAAE,GAC/E;IAAE,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,EAAE,EAAE,QAAQ,CAAA;CAAE,CAAC;AAEzD,+CAA+C;AAC/C,MAAM,WAAW,mBAAmB;IAClC,kFAAkF;IAClF,QAAQ,CAAC,KAAK,EAAE,aAAa,GAAG,SAAS,CAAC;IAC1C,0FAA0F;IAC1F,QAAQ,CAAC,KAAK,EAAE,aAAa,GAAG,SAAS,CAAC;IAC1C,qFAAqF;IACrF,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,iFAAiF;IACjF,QAAQ,CAAC,OAAO,EAAE,iBAAiB,CAAC;IACpC,mEAAmE;IACnE,QAAQ,CAAC,SAAS,EAAE,CAAC,OAAO,EAAE,oBAAoB,KAAK,IAAI,CAAC;CAC7D;AAED,iFAAiF;AACjF,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAC7B;;8DAE0D;IAC1D,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,mDAAmD;IACnD,MAAM,IAAI,IAAI,CAAC;IACf,6DAA6D;IAC7D,QAAQ,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC;CACjC;AAID;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,mBAAmB,GAAG,iBAAiB,CAWhF"}
|
|
@@ -28,6 +28,7 @@ import type { MiddlewareAsk } from '../core/pause.js';
|
|
|
28
28
|
import type { AgentRunCheckpoint } from '../core/runCheckpoint.js';
|
|
29
29
|
import type { AwaitingInput } from '../core/inputRequest.js';
|
|
30
30
|
import type { Unsubscribe } from '../events/dispatcher.js';
|
|
31
|
+
import type { ToolArtifacts } from '../artifacts/capability.js';
|
|
31
32
|
import type { ArtifactWireRequest, ArtifactWireResult } from './artifactWire.js';
|
|
32
33
|
import type { IdentityVerificationOptions } from './identityVerification.js';
|
|
33
34
|
import type { AdmissionPolicy } from './admission.js';
|
|
@@ -88,6 +89,11 @@ export interface HostRequest {
|
|
|
88
89
|
* anyone who can reach the host can put any string here, including someone
|
|
89
90
|
* else's. Authenticate the caller by your own means, then check that the
|
|
90
91
|
* authenticated principal is allowed this session, before you serve it.
|
|
92
|
+
*
|
|
93
|
+
* Bounded at every door the library ships: an id longer than
|
|
94
|
+
* `MAX_SESSION_ID_LENGTH` or holding a control character is refused before
|
|
95
|
+
* any handler sees the request, because it travels into every stored row,
|
|
96
|
+
* log line and trace span of the conversation.
|
|
91
97
|
*/
|
|
92
98
|
readonly sessionId?: string;
|
|
93
99
|
/**
|
|
@@ -239,9 +245,118 @@ export interface HostReply {
|
|
|
239
245
|
* Handler code is identical either way: emit freely, complete once.
|
|
240
246
|
*/
|
|
241
247
|
emit?(chunk: string): void;
|
|
248
|
+
/**
|
|
249
|
+
* The turn's artifact store, **already bound** to the scope this request's
|
|
250
|
+
* claim tickets are redeemed under — so host code that files its OWN
|
|
251
|
+
* artifacts for a turn (a story, the person's clicks, anything joined to it)
|
|
252
|
+
* files them where `artifact-get` will look for the same caller, without
|
|
253
|
+
* ever composing a scope.
|
|
254
|
+
*
|
|
255
|
+
* ── Awaited, inside the turn — and bounded ────────────────────────────────
|
|
256
|
+
* Not a terminal. The composer calls it exactly ONCE per turn, AWAITS it
|
|
257
|
+
* while the session's lane is still held, and only then ends the reply with
|
|
258
|
+
* `complete` or `awaiting` — so a ticket filed here exists before the body
|
|
259
|
+
* that carries it is composed. Never called for a request that is not a turn
|
|
260
|
+
* (an artifact redemption, a session op) or for a turn that ends through
|
|
261
|
+
* `fail`.
|
|
262
|
+
*
|
|
263
|
+
* The wait is BOUNDED: the hook and every operation it started must settle
|
|
264
|
+
* within `turnArtifactsTimeoutMs` (default `TURN_ARTIFACTS_TIMEOUT_MS`, 5 s)
|
|
265
|
+
* and before the request's own `signal` aborts. Whichever comes first ends
|
|
266
|
+
* the hand-over: the binding is revoked, what is in flight is NOT cancelled
|
|
267
|
+
* (it may still land, stamped with this turn's session and run), the cause is
|
|
268
|
+
* reported, and the terminal is delivered. In the shared `{ agent }` shape
|
|
269
|
+
* every session waits behind this turn's lane, so the hook's I/O is paid by
|
|
270
|
+
* everyone — keep it to filing.
|
|
271
|
+
*
|
|
272
|
+
* ── Live only for its turn ─────────────────────────────────────────────────
|
|
273
|
+
* The binding is live while the hand-over is: after the composer has waited
|
|
274
|
+
* for every operation started through it (a `put` that was not awaited
|
|
275
|
+
* included), or after the bound ended the wait, it REVOKES it. A verb called
|
|
276
|
+
* later rejects with `TurnArtifactsExpiredError` — a rejection already
|
|
277
|
+
* handled, so a floating late call cannot crash the process — and is reported
|
|
278
|
+
* as `'expired'`. File inside the hook; never hold the binding.
|
|
279
|
+
*
|
|
280
|
+
* ── Never decides the reply, never silent ──────────────────────────────────
|
|
281
|
+
* A hook that throws or rejects, an operation that fails (awaited or not), the
|
|
282
|
+
* bound, the abort and a late call are all put on the serving agent's stream
|
|
283
|
+
* as `agentfootprint.artifacts.hand_over_failed { cause, op?, errorClass?,
|
|
284
|
+
* errorCode? }` — class only, stamped with the session — and the FIRST of
|
|
285
|
+
* them on the ingress record (`IngressRecord.turnArtifactsFailure`). None of
|
|
286
|
+
* them turns a delivered answer, or a stored question, into a failure.
|
|
287
|
+
* Awaiting another turn of the same standing agent from inside the hook can
|
|
288
|
+
* never finish (that turn queues behind this one); the bound ends the wait.
|
|
289
|
+
|
|
290
|
+
* ── The scope, and what it is not ─────────────────────────────────────────
|
|
291
|
+
* The scope is the one {@link HostRequest.artifact} redemption re-composes
|
|
292
|
+
* for this request: the verified user (or the transport's own `userId` when
|
|
293
|
+
* no verifier is configured), the stored conversation's tenant and
|
|
294
|
+
* namespace, else the session rung `{ conversationId: sessionId }`. One
|
|
295
|
+
* owner of that tuple — the library — so an app cannot derive a slightly
|
|
296
|
+
* different one. It is where the DOOR redeems, which is not always where the
|
|
297
|
+
* run filed its own recording: at an unverified door a conversation that
|
|
298
|
+
* carries an identity of its own can put the recording elsewhere (the known
|
|
299
|
+
* edges are listed in `src/hosting/README.md`).
|
|
300
|
+
*
|
|
301
|
+
* Every put is stamped `origin: { runId }` with the run this turn executed,
|
|
302
|
+
* or carries no origin when it executed none (a partial answer to an input
|
|
303
|
+
* request, or its cancellation); a caller's own `origin` is always dropped.
|
|
304
|
+
* A PAUSED turn's run id names a run that files no recording — a pause is
|
|
305
|
+
* not a finished run, and the resumed run records under its own id — so a
|
|
306
|
+
* reader joining on it must say "paused, no recording", not "missing". Each
|
|
307
|
+
* filing lands on the serving agent's record as
|
|
308
|
+
* `agentfootprint.artifacts.minted` with no `tool` field, its meta naming the
|
|
309
|
+
* session and the run it was filed FOR — captured when the binding was
|
|
310
|
+
* built, never read from whichever run is live when a late fact lands.
|
|
311
|
+
*
|
|
312
|
+
* When there is nothing to bind, the value SAYS so rather than inventing a
|
|
313
|
+
* scope — see {@link TurnArtifacts}.
|
|
314
|
+
*
|
|
315
|
+
* Optional, and feature-detected: a host that does not implement it is
|
|
316
|
+
* served exactly as before.
|
|
317
|
+
*
|
|
318
|
+
* @example File a turn's story and carry its ticket on the reply
|
|
319
|
+
* turnArtifacts: async (turn) => {
|
|
320
|
+
* if (!turn.bound) return;
|
|
321
|
+
* const story = await turn.artifacts.put({ kind: 'story/turn', mediaType: 'application/json', data });
|
|
322
|
+
* ticketForThisReply = story.ref; // the body `complete` composes next can carry it
|
|
323
|
+
* },
|
|
324
|
+
*/
|
|
325
|
+
turnArtifacts?(turn: TurnArtifacts): void | Promise<void>;
|
|
242
326
|
/** End the reply with a failure. */
|
|
243
327
|
fail(error: Error): void;
|
|
244
328
|
}
|
|
329
|
+
/**
|
|
330
|
+
* What {@link HostReply.turnArtifacts} is handed: this turn's artifact store,
|
|
331
|
+
* bound to exactly one scope — or the reason there is none.
|
|
332
|
+
*
|
|
333
|
+
* `artifacts` has the shape a tool gets as `ctx.artifacts`: five verbs, none
|
|
334
|
+
* of which takes a scope, so a binding can reach this request's scope and no
|
|
335
|
+
* other. The scope itself is deliberately NOT on the value — a tuple a host
|
|
336
|
+
* can read is a tuple a host can copy, edit and put under. The verbs work only
|
|
337
|
+
* while the hand-over is live (then `TurnArtifactsExpiredError`, already
|
|
338
|
+
* handled, reported as `'expired'`).
|
|
339
|
+
*
|
|
340
|
+
* A filing's `origin.runId` is the run the turn executed — none for a turn that
|
|
341
|
+
* executed none. On a PAUSED turn that run files no recording (a pause is not a
|
|
342
|
+
* finished run; the resumed run records under its own id), so a reader joining
|
|
343
|
+
* a filing to "its recording" by run id must read the absence as "paused, no
|
|
344
|
+
* recording", never as "missing".
|
|
345
|
+
*
|
|
346
|
+
* `bound: false` says why nothing was bound, checked in this order:
|
|
347
|
+
* - `'no-session'` — the request named no session. An anonymous run scopes
|
|
348
|
+
* its artifacts to its own run id, which no later request can present, so
|
|
349
|
+
* there is no scope to bind — and none is invented. Wins over `'no-store'`
|
|
350
|
+
* when both apply.
|
|
351
|
+
* - `'no-store'` — the serving agent has no artifact store.
|
|
352
|
+
*/
|
|
353
|
+
export type TurnArtifacts = {
|
|
354
|
+
readonly bound: true;
|
|
355
|
+
readonly artifacts: ToolArtifacts;
|
|
356
|
+
} | {
|
|
357
|
+
readonly bound: false;
|
|
358
|
+
readonly reason: 'no-session' | 'no-store';
|
|
359
|
+
};
|
|
245
360
|
/**
|
|
246
361
|
* What you hand {@link AgentHost.serve}. Throwing is treated exactly like
|
|
247
362
|
* calling `reply.fail(err)` — a handler that throws is a failed request, never
|
|
@@ -264,6 +379,35 @@ export interface HostHandle {
|
|
|
264
379
|
*/
|
|
265
380
|
close(): Promise<void>;
|
|
266
381
|
}
|
|
382
|
+
/**
|
|
383
|
+
* A request the HOST refused before any handler saw it — the door guard's
|
|
384
|
+
* decision about a caller: a cross-site shape, a Host this door does not answer
|
|
385
|
+
* for, a session id it will not carry.
|
|
386
|
+
*
|
|
387
|
+
* Only decisions travel here. A body that is merely malformed (unparseable
|
|
388
|
+
* JSON, an unknown wire op, a body over the ceiling) is a broken request, not a
|
|
389
|
+
* decision about who is knocking, and stays the transport's own 4xx.
|
|
390
|
+
*
|
|
391
|
+
* Carries the refusal's class and the fact of a credential — never a header,
|
|
392
|
+
* never the credential, never the session id. It is what
|
|
393
|
+
* {@link AgentHost.onRefusal} hands a listener, and a listener is free to log
|
|
394
|
+
* all of it.
|
|
395
|
+
*/
|
|
396
|
+
export interface HostRefusal {
|
|
397
|
+
/**
|
|
398
|
+
* Which door refused: `'request'` — the one-exchange door, refused before
|
|
399
|
+
* the body was read or before the handler was called (which of the
|
|
400
|
+
* composer's turn / session-op / artifact doors it was headed for is not
|
|
401
|
+
* recorded) — or `'conversation'`, an upgrade refused before the 101.
|
|
402
|
+
*/
|
|
403
|
+
readonly door: 'request' | 'conversation';
|
|
404
|
+
/** The named refusal the caller was answered with. Its `code` is stable. */
|
|
405
|
+
readonly error: Error & {
|
|
406
|
+
readonly code: string;
|
|
407
|
+
};
|
|
408
|
+
/** Whether an `authorization: Bearer …` credential was PRESENT. Never its value. */
|
|
409
|
+
readonly bearerPresent: boolean;
|
|
410
|
+
}
|
|
267
411
|
/**
|
|
268
412
|
* The port: something that can carry requests to one handler and carry its
|
|
269
413
|
* replies back.
|
|
@@ -278,6 +422,20 @@ export interface AgentHost {
|
|
|
278
422
|
readonly capabilities: readonly HostCapability[];
|
|
279
423
|
/** Start serving. Resolves once the host is actually live. */
|
|
280
424
|
serve(handler: HostHandler): Promise<HostHandle>;
|
|
425
|
+
/**
|
|
426
|
+
* Hear about every request this host refuses BEFORE a handler sees it — on
|
|
427
|
+
* any of its doors, the conversation door included. Returns the way to stop
|
|
428
|
+
* listening.
|
|
429
|
+
*
|
|
430
|
+
* Optional, and feature-detected: a host that refuses nothing on its own
|
|
431
|
+
* has nothing to report. Every host built on `httpHost` has it, and
|
|
432
|
+
* `standingAgent` subscribes whenever `onIngressDecision` is set — which is
|
|
433
|
+
* how a forged request the host turned away still lands in the ingress
|
|
434
|
+
* record, though no run, no handler and no verifier ever saw it.
|
|
435
|
+
*
|
|
436
|
+
* A listener that throws is contained: the refusal is still answered.
|
|
437
|
+
*/
|
|
438
|
+
onRefusal?(listener: (refusal: HostRefusal) => void): Unsubscribe;
|
|
281
439
|
}
|
|
282
440
|
/**
|
|
283
441
|
* A door that stays open: one session-scoped, two-way channel.
|
|
@@ -1092,10 +1250,17 @@ export interface StandingAgentBaseOptions<TH extends HostHandle = HostHandle> {
|
|
|
1092
1250
|
* header, never a claim set, never an error's message. See
|
|
1093
1251
|
* {@link IngressRecord} for the field-by-field contract and for the one thing
|
|
1094
1252
|
* it deliberately does not cover (a body the transport's own wire grammar
|
|
1095
|
-
* refused before this composer ever saw it).
|
|
1253
|
+
* refused as malformed before this composer ever saw it).
|
|
1254
|
+
*
|
|
1255
|
+
* The HOST's own refusals are on it too: set this, and the composer
|
|
1256
|
+
* subscribes to the host's `onRefusal`, so a forged request the door guard
|
|
1257
|
+
* turned away, or a session id over the bound, is recorded
|
|
1258
|
+
* (`'cross-site-refused'` / `'refused'`, door `'request'` or
|
|
1259
|
+
* `'conversation'`) though no handler ever saw it.
|
|
1096
1260
|
*
|
|
1097
|
-
* Unset — the default — nothing is built, nothing is wrapped,
|
|
1098
|
-
* the handler uses is the host's own object, to the
|
|
1261
|
+
* Unset — the default — nothing is built, nothing is wrapped, nothing is
|
|
1262
|
+
* subscribed, and the reply the handler uses is the host's own object, to the
|
|
1263
|
+
* byte.
|
|
1099
1264
|
*
|
|
1100
1265
|
* @example
|
|
1101
1266
|
* onIngressDecision: (record) => {
|
|
@@ -1159,10 +1324,38 @@ export interface StandingAgentBaseOptions<TH extends HostHandle = HostHandle> {
|
|
|
1159
1324
|
* await standingAgent({ agent, sessions, host, shutdownOn: ['SIGTERM', 'SIGINT'] });
|
|
1160
1325
|
*/
|
|
1161
1326
|
readonly shutdownOn?: readonly NodeJS.Signals[];
|
|
1327
|
+
/**
|
|
1328
|
+
* How long a turn's artifact hand-over (`HostReply.turnArtifacts`) may hold
|
|
1329
|
+
* the reply — the hook AND every operation it started — before the composer
|
|
1330
|
+
* stops waiting. Default {@link TURN_ARTIFACTS_TIMEOUT_MS} (5 s). The
|
|
1331
|
+
* request's own `signal` ends the wait earlier when the caller hangs up.
|
|
1332
|
+
*
|
|
1333
|
+
* On expiry the binding is revoked, nothing in flight is cancelled (it may
|
|
1334
|
+
* still land, attributed to its own session and run), the cause is reported
|
|
1335
|
+
* (`agentfootprint.artifacts.hand_over_failed { cause: 'timeout' }`), the
|
|
1336
|
+
* terminal is delivered and the lane released — so one host's hung store or
|
|
1337
|
+
* hook can hold neither every other session (the shared shape), nor a pooled
|
|
1338
|
+
* lane past `maxActiveSessions`, nor `close()` on the SIGTERM path.
|
|
1339
|
+
*
|
|
1340
|
+
* Must be a positive, finite number of milliseconds — a bound that can never
|
|
1341
|
+
* fire is not a bound; anything else is refused at construction. Only read
|
|
1342
|
+
* when the host implements the hook.
|
|
1343
|
+
*/
|
|
1344
|
+
readonly turnArtifactsTimeoutMs?: number;
|
|
1162
1345
|
}
|
|
1163
1346
|
/** How many sessions a `agentFactory` pool holds before it evicts the least
|
|
1164
1347
|
* recently used one. See {@link StandingAgentPoolOptions.maxActiveSessions}. */
|
|
1165
1348
|
export declare const DEFAULT_MAX_ACTIVE_SESSIONS = 100;
|
|
1349
|
+
/**
|
|
1350
|
+
* How long a turn's artifact hand-over may hold its reply by default — the
|
|
1351
|
+
* hook plus the operations it started. Five seconds: the order of
|
|
1352
|
+
* `TOOL_TEARDOWN_TIMEOUT_MS`, and for the same reason — both sit on the
|
|
1353
|
+
* shutdown path (`close()` drains in-flight requests), where an unbounded wait
|
|
1354
|
+
* turns a container stop into a wait for SIGKILL — while leaving a store room
|
|
1355
|
+
* for a few ordinary writes. See
|
|
1356
|
+
* {@link StandingAgentBaseOptions.turnArtifactsTimeoutMs}.
|
|
1357
|
+
*/
|
|
1358
|
+
export declare const TURN_ARTIFACTS_TIMEOUT_MS = 5000;
|
|
1166
1359
|
/**
|
|
1167
1360
|
* One shared agent, serving every session — the original shape, and still the
|
|
1168
1361
|
* right one for most deployments.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/hosting/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAEvD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AACnE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,KAAK,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACjF,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,2BAA2B,CAAC;AAC7E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,KAAK,EAAE,cAAc,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAE9F,YAAY,EAAE,WAAW,EAAE,CAAC;AAI5B;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,MAAM,cAAc,GAAG,WAAW,GAAG,cAAc,CAAC;AAE1D;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,iCAAiC;IACjC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB;;;;;;;;;;;;;;;;OAgBG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/hosting/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -9,6 +9,11 @@
|
|
|
9
9
|
* port-shaped lives in `types.ts`; this file is the join.
|
|
10
10
|
*
|
|
11
11
|
* ── The laws it keeps, all of them pinned by tests ───────────────────────────
|
|
12
|
+
* - **A handshake the door guard refuses never gets a 101.** A WebSocket is
|
|
13
|
+
* not bound by the same-origin policy and its browser API cannot set a
|
|
14
|
+
* header, so there is no preflight to force: the host's guard judges Host,
|
|
15
|
+
* Origin and Fetch metadata on the handshake itself, and the session id the
|
|
16
|
+
* dialect read is bounded before the channel opens.
|
|
12
17
|
* - **A path this door does not own is not touched.** `node:http` calls EVERY
|
|
13
18
|
* `'upgrade'` listener for every upgrade, exactly as it calls every
|
|
14
19
|
* `'request'` listener — so a caller's own protocol lives beside this one on
|
|
@@ -40,7 +45,8 @@
|
|
|
40
45
|
/// <reference types="node" />
|
|
41
46
|
import type { IncomingMessage } from 'node:http';
|
|
42
47
|
import type { Duplex } from 'node:stream';
|
|
43
|
-
import
|
|
48
|
+
import { type DoorGuard } from './doorGuard.js';
|
|
49
|
+
import type { ConversationHandler, ConversationLimits, HostRefusal } from './types.js';
|
|
44
50
|
/**
|
|
45
51
|
* What a wire read out of one handshake — the conversation half of a
|
|
46
52
|
* deployment's dialect.
|
|
@@ -83,6 +89,14 @@ export interface ConversationDoorOptions {
|
|
|
83
89
|
readonly handler: ConversationHandler;
|
|
84
90
|
/** Whether the host is still taking conversations — false after `close()`. */
|
|
85
91
|
readonly accepting: () => boolean;
|
|
92
|
+
/**
|
|
93
|
+
* The host's door guard — Host and Origin (and the browser's Fetch
|
|
94
|
+
* metadata) judged on the handshake, BEFORE the 101. Absent, no handshake is
|
|
95
|
+
* judged, which is the conversation door as it was before the guard.
|
|
96
|
+
*/
|
|
97
|
+
readonly guard?: DoorGuard;
|
|
98
|
+
/** Told about every handshake this door refuses on the guard's or the session bound's word. */
|
|
99
|
+
readonly onRefusal?: (refusal: HostRefusal) => void;
|
|
86
100
|
}
|
|
87
101
|
/** What a handshake dialect may read. Deliberately the same shape a request wire gets, minus the body. */
|
|
88
102
|
export interface HandshakeFacts {
|