@fastagent-sh/fastagent 0.19.0 → 0.21.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 +5 -1
- package/dist/atomic-write.d.ts +11 -7
- package/dist/atomic-write.js +16 -11
- package/dist/channels/agentcore-limits.d.ts +9 -0
- package/dist/channels/agentcore-limits.js +9 -0
- package/dist/channels/agentcore-protocol.d.ts +112 -0
- package/dist/channels/agentcore-protocol.js +22 -0
- package/dist/channels/agentcore-service.d.ts +12 -15
- package/dist/channels/agentcore-service.js +15 -24
- package/dist/channels/agentcore-state.d.ts +5 -11
- package/dist/channels/agentcore-state.js +4 -1
- package/dist/channels/agentcore.d.ts +9 -83
- package/dist/channels/agentcore.js +101 -93
- package/dist/channels/control.d.ts +50 -12
- package/dist/channels/control.js +251 -157
- package/dist/channels/discover.d.ts +26 -5
- package/dist/channels/discover.js +13 -26
- package/dist/channels/feishu/context-buffer.d.ts +6 -0
- package/dist/channels/feishu/context-buffer.js +0 -38
- package/dist/channels/feishu/crypto.d.ts +0 -2
- package/dist/channels/feishu/crypto.js +3 -8
- package/dist/channels/feishu/feishu-api.js +7 -12
- package/dist/channels/feishu/feishu.js +86 -128
- package/dist/channels/feishu/parse.d.ts +4 -3
- package/dist/channels/feishu/parse.js +5 -4
- package/dist/channels/feishu/register-webhook.d.ts +5 -5
- package/dist/channels/feishu/register-webhook.js +43 -57
- package/dist/channels/feishu/scaffold/feishu-send.ts +12 -67
- package/dist/channels/feishu/setup-mode.d.ts +30 -0
- package/dist/channels/feishu/setup-mode.js +26 -0
- package/dist/channels/feishu/shared-api.d.ts +10 -0
- package/dist/channels/feishu/shared-api.js +38 -0
- package/dist/channels/http.d.ts +0 -8
- package/dist/channels/http.js +4 -56
- package/dist/channels/kit/attachment-path.d.ts +12 -0
- package/dist/channels/kit/attachment-path.js +43 -0
- package/dist/channels/kit/context-buffer.d.ts +9 -0
- package/dist/channels/kit/context-buffer.js +11 -0
- package/dist/channels/kit/signature.d.ts +12 -0
- package/dist/channels/kit/signature.js +17 -0
- package/dist/channels/kit/stop-command.js +3 -3
- package/dist/channels/kit/tasks.d.ts +1 -1
- package/dist/channels/kit/tasks.js +10 -4
- package/dist/channels/kit/turn-runner.d.ts +59 -0
- package/dist/channels/kit/turn-runner.js +84 -0
- package/dist/channels/kit/turn-store.d.ts +19 -3
- package/dist/channels/kit/turn-store.js +29 -2
- package/dist/channels/lark/scaffold/lark-send.ts +12 -67
- package/dist/channels/registration.d.ts +36 -1
- package/dist/channels/registration.js +57 -1
- package/dist/channels/secret.d.ts +1 -0
- package/dist/channels/secret.js +16 -0
- package/dist/channels/slack/config-api.d.ts +35 -3
- package/dist/channels/slack/config-api.js +51 -9
- package/dist/channels/slack/invoke-turn.d.ts +1 -1
- package/dist/channels/slack/invoke-turn.js +5 -1
- package/dist/channels/slack/manifest.js +5 -1
- package/dist/channels/slack/onboard.d.ts +5 -5
- package/dist/channels/slack/onboard.js +44 -23
- package/dist/channels/slack/onboarding-state.d.ts +7 -3
- package/dist/channels/slack/onboarding-state.js +13 -20
- package/dist/channels/slack/register-webhook.d.ts +3 -2
- package/dist/channels/slack/register-webhook.js +35 -15
- package/dist/channels/slack/scaffold/channel.ts +3 -10
- package/dist/channels/slack/scaffold/slack-send.ts +18 -141
- package/dist/channels/slack/shared-api.d.ts +10 -0
- package/dist/channels/slack/shared-api.js +34 -0
- package/dist/channels/slack/slack-api.d.ts +20 -2
- package/dist/channels/slack/slack-api.js +100 -73
- package/dist/channels/slack/slack.d.ts +0 -10
- package/dist/channels/slack/slack.js +68 -107
- package/dist/channels/sse.d.ts +4 -0
- package/dist/channels/sse.js +66 -0
- package/dist/channels/telegram/parse.d.ts +21 -1
- package/dist/channels/telegram/parse.js +65 -11
- package/dist/channels/telegram/register-webhook.d.ts +6 -9
- package/dist/channels/telegram/register-webhook.js +44 -42
- package/dist/channels/telegram/scaffold/channel.ts +7 -3
- package/dist/channels/telegram/telegram-api.js +5 -6
- package/dist/channels/telegram/telegram.d.ts +2 -2
- package/dist/channels/telegram/telegram.js +97 -204
- package/dist/channels/wait-health.js +7 -4
- package/dist/cli/add-feishu.js +3 -10
- package/dist/cli/add-slack.js +13 -25
- package/dist/cli/commands/add.d.ts +0 -1
- package/dist/cli/commands/add.js +22 -35
- package/dist/cli/commands/attach.d.ts +2 -4
- package/dist/cli/commands/attach.js +17 -15
- package/dist/cli/commands/chat.js +6 -12
- package/dist/cli/commands/deploy/agentcore.d.ts +2 -0
- package/dist/cli/commands/deploy/agentcore.js +178 -0
- package/dist/cli/commands/deploy/docker.d.ts +2 -0
- package/dist/cli/commands/deploy/docker.js +119 -0
- package/dist/cli/commands/deploy/fly.d.ts +2 -0
- package/dist/cli/commands/deploy/fly.js +131 -0
- package/dist/cli/commands/deploy/railway.d.ts +2 -0
- package/dist/cli/commands/deploy/railway.js +71 -0
- package/dist/cli/commands/deploy/shared.d.ts +114 -0
- package/dist/cli/commands/deploy/shared.js +124 -0
- package/dist/cli/commands/deploy.d.ts +38 -25
- package/dist/cli/commands/deploy.js +101 -631
- package/dist/cli/commands/dev.js +20 -76
- package/dist/cli/commands/fire.js +6 -12
- package/dist/cli/commands/info.js +1 -1
- package/dist/cli/commands/init.js +1 -2
- package/dist/cli/commands/invoke.js +4 -11
- package/dist/cli/commands/schedule.js +1 -1
- package/dist/cli/commands/start.js +41 -80
- package/dist/cli/commands/tool.js +3 -8
- package/dist/cli/kernel.d.ts +0 -2
- package/dist/cli/kernel.js +0 -2
- package/dist/cli/program.js +7 -12
- package/dist/cli/serve.d.ts +42 -34
- package/dist/cli/serve.js +107 -28
- package/dist/cli/shared.d.ts +52 -27
- package/dist/cli/shared.js +69 -6
- package/dist/deploy/agentcore/forwarder.js +250 -0
- package/dist/deploy/agentcore/logs.d.ts +2 -2
- package/dist/deploy/agentcore/logs.js +2 -2
- package/dist/deploy/agentcore/plan.d.ts +34 -11
- package/dist/deploy/agentcore/plan.js +52 -259
- package/dist/deploy/agentcore/run.d.ts +9 -24
- package/dist/deploy/agentcore/run.js +35 -43
- package/dist/deploy/channel-ingress.d.ts +73 -0
- package/dist/deploy/channel-ingress.js +101 -0
- package/dist/deploy/docker/plan.d.ts +3 -7
- package/dist/deploy/docker/plan.js +4 -15
- package/dist/deploy/docker/run.d.ts +35 -4
- package/dist/deploy/docker/run.js +40 -8
- package/dist/deploy/fly/plan.d.ts +4 -5
- package/dist/deploy/fly/plan.js +14 -22
- package/dist/deploy/fly/run.d.ts +36 -23
- package/dist/deploy/fly/run.js +129 -83
- package/dist/deploy/hosts.d.ts +5 -0
- package/dist/deploy/hosts.js +4 -0
- package/dist/deploy/preflight.d.ts +6 -7
- package/dist/deploy/preflight.js +27 -23
- package/dist/deploy/railway/plan.d.ts +9 -5
- package/dist/deploy/railway/plan.js +18 -26
- package/dist/deploy/railway/run.d.ts +11 -10
- package/dist/deploy/railway/run.js +44 -43
- package/dist/deploy/runner.js +22 -2
- package/dist/deploy/secrets.d.ts +18 -9
- package/dist/deploy/secrets.js +63 -28
- package/dist/dev-supervisor.js +3 -4
- package/dist/engines/pi/agent-session-factory.d.ts +37 -17
- package/dist/engines/pi/agent-session-factory.js +111 -106
- package/dist/engines/pi/auth.js +43 -43
- package/dist/engines/pi/config.d.ts +2 -2
- package/dist/engines/pi/create.d.ts +22 -27
- package/dist/engines/pi/create.js +59 -74
- package/dist/engines/pi/definition.d.ts +1 -1
- package/dist/engines/pi/definition.js +11 -12
- package/dist/engines/pi/invoke-session.js +13 -30
- package/dist/engines/pi/login.js +32 -16
- package/dist/engines/pi/open.d.ts +3 -4
- package/dist/engines/pi/open.js +32 -42
- package/dist/engines/pi/retry-event.d.ts +6 -0
- package/dist/engines/pi/retry-event.js +15 -0
- package/dist/engines/pi/search-tools.js +1 -1
- package/dist/engines/pi/service.d.ts +1 -1
- package/dist/engines/pi/service.js +8 -0
- package/dist/engines/pi/session-builder.js +26 -140
- package/dist/engines/pi/session-control.d.ts +27 -22
- package/dist/engines/pi/session-control.js +551 -490
- package/dist/engines/pi/session-inheritance.d.ts +8 -22
- package/dist/engines/pi/session-inheritance.js +95 -76
- package/dist/engines/pi/session-markers.d.ts +48 -0
- package/dist/engines/pi/session-markers.js +59 -0
- package/dist/engines/pi/session-settings.d.ts +5 -5
- package/dist/engines/pi/session-settings.js +8 -5
- package/dist/engines/pi/session-store.d.ts +91 -26
- package/dist/engines/pi/session-store.js +413 -82
- package/dist/engines/pi/tool-context.d.ts +24 -11
- package/dist/engines/pi/tool-context.js +29 -4
- package/dist/engines/pi/tool.d.ts +6 -9
- package/dist/engines/pi/tool.js +3 -2
- package/dist/env.js +1 -2
- package/dist/feishu.d.ts +1 -0
- package/dist/feishu.js +1 -0
- package/dist/lark.d.ts +1 -0
- package/dist/lark.js +1 -0
- package/dist/loader.d.ts +51 -7
- package/dist/loader.js +84 -18
- package/dist/log.d.ts +9 -17
- package/dist/log.js +25 -30
- package/dist/paths.d.ts +26 -3
- package/dist/paths.js +43 -5
- package/dist/scaffold/add-channel.d.ts +6 -1
- package/dist/scaffold/add-channel.js +50 -67
- package/dist/scaffold/init.js +7 -2
- package/dist/scaffold/templates/tools/fetch-url.ts +0 -2
- package/dist/schedule/discover.js +3 -15
- package/dist/schedule/wake-alarm.d.ts +14 -19
- package/dist/schedule/wake-alarm.js +89 -48
- package/dist/schedule/wakeups.d.ts +1 -1
- package/dist/schedule/wakeups.js +10 -7
- package/dist/service.d.ts +24 -24
- package/dist/service.js +33 -77
- package/dist/session-remote.d.ts +12 -7
- package/dist/session-remote.js +185 -118
- package/dist/session.d.ts +227 -93
- package/dist/session.js +61 -23
- package/dist/slack.d.ts +2 -0
- package/dist/slack.js +1 -0
- package/dist/telegram.d.ts +1 -1
- package/dist/telegram.js +1 -1
- package/dist/tunnel.d.ts +34 -9
- package/dist/tunnel.js +83 -50
- package/package.json +5 -4
- package/dist/channels/slack/bot-auth.d.ts +0 -15
- package/dist/channels/slack/bot-auth.js +0 -135
package/README.md
CHANGED
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
[](https://nodejs.org)
|
|
9
9
|
[](https://pi.dev)
|
|
10
10
|
[](https://github.com/fastagent-sh/fastagent/stargazers)
|
|
11
|
+
[](https://x.com/kid7st)
|
|
11
12
|
|
|
12
13
|
<p align="center">
|
|
13
14
|
<sub>Built on</sub>
|
|
@@ -64,7 +65,9 @@ FastAgent stays a small serving layer, so it never dictates your stack. Capabili
|
|
|
64
65
|
|
|
65
66
|
## Install
|
|
66
67
|
|
|
67
|
-
|
|
68
|
+
Start with the [agent development guide](https://github.com/fastagent-sh/fastagent/blob/main/docs/ai-start.md), the authoring entry point for both humans and coding agents. It covers responsibilities, TypeScript tools, verification, channels, scheduling, and deployment. FastAgent's repository `AGENTS.md` is for maintainers.
|
|
69
|
+
|
|
70
|
+
To work with Claude Code, Codex, Cursor, or another coding agent, paste:
|
|
68
71
|
|
|
69
72
|
> Read https://fastagent.sh/start.md and build an agent in this project.
|
|
70
73
|
|
|
@@ -138,6 +141,7 @@ const agent = createPiAgent({
|
|
|
138
141
|
|
|
139
142
|
| Document | Purpose |
|
|
140
143
|
|---|---|
|
|
144
|
+
| [Agent development guide](https://github.com/fastagent-sh/fastagent/blob/main/docs/ai-start.md) | Canonical authoring path for humans and coding agents |
|
|
141
145
|
| [Documentation index](https://fastagent.sh/docs/) | Documentation map |
|
|
142
146
|
| [Quickstart](https://fastagent.sh/docs/quickstart/) | Scaffold, run, add a tool, and start |
|
|
143
147
|
| [Configuration](https://fastagent.sh/docs/configuration/) | Configure model, auth, ports, sessions, tools, and channels |
|
package/dist/atomic-write.d.ts
CHANGED
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Write a file so a reader sees the whole thing or nothing: same-directory temp, then rename.
|
|
3
3
|
*
|
|
4
|
-
* The temp name is fixed (`<path>.tmp`).
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
4
|
+
* The temp name is fixed (`<path>.tmp`). It holds wherever one process writes one state root: a
|
|
5
|
+
* deployment runs one container, `dev`'s supervisor respawns its worker only after the old one has
|
|
6
|
+
* EXITED (dev-supervisor.ts), and these writes are synchronous, so an exited process has none in
|
|
7
|
+
* flight. Slack's onboarding state is the one file with two writers — `add slack`, and the
|
|
8
|
+
* config-token rotation inside `--tunnel` webhook registration — so a second terminal running
|
|
9
|
+
* `add slack --replace-config` can overlap a live `dev --tunnel`. Kept fixed anyway: that window is
|
|
10
|
+
* a single write at tunnel startup, its repair is the `add slack --replace-config` the registration
|
|
11
|
+
* failure already prints, and the fixed name is the seam several channel tests use to inject a write
|
|
12
|
+
* failure by occupying that path with a directory. Revisit for a writer that is neither rare nor
|
|
13
|
+
* self-repairing.
|
|
10
14
|
*
|
|
11
15
|
* `mode` is applied to the temp first, so the content is never briefly world-readable.
|
|
12
16
|
*
|
|
@@ -16,4 +20,4 @@
|
|
|
16
20
|
* It runs on the temp, before the rename — the final path is then never observable with the wrong
|
|
17
21
|
* permissions, which a chmod after the rename cannot promise.
|
|
18
22
|
*/
|
|
19
|
-
export declare function writeFileAtomic(path: string, data: string, mode?: number): void;
|
|
23
|
+
export declare function writeFileAtomic(path: string, data: string | Buffer, mode?: number): void;
|
package/dist/atomic-write.js
CHANGED
|
@@ -1,22 +1,27 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* One spelling of "a reader sees the whole file or none of it"
|
|
3
|
-
*
|
|
4
|
-
* handling.
|
|
2
|
+
* One spelling of "a reader sees the whole file or none of it", after five copies of it drifted
|
|
3
|
+
* apart: two identical, three with different temp names and different permission handling.
|
|
5
4
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
5
|
+
* Synchronous, and there is no async sibling: every caller either sits on a path where a KB-sized
|
|
6
|
+
* write must complete BEFORE a transport ACK (channel state — an ACKed delivery is not redelivered)
|
|
7
|
+
* or on a CLI/startup path where the cost is not observable. An async spelling would buy one of them
|
|
8
|
+
* nothing and cost this module a second set of rules to keep true.
|
|
8
9
|
*/
|
|
9
10
|
import { chmodSync, mkdirSync, renameSync, rmSync, writeFileSync } from "node:fs";
|
|
10
11
|
import { dirname } from "node:path";
|
|
11
12
|
/**
|
|
12
13
|
* Write a file so a reader sees the whole thing or nothing: same-directory temp, then rename.
|
|
13
14
|
*
|
|
14
|
-
* The temp name is fixed (`<path>.tmp`).
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
15
|
+
* The temp name is fixed (`<path>.tmp`). It holds wherever one process writes one state root: a
|
|
16
|
+
* deployment runs one container, `dev`'s supervisor respawns its worker only after the old one has
|
|
17
|
+
* EXITED (dev-supervisor.ts), and these writes are synchronous, so an exited process has none in
|
|
18
|
+
* flight. Slack's onboarding state is the one file with two writers — `add slack`, and the
|
|
19
|
+
* config-token rotation inside `--tunnel` webhook registration — so a second terminal running
|
|
20
|
+
* `add slack --replace-config` can overlap a live `dev --tunnel`. Kept fixed anyway: that window is
|
|
21
|
+
* a single write at tunnel startup, its repair is the `add slack --replace-config` the registration
|
|
22
|
+
* failure already prints, and the fixed name is the seam several channel tests use to inject a write
|
|
23
|
+
* failure by occupying that path with a directory. Revisit for a writer that is neither rare nor
|
|
24
|
+
* self-repairing.
|
|
20
25
|
*
|
|
21
26
|
* `mode` is applied to the temp first, so the content is never briefly world-readable.
|
|
22
27
|
*
|
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The HOST's body ceilings, and the one place they are computed.
|
|
3
|
+
*
|
|
4
|
+
* Lambda Function URLs cap a request at 6 MB, so the forwarder cannot deliver more than that no
|
|
5
|
+
* matter what the adapter accepts; the body arrives base64-encoded (×4/3) inside a JSON envelope, so
|
|
6
|
+
* the ORIGINAL body ceiling is smaller still. This is a real capability difference from a resident
|
|
7
|
+
* host — the GitHub channel's own contract is 25 MiB — which is why `deploy agentcore` states it at
|
|
8
|
+
* plan time rather than letting an oversized payload surface as an opaque 502.
|
|
9
|
+
*/
|
|
1
10
|
/**
|
|
2
11
|
* Maximum original webhook body after reserving JSON-envelope overhead and base64 expansion.
|
|
3
12
|
* Enforced by both the public forwarder and the runtime adapter.
|
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The HOST's body ceilings, and the one place they are computed.
|
|
3
|
+
*
|
|
4
|
+
* Lambda Function URLs cap a request at 6 MB, so the forwarder cannot deliver more than that no
|
|
5
|
+
* matter what the adapter accepts; the body arrives base64-encoded (×4/3) inside a JSON envelope, so
|
|
6
|
+
* the ORIGINAL body ceiling is smaller still. This is a real capability difference from a resident
|
|
7
|
+
* host — the GitHub channel's own contract is 25 MiB — which is why `deploy agentcore` states it at
|
|
8
|
+
* plan time rather than letting an oversized payload surface as an opaque 502.
|
|
9
|
+
*/
|
|
1
10
|
/** AWS Lambda Function URLs accept request payloads up to 6 MB. */
|
|
2
11
|
const FUNCTION_URL_REQUEST_LIMIT = 6 * 1000 * 1000;
|
|
3
12
|
/**
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The wire between the forwarder Lambda and the container, in ONE place: the envelope every
|
|
3
|
+
* trigger arrives as, the reply a webhook rides back in, the presigned-URL pair the state snapshot
|
|
4
|
+
* uses, the wake-alarm request, and the forwarder's reserved paths. The forwarder itself is JavaScript
|
|
5
|
+
* (`deploy/agentcore/forwarder.js`) and cannot import this, so `agentcore-forwarder.test.ts` pins its
|
|
6
|
+
* literals to these — a rename here fails there, not on a live box.
|
|
7
|
+
*
|
|
8
|
+
* Pure types and constants: the adapter, the state sync, the wake sink and the deploy driver all
|
|
9
|
+
* read it, and none of them may pull the others in for it.
|
|
10
|
+
*/
|
|
11
|
+
/** Paths the forwarder answers ITSELF — never forwarded to a channel route. */
|
|
12
|
+
export declare const RESERVED_PATHS: {
|
|
13
|
+
/** The deploy driver's post-deploy verification (ingress secret). */
|
|
14
|
+
readonly probe: "/__fastagent/probe";
|
|
15
|
+
/** The container's wake-alarm mirror callback (wake secret). */
|
|
16
|
+
readonly wakeAlarm: "/__fastagent/wake-alarm";
|
|
17
|
+
/** Re-mint the state snapshot's presigned URLs with current Lambda credentials (ingress secret). */
|
|
18
|
+
readonly stateUrls: "/__fastagent/state-urls";
|
|
19
|
+
};
|
|
20
|
+
/** Presigned S3 URLs for the one snapshot object, minted per envelope by the forwarder. */
|
|
21
|
+
export interface StateUrls {
|
|
22
|
+
getUrl: string;
|
|
23
|
+
putUrl: string;
|
|
24
|
+
/** Authenticated forwarder callback that re-mints URLs with current Lambda credentials. */
|
|
25
|
+
refresh?: {
|
|
26
|
+
url: string;
|
|
27
|
+
auth: string;
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
/** Every kind the container's `POST /invocations` dispatches on. Listed as a value so the forwarder
|
|
31
|
+
* pin test can check each one is spelled the same on the other side. */
|
|
32
|
+
export declare const ENVELOPE_KINDS: readonly ["webhook", "schedule-fire", "invoke", "wake-poke", "checkpoint", "probe"];
|
|
33
|
+
/** What the forwarder Lambda / EventBridge deliver in the `/invocations` payload. Every kind may
|
|
34
|
+
* carry `wake` — the forwarder's self-resolved public URL, which the adapter persists so the wake
|
|
35
|
+
* ALARM sink (schedule/wake-alarm.ts) can call back without the URL being baked anywhere. */
|
|
36
|
+
export type AgentcoreEnvelope = {
|
|
37
|
+
/** Shared secret proving this envelope came from the forwarder (FASTAGENT_INGRESS_SECRET). The
|
|
38
|
+
* public `invoke` data plane neither has nor needs it — and may not carry the fields below. */
|
|
39
|
+
auth?: string;
|
|
40
|
+
wake?: {
|
|
41
|
+
url: string;
|
|
42
|
+
};
|
|
43
|
+
state?: StateUrls;
|
|
44
|
+
} & ({
|
|
45
|
+
kind: "webhook";
|
|
46
|
+
/** Original webhook request line, verbatim. `path` must be absolute ("/telegram"). */
|
|
47
|
+
method: string;
|
|
48
|
+
path: string;
|
|
49
|
+
/** Original raw query string (no leading `?`) — "verbatim" includes it; a channel reading
|
|
50
|
+
* `request.url.searchParams` must see what the webhook sender sent. */
|
|
51
|
+
query?: string;
|
|
52
|
+
/** Original headers — signature material (secret tokens, Feishu signatures) rides here. */
|
|
53
|
+
headers?: Record<string, string>;
|
|
54
|
+
/** Original body, base64 (webhook bodies are JSON but the tunnel must be byte-exact). */
|
|
55
|
+
bodyB64?: string;
|
|
56
|
+
} | {
|
|
57
|
+
kind: "schedule-fire";
|
|
58
|
+
name: string;
|
|
59
|
+
/** The cron instant this fire is FOR (ISO) — the slot-idempotency key. */
|
|
60
|
+
slot: string;
|
|
61
|
+
} | {
|
|
62
|
+
kind: "invoke";
|
|
63
|
+
session: string;
|
|
64
|
+
text: string;
|
|
65
|
+
}
|
|
66
|
+
/** An EventBridge wake-up poke: the invocation ITSELF is the payload — it wakes the container,
|
|
67
|
+
* whose boot drain / 30s wake pump then fires whatever is due. The handler only acks. */
|
|
68
|
+
| {
|
|
69
|
+
kind: "wake-poke";
|
|
70
|
+
}
|
|
71
|
+
/** Pre-stop checkpoint (`--run`, right before stop-runtime-session): push the state snapshot NOW.
|
|
72
|
+
* A stop cuts an in-flight turn, and its durable turn intent — written pre-ACK by every replaying
|
|
73
|
+
* channel — lives on a mount the version update is about to erase. Flushing first is what makes
|
|
74
|
+
* "channels with replay re-run it" true rather than aspirational. */
|
|
75
|
+
| {
|
|
76
|
+
kind: "checkpoint";
|
|
77
|
+
}
|
|
78
|
+
/** The deploy driver's post-deploy verification (relayed by the forwarder's reserved probe path,
|
|
79
|
+
* which answers on EVERY forwarder topology — schedule-only URLs refuse ordinary public traffic).
|
|
80
|
+
* Runs restore + channel construction end to end and answers a TRANSPORT-200 structured verdict
|
|
81
|
+
* `{ ok, error? }`: the ordinary webhook path folds a non-200 transport into an opaque 502 at the
|
|
82
|
+
* forwarder, which would strip exactly the diagnostics this probe exists to carry. */
|
|
83
|
+
| {
|
|
84
|
+
kind: "probe";
|
|
85
|
+
});
|
|
86
|
+
/** The webhook envelope's reply: the channel's real HTTP response, ridden inside a transport-200
|
|
87
|
+
* body so the forwarder can re-emit it verbatim (AgentCore folds a container non-2xx into its own
|
|
88
|
+
* 424 RuntimeClientError). */
|
|
89
|
+
export interface WebhookReply {
|
|
90
|
+
status: number;
|
|
91
|
+
headers: Record<string, string>;
|
|
92
|
+
bodyB64: string;
|
|
93
|
+
}
|
|
94
|
+
/** One desired alarm: mirror of a pending wake-up (id names the EventBridge schedule; at = fireAt). */
|
|
95
|
+
export interface WakeAlarm {
|
|
96
|
+
id: string;
|
|
97
|
+
at: string;
|
|
98
|
+
}
|
|
99
|
+
/** The wire shape the wake sink POSTs to {@link RESERVED_PATHS.wakeAlarm} (the forwarder validates `secret`). */
|
|
100
|
+
export interface WakeAlarmRequest {
|
|
101
|
+
secret: string;
|
|
102
|
+
alarms: WakeAlarm[];
|
|
103
|
+
}
|
|
104
|
+
/** What EventBridge hands the forwarder for a cron slot; `slot` is `<aws.scheduler.scheduled-time>`.
|
|
105
|
+
* Its sibling, the wake-alarm poke `{ wakePoke: true }`, is minted and read inside the forwarder
|
|
106
|
+
* alone (`syncAlarms` writes it, the handler reads it), so it has no type here. */
|
|
107
|
+
export interface ScheduleFireEvent {
|
|
108
|
+
scheduleFire: {
|
|
109
|
+
name: string;
|
|
110
|
+
slot: string;
|
|
111
|
+
};
|
|
112
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The wire between the forwarder Lambda and the container, in ONE place: the envelope every
|
|
3
|
+
* trigger arrives as, the reply a webhook rides back in, the presigned-URL pair the state snapshot
|
|
4
|
+
* uses, the wake-alarm request, and the forwarder's reserved paths. The forwarder itself is JavaScript
|
|
5
|
+
* (`deploy/agentcore/forwarder.js`) and cannot import this, so `agentcore-forwarder.test.ts` pins its
|
|
6
|
+
* literals to these — a rename here fails there, not on a live box.
|
|
7
|
+
*
|
|
8
|
+
* Pure types and constants: the adapter, the state sync, the wake sink and the deploy driver all
|
|
9
|
+
* read it, and none of them may pull the others in for it.
|
|
10
|
+
*/
|
|
11
|
+
/** Paths the forwarder answers ITSELF — never forwarded to a channel route. */
|
|
12
|
+
export const RESERVED_PATHS = {
|
|
13
|
+
/** The deploy driver's post-deploy verification (ingress secret). */
|
|
14
|
+
probe: "/__fastagent/probe",
|
|
15
|
+
/** The container's wake-alarm mirror callback (wake secret). */
|
|
16
|
+
wakeAlarm: "/__fastagent/wake-alarm",
|
|
17
|
+
/** Re-mint the state snapshot's presigned URLs with current Lambda credentials (ingress secret). */
|
|
18
|
+
stateUrls: "/__fastagent/state-urls",
|
|
19
|
+
};
|
|
20
|
+
/** Every kind the container's `POST /invocations` dispatches on. Listed as a value so the forwarder
|
|
21
|
+
* pin test can check each one is spelled the same on the other side. */
|
|
22
|
+
export const ENVELOPE_KINDS = ["webhook", "schedule-fire", "invoke", "wake-poke", "checkpoint", "probe"];
|
|
@@ -18,37 +18,34 @@ import type { Agent } from "../agent.ts";
|
|
|
18
18
|
import type { Routes } from "../channel.ts";
|
|
19
19
|
import type { LoadedSchedule } from "../schedule/schedule.ts";
|
|
20
20
|
import { type AgentService, type MountableAgent } from "../service.ts";
|
|
21
|
-
import { type
|
|
21
|
+
import { type AgentcoreAdapterOptions } from "./agentcore.ts";
|
|
22
22
|
export interface MountAgentcoreServiceOptions {
|
|
23
23
|
/** Wrap the opened agent before anything binds to it (the CLI's turn trace). */
|
|
24
24
|
wrapAgent?: (agent: Agent) => Agent;
|
|
25
25
|
/** Runs once the state snapshot is restored. The wake-alarm reconcile passes through here because
|
|
26
26
|
* its sink is a PROCESS-global: the process entry owns that, not a service that can be closed. */
|
|
27
27
|
onStateReady?: () => void;
|
|
28
|
-
control?: {
|
|
29
|
-
tunnel?: boolean;
|
|
30
|
-
host?: string;
|
|
31
|
-
};
|
|
32
28
|
}
|
|
33
29
|
/** Is this process running inside the AgentCore Runtime? Set by the generated deploy artifacts. */
|
|
34
30
|
export declare function isAgentcoreRuntime(): boolean;
|
|
35
31
|
export declare function mountAgentcoreService(opened: MountableAgent, options?: MountAgentcoreServiceOptions): Promise<AgentService>;
|
|
36
32
|
/**
|
|
37
|
-
* Mount the AgentCore Runtime adapter (`POST /invocations` + `GET /ping`)
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
* the
|
|
33
|
+
* Mount the AgentCore Runtime adapter (`POST /invocations` + `GET /ping`) — the deployed container's
|
|
34
|
+
* ONLY reachable surface (channels/agentcore.ts). Wired by `start` when `FASTAGENT_AGENTCORE=1` (set
|
|
35
|
+
* by the generated deploy artifacts, never by hand).
|
|
36
|
+
*
|
|
37
|
+
* The adapter IS the surface: the agent's channels live in a table INSIDE the envelope dispatch, a
|
|
38
|
+
* separate namespace from these two paths, so a channel route named `/invocations` is reached
|
|
39
|
+
* through the Function URL as itself and cannot shadow anything.
|
|
42
40
|
*/
|
|
43
|
-
export declare function mountAgentcore(
|
|
41
|
+
export declare function mountAgentcore(options: {
|
|
44
42
|
agent: Agent;
|
|
45
43
|
stateRoot: string;
|
|
46
44
|
schedules: readonly LoadedSchedule[];
|
|
47
45
|
onStateReady?: () => void;
|
|
48
46
|
/** Cancels the adapter's process-global registrations on close. */
|
|
49
47
|
signal?: AbortSignal;
|
|
50
|
-
/** The
|
|
51
|
-
*
|
|
52
|
-
|
|
53
|
-
lazyChannels?: () => Promise<RouteSurface>;
|
|
48
|
+
/** The channel surface, constructed on the first envelope AFTER the state-snapshot restore — never
|
|
49
|
+
* at boot, where the mount is pre-restore (channels/agentcore.ts). */
|
|
50
|
+
channels: AgentcoreAdapterOptions["channels"];
|
|
54
51
|
}): Routes;
|
|
@@ -4,7 +4,7 @@ import { assertNoControlPlaneCollision, mountSessionControl, routesFor, startSch
|
|
|
4
4
|
import { UnknownScheduleError, agentcoreRoutes } from "./agentcore.js";
|
|
5
5
|
import { createStateSync } from "./agentcore-state.js";
|
|
6
6
|
import { activeWork } from "./busy.js";
|
|
7
|
-
import {
|
|
7
|
+
import { router } from "./serve.js";
|
|
8
8
|
/** Is this process running inside the AgentCore Runtime? Set by the generated deploy artifacts. */
|
|
9
9
|
export function isAgentcoreRuntime() {
|
|
10
10
|
return process.env.FASTAGENT_AGENTCORE === "1";
|
|
@@ -14,7 +14,7 @@ export async function mountAgentcoreService(opened, options = {}) {
|
|
|
14
14
|
const agent = options.wrapAgent?.(opened.agent) ?? opened.agent;
|
|
15
15
|
// The control plane mounts over an EMPTY route surface: the lazy channels join it later, and the
|
|
16
16
|
// collision rule runs again then (below) against what they actually brought.
|
|
17
|
-
const withControl = mountSessionControl({}, sessionControl,
|
|
17
|
+
const withControl = mountSessionControl({}, sessionControl, { agent });
|
|
18
18
|
const scheduled = await startSchedules(agentDir, agent, stateRoot, opened.selfSchedule, {
|
|
19
19
|
externalClock: true,
|
|
20
20
|
});
|
|
@@ -32,17 +32,16 @@ export async function mountAgentcoreService(opened, options = {}) {
|
|
|
32
32
|
};
|
|
33
33
|
// The adapter registers process-global listeners; this is what takes them down on close.
|
|
34
34
|
const closed = new AbortController();
|
|
35
|
-
const adapterRoutes = mountAgentcore({
|
|
35
|
+
const adapterRoutes = mountAgentcore({
|
|
36
36
|
signal: closed.signal,
|
|
37
37
|
agent,
|
|
38
38
|
stateRoot,
|
|
39
39
|
schedules: scheduled.schedules,
|
|
40
40
|
onStateReady: options.onStateReady,
|
|
41
|
-
lazyChannels,
|
|
41
|
+
channels: lazyChannels,
|
|
42
42
|
});
|
|
43
43
|
const handler = router(adapterRoutes, withControl.mounts);
|
|
44
44
|
log.info(`[fastagent] agentcore: serving POST /invocations + GET /ping (FASTAGENT_AGENTCORE=1)`);
|
|
45
|
-
let unannounce;
|
|
46
45
|
return {
|
|
47
46
|
handler,
|
|
48
47
|
agent,
|
|
@@ -56,30 +55,28 @@ export async function mountAgentcoreService(opened, options = {}) {
|
|
|
56
55
|
schedules: scheduled.schedules,
|
|
57
56
|
ready: Promise.resolve(), // nothing to open: no port of our own, no resident connections
|
|
58
57
|
...(withControl.control ? { control: withControl.control } : {}),
|
|
59
|
-
announce(boundPort) {
|
|
60
|
-
unannounce = withControl.announce(boundPort);
|
|
61
|
-
},
|
|
62
58
|
async close() {
|
|
63
59
|
// UNTESTED, deliberately noted: no test observes these timers being cleared. Installing fake
|
|
64
60
|
// timers early enough to count them deadlocks the assembly's own IO. What IS tested is that
|
|
65
61
|
// close() runs and is idempotent; the stop itself rides on scheduler.stop()'s own tests.
|
|
66
62
|
scheduled.stop();
|
|
67
63
|
closed.abort();
|
|
68
|
-
unannounce?.(); // a stale discovery file would point `attach` at a stopped service
|
|
69
64
|
},
|
|
70
65
|
};
|
|
71
66
|
}
|
|
72
67
|
/**
|
|
73
|
-
* Mount the AgentCore Runtime adapter (`POST /invocations` + `GET /ping`)
|
|
74
|
-
*
|
|
75
|
-
*
|
|
76
|
-
*
|
|
77
|
-
* the
|
|
68
|
+
* Mount the AgentCore Runtime adapter (`POST /invocations` + `GET /ping`) — the deployed container's
|
|
69
|
+
* ONLY reachable surface (channels/agentcore.ts). Wired by `start` when `FASTAGENT_AGENTCORE=1` (set
|
|
70
|
+
* by the generated deploy artifacts, never by hand).
|
|
71
|
+
*
|
|
72
|
+
* The adapter IS the surface: the agent's channels live in a table INSIDE the envelope dispatch, a
|
|
73
|
+
* separate namespace from these two paths, so a channel route named `/invocations` is reached
|
|
74
|
+
* through the Function URL as itself and cannot shadow anything.
|
|
78
75
|
*/
|
|
79
|
-
export function mountAgentcore(
|
|
80
|
-
const { agent, stateRoot, schedules, onStateReady,
|
|
81
|
-
|
|
82
|
-
|
|
76
|
+
export function mountAgentcore(options) {
|
|
77
|
+
const { agent, stateRoot, schedules, onStateReady, channels, signal } = options;
|
|
78
|
+
return agentcoreRoutes({
|
|
79
|
+
channels,
|
|
83
80
|
agent,
|
|
84
81
|
stateRoot,
|
|
85
82
|
isBusy: () => activeWork() > 0,
|
|
@@ -102,10 +99,4 @@ export function mountAgentcore(routes, options) {
|
|
|
102
99
|
return fireScheduleOnce({ agent, stateRoot, schedule, slot });
|
|
103
100
|
},
|
|
104
101
|
});
|
|
105
|
-
const collisions = Object.keys(routes).filter((key) => Object.keys(mounted).some((adapterKey) => routeKeysConflict(key, adapterKey)));
|
|
106
|
-
if (collisions.length > 0) {
|
|
107
|
-
throw new Error(`channel route(s) ${collisions.map((key) => `"${key}"`).join(", ")} collide with the AgentCore adapter ` +
|
|
108
|
-
`(/invocations, /ping) — rename the channel route`);
|
|
109
|
-
}
|
|
110
|
-
return { ...routes, ...mounted };
|
|
111
102
|
}
|
|
@@ -19,21 +19,15 @@
|
|
|
19
19
|
* half-applied state root is far worse than a slightly stale one.
|
|
20
20
|
*/
|
|
21
21
|
import { Buffer } from "node:buffer";
|
|
22
|
+
import type { StateUrls } from "./agentcore-protocol.ts";
|
|
22
23
|
/** Snapshot envelope version — an unknown version fails the restore loudly (never a silent skip). */
|
|
23
24
|
export declare const SNAPSHOT_VERSION = 1;
|
|
24
25
|
/** Refuse to pack beyond this (before gzip): a runaway state root would OOM the microVM silently. */
|
|
25
26
|
export declare const MAX_SNAPSHOT_BYTES: number;
|
|
26
|
-
/**
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
/** Authenticated forwarder callback that re-mints URLs with current Lambda credentials. */
|
|
31
|
-
refresh?: {
|
|
32
|
-
url: string;
|
|
33
|
-
auth: string;
|
|
34
|
-
};
|
|
35
|
-
}
|
|
36
|
-
/** Pack the whole state root into one gzipped snapshot object. */
|
|
27
|
+
/** Pack the whole state root into one gzipped snapshot object.
|
|
28
|
+
* ponytail: the WHOLE root, every idle edge — O(state size) per settled turn, and session jsonl
|
|
29
|
+
* grows without bound. Upgrade path when the 16 MiB warning is real for someone: a per-file
|
|
30
|
+
* manifest with content hashes, uploading only what changed. */
|
|
37
31
|
export declare function packStateRoot(stateRoot: string, maxBytes?: number): Promise<Buffer>;
|
|
38
32
|
/** Apply a snapshot over the state root. Returns how many files were written. */
|
|
39
33
|
export declare function unpackIntoStateRoot(stateRoot: string, packed: Buffer): Promise<number>;
|
|
@@ -72,7 +72,10 @@ async function walk(root, dir = root, out = []) {
|
|
|
72
72
|
}
|
|
73
73
|
return out;
|
|
74
74
|
}
|
|
75
|
-
/** Pack the whole state root into one gzipped snapshot object.
|
|
75
|
+
/** Pack the whole state root into one gzipped snapshot object.
|
|
76
|
+
* ponytail: the WHOLE root, every idle edge — O(state size) per settled turn, and session jsonl
|
|
77
|
+
* grows without bound. Upgrade path when the 16 MiB warning is real for someone: a per-file
|
|
78
|
+
* manifest with content hashes, uploading only what changed. */
|
|
76
79
|
export async function packStateRoot(stateRoot, maxBytes = MAX_SNAPSHOT_BYTES) {
|
|
77
80
|
const files = {};
|
|
78
81
|
let raw = 0;
|
|
@@ -1,77 +1,8 @@
|
|
|
1
1
|
import type { Agent } from "../agent.ts";
|
|
2
|
-
import type { StateSync
|
|
2
|
+
import type { StateSync } from "./agentcore-state.ts";
|
|
3
3
|
import type { Routes } from "../channel.ts";
|
|
4
4
|
import { type PrefixMount } from "../channels/serve.ts";
|
|
5
5
|
import type { ScheduleFireOutcome } from "../schedule/scheduler.ts";
|
|
6
|
-
/**
|
|
7
|
-
* The HOST's webhook body limit, and the one place it is computed. Lambda Function URLs cap a request
|
|
8
|
-
* at 6 MB, so the forwarder cannot deliver more than that no matter what the adapter accepts; the
|
|
9
|
-
* body arrives base64-encoded (×4/3) inside a JSON envelope, so the ORIGINAL body ceiling is smaller
|
|
10
|
-
* still. This is a real capability difference from a resident host — the GitHub channel's own
|
|
11
|
-
* contract is 25 MiB — so `deploy agentcore` says so at plan time rather than letting an oversized
|
|
12
|
-
* payload surface as an opaque 502.
|
|
13
|
-
*/
|
|
14
|
-
/** What the forwarder Lambda / EventBridge deliver in the `/invocations` payload. Every kind may
|
|
15
|
-
* carry `wake` — the forwarder's self-resolved public URL, which the adapter persists so the wake
|
|
16
|
-
* ALARM sink (schedule/wake-alarm.ts) can call back without the URL being baked anywhere. */
|
|
17
|
-
export type AgentcoreEnvelope = {
|
|
18
|
-
/** Shared secret proving this envelope came from the forwarder (FASTAGENT_INGRESS_SECRET). The
|
|
19
|
-
* public `invoke` data plane neither has nor needs it — and may not carry the fields below. */
|
|
20
|
-
auth?: string;
|
|
21
|
-
wake?: {
|
|
22
|
-
url: string;
|
|
23
|
-
};
|
|
24
|
-
state?: StateUrls;
|
|
25
|
-
} & ({
|
|
26
|
-
kind: "webhook";
|
|
27
|
-
/** Original webhook request line, verbatim. `path` must be absolute ("/telegram"). */
|
|
28
|
-
method: string;
|
|
29
|
-
path: string;
|
|
30
|
-
/** Original raw query string (no leading `?`) — "verbatim" includes it; a channel reading
|
|
31
|
-
* `request.url.searchParams` must see what the webhook sender sent. */
|
|
32
|
-
query?: string;
|
|
33
|
-
/** Original headers — signature material (secret tokens, Feishu signatures) rides here. */
|
|
34
|
-
headers?: Record<string, string>;
|
|
35
|
-
/** Original body, base64 (webhook bodies are JSON but the tunnel must be byte-exact). */
|
|
36
|
-
bodyB64?: string;
|
|
37
|
-
} | {
|
|
38
|
-
kind: "schedule-fire";
|
|
39
|
-
name: string;
|
|
40
|
-
/** The cron instant this fire is FOR (ISO) — the slot-idempotency key. */
|
|
41
|
-
slot: string;
|
|
42
|
-
} | {
|
|
43
|
-
kind: "invoke";
|
|
44
|
-
session: string;
|
|
45
|
-
text: string;
|
|
46
|
-
}
|
|
47
|
-
/** An EventBridge wake-up poke: the invocation ITSELF is the payload — it wakes the container,
|
|
48
|
-
* whose boot drain / 30s wake pump then fires whatever is due. The handler only acks. */
|
|
49
|
-
| {
|
|
50
|
-
kind: "wake-poke";
|
|
51
|
-
}
|
|
52
|
-
/** Pre-stop checkpoint (`--run`, right before stop-runtime-session): push the state snapshot NOW.
|
|
53
|
-
* A stop cuts an in-flight turn, and its durable turn intent — written pre-ACK by every replaying
|
|
54
|
-
* channel — lives on a mount the version update is about to erase. Flushing first is what makes
|
|
55
|
-
* "channels with replay re-run it" true rather than aspirational. */
|
|
56
|
-
| {
|
|
57
|
-
kind: "checkpoint";
|
|
58
|
-
}
|
|
59
|
-
/** The deploy driver's post-deploy verification (relayed by the forwarder's reserved
|
|
60
|
-
* `/__fastagent/probe` path, which answers on EVERY forwarder topology — schedule-only URLs
|
|
61
|
-
* refuse ordinary public traffic). Runs restore + channel construction end to end and answers a
|
|
62
|
-
* TRANSPORT-200 structured verdict `{ ok, error? }`: the ordinary webhook path folds a non-200
|
|
63
|
-
* transport into an opaque 502 at the forwarder, which would strip exactly the diagnostics this
|
|
64
|
-
* probe exists to carry. */
|
|
65
|
-
| {
|
|
66
|
-
kind: "probe";
|
|
67
|
-
});
|
|
68
|
-
/** The webhook envelope's reply: the channel's real HTTP response, ridden inside a transport-200
|
|
69
|
-
* body so the forwarder can re-emit it verbatim (see the module header on AgentCore's 424 folding). */
|
|
70
|
-
export interface WebhookReply {
|
|
71
|
-
status: number;
|
|
72
|
-
headers: Record<string, string>;
|
|
73
|
-
bodyB64: string;
|
|
74
|
-
}
|
|
75
6
|
/** What the lazy factory hands back: literal routes plus any prefix-owning mounts (the control
|
|
76
7
|
* plane), so the adapter's INNER dispatch is assembled exactly like a direct host's. */
|
|
77
8
|
export interface RouteSurface {
|
|
@@ -79,13 +10,14 @@ export interface RouteSurface {
|
|
|
79
10
|
mounts?: readonly PrefixMount[];
|
|
80
11
|
}
|
|
81
12
|
export interface AgentcoreAdapterOptions {
|
|
82
|
-
/** The serving routes a direct deployment would mount (channels or the builtin invoke + health)
|
|
83
|
-
*
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
*
|
|
87
|
-
*
|
|
88
|
-
|
|
13
|
+
/** The serving routes a direct deployment would mount (channels or the builtin invoke + health),
|
|
14
|
+
* built LAZILY: channel construction loads channel state and replays durable turn intent, so on
|
|
15
|
+
* AgentCore it must not run until the state root is authoritative — which happens at the first
|
|
16
|
+
* envelope's `stateSync.ready()` (the restore URLs only an envelope carries), never at boot, where
|
|
17
|
+
* the mount is pre-restore (empty after every version update). A factory, not a value: there is no
|
|
18
|
+
* moment during construction at which the right answer is knowable. May answer synchronously — the
|
|
19
|
+
* resolution chain normalizes it either way. */
|
|
20
|
+
channels: () => Promise<RouteSurface> | RouteSurface;
|
|
89
21
|
agent: Agent;
|
|
90
22
|
/** Where the forwarder URL from envelopes is persisted for the wake-alarm sink (the state root). */
|
|
91
23
|
stateRoot: string;
|
|
@@ -108,12 +40,6 @@ export interface AgentcoreAdapterOptions {
|
|
|
108
40
|
* at boot would see the mount the platform just wiped and conclude there is nothing pending. */
|
|
109
41
|
onStateReady?: () => void;
|
|
110
42
|
}
|
|
111
|
-
/**
|
|
112
|
-
* Build the AgentCore serving surface: `{ "POST /invocations", "GET /ping" }`. The caller merges it
|
|
113
|
-
* over its routes (collision-checked at the mount site, serve.ts) — the inner routes stay mounted
|
|
114
|
-
* too, which is harmless (AgentCore routes only /invocations and /ping into the container) and keeps
|
|
115
|
-
* a local `curl` debug surface.
|
|
116
|
-
*/
|
|
117
43
|
export declare function agentcoreRoutes(options: AgentcoreAdapterOptions): Routes;
|
|
118
44
|
/** Thrown by the mount-site `fire` binding when the envelope names a schedule this workspace does
|
|
119
45
|
* not have — the adapter maps it to 404 (deploy drift stays visible in the external clock's logs). */
|