@fastagent-sh/fastagent 0.18.0 → 0.20.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 +25 -7
- package/dist/agent.d.ts +1 -1
- package/dist/agent.js +1 -1
- package/dist/atomic-write.d.ts +23 -0
- package/dist/atomic-write.js +53 -0
- package/dist/{host/node.d.ts → channel.d.ts} +24 -28
- package/dist/channel.js +1 -0
- package/dist/channels/agentcore-limits.d.ts +9 -0
- package/dist/channels/agentcore-limits.js +9 -0
- package/dist/channels/agentcore-service.d.ts +55 -0
- package/dist/channels/agentcore-service.js +107 -0
- package/dist/channels/agentcore.d.ts +22 -20
- package/dist/channels/agentcore.js +20 -11
- package/dist/channels/busy.d.ts +1 -1
- package/dist/channels/busy.js +1 -1
- package/dist/channels/control.d.ts +55 -7
- package/dist/channels/control.js +312 -67
- package/dist/channels/discover.d.ts +59 -0
- package/dist/{engines/pi/channel.js → channels/discover.js} +19 -34
- package/dist/channels/feishu/card.js +1 -1
- package/dist/channels/feishu/context-buffer.d.ts +1 -1
- package/dist/channels/feishu/context-buffer.js +4 -4
- package/dist/channels/feishu/feishu-api.js +6 -9
- package/dist/channels/feishu/feishu.d.ts +1 -1
- package/dist/channels/feishu/feishu.js +41 -24
- package/dist/channels/feishu/invoke-turn.d.ts +1 -1
- package/dist/channels/feishu/invoke-turn.js +3 -4
- package/dist/channels/feishu/preview.d.ts +1 -1
- package/dist/channels/feishu/preview.js +7 -3
- package/dist/channels/feishu/ws-ingress.d.ts +1 -1
- package/dist/channels/github/github.d.ts +1 -1
- package/dist/channels/http.d.ts +11 -7
- package/dist/channels/http.js +1 -109
- package/dist/channels/kit/attachment-path.d.ts +12 -0
- package/dist/channels/kit/attachment-path.js +43 -0
- package/dist/channels/{context-buffer.d.ts → kit/context-buffer.d.ts} +9 -0
- package/dist/channels/{context-buffer.js → kit/context-buffer.js} +13 -2
- package/dist/channels/{invoke-turn-kit.d.ts → kit/invoke-turn-kit.d.ts} +14 -3
- package/dist/channels/{invoke-turn-kit.js → kit/invoke-turn-kit.js} +17 -6
- package/dist/channels/{preview-kit.d.ts → kit/preview-kit.d.ts} +3 -1
- package/dist/channels/{seen.js → kit/seen.js} +1 -1
- package/dist/channels/kit/signature.d.ts +12 -0
- package/dist/channels/kit/signature.js +17 -0
- package/dist/channels/{state.js → kit/state.js} +4 -7
- package/dist/channels/{stop-command.d.ts → kit/stop-command.d.ts} +1 -1
- package/dist/channels/{stop-command.js → kit/stop-command.js} +5 -5
- package/dist/channels/{tasks.d.ts → kit/tasks.d.ts} +1 -1
- package/dist/channels/{tasks.js → kit/tasks.js} +11 -5
- package/dist/channels/{thread-participants.js → kit/thread-participants.js} +1 -1
- package/dist/channels/{turn-queue.js → kit/turn-queue.js} +2 -2
- package/dist/channels/{turn-store.d.ts → kit/turn-store.d.ts} +19 -3
- package/dist/channels/{turn-store.js → kit/turn-store.js} +30 -3
- package/dist/channels/lark/lark.d.ts +1 -1
- package/dist/channels/serve.d.ts +73 -0
- package/dist/channels/serve.js +243 -0
- package/dist/channels/slack/bot-auth.js +3 -14
- package/dist/channels/slack/context-buffer.d.ts +2 -2
- package/dist/channels/slack/context-buffer.js +2 -2
- package/dist/channels/slack/invoke-turn.d.ts +2 -2
- package/dist/channels/slack/invoke-turn.js +13 -6
- package/dist/channels/slack/onboard.js +5 -5
- package/dist/channels/slack/onboarding-state.d.ts +7 -3
- package/dist/channels/slack/onboarding-state.js +13 -20
- package/dist/channels/slack/parse.js +2 -2
- package/dist/channels/slack/preview.d.ts +1 -1
- package/dist/channels/slack/preview.js +11 -3
- package/dist/channels/slack/register-webhook.js +1 -1
- package/dist/channels/slack/scaffold/slack-send.ts +2 -17
- package/dist/channels/slack/slack-api.js +23 -55
- package/dist/channels/slack/slack.d.ts +1 -1
- package/dist/channels/slack/slack.js +20 -20
- package/dist/channels/slack/welcomed.js +1 -1
- package/dist/channels/telegram/context-buffer.d.ts +2 -2
- package/dist/channels/telegram/context-buffer.js +2 -2
- package/dist/channels/telegram/invoke-turn.d.ts +1 -1
- package/dist/channels/telegram/invoke-turn.js +1 -1
- package/dist/channels/telegram/parse.d.ts +21 -1
- package/dist/channels/telegram/parse.js +67 -13
- package/dist/channels/telegram/preview.d.ts +1 -1
- package/dist/channels/telegram/preview.js +6 -2
- 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 +3 -3
- package/dist/channels/telegram/telegram.js +60 -72
- package/dist/channels/telegram/turn-store.d.ts +2 -2
- package/dist/channels/telegram/turn-store.js +2 -2
- package/dist/cli/add-slack.js +6 -5
- package/dist/cli/commands/add.js +1 -5
- package/dist/cli/commands/attach.d.ts +2 -4
- package/dist/cli/commands/attach.js +17 -15
- package/dist/cli/commands/deploy.d.ts +50 -5
- package/dist/cli/commands/deploy.js +183 -134
- package/dist/cli/commands/dev.js +25 -40
- package/dist/cli/commands/fire.js +1 -1
- package/dist/cli/commands/info.js +7 -5
- package/dist/cli/commands/init.js +1 -2
- package/dist/cli/commands/schedule.js +1 -1
- package/dist/cli/commands/start.js +80 -121
- package/dist/cli/commands/tool.js +5 -7
- package/dist/cli/program.js +1 -1
- package/dist/cli/serve.d.ts +22 -70
- package/dist/cli/serve.js +66 -257
- package/dist/cli/shared.d.ts +40 -10
- package/dist/cli/shared.js +53 -6
- package/dist/core.d.ts +3 -5
- package/dist/core.js +7 -5
- package/dist/deploy/agentcore/logs.d.ts +2 -2
- package/dist/deploy/agentcore/logs.js +2 -2
- package/dist/deploy/agentcore/plan.d.ts +12 -10
- package/dist/deploy/agentcore/plan.js +39 -31
- package/dist/deploy/agentcore/run.d.ts +5 -4
- package/dist/deploy/agentcore/run.js +13 -36
- 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 +18 -1
- package/dist/deploy/docker/run.js +10 -0
- package/dist/deploy/fly/plan.d.ts +4 -5
- package/dist/deploy/fly/plan.js +7 -22
- package/dist/deploy/fly/run.d.ts +9 -23
- package/dist/deploy/fly/run.js +32 -68
- package/dist/deploy/preflight.d.ts +6 -7
- package/dist/deploy/preflight.js +27 -23
- package/dist/deploy/railway/plan.d.ts +4 -5
- package/dist/deploy/railway/plan.js +11 -26
- package/dist/deploy/railway/run.d.ts +9 -9
- package/dist/deploy/railway/run.js +40 -40
- package/dist/deploy/runner.js +22 -2
- package/dist/deploy/secrets.d.ts +18 -9
- package/dist/deploy/secrets.js +64 -12
- package/dist/dev-supervisor.js +11 -6
- package/dist/engines/pi/agent-session-factory.d.ts +104 -0
- package/dist/engines/pi/agent-session-factory.js +295 -0
- package/dist/engines/pi/auth.js +43 -43
- package/dist/engines/pi/config.d.ts +5 -5
- package/dist/engines/pi/config.js +1 -1
- package/dist/engines/pi/create.d.ts +67 -42
- package/dist/engines/pi/create.js +142 -72
- package/dist/engines/pi/definition.d.ts +42 -8
- package/dist/engines/pi/definition.js +114 -11
- package/dist/engines/pi/invoke-session.d.ts +22 -19
- package/dist/engines/pi/invoke-session.js +286 -100
- package/dist/engines/pi/login.js +39 -20
- package/dist/engines/pi/models.d.ts +14 -0
- package/dist/engines/pi/models.js +9 -1
- package/dist/engines/pi/open.d.ts +10 -8
- package/dist/engines/pi/open.js +21 -11
- package/dist/engines/pi/report.d.ts +0 -4
- package/dist/engines/pi/report.js +0 -7
- package/dist/engines/pi/search-tools.js +1 -1
- package/dist/engines/pi/service.d.ts +23 -0
- package/dist/engines/pi/service.js +27 -0
- package/dist/engines/pi/session-builder.js +87 -118
- package/dist/engines/pi/session-control.d.ts +28 -14
- package/dist/engines/pi/session-control.js +570 -438
- package/dist/engines/pi/session-inheritance.d.ts +30 -0
- package/dist/engines/pi/session-inheritance.js +261 -0
- 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 +15 -3
- package/dist/engines/pi/session-settings.js +22 -1
- package/dist/engines/pi/session-store.d.ts +140 -0
- package/dist/engines/pi/session-store.js +666 -0
- package/dist/engines/pi/tool-context.d.ts +36 -13
- package/dist/engines/pi/tool-context.js +51 -4
- package/dist/engines/pi/tool.d.ts +5 -5
- package/dist/engines/pi/tool.js +3 -3
- package/dist/engines/pi/turn-kit.d.ts +32 -6
- package/dist/engines/pi/turn-kit.js +28 -1
- package/dist/engines/pi/wake-tool.js +1 -1
- package/dist/env.js +1 -2
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/loader.d.ts +49 -7
- package/dist/loader.js +79 -18
- package/dist/log.d.ts +3 -0
- package/dist/log.js +5 -1
- package/dist/node.d.ts +16 -0
- package/dist/node.js +20 -0
- package/dist/paths.d.ts +26 -0
- package/dist/paths.js +37 -2
- package/dist/pi.d.ts +14 -8
- package/dist/pi.js +6 -5
- package/dist/scaffold/add-channel.js +2 -2
- package/dist/scaffold/init.js +7 -2
- package/dist/scaffold/templates/persona.md +2 -2
- package/dist/scaffold/templates/tools/fetch-url.ts +0 -2
- package/dist/schedule/discover.js +3 -15
- package/dist/schedule/state.js +4 -9
- package/dist/schedule/wake-alarm.d.ts +13 -7
- package/dist/schedule/wake-alarm.js +88 -46
- package/dist/schedule/wakeups.d.ts +2 -2
- package/dist/schedule/wakeups.js +11 -8
- package/dist/service.d.ts +157 -0
- package/dist/service.js +376 -0
- package/dist/session-remote.d.ts +8 -3
- package/dist/session-remote.js +162 -92
- package/dist/session.d.ts +229 -93
- package/dist/session.js +61 -23
- package/dist/telegram.d.ts +1 -1
- package/dist/telegram.js +1 -1
- package/dist/tunnel.d.ts +18 -3
- package/dist/tunnel.js +32 -40
- package/package.json +14 -5
- package/dist/engines/pi/channel.d.ts +0 -37
- package/dist/engines/pi/harness.d.ts +0 -115
- package/dist/engines/pi/harness.js +0 -154
- package/dist/engines/pi/invoke.d.ts +0 -60
- package/dist/engines/pi/invoke.js +0 -459
- package/dist/engines/pi/read-image.d.ts +0 -4
- package/dist/engines/pi/read-image.js +0 -62
- package/dist/engines/pi/sessions.d.ts +0 -60
- package/dist/engines/pi/sessions.js +0 -464
- package/dist/host/node.js +0 -52
- /package/dist/channels/{preview-kit.js → kit/preview-kit.js} +0 -0
- /package/dist/channels/{seen.d.ts → kit/seen.d.ts} +0 -0
- /package/dist/channels/{state.d.ts → kit/state.d.ts} +0 -0
- /package/dist/channels/{text.d.ts → kit/text.d.ts} +0 -0
- /package/dist/channels/{text.js → kit/text.js} +0 -0
- /package/dist/channels/{thread-participants.d.ts → kit/thread-participants.d.ts} +0 -0
- /package/dist/channels/{turn-queue.d.ts → kit/turn-queue.d.ts} +0 -0
package/dist/session.d.ts
CHANGED
|
@@ -1,63 +1,193 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Session control plane — the engine-neutral serving extension beside Agent Handler
|
|
3
|
-
* (docs/design/session-control.md).
|
|
4
|
-
* implementation here is forbidden, exactly like agent.ts.
|
|
3
|
+
* (docs/design/session-control.md). Zero dependencies, no engine import, exactly like agent.ts.
|
|
5
4
|
*
|
|
6
|
-
*
|
|
7
|
-
* modulates the
|
|
5
|
+
* `invoke` remains the only data plane: no run exists without one. Everything here observes a run,
|
|
6
|
+
* modulates it, or manages the records it leaves behind — and the shape follows which of those a
|
|
7
|
+
* call is, not the transport that carries it. A session's PROPERTIES (name, model, thinking level,
|
|
8
|
+
* where its leaf points) are updated; things that HAPPEN to a run (steer, abort, compact) are
|
|
9
|
+
* actions; the set of sessions is a collection. One verb over all three would make a client spell
|
|
10
|
+
* the session id on every call and read "delete" as something dispatched INTO a session that is
|
|
11
|
+
* about to stop existing.
|
|
8
12
|
*/
|
|
9
13
|
import type { Json, Prompt } from "./agent.ts";
|
|
10
14
|
export interface SessionControl {
|
|
11
15
|
capabilities(): SessionCapabilities;
|
|
12
|
-
/** The names this agent exposes — what a composer's `/` completion LISTS. A listing, not
|
|
13
|
-
*
|
|
14
|
-
* sending "use the X skill", filtering a menu) is the client's business. Sessionless (the
|
|
16
|
+
/** The names this agent exposes — what a composer's `/` completion LISTS. A listing, not an
|
|
17
|
+
* invocation surface: the data plane takes prompts as text, so what typing one means (expanding
|
|
18
|
+
* it, sending "use the X skill", filtering a menu) is the client's business. Sessionless (the
|
|
15
19
|
* definition is a deployment fact) but ASYNC, because a definition is allowed to be live: an
|
|
16
20
|
* implementation that re-reads it per turn must answer from that same read, or the list and the
|
|
17
21
|
* behavior diverge. `[]` is a complete answer, not a missing one; a definition the implementation
|
|
18
22
|
* cannot read at all is a deployment fault and MAY reject. */
|
|
19
23
|
commands(): Promise<AgentCommand[]>;
|
|
20
|
-
|
|
24
|
+
sessions: SessionCollection;
|
|
25
|
+
}
|
|
26
|
+
/** The deployment's sessions, as a collection. */
|
|
27
|
+
export interface SessionCollection {
|
|
28
|
+
/** Every session this DEPLOYMENT holds — what a GUI shows as its conversation list, and the only
|
|
29
|
+
* call that is not about ONE session. Deployment-level on purpose: a multi-tenant facade in front
|
|
30
|
+
* of one deployment MUST NOT expose it, because it answers for every user at once. Such a facade
|
|
31
|
+
* does not need it either — `Scope.session` is the Caller's own string, so it already holds the
|
|
32
|
+
* mapping this would return (design §5).
|
|
33
|
+
*
|
|
34
|
+
* The one read that MAY reject: `[]` is a complete answer for a deployment with no sessions, so
|
|
35
|
+
* it would be a lie for a store that cannot be enumerated. Every other read stays TOTAL — their
|
|
36
|
+
* absent fields are answers a control-less deployment gives too. */
|
|
37
|
+
list(): Promise<SessionSummary[]>;
|
|
38
|
+
/**
|
|
39
|
+
* Copy `from`'s history up to entry `at` into a session called `into` — the growth verb beside
|
|
40
|
+
* {@link SessionUpdate.leafEntryId}'s walk, and the two together are what make a session tree
|
|
41
|
+
* usable. Cloning is this with the source's own `leafEntryId`.
|
|
42
|
+
*
|
|
43
|
+
* IDEMPOTENT: `into` is the CALLER's id (the plane never invents one), so repeating a fork that
|
|
44
|
+
* already landed is `ok: true` and writes nothing — a client that retries a request whose response
|
|
45
|
+
* it never saw does not get a second record. `into` naming a session that exists but came from
|
|
46
|
+
* somewhere else rejects `invalid_command`: same id, different history is what the id would then
|
|
47
|
+
* be lying about.
|
|
48
|
+
*
|
|
49
|
+
* Answers a result, not the new session: the caller minted `into` and can {@link get} it.
|
|
50
|
+
*/
|
|
51
|
+
fork(options: {
|
|
52
|
+
from: string;
|
|
53
|
+
at: string;
|
|
54
|
+
into: string;
|
|
55
|
+
}): Promise<SessionResult>;
|
|
56
|
+
/** Bind an id. A PURE BINDING — an id plus the transport it travels on: no state, no lifecycle,
|
|
57
|
+
* nothing to dispose, and it does not check that the session exists (the calls on it answer that,
|
|
58
|
+
* each in its own vocabulary). Two handles for one id are interchangeable. */
|
|
59
|
+
get(session: string): Session;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Can this id be ADDRESSED by a client? A session id is an opaque Caller string, and the data plane
|
|
63
|
+
* takes any of it — but a control plane carries the id as a URL path segment, and three strings are
|
|
64
|
+
* not path segments: the empty one, `.` and `..`. URL normalisation eats them before any router
|
|
65
|
+
* sees them (`encodeURIComponent` does not help; the spec normalises `%2E` too), so a request for
|
|
66
|
+
* `.` arrives as a request for the collection and answers about something else entirely.
|
|
67
|
+
*
|
|
68
|
+
* The rule lives HERE, in the contract, because both sides enforce it and they must not drift: a
|
|
69
|
+
* transport rejects such an id rather than sending a request that will silently address its
|
|
70
|
+
* neighbour, and an implementation refuses to MINT one (a fork target nothing could open) — while a
|
|
71
|
+
* session a channel already created under one keeps running, and keeps appearing in `list()`, since
|
|
72
|
+
* hiding it would be the silent half of the same problem.
|
|
73
|
+
*/
|
|
74
|
+
export declare function isAddressableSession(session: string): boolean;
|
|
75
|
+
/**
|
|
76
|
+
* One session, bound. Every call here is about THIS session, so the id is spelled once.
|
|
77
|
+
*
|
|
78
|
+
* The split inside it is the one the contract is built on: {@link update} sets PROPERTIES (durable,
|
|
79
|
+
* last-wins, applied by the next turn), while the action methods do things TO A RUN (admitted or
|
|
80
|
+
* rejected now, outcome later on the event stream). {@link SessionResult} says which of the two a
|
|
81
|
+
* given answer is.
|
|
82
|
+
*/
|
|
83
|
+
export interface Session {
|
|
84
|
+
readonly id: string;
|
|
85
|
+
state(): Promise<SessionState>;
|
|
21
86
|
/** `since` is an APPEND-ORDER position cursor: "every record appended after the one with this
|
|
22
87
|
* id", regardless of branch structure. Reconstructing the active path in a branched session is
|
|
23
88
|
* the client's job via `parentId` chains from `leafEntryId`. An unknown cursor falls back to a
|
|
24
89
|
* full backfill (correct, merely larger). */
|
|
25
|
-
entries(
|
|
90
|
+
entries(options?: {
|
|
26
91
|
since?: string;
|
|
27
92
|
}): Promise<SessionEntries>;
|
|
28
|
-
events(
|
|
29
|
-
|
|
93
|
+
events(): AsyncIterable<SessionEvent>;
|
|
94
|
+
/** Set durable session properties. Last-wins, applied by every later turn; an empty patch is a
|
|
95
|
+
* no-op that still answers `ok: true`. Fields outside {@link SessionCapabilities.updatable}
|
|
96
|
+
* reject `unsupported_capability`; invalid values reject `invalid_command`. Takes the same lease
|
|
97
|
+
* as a run (`session_busy` while one is in flight).
|
|
98
|
+
*
|
|
99
|
+
* VALIDATION is all-or-nothing: a rejected patch leaves nothing behind, which is what makes
|
|
100
|
+
* `ok: false` safe to retry. The WRITES need not be one operation — an engine may record each
|
|
101
|
+
* property separately — so a failure BETWEEN them answers {@link PARTIAL_UPDATE_CODE}, naming
|
|
102
|
+
* what landed, after an event reporting the record as it now is. */
|
|
103
|
+
update(patch: SessionUpdate): Promise<SessionResult>;
|
|
104
|
+
/** Join the active run: delivered after the current turn's tool calls, before the next model
|
|
105
|
+
* call. Not polyfillable — its delivery point is an engine primitive. */
|
|
106
|
+
steer(prompt: Prompt): Promise<SessionResult>;
|
|
107
|
+
/** Queue for the active run, FIFO, delivered when it is otherwise idle. */
|
|
108
|
+
followUp(prompt: Prompt): Promise<SessionResult>;
|
|
109
|
+
/** Stop the active run — its queues, its retry delay, its cancellable tool work — or an in-flight
|
|
110
|
+
* {@link compact}, which is the same kind of thing: a model call a client must be able to stop. */
|
|
111
|
+
abort(): Promise<SessionResult>;
|
|
112
|
+
/** Summarize the history at a session boundary. ACCEPT-FAST: a full model call, so `ok: true`
|
|
113
|
+
* means admitted and the outcome travels as `compaction_finished{summary|error|aborted}`. */
|
|
114
|
+
compact(options?: {
|
|
115
|
+
instructions?: string;
|
|
116
|
+
}): Promise<SessionResult>;
|
|
117
|
+
/** Destroy the record. The plane's only IRREVERSIBLE call, guarded by the same bearer token as
|
|
118
|
+
* everything else — the only key the framework owns (design §14). Live {@link events} streams for
|
|
119
|
+
* this session END; a later {@link state} answers for a session that no longer exists. */
|
|
120
|
+
delete(): Promise<SessionResult>;
|
|
30
121
|
}
|
|
122
|
+
/** The durable properties {@link Session.update} sets. Every field is optional and last-wins; which
|
|
123
|
+
* ones a deployment accepts is {@link SessionCapabilities.updatable}. */
|
|
124
|
+
export interface SessionUpdate {
|
|
125
|
+
/** The display name `list()` reports — a label, not an identity: the id stays the Caller's. */
|
|
126
|
+
name?: string;
|
|
127
|
+
/** A FastAgent model spec, constrained to {@link SessionCapabilities.allowedModels}. Never a
|
|
128
|
+
* provider credential. */
|
|
129
|
+
model?: string;
|
|
130
|
+
/** A string because supported levels are MODEL-dependent — the set for this session's current
|
|
131
|
+
* model is {@link SessionState.availableThinkingLevels}. */
|
|
132
|
+
thinkingLevel?: string;
|
|
133
|
+
/** Move the session's active leaf: the write verb for the tree `entries()` publishes, and how
|
|
134
|
+
* sibling branches come to exist (the next turn hangs off it). Every entry `entries()` publishes
|
|
135
|
+
* is a legal target; anything else rejects `invalid_command`. A move to where the leaf already is
|
|
136
|
+
* writes nothing. There is no move to the ROOT — "start from nothing" is a new session, not an
|
|
137
|
+
* emptied one. */
|
|
138
|
+
leafEntryId?: string;
|
|
139
|
+
}
|
|
140
|
+
/** What {@link Session.update} can be asked to set. */
|
|
141
|
+
export type SessionUpdateField = keyof SessionUpdate;
|
|
142
|
+
/** Every field name, as a value — what an implementation checks a patch against, and what a
|
|
143
|
+
* transport rejects an unknown key by. The `satisfies` anchor keeps it exhaustive: a field added to
|
|
144
|
+
* {@link SessionUpdate} must be added here too, or this stops compiling. */
|
|
145
|
+
export declare const UPDATE_FIELDS: readonly ["name", "model", "thinkingLevel", "leafEntryId"];
|
|
146
|
+
/**
|
|
147
|
+
* The wire form of the run actions — what a transport carries for {@link Session.steer} and its
|
|
148
|
+
* siblings. Clients use the METHODS; this exists so a transport has one body shape to parse, and so
|
|
149
|
+
* an implementation can answer an unknown `type` as `invalid_command` rather than crashing.
|
|
150
|
+
*/
|
|
151
|
+
export type SessionAction = {
|
|
152
|
+
type: "steer";
|
|
153
|
+
prompt: Prompt;
|
|
154
|
+
} | {
|
|
155
|
+
type: "follow_up";
|
|
156
|
+
prompt: Prompt;
|
|
157
|
+
} | {
|
|
158
|
+
type: "abort";
|
|
159
|
+
} | {
|
|
160
|
+
type: "compact";
|
|
161
|
+
instructions?: string;
|
|
162
|
+
};
|
|
31
163
|
/**
|
|
32
|
-
* STATIC support declaration — sessionless, so nothing here may depend on a session. Two kinds of
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
164
|
+
* STATIC support declaration — sessionless, so nothing here may depend on a session. Two kinds of
|
|
165
|
+
* flag, and the difference decides what a client does with them:
|
|
166
|
+
* - GATES (`steering`, `followUp`, `compaction`, `fork`, `delete`, `updatable`): a client MUST gate
|
|
167
|
+
* its controls on these; calling past one rejects before acceptance with
|
|
36
168
|
* {@link UNSUPPORTED_CAPABILITY_CODE}.
|
|
37
|
-
* - OBSERVATION
|
|
38
|
-
*
|
|
169
|
+
* - OBSERVATION QUALITY (`toolProgress`, `usage`): whether those events/state fields appear at all —
|
|
170
|
+
* nothing to call, nothing to reject.
|
|
39
171
|
*
|
|
40
|
-
* `
|
|
41
|
-
*
|
|
172
|
+
* `allowedModels` may live here because the registry is a deployment fact; thinking LEVELS depend on
|
|
173
|
+
* the model a session is currently running, so they live on
|
|
174
|
+
* {@link SessionState.availableThinkingLevels} — a static list could only answer for one model.
|
|
42
175
|
*
|
|
43
|
-
* `state`/`entries`/`events` are mandatory (the reconnect contract
|
|
176
|
+
* `state`/`entries`/`events` and `sessions.list()` are mandatory (the reconnect contract and the
|
|
177
|
+
* conversation list) and deliberately absent here.
|
|
44
178
|
*/
|
|
45
179
|
export interface SessionCapabilities {
|
|
46
180
|
steering: boolean;
|
|
47
181
|
followUp: boolean;
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
*
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
|
|
57
|
-
* (`SessionEntry.parentId` + `SessionEntries.leafEntryId`) is read-only here. Named after its COMMAND, unlike the older gates (`manualCompaction` gates
|
|
58
|
-
* `compact`, `thinkingLevel` gates `set_thinking`): those already force a client to translate,
|
|
59
|
-
* and a gate keyed by the command literal is the only naming a derived map could ever produce. */
|
|
60
|
-
navigate: boolean;
|
|
182
|
+
compaction: boolean;
|
|
183
|
+
fork: boolean;
|
|
184
|
+
delete: boolean;
|
|
185
|
+
/** Which {@link SessionUpdate} fields this deployment accepts. A patch naming anything else
|
|
186
|
+
* rejects `unsupported_capability` — a LIST rather than a flag per field, so a client reads the
|
|
187
|
+
* same names it writes. */
|
|
188
|
+
updatable: SessionUpdateField[];
|
|
189
|
+
/** The specs `update({ model })` accepts — present iff `model` is updatable. */
|
|
190
|
+
allowedModels?: string[];
|
|
61
191
|
toolProgress: boolean;
|
|
62
192
|
usage: boolean;
|
|
63
193
|
}
|
|
@@ -73,26 +203,28 @@ export interface AgentCommand {
|
|
|
73
203
|
description?: string;
|
|
74
204
|
source: string;
|
|
75
205
|
}
|
|
76
|
-
/** Stable `SessionResult.error.code` for a
|
|
206
|
+
/** Stable `SessionResult.error.code` for a call, or an update field, the implementation does not
|
|
207
|
+
* support — the answer to calling past a {@link SessionCapabilities} gate. */
|
|
77
208
|
export declare const UNSUPPORTED_CAPABILITY_CODE = "unsupported_capability";
|
|
78
|
-
/** Stable `SessionResult.error.code` for a run
|
|
79
|
-
*
|
|
80
|
-
* compaction either (`abort` is also the door out of a `compacting` state; the outcome
|
|
81
|
-
* travels as `compaction_finished{aborted}`). `retryable: false` —
|
|
82
|
-
*
|
|
209
|
+
/** Stable `SessionResult.error.code` for a run action
|
|
210
|
+
* (`steer`/`follow_up`/`abort`) called while the session has no active run — and, for `abort`, no
|
|
211
|
+
* in-flight compaction either (`abort` is also the door out of a `compacting` state; the outcome
|
|
212
|
+
* then travels as `compaction_finished{aborted}`). `retryable: false` — the same call fails again;
|
|
213
|
+
* call it after `state()` shows an active run. */
|
|
83
214
|
export declare const NO_ACTIVE_RUN_CODE = "no_active_run";
|
|
84
|
-
/** Stable `SessionResult.error.code` for a
|
|
85
|
-
*
|
|
86
|
-
*
|
|
215
|
+
/** Stable `SessionResult.error.code` for a PAYLOAD that is invalid for this runtime — an unknown
|
|
216
|
+
* model spec, an unsupported thinking level, an entry id that is not a position, a fork onto an id
|
|
217
|
+
* another history already holds. Permanent for that payload; a different value may succeed.
|
|
218
|
+
* Rejected before acceptance. */
|
|
87
219
|
export declare const INVALID_COMMAND_CODE = "invalid_command";
|
|
88
|
-
/** Stable `SessionResult.error.code` for a
|
|
89
|
-
*
|
|
90
|
-
* unknown id (a typo, a not-yet-started conversation) must not
|
|
91
|
-
* before acceptance; retry
|
|
220
|
+
/** Stable `SessionResult.error.code` for a write against a session that does not exist. Sessions are
|
|
221
|
+
* created by the DATA plane (`invoke`) or copied by `fork`, never minted by an update — a write on
|
|
222
|
+
* an unknown id (a typo, a not-yet-started conversation) must not create a ghost record. Rejected
|
|
223
|
+
* before acceptance; retry once the session's first turn exists. */
|
|
92
224
|
export declare const NO_SUCH_SESSION_CODE = "no_such_session";
|
|
93
|
-
/** Stable `SessionResult.error.code` for a
|
|
94
|
-
*
|
|
95
|
-
*
|
|
225
|
+
/** Stable `SessionResult.error.code` for a write rejected BEFORE acceptance with nothing durable
|
|
226
|
+
* landed — a failed property append, a fork whose copy could not be written, or compact's admission
|
|
227
|
+
* failing (binding the session, the local preparation). Acceptance sits where the work becomes asynchronous and
|
|
96
228
|
* expensive: the model call — compact is accept-fast (holding the dispatch open for a full model
|
|
97
229
|
* call would make acceptance = outcome), and post-acceptance outcomes travel as
|
|
98
230
|
* `compaction_finished{summary|error|aborted}` events. `retryable: true` throughout: the same
|
|
@@ -101,52 +233,35 @@ export declare const NO_SUCH_SESSION_CODE = "no_such_session";
|
|
|
101
233
|
export declare const BOUNDARY_COMMAND_FAILED_CODE = "boundary_command_failed";
|
|
102
234
|
/** Stable `SessionResult.error.code` for `compact` on a session with no compactable history yet —
|
|
103
235
|
* a no-op, not a failure, rejected before acceptance. The {@link NO_ACTIVE_RUN_CODE} pattern:
|
|
104
|
-
* `retryable: false` (as-is retry fails now),
|
|
236
|
+
* `retryable: false` (as-is retry fails now), call it again once the session has grown. */
|
|
105
237
|
export declare const NOTHING_TO_COMPACT_CODE = "nothing_to_compact";
|
|
106
|
-
/** Stable `SessionResult.error.code` for a run
|
|
107
|
-
*
|
|
108
|
-
* {@link NO_ACTIVE_RUN_CODE}: the run existed — and TRANSIENT: the session's next run can be
|
|
109
|
-
*
|
|
110
|
-
*
|
|
111
|
-
*
|
|
238
|
+
/** Stable `SessionResult.error.code` for a run action that reached an active run but could not take
|
|
239
|
+
* effect because the run raced to settlement (or the engine refused it). Distinct from
|
|
240
|
+
* {@link NO_ACTIVE_RUN_CODE}: the run existed — and TRANSIENT: the session's next run can be acted
|
|
241
|
+
* on. Still pre-acceptance — nothing was queued — and `retryable: false`: the same call fails
|
|
242
|
+
* again. (A run registered without modulation controls is a capability problem, not a run problem,
|
|
243
|
+
* and rejects with {@link UNSUPPORTED_CAPABILITY_CODE}.) */
|
|
112
244
|
export declare const RUN_COMMAND_FAILED_CODE = "run_command_failed";
|
|
113
|
-
/**
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
instructions?: string;
|
|
125
|
-
} | {
|
|
126
|
-
type: "set_model";
|
|
127
|
-
model: string;
|
|
128
|
-
} | {
|
|
129
|
-
type: "set_thinking";
|
|
130
|
-
level: string;
|
|
131
|
-
}
|
|
132
|
-
/** Move the session's active leaf to `targetId`, an existing entry — the write verb for the tree
|
|
133
|
-
* `entries()` already publishes (and how sibling branches come to exist: the next turn hangs off
|
|
134
|
-
* the new leaf). Every entry `entries()` publishes is a legal target; a `targetId` that is not
|
|
135
|
-
* one rejects `invalid_command`. A boundary mutation otherwise: same lease as a run. */
|
|
136
|
-
| {
|
|
137
|
-
type: "navigate";
|
|
138
|
-
targetId: string;
|
|
139
|
-
};
|
|
245
|
+
/** What {@link SessionCollection.list} rejects with — the only read that can (see it for why). Not a
|
|
246
|
+
* `SessionResult`: it REJECTS, and a transport carries this code in the error body of a non-2xx
|
|
247
|
+
* (design §13). `retryable: true` — the condition is the store's availability, not the request. */
|
|
248
|
+
export declare const SESSIONS_UNAVAILABLE_CODE = "sessions_unavailable";
|
|
249
|
+
/** Stable `SessionResult.error.code` for a multi-field {@link Session.update} that wrote some of its
|
|
250
|
+
* fields and then failed. It exists because {@link BOUNDARY_COMMAND_FAILED_CODE} promises the
|
|
251
|
+
* opposite — nothing durable landed — and an implementation cannot keep that promise across
|
|
252
|
+
* properties an engine records as separate journal entries. `retryable: false`: re-sending the same
|
|
253
|
+
* patch would re-apply what already landed, so a client reads `state()` (or the `state_changed`
|
|
254
|
+
* this emits first, which reports the record as it now is) and decides what is left to ask for. */
|
|
255
|
+
export declare const PARTIAL_UPDATE_CODE = "partial_update";
|
|
140
256
|
/**
|
|
141
257
|
* Acceptance is not outcome: `ok: true` means admitted or applied, never that the run ultimately
|
|
142
258
|
* succeeded (outcomes are `run_settled` events / the invoke terminal). `ok: false` is guaranteed to
|
|
143
259
|
* mean rejection BEFORE acceptance — nothing was queued or applied. ONE exception to "nothing took
|
|
144
260
|
* effect": a rejected `abort` may still have attributed a concurrently-settling run as `aborted`
|
|
145
261
|
* (the intent was live while the run resolved — see the guarantee boundary in the pi
|
|
146
|
-
* implementation); the settlement is the truth. `error.retryable` means "
|
|
147
|
-
*
|
|
148
|
-
*
|
|
149
|
-
* changed.
|
|
262
|
+
* implementation); the settlement is the truth. `error.retryable` means "the SAME call as-is may
|
|
263
|
+
* succeed"; a `false` with a state-dependent code (e.g. {@link NO_ACTIVE_RUN_CODE}) invites another
|
|
264
|
+
* call only after `state()` shows the condition changed.
|
|
150
265
|
*/
|
|
151
266
|
export type SessionResult = {
|
|
152
267
|
ok: true;
|
|
@@ -159,7 +274,22 @@ export type SessionResult = {
|
|
|
159
274
|
retryable: boolean;
|
|
160
275
|
};
|
|
161
276
|
};
|
|
277
|
+
/** One session in {@link SessionControl.sessions} — a conversation-list row, not a session's
|
|
278
|
+
* contents. `session` is the CALLER's id (the string a channel minted), never a storage name. */
|
|
279
|
+
export interface SessionSummary {
|
|
280
|
+
session: string;
|
|
281
|
+
/** Set by `update({ name })`; absent until then — a client showing a list falls back to `preview`. */
|
|
282
|
+
name?: string;
|
|
283
|
+
createdAt: number;
|
|
284
|
+
updatedAt: number;
|
|
285
|
+
messageCount: number;
|
|
286
|
+
/** First user message, truncated — enough for a list row, not a transcript. */
|
|
287
|
+
preview?: string;
|
|
288
|
+
}
|
|
162
289
|
export interface SessionState {
|
|
290
|
+
/** Set by `update({ name })`, so a client that opens a session directly gets the same label the list
|
|
291
|
+
* showed. */
|
|
292
|
+
name?: string;
|
|
163
293
|
/** `compacting` refers to Phase 2 MANUAL compaction at a session boundary. Automatic overflow
|
|
164
294
|
* compaction happens inside a run's activity window and reports as `running`. */
|
|
165
295
|
status: "idle" | "running" | "compacting";
|
|
@@ -169,7 +299,7 @@ export interface SessionState {
|
|
|
169
299
|
* model cannot do is clamped). Absent where the implementation exposes no model control. */
|
|
170
300
|
model?: string;
|
|
171
301
|
thinkingLevel?: string;
|
|
172
|
-
/** What `
|
|
302
|
+
/** What `update({ thinkingLevel })` accepts for THIS session — re-read after a model change. */
|
|
173
303
|
availableThinkingLevels?: string[];
|
|
174
304
|
pending: {
|
|
175
305
|
steering: number;
|
|
@@ -263,11 +393,15 @@ export type QueueChangedEvent = SessionEvent<"queue_changed", {
|
|
|
263
393
|
}> & {
|
|
264
394
|
runId: string;
|
|
265
395
|
};
|
|
266
|
-
/**
|
|
267
|
-
*
|
|
268
|
-
*
|
|
269
|
-
*
|
|
396
|
+
/** An {@link Session.update} changed durable session state (L2; no runId — a property is set between
|
|
397
|
+
* runs). Carries what LANDED, read back from the record: a patch that set two fields reports both,
|
|
398
|
+
* and one that failed partway reports only what applied.
|
|
399
|
+
*
|
|
400
|
+
* `leafEntryId` reports a deliberate move of the branch head, which a second attached client would
|
|
401
|
+
* otherwise have no signal for. It is NOT a general leaf feed: every turn advances the leaf too,
|
|
402
|
+
* and that is read from `entries()`/`state()` after the run. */
|
|
270
403
|
export type StateChangedEvent = SessionEvent<"state_changed", {
|
|
404
|
+
name?: string;
|
|
271
405
|
model?: string;
|
|
272
406
|
thinkingLevel?: string;
|
|
273
407
|
leafEntryId?: string;
|
|
@@ -289,7 +423,9 @@ export type CompactionFinishedEvent = SessionEvent<"compaction_finished", {
|
|
|
289
423
|
* the next event (message_*, `run_settled`, `compaction_finished`) is the closure, and the
|
|
290
424
|
* engine's `retry_finished` carries no outcome to forward. */
|
|
291
425
|
export type RetryScheduledEvent = SessionEvent<"retry_scheduled", {
|
|
292
|
-
|
|
426
|
+
/** "assistant" is an engine that retries the ANSWER request itself (pi's AgentSession does;
|
|
427
|
+
* pi's own session does; a summarization call is the other two). */
|
|
428
|
+
operation: "assistant" | "compaction" | "branch_summary";
|
|
293
429
|
attempt: number;
|
|
294
430
|
maxAttempts: number;
|
|
295
431
|
delayMs: number;
|
package/dist/session.js
CHANGED
|
@@ -1,23 +1,50 @@
|
|
|
1
|
-
/**
|
|
1
|
+
/**
|
|
2
|
+
* Can this id be ADDRESSED by a client? A session id is an opaque Caller string, and the data plane
|
|
3
|
+
* takes any of it — but a control plane carries the id as a URL path segment, and three strings are
|
|
4
|
+
* not path segments: the empty one, `.` and `..`. URL normalisation eats them before any router
|
|
5
|
+
* sees them (`encodeURIComponent` does not help; the spec normalises `%2E` too), so a request for
|
|
6
|
+
* `.` arrives as a request for the collection and answers about something else entirely.
|
|
7
|
+
*
|
|
8
|
+
* The rule lives HERE, in the contract, because both sides enforce it and they must not drift: a
|
|
9
|
+
* transport rejects such an id rather than sending a request that will silently address its
|
|
10
|
+
* neighbour, and an implementation refuses to MINT one (a fork target nothing could open) — while a
|
|
11
|
+
* session a channel already created under one keeps running, and keeps appearing in `list()`, since
|
|
12
|
+
* hiding it would be the silent half of the same problem.
|
|
13
|
+
*/
|
|
14
|
+
export function isAddressableSession(session) {
|
|
15
|
+
return session !== "" && session !== "." && session !== "..";
|
|
16
|
+
}
|
|
17
|
+
/** Every field name, as a value — what an implementation checks a patch against, and what a
|
|
18
|
+
* transport rejects an unknown key by. The `satisfies` anchor keeps it exhaustive: a field added to
|
|
19
|
+
* {@link SessionUpdate} must be added here too, or this stops compiling. */
|
|
20
|
+
export const UPDATE_FIELDS = [
|
|
21
|
+
"name",
|
|
22
|
+
"model",
|
|
23
|
+
"thinkingLevel",
|
|
24
|
+
"leafEntryId",
|
|
25
|
+
];
|
|
26
|
+
/** Stable `SessionResult.error.code` for a call, or an update field, the implementation does not
|
|
27
|
+
* support — the answer to calling past a {@link SessionCapabilities} gate. */
|
|
2
28
|
export const UNSUPPORTED_CAPABILITY_CODE = "unsupported_capability";
|
|
3
|
-
/** Stable `SessionResult.error.code` for a run
|
|
4
|
-
*
|
|
5
|
-
* compaction either (`abort` is also the door out of a `compacting` state; the outcome
|
|
6
|
-
* travels as `compaction_finished{aborted}`). `retryable: false` —
|
|
7
|
-
*
|
|
29
|
+
/** Stable `SessionResult.error.code` for a run action
|
|
30
|
+
* (`steer`/`follow_up`/`abort`) called while the session has no active run — and, for `abort`, no
|
|
31
|
+
* in-flight compaction either (`abort` is also the door out of a `compacting` state; the outcome
|
|
32
|
+
* then travels as `compaction_finished{aborted}`). `retryable: false` — the same call fails again;
|
|
33
|
+
* call it after `state()` shows an active run. */
|
|
8
34
|
export const NO_ACTIVE_RUN_CODE = "no_active_run";
|
|
9
|
-
/** Stable `SessionResult.error.code` for a
|
|
10
|
-
*
|
|
11
|
-
*
|
|
35
|
+
/** Stable `SessionResult.error.code` for a PAYLOAD that is invalid for this runtime — an unknown
|
|
36
|
+
* model spec, an unsupported thinking level, an entry id that is not a position, a fork onto an id
|
|
37
|
+
* another history already holds. Permanent for that payload; a different value may succeed.
|
|
38
|
+
* Rejected before acceptance. */
|
|
12
39
|
export const INVALID_COMMAND_CODE = "invalid_command";
|
|
13
|
-
/** Stable `SessionResult.error.code` for a
|
|
14
|
-
*
|
|
15
|
-
* unknown id (a typo, a not-yet-started conversation) must not
|
|
16
|
-
* before acceptance; retry
|
|
40
|
+
/** Stable `SessionResult.error.code` for a write against a session that does not exist. Sessions are
|
|
41
|
+
* created by the DATA plane (`invoke`) or copied by `fork`, never minted by an update — a write on
|
|
42
|
+
* an unknown id (a typo, a not-yet-started conversation) must not create a ghost record. Rejected
|
|
43
|
+
* before acceptance; retry once the session's first turn exists. */
|
|
17
44
|
export const NO_SUCH_SESSION_CODE = "no_such_session";
|
|
18
|
-
/** Stable `SessionResult.error.code` for a
|
|
19
|
-
*
|
|
20
|
-
*
|
|
45
|
+
/** Stable `SessionResult.error.code` for a write rejected BEFORE acceptance with nothing durable
|
|
46
|
+
* landed — a failed property append, a fork whose copy could not be written, or compact's admission
|
|
47
|
+
* failing (binding the session, the local preparation). Acceptance sits where the work becomes asynchronous and
|
|
21
48
|
* expensive: the model call — compact is accept-fast (holding the dispatch open for a full model
|
|
22
49
|
* call would make acceptance = outcome), and post-acceptance outcomes travel as
|
|
23
50
|
* `compaction_finished{summary|error|aborted}` events. `retryable: true` throughout: the same
|
|
@@ -26,12 +53,23 @@ export const NO_SUCH_SESSION_CODE = "no_such_session";
|
|
|
26
53
|
export const BOUNDARY_COMMAND_FAILED_CODE = "boundary_command_failed";
|
|
27
54
|
/** Stable `SessionResult.error.code` for `compact` on a session with no compactable history yet —
|
|
28
55
|
* a no-op, not a failure, rejected before acceptance. The {@link NO_ACTIVE_RUN_CODE} pattern:
|
|
29
|
-
* `retryable: false` (as-is retry fails now),
|
|
56
|
+
* `retryable: false` (as-is retry fails now), call it again once the session has grown. */
|
|
30
57
|
export const NOTHING_TO_COMPACT_CODE = "nothing_to_compact";
|
|
31
|
-
/** Stable `SessionResult.error.code` for a run
|
|
32
|
-
*
|
|
33
|
-
* {@link NO_ACTIVE_RUN_CODE}: the run existed — and TRANSIENT: the session's next run can be
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
58
|
+
/** Stable `SessionResult.error.code` for a run action that reached an active run but could not take
|
|
59
|
+
* effect because the run raced to settlement (or the engine refused it). Distinct from
|
|
60
|
+
* {@link NO_ACTIVE_RUN_CODE}: the run existed — and TRANSIENT: the session's next run can be acted
|
|
61
|
+
* on. Still pre-acceptance — nothing was queued — and `retryable: false`: the same call fails
|
|
62
|
+
* again. (A run registered without modulation controls is a capability problem, not a run problem,
|
|
63
|
+
* and rejects with {@link UNSUPPORTED_CAPABILITY_CODE}.) */
|
|
37
64
|
export const RUN_COMMAND_FAILED_CODE = "run_command_failed";
|
|
65
|
+
/** What {@link SessionCollection.list} rejects with — the only read that can (see it for why). Not a
|
|
66
|
+
* `SessionResult`: it REJECTS, and a transport carries this code in the error body of a non-2xx
|
|
67
|
+
* (design §13). `retryable: true` — the condition is the store's availability, not the request. */
|
|
68
|
+
export const SESSIONS_UNAVAILABLE_CODE = "sessions_unavailable";
|
|
69
|
+
/** Stable `SessionResult.error.code` for a multi-field {@link Session.update} that wrote some of its
|
|
70
|
+
* fields and then failed. It exists because {@link BOUNDARY_COMMAND_FAILED_CODE} promises the
|
|
71
|
+
* opposite — nothing durable landed — and an implementation cannot keep that promise across
|
|
72
|
+
* properties an engine records as separate journal entries. `retryable: false`: re-sending the same
|
|
73
|
+
* patch would re-apply what already landed, so a client reads `state()` (or the `state_changed`
|
|
74
|
+
* this emits first, which reports the record as it now is) and decides what is left to ask for. */
|
|
75
|
+
export const PARTIAL_UPDATE_CODE = "partial_update";
|
package/dist/telegram.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/** `@fastagent-sh/fastagent/telegram` — the Telegram bot channel subpath export, kept off the root surface. */
|
|
2
|
-
export { telegramChannel, defaultTelegramRoute, telegramEnvelope, type TelegramChannelOptions, type TelegramUpdate, type TelegramMessage, type TelegramRoute, type TelegramFailure, } from "./channels/telegram/telegram.ts";
|
|
2
|
+
export { telegramChannel, defaultTelegramRoute, telegramEnvelope, telegramStop, type TelegramChannelOptions, type TelegramUpdate, type TelegramMessage, type TelegramRoute, type TelegramFailure, } from "./channels/telegram/telegram.ts";
|
package/dist/telegram.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/** `@fastagent-sh/fastagent/telegram` — the Telegram bot channel subpath export, kept off the root surface. */
|
|
2
|
-
export { telegramChannel, defaultTelegramRoute, telegramEnvelope, } from "./channels/telegram/telegram.js";
|
|
2
|
+
export { telegramChannel, defaultTelegramRoute, telegramEnvelope, telegramStop, } from "./channels/telegram/telegram.js";
|
package/dist/tunnel.d.ts
CHANGED
|
@@ -7,6 +7,8 @@
|
|
|
7
7
|
* Process orchestration, not assembly — lives outside the engine, beside dev-supervisor.ts.
|
|
8
8
|
*/
|
|
9
9
|
import { type ChildProcess } from "node:child_process";
|
|
10
|
+
import type { RegistrationOutcome } from "./channels/registration.ts";
|
|
11
|
+
import type { DeclaredChannel } from "./channels/discover.ts";
|
|
10
12
|
export interface Tunnel {
|
|
11
13
|
url: string;
|
|
12
14
|
close(): void;
|
|
@@ -28,10 +30,23 @@ export declare function startCloudflareTunnel(port: number, spawnFn?: SpawnCloud
|
|
|
28
30
|
* Print the public URL and wire up first-party webhook channels found under `dir` (the agent
|
|
29
31
|
* ROOT): Telegram and Feishu/Lark use runtime credentials; onboarded Slack uses its owner-local config
|
|
30
32
|
* token; GitHub and a manually scaffolded Slack app receive explicit console URLs.
|
|
33
|
+
*
|
|
34
|
+
* Returns what each registrar ANSWERED, because two kinds of caller need different things from a
|
|
35
|
+
* failure. `dev`/`start` are long-running: a webhook that did not register is a logged problem, not
|
|
36
|
+
* a reason to stop serving, and they void this. `deploy … --run` is a command that exits, and an
|
|
37
|
+
* exit 0 there tells its caller the deployment is reachable — so it feeds these through
|
|
38
|
+
* `registrationGate`, exactly as the fly/railway/agentcore runners feed their own registrar calls
|
|
39
|
+
* (docker used to be the one host that could not, because this returned nothing).
|
|
31
40
|
*/
|
|
32
|
-
export declare function announceWebhooks(dir: string, baseUrl: string,
|
|
41
|
+
export declare function announceWebhooks(dir: string, baseUrl: string,
|
|
42
|
+
/** Every declared channel with its ingress. Not a pre-filtered list: this used to accept "the route
|
|
43
|
+
* channels" and default to every basename in `channels/`, which pointed a webhook at a
|
|
44
|
+
* long-connection channel whenever a caller forgot to filter. {@link pointChannelsAt} filters. */
|
|
45
|
+
channels: readonly DeclaredChannel[], opts?: {
|
|
33
46
|
openUrl?: (url: string) => void;
|
|
34
|
-
routeChannels?: string[];
|
|
35
47
|
stateRoot?: string;
|
|
36
|
-
}): Promise<
|
|
48
|
+
}): Promise<{
|
|
49
|
+
kind: string;
|
|
50
|
+
outcome: RegistrationOutcome;
|
|
51
|
+
}[]>;
|
|
37
52
|
export {};
|