@ably/ai-transport 0.1.0 → 0.3.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 +93 -111
- package/dist/ably-ai-transport.js +2401 -1387
- package/dist/ably-ai-transport.js.map +1 -1
- package/dist/ably-ai-transport.umd.cjs +1 -1
- package/dist/ably-ai-transport.umd.cjs.map +1 -1
- package/dist/constants.d.ts +116 -42
- package/dist/core/agent.d.ts +44 -0
- package/dist/core/channel-options.d.ts +57 -0
- package/dist/core/codec/codec-event.d.ts +9 -0
- package/dist/core/codec/decoder.d.ts +24 -24
- package/dist/core/codec/define-codec.d.ts +100 -0
- package/dist/core/codec/encoder.d.ts +10 -12
- package/dist/core/codec/field-bag.d.ts +85 -0
- package/dist/core/codec/fields.d.ts +141 -0
- package/dist/core/codec/index.d.ts +8 -2
- package/dist/core/codec/input-descriptor-decoder.d.ts +19 -0
- package/dist/core/codec/input-descriptor-encoder.d.ts +22 -0
- package/dist/core/codec/input-descriptors.d.ts +281 -0
- package/dist/core/codec/lifecycle-tracker.d.ts +10 -9
- package/dist/core/codec/output-descriptor-decoder.d.ts +29 -0
- package/dist/core/codec/output-descriptor-encoder.d.ts +31 -0
- package/dist/core/codec/output-descriptors.d.ts +237 -0
- package/dist/core/codec/types.d.ts +470 -119
- package/dist/core/codec/well-known-inputs.d.ts +52 -0
- package/dist/core/transport/agent-session.d.ts +10 -0
- package/dist/core/transport/agent-view.d.ts +296 -0
- package/dist/core/transport/client-session.d.ts +13 -0
- package/dist/core/transport/decode-fold.d.ts +55 -0
- package/dist/core/transport/headers.d.ts +121 -14
- package/dist/core/transport/index.d.ts +5 -6
- package/dist/core/transport/internal/bounded-map.d.ts +20 -0
- package/dist/core/transport/invocation.d.ts +74 -0
- package/dist/core/transport/load-history-pages.d.ts +71 -0
- package/dist/core/transport/load-history.d.ts +44 -0
- package/dist/core/transport/pipe-stream.d.ts +9 -9
- package/dist/core/transport/run-manager.d.ts +76 -0
- package/dist/core/transport/session-support.d.ts +55 -0
- package/dist/core/transport/tree.d.ts +523 -109
- package/dist/core/transport/types/agent.d.ts +375 -0
- package/dist/core/transport/types/client.d.ts +201 -0
- package/dist/core/transport/types/shared.d.ts +24 -0
- package/dist/core/transport/types/tree.d.ts +357 -0
- package/dist/core/transport/types/view.d.ts +249 -0
- package/dist/core/transport/types.d.ts +13 -553
- package/dist/core/transport/view.d.ts +390 -84
- package/dist/core/transport/wire-log.d.ts +102 -0
- package/dist/errors.d.ts +27 -10
- package/dist/index.d.ts +8 -9
- package/dist/logger.d.ts +12 -0
- package/dist/react/ably-ai-transport-react.js +1365 -1010
- package/dist/react/ably-ai-transport-react.js.map +1 -1
- package/dist/react/ably-ai-transport-react.umd.cjs +1 -1
- package/dist/react/ably-ai-transport-react.umd.cjs.map +1 -1
- package/dist/react/contexts/client-session-context.d.ts +37 -0
- package/dist/react/contexts/client-session-provider.d.ts +56 -0
- package/dist/react/create-session-hooks.d.ts +116 -0
- package/dist/react/index.d.ts +13 -12
- package/dist/react/internal/skipped-session.d.ts +8 -0
- package/dist/react/internal/use-resolved-session.d.ts +36 -0
- package/dist/react/use-ably-messages.d.ts +17 -14
- package/dist/react/use-client-session.d.ts +81 -0
- package/dist/react/use-create-view.d.ts +14 -13
- package/dist/react/use-tree.d.ts +30 -15
- package/dist/react/use-view.d.ts +81 -50
- package/dist/utils.d.ts +48 -71
- package/dist/vercel/ably-ai-transport-vercel.js +3257 -2499
- package/dist/vercel/ably-ai-transport-vercel.js.map +1 -1
- package/dist/vercel/ably-ai-transport-vercel.umd.cjs +1 -1
- package/dist/vercel/ably-ai-transport-vercel.umd.cjs.map +1 -1
- package/dist/vercel/codec/decode-lifecycle.d.ts +9 -0
- package/dist/vercel/codec/events.d.ts +50 -0
- package/dist/vercel/codec/fields.d.ts +44 -0
- package/dist/vercel/codec/fold-content.d.ts +16 -0
- package/dist/vercel/codec/fold-data.d.ts +16 -0
- package/dist/vercel/codec/fold-input.d.ts +67 -0
- package/dist/vercel/codec/fold-lifecycle.d.ts +16 -0
- package/dist/vercel/codec/fold-text.d.ts +16 -0
- package/dist/vercel/codec/fold-tool-input.d.ts +17 -0
- package/dist/vercel/codec/fold-tool-output.d.ts +16 -0
- package/dist/vercel/codec/index.d.ts +7 -20
- package/dist/vercel/codec/inputs.d.ts +11 -0
- package/dist/vercel/codec/outputs.d.ts +11 -0
- package/dist/vercel/codec/reducer-state.d.ts +121 -0
- package/dist/vercel/codec/reducer.d.ts +62 -0
- package/dist/vercel/codec/tool-transitions.d.ts +2 -8
- package/dist/vercel/codec/wire-data.d.ts +34 -0
- package/dist/vercel/index.d.ts +5 -5
- package/dist/vercel/react/ably-ai-transport-vercel-react.js +2859 -9705
- package/dist/vercel/react/ably-ai-transport-vercel-react.js.map +1 -1
- package/dist/vercel/react/ably-ai-transport-vercel-react.umd.cjs +1 -45
- package/dist/vercel/react/ably-ai-transport-vercel-react.umd.cjs.map +1 -1
- package/dist/vercel/react/contexts/chat-transport-context.d.ts +9 -7
- package/dist/vercel/react/contexts/chat-transport-provider.d.ts +53 -41
- package/dist/vercel/react/index.d.ts +1 -2
- package/dist/vercel/react/use-chat-transport.d.ts +30 -26
- package/dist/vercel/react/use-message-sync.d.ts +17 -30
- package/dist/vercel/run-end-reason.d.ts +84 -0
- package/dist/vercel/tool-part.d.ts +21 -0
- package/dist/vercel/transport/chat-transport.d.ts +41 -24
- package/dist/vercel/transport/index.d.ts +24 -20
- package/dist/vercel/transport/run-output-stream.d.ts +54 -0
- package/dist/version.d.ts +2 -0
- package/package.json +31 -24
- package/src/constants.ts +124 -51
- package/src/core/agent.ts +92 -0
- package/src/core/channel-options.ts +89 -0
- package/src/core/codec/codec-event.ts +27 -0
- package/src/core/codec/decoder.ts +202 -105
- package/src/core/codec/define-codec.ts +432 -0
- package/src/core/codec/encoder.ts +114 -107
- package/src/core/codec/field-bag.ts +142 -0
- package/src/core/codec/fields.ts +193 -0
- package/src/core/codec/index.ts +56 -6
- package/src/core/codec/input-descriptor-decoder.ts +97 -0
- package/src/core/codec/input-descriptor-encoder.ts +150 -0
- package/src/core/codec/input-descriptors.ts +373 -0
- package/src/core/codec/lifecycle-tracker.ts +10 -9
- package/src/core/codec/output-descriptor-decoder.ts +139 -0
- package/src/core/codec/output-descriptor-encoder.ts +101 -0
- package/src/core/codec/output-descriptors.ts +307 -0
- package/src/core/codec/types.ts +505 -126
- package/src/core/codec/well-known-inputs.ts +96 -0
- package/src/core/transport/agent-session.ts +1085 -0
- package/src/core/transport/agent-view.ts +738 -0
- package/src/core/transport/client-session.ts +780 -0
- package/src/core/transport/decode-fold.ts +101 -0
- package/src/core/transport/headers.ts +234 -22
- package/src/core/transport/index.ts +27 -27
- package/src/core/transport/internal/bounded-map.ts +27 -0
- package/src/core/transport/invocation.ts +98 -0
- package/src/core/transport/load-history-pages.ts +220 -0
- package/src/core/transport/load-history.ts +271 -0
- package/src/core/transport/pipe-stream.ts +63 -39
- package/src/core/transport/run-manager.ts +243 -0
- package/src/core/transport/session-support.ts +96 -0
- package/src/core/transport/tree.ts +1293 -308
- package/src/core/transport/types/agent.ts +434 -0
- package/src/core/transport/types/client.ts +247 -0
- package/src/core/transport/types/shared.ts +27 -0
- package/src/core/transport/types/tree.ts +393 -0
- package/src/core/transport/types/view.ts +288 -0
- package/src/core/transport/types.ts +13 -706
- package/src/core/transport/view.ts +1229 -450
- package/src/core/transport/wire-log.ts +189 -0
- package/src/errors.ts +29 -9
- package/src/event-emitter.ts +3 -2
- package/src/index.ts +86 -42
- package/src/logger.ts +14 -1
- package/src/react/contexts/client-session-context.ts +41 -0
- package/src/react/contexts/client-session-provider.tsx +222 -0
- package/src/react/create-session-hooks.ts +141 -0
- package/src/react/index.ts +24 -13
- package/src/react/internal/skipped-session.ts +62 -0
- package/src/react/internal/use-resolved-session.ts +63 -0
- package/src/react/use-ably-messages.ts +32 -22
- package/src/react/use-client-session.ts +178 -0
- package/src/react/use-create-view.ts +33 -29
- package/src/react/use-tree.ts +61 -30
- package/src/react/use-view.ts +138 -96
- package/src/utils.ts +83 -131
- package/src/vercel/codec/decode-lifecycle.ts +70 -0
- package/src/vercel/codec/events.ts +85 -0
- package/src/vercel/codec/fields.ts +58 -0
- package/src/vercel/codec/fold-content.ts +54 -0
- package/src/vercel/codec/fold-data.ts +46 -0
- package/src/vercel/codec/fold-input.ts +255 -0
- package/src/vercel/codec/fold-lifecycle.ts +85 -0
- package/src/vercel/codec/fold-text.ts +55 -0
- package/src/vercel/codec/fold-tool-input.ts +86 -0
- package/src/vercel/codec/fold-tool-output.ts +79 -0
- package/src/vercel/codec/index.ts +28 -21
- package/src/vercel/codec/inputs.ts +116 -0
- package/src/vercel/codec/outputs.ts +207 -0
- package/src/vercel/codec/reducer-state.ts +169 -0
- package/src/vercel/codec/reducer.ts +191 -0
- package/src/vercel/codec/tool-transitions.ts +3 -14
- package/src/vercel/codec/wire-data.ts +64 -0
- package/src/vercel/index.ts +7 -19
- package/src/vercel/react/contexts/chat-transport-context.ts +8 -7
- package/src/vercel/react/contexts/chat-transport-provider.tsx +87 -59
- package/src/vercel/react/index.ts +3 -5
- package/src/vercel/react/use-chat-transport.ts +44 -66
- package/src/vercel/react/use-message-sync.ts +75 -39
- package/src/vercel/run-end-reason.ts +157 -0
- package/src/vercel/tool-part.ts +25 -0
- package/src/vercel/transport/chat-transport.ts +380 -98
- package/src/vercel/transport/index.ts +38 -37
- package/src/vercel/transport/run-output-stream.ts +169 -0
- package/src/version.ts +2 -0
- package/dist/core/transport/client-transport.d.ts +0 -10
- package/dist/core/transport/decode-history.d.ts +0 -43
- package/dist/core/transport/server-transport.d.ts +0 -7
- package/dist/core/transport/stream-router.d.ts +0 -29
- package/dist/core/transport/turn-manager.d.ts +0 -37
- package/dist/react/contexts/transport-context.d.ts +0 -31
- package/dist/react/contexts/transport-provider.d.ts +0 -49
- package/dist/react/create-transport-hooks.d.ts +0 -124
- package/dist/react/use-active-turns.d.ts +0 -12
- package/dist/react/use-client-transport.d.ts +0 -80
- package/dist/vercel/codec/accumulator.d.ts +0 -21
- package/dist/vercel/codec/decoder.d.ts +0 -22
- package/dist/vercel/codec/encoder.d.ts +0 -41
- package/dist/vercel/react/use-staged-add-tool-approval-response.d.ts +0 -30
- package/dist/vercel/tool-approvals.d.ts +0 -124
- package/dist/vercel/tool-events.d.ts +0 -26
- package/src/core/transport/client-transport.ts +0 -977
- package/src/core/transport/decode-history.ts +0 -485
- package/src/core/transport/server-transport.ts +0 -612
- package/src/core/transport/stream-router.ts +0 -136
- package/src/core/transport/turn-manager.ts +0 -165
- package/src/react/contexts/transport-context.ts +0 -37
- package/src/react/contexts/transport-provider.tsx +0 -164
- package/src/react/create-transport-hooks.ts +0 -144
- package/src/react/use-active-turns.ts +0 -72
- package/src/react/use-client-transport.ts +0 -197
- package/src/vercel/codec/accumulator.ts +0 -588
- package/src/vercel/codec/decoder.ts +0 -618
- package/src/vercel/codec/encoder.ts +0 -410
- package/src/vercel/react/use-staged-add-tool-approval-response.ts +0 -87
- package/src/vercel/tool-approvals.ts +0 -380
- package/src/vercel/tool-events.ts +0 -53
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared wire decode-and-apply engine.
|
|
3
|
+
*
|
|
4
|
+
* The client's live decode loop and the View's history replay both reconstruct
|
|
5
|
+
* the conversation Tree from the same raw Ably wire log. This module is the one
|
|
6
|
+
* place that classifies a wire message (run-lifecycle vs codec-decoded), parses
|
|
7
|
+
* or decodes it, and applies it to the Tree — so the two paths can never drift.
|
|
8
|
+
*
|
|
9
|
+
* The engine is exposed as a {@link WireApplier} binding one Tree to one
|
|
10
|
+
* decoder. A Tree has exactly one applier (the session constructs it and hands
|
|
11
|
+
* it to every View), so every route a wire message can arrive by — the live
|
|
12
|
+
* subscription, View history pagination, the agent's hydration walks — feeds
|
|
13
|
+
* the same decoder. The decoder's version-guarded stream trackers then make
|
|
14
|
+
* re-delivery across routes (an attach-boundary in-flight stream, a replayed
|
|
15
|
+
* history page) decode to nothing instead of double-folding. The delivery's
|
|
16
|
+
* `version.serial` is also threaded into the Tree, whose per-entry
|
|
17
|
+
* `decodedThrough` high-water-mark drops whole-wire replays that no decoder
|
|
18
|
+
* state can see (stateless discrete re-decodes).
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
import type * as Ably from 'ably';
|
|
22
|
+
|
|
23
|
+
import { HEADER_RUN_ID } from '../../constants.js';
|
|
24
|
+
import { getTransportHeaders } from '../../utils.js';
|
|
25
|
+
import type { CodecInputEvent, CodecOutputEvent, Decoder } from '../codec/types.js';
|
|
26
|
+
import { isRunLifecycleName, parseRunLifecycle } from './headers.js';
|
|
27
|
+
import type { TreeInternal } from './tree.js';
|
|
28
|
+
import type { RunLifecycleEvent } from './types.js';
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* The decode-and-apply engine for one Tree: a single codec decoder bound to a
|
|
32
|
+
* single Tree, shared by every route that feeds the Tree wire messages.
|
|
33
|
+
*/
|
|
34
|
+
export interface WireApplier {
|
|
35
|
+
/**
|
|
36
|
+
* Apply one inbound wire message to the bound tree.
|
|
37
|
+
*
|
|
38
|
+
* Run-lifecycle messages are turned into a {@link RunLifecycleEvent} via
|
|
39
|
+
* {@link parseRunLifecycle} and applied with `applyRunLifecycle`; everything
|
|
40
|
+
* else is decoded with the bound decoder and applied with `applyMessage`,
|
|
41
|
+
* skipping wire-only carriers that decode to no events and carry no run-id
|
|
42
|
+
* (the eventual reply run is created later by its run-start).
|
|
43
|
+
*
|
|
44
|
+
* Does NOT emit the tree's `ably-message` event — the caller owns that,
|
|
45
|
+
* because the live loop emits per message while history replay emits in a
|
|
46
|
+
* batch once the whole page is applied. Returns the parsed lifecycle event
|
|
47
|
+
* so a live caller can run its own side-effects (resolving a pending
|
|
48
|
+
* run-start, surfacing an agent error); returns `undefined` for a
|
|
49
|
+
* codec-decoded message or a lifecycle message that carried no run-id.
|
|
50
|
+
* @param rawMsg - The inbound Ably wire message.
|
|
51
|
+
* @returns The parsed run-lifecycle event, or `undefined`.
|
|
52
|
+
*/
|
|
53
|
+
apply(rawMsg: Ably.InboundMessage): RunLifecycleEvent | undefined;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Classify, decode, and apply one inbound wire message to the tree. See
|
|
58
|
+
* {@link WireApplier.apply} for the contract.
|
|
59
|
+
* @param tree - The tree to apply the message to.
|
|
60
|
+
* @param decoder - The codec decoder used for non-lifecycle messages.
|
|
61
|
+
* @param rawMsg - The inbound Ably wire message.
|
|
62
|
+
* @returns The parsed run-lifecycle event, or `undefined`.
|
|
63
|
+
*/
|
|
64
|
+
const applyWireMessage = <TInput extends CodecInputEvent, TOutput extends CodecOutputEvent, TProjection>(
|
|
65
|
+
tree: TreeInternal<TInput, TOutput, TProjection>,
|
|
66
|
+
decoder: Decoder<TInput, TOutput>,
|
|
67
|
+
rawMsg: Ably.InboundMessage,
|
|
68
|
+
): RunLifecycleEvent | undefined => {
|
|
69
|
+
const headers = getTransportHeaders(rawMsg);
|
|
70
|
+
const serial = rawMsg.serial;
|
|
71
|
+
// Top-level timestamp — the message's create time on every delivery (an
|
|
72
|
+
// append's own receive time lives in `version.timestamp`). The retention
|
|
73
|
+
// clock is sound on this timeline because run-end, a fresh create published
|
|
74
|
+
// after every wire of its run, bounds the node's last activity.
|
|
75
|
+
const timestamp = rawMsg.timestamp;
|
|
76
|
+
|
|
77
|
+
if (isRunLifecycleName(rawMsg.name)) {
|
|
78
|
+
const event = parseRunLifecycle(rawMsg.name, headers, serial, timestamp);
|
|
79
|
+
if (event) tree.applyRunLifecycle(event);
|
|
80
|
+
return event;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const { inputs, outputs } = decoder.decode(rawMsg);
|
|
84
|
+
if (inputs.length > 0 || outputs.length > 0 || headers[HEADER_RUN_ID]) {
|
|
85
|
+
tree.applyMessage({ inputs, outputs }, headers, serial, timestamp, rawMsg.version.serial);
|
|
86
|
+
}
|
|
87
|
+
return undefined;
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Bind a Tree and a decoder into the Tree's single {@link WireApplier}.
|
|
92
|
+
* @param tree - The tree the applier feeds.
|
|
93
|
+
* @param decoder - The codec decoder shared by every route into the tree.
|
|
94
|
+
* @returns The applier.
|
|
95
|
+
*/
|
|
96
|
+
export const createWireApplier = <TInput extends CodecInputEvent, TOutput extends CodecOutputEvent, TProjection>(
|
|
97
|
+
tree: TreeInternal<TInput, TOutput, TProjection>,
|
|
98
|
+
decoder: Decoder<TInput, TOutput>,
|
|
99
|
+
): WireApplier => ({
|
|
100
|
+
apply: (rawMsg: Ably.InboundMessage): RunLifecycleEvent | undefined => applyWireMessage(tree, decoder, rawMsg),
|
|
101
|
+
});
|
|
@@ -1,50 +1,262 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Transport header builder.
|
|
3
3
|
*
|
|
4
|
-
* Single source of truth for which
|
|
5
|
-
* message carries. Used by the
|
|
6
|
-
*
|
|
4
|
+
* Single source of truth for which transport headers every transport
|
|
5
|
+
* message carries. Used by the agent session (pipe) and by
|
|
6
|
+
* the client session (optimistic message stamping).
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
+
import * as Ably from 'ably';
|
|
10
|
+
|
|
9
11
|
import {
|
|
10
|
-
|
|
12
|
+
EVENT_RUN_END,
|
|
13
|
+
EVENT_RUN_RESUME,
|
|
14
|
+
EVENT_RUN_START,
|
|
15
|
+
EVENT_RUN_SUSPEND,
|
|
16
|
+
HEADER_CODEC_MESSAGE_ID,
|
|
17
|
+
HEADER_ERROR_CODE,
|
|
18
|
+
HEADER_ERROR_MESSAGE,
|
|
19
|
+
HEADER_EVENT_ID,
|
|
11
20
|
HEADER_FORK_OF,
|
|
12
|
-
|
|
21
|
+
HEADER_INPUT_CLIENT_ID,
|
|
22
|
+
HEADER_INPUT_CODEC_MESSAGE_ID,
|
|
23
|
+
HEADER_INVOCATION_ID,
|
|
24
|
+
HEADER_MSG_REGENERATE,
|
|
13
25
|
HEADER_PARENT,
|
|
14
26
|
HEADER_ROLE,
|
|
15
|
-
|
|
16
|
-
|
|
27
|
+
HEADER_RUN_CLIENT_ID,
|
|
28
|
+
HEADER_RUN_ID,
|
|
29
|
+
HEADER_RUN_REASON,
|
|
17
30
|
} from '../../constants.js';
|
|
31
|
+
import { ErrorCode } from '../../errors.js';
|
|
32
|
+
import type { RunEndReason, RunLifecycleEvent } from './types.js';
|
|
18
33
|
|
|
19
34
|
/**
|
|
20
35
|
* Build the standard transport header set for a message.
|
|
21
36
|
* @param opts - The header values to include.
|
|
22
37
|
* @param opts.role - Message role (e.g. "user", "assistant").
|
|
23
|
-
* @param opts.
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
* @param opts.
|
|
27
|
-
* @param opts.
|
|
28
|
-
* @param opts.
|
|
29
|
-
* @
|
|
38
|
+
* @param opts.runId - Run correlation ID, or `undefined` for a fresh client
|
|
39
|
+
* input (the agent mints run-ids, so it is not known synchronously). Omitted
|
|
40
|
+
* from the headers when undefined; a continuation still carries the known run-id.
|
|
41
|
+
* @param opts.codecMessageId - Message identity — the wire `codec-message-id` for this message.
|
|
42
|
+
* @param opts.runClientId - ClientId of the run initiator.
|
|
43
|
+
* @param opts.parent - Preceding message's codec-message-id (for branching).
|
|
44
|
+
* @param opts.forkOf - Forked user-prompt's codec-message-id (for edits — creates a Run-level fork sibling).
|
|
45
|
+
* @param opts.regenerates - Assistant codec-message-id this run regenerates. Stamps
|
|
46
|
+
* `msg-regenerate`. Distinct from `forkOf`: regenerate is a
|
|
47
|
+
* continuation of the prior run (no Run-level fork), with the message
|
|
48
|
+
* replacement resolved at projection extraction time.
|
|
49
|
+
* @param opts.invocationId - Agent-minted invocation id. Stamped by the agent on every event it publishes for the invocation (run lifecycle + outputs) so the client can observe it; not set by the client on the input.
|
|
50
|
+
* @param opts.inputClientId - ClientId of the input event (the `ai-input`) that
|
|
51
|
+
* drove the current invocation. The agent reads it from the publisher's
|
|
52
|
+
* Ably-level `clientId` on the matched input event and re-stamps it on its
|
|
53
|
+
* own publishes (run lifecycle + outputs). Differs from `runClientId` on
|
|
54
|
+
* continuation invocations driven by an input from a non-owner.
|
|
55
|
+
* @param opts.inputEventId - Per-event identifier. Set on each client-published user-prompt message; the invocation body's `inputEventIds` lists the ids the agent should look up.
|
|
56
|
+
* @param opts.inputCodecMessageId - The codec-message-id of the input event that
|
|
57
|
+
* triggered the current invocation (the one whose `event-id` matched the
|
|
58
|
+
* invocation's `inputEventId`). The agent re-stamps it on every event it
|
|
59
|
+
* publishes for the invocation (run lifecycle + outputs), mirroring
|
|
60
|
+
* `inputClientId`, so the client can correlate any of those events back to
|
|
61
|
+
* the originating input by the id it owned at send time.
|
|
62
|
+
* @returns A headers record with the transport headers set.
|
|
30
63
|
*/
|
|
31
64
|
export const buildTransportHeaders = (opts: {
|
|
32
65
|
role: string;
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
66
|
+
runId?: string;
|
|
67
|
+
codecMessageId: string;
|
|
68
|
+
runClientId?: string;
|
|
36
69
|
parent?: string;
|
|
37
70
|
forkOf?: string;
|
|
38
|
-
|
|
71
|
+
regenerates?: string;
|
|
72
|
+
invocationId?: string;
|
|
73
|
+
inputClientId?: string;
|
|
74
|
+
inputCodecMessageId?: string;
|
|
75
|
+
inputEventId?: string;
|
|
39
76
|
}): Record<string, string> => {
|
|
40
77
|
const h: Record<string, string> = {
|
|
41
78
|
[HEADER_ROLE]: opts.role,
|
|
42
|
-
[
|
|
43
|
-
[HEADER_MSG_ID]: opts.msgId,
|
|
79
|
+
[HEADER_CODEC_MESSAGE_ID]: opts.codecMessageId,
|
|
44
80
|
};
|
|
45
|
-
if (opts.
|
|
81
|
+
if (opts.runId !== undefined) h[HEADER_RUN_ID] = opts.runId;
|
|
82
|
+
if (opts.runClientId !== undefined) h[HEADER_RUN_CLIENT_ID] = opts.runClientId;
|
|
46
83
|
if (opts.parent) h[HEADER_PARENT] = opts.parent;
|
|
47
84
|
if (opts.forkOf) h[HEADER_FORK_OF] = opts.forkOf;
|
|
48
|
-
if (opts.
|
|
85
|
+
if (opts.regenerates) h[HEADER_MSG_REGENERATE] = opts.regenerates;
|
|
86
|
+
if (opts.invocationId) h[HEADER_INVOCATION_ID] = opts.invocationId;
|
|
87
|
+
if (opts.inputClientId !== undefined) h[HEADER_INPUT_CLIENT_ID] = opts.inputClientId;
|
|
88
|
+
if (opts.inputCodecMessageId !== undefined) h[HEADER_INPUT_CODEC_MESSAGE_ID] = opts.inputCodecMessageId;
|
|
89
|
+
if (opts.inputEventId) h[HEADER_EVENT_ID] = opts.inputEventId;
|
|
90
|
+
return h;
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Build the transport header set for a run-lifecycle event (run-start,
|
|
95
|
+
* run-resume, run-suspend, run-end). Single source of truth for lifecycle
|
|
96
|
+
* header stamping, mirroring {@link buildTransportHeaders} for the
|
|
97
|
+
* message-carrier path. Every field except `runId`/`runClientId` is optional
|
|
98
|
+
* and omitted when not provided.
|
|
99
|
+
*
|
|
100
|
+
* A resume suppresses the structural `parent` / `forkOf` / `regenerates`
|
|
101
|
+
* headers — the caller passes them only for a fresh run-start. `reason` is
|
|
102
|
+
* stamped only on run-end.
|
|
103
|
+
* @param opts - The lifecycle header values to include.
|
|
104
|
+
* @param opts.runId - The run's id.
|
|
105
|
+
* @param opts.runClientId - ClientId of the run initiator (empty string when unknown).
|
|
106
|
+
* @param opts.parent - Structural parent codec-message-id (fresh run-start only).
|
|
107
|
+
* @param opts.forkOf - Forked user-prompt codec-message-id (fresh run-start only).
|
|
108
|
+
* @param opts.regenerates - Regenerated assistant codec-message-id (fresh run-start only).
|
|
109
|
+
* @param opts.invocationId - Agent-minted invocation id; carried on every lifecycle event.
|
|
110
|
+
* @param opts.inputClientId - ClientId of the triggering input event.
|
|
111
|
+
* @param opts.inputCodecMessageId - Codec-message-id of the triggering input event.
|
|
112
|
+
* @param opts.reason - Terminal reason; stamped on run-end only.
|
|
113
|
+
* @param opts.errorCode - Numeric error code stamped as `error-code` on
|
|
114
|
+
* run-end. Set only when the run ended in error and the agent supplied an
|
|
115
|
+
* error to surface; gives codec-agnostic consumers a baseline failure detail.
|
|
116
|
+
* @param opts.errorMessage - Error message stamped as `error-message` on
|
|
117
|
+
* run-end. Paired with `errorCode`; set under the same condition.
|
|
118
|
+
* @returns A headers record with the lifecycle headers set.
|
|
119
|
+
*/
|
|
120
|
+
export const buildLifecycleHeaders = (opts: {
|
|
121
|
+
runId: string;
|
|
122
|
+
runClientId: string;
|
|
123
|
+
parent?: string;
|
|
124
|
+
forkOf?: string;
|
|
125
|
+
regenerates?: string;
|
|
126
|
+
invocationId?: string;
|
|
127
|
+
inputClientId?: string;
|
|
128
|
+
inputCodecMessageId?: string;
|
|
129
|
+
reason?: RunEndReason;
|
|
130
|
+
errorCode?: number;
|
|
131
|
+
errorMessage?: string;
|
|
132
|
+
}): Record<string, string> => {
|
|
133
|
+
const h: Record<string, string> = {
|
|
134
|
+
[HEADER_RUN_ID]: opts.runId,
|
|
135
|
+
[HEADER_RUN_CLIENT_ID]: opts.runClientId,
|
|
136
|
+
};
|
|
137
|
+
if (opts.reason !== undefined) h[HEADER_RUN_REASON] = opts.reason;
|
|
138
|
+
if (opts.parent !== undefined) h[HEADER_PARENT] = opts.parent;
|
|
139
|
+
if (opts.forkOf !== undefined) h[HEADER_FORK_OF] = opts.forkOf;
|
|
140
|
+
if (opts.regenerates !== undefined) h[HEADER_MSG_REGENERATE] = opts.regenerates;
|
|
141
|
+
if (opts.invocationId !== undefined) h[HEADER_INVOCATION_ID] = opts.invocationId;
|
|
142
|
+
if (opts.inputClientId !== undefined) h[HEADER_INPUT_CLIENT_ID] = opts.inputClientId;
|
|
143
|
+
if (opts.inputCodecMessageId !== undefined) h[HEADER_INPUT_CODEC_MESSAGE_ID] = opts.inputCodecMessageId;
|
|
144
|
+
if (opts.errorCode !== undefined) h[HEADER_ERROR_CODE] = String(opts.errorCode);
|
|
145
|
+
if (opts.errorMessage !== undefined) h[HEADER_ERROR_MESSAGE] = opts.errorMessage;
|
|
49
146
|
return h;
|
|
50
147
|
};
|
|
148
|
+
|
|
149
|
+
/** The four run-lifecycle Ably message names. */
|
|
150
|
+
type RunLifecycleName =
|
|
151
|
+
| typeof EVENT_RUN_START
|
|
152
|
+
| typeof EVENT_RUN_SUSPEND
|
|
153
|
+
| typeof EVENT_RUN_RESUME
|
|
154
|
+
| typeof EVENT_RUN_END;
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Whether an Ably message `name` is one of the run-lifecycle event names
|
|
158
|
+
* (run-start / run-suspend / run-resume / run-end). Single source of truth for
|
|
159
|
+
* the classification both decode loops and the agent's history scan use to
|
|
160
|
+
* route lifecycle wires away from the codec decoder. Narrows `name` to a
|
|
161
|
+
* lifecycle name so callers can pass it straight to {@link parseRunLifecycle}.
|
|
162
|
+
* @param name - The inbound Ably message `name`, or undefined.
|
|
163
|
+
* @returns True when `name` is a run-lifecycle event name.
|
|
164
|
+
*/
|
|
165
|
+
export const isRunLifecycleName = (name: string | undefined): name is RunLifecycleName =>
|
|
166
|
+
name === EVENT_RUN_START || name === EVENT_RUN_SUSPEND || name === EVENT_RUN_RESUME || name === EVENT_RUN_END;
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Reconstruct the terminal `Ably.ErrorInfo` for a run that ended in error, from
|
|
170
|
+
* its run-end transport headers. Reads the `error-code` / `error-message`
|
|
171
|
+
* headers the agent stamps (see {@link buildLifecycleHeaders}); falls back to a
|
|
172
|
+
* generic code/message when a run ended in error without detail. Single source
|
|
173
|
+
* of truth for the header→ErrorInfo derivation, shared by the client session's
|
|
174
|
+
* `on('error')` emit and the Tree's `RunInfo.error`.
|
|
175
|
+
* @param headers - Transport headers from the inbound run-end message.
|
|
176
|
+
* @returns The reconstructed terminal error.
|
|
177
|
+
*/
|
|
178
|
+
export const buildRunEndError = (headers: Record<string, string>): Ably.ErrorInfo => {
|
|
179
|
+
const codeRaw = headers[HEADER_ERROR_CODE];
|
|
180
|
+
const parsedCode = codeRaw === undefined ? Number.NaN : Number(codeRaw);
|
|
181
|
+
const code = Number.isFinite(parsedCode) ? parsedCode : ErrorCode.SessionSubscriptionError;
|
|
182
|
+
const message = headers[HEADER_ERROR_MESSAGE] ?? 'agent reported an error';
|
|
183
|
+
// 5-digit codes encode their HTTP status in the leading 3 digits; otherwise 500.
|
|
184
|
+
const statusCode = code >= 10000 && code < 60000 ? Math.floor(code / 100) : 500;
|
|
185
|
+
return new Ably.ErrorInfo(message, code, statusCode);
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Parse an inbound run-lifecycle Ably message into a {@link RunLifecycleEvent}.
|
|
190
|
+
*
|
|
191
|
+
* Single source of truth for turning the wire run-lifecycle message `name`,
|
|
192
|
+
* transport headers, and channel serial into the structured lifecycle event
|
|
193
|
+
* the Tree consumes. Used by the client decode loop (live) and the View's
|
|
194
|
+
* history replay so both build the event identically.
|
|
195
|
+
* @param name - The inbound Ably message `name`.
|
|
196
|
+
* @param headers - Transport headers from the inbound Ably message.
|
|
197
|
+
* @param serial - Ably channel serial of the message, or `undefined` for an
|
|
198
|
+
* optimistic local event. Stamped onto the returned event.
|
|
199
|
+
* @param timestamp - Ably server timestamp (epoch ms) of the message, or
|
|
200
|
+
* `undefined` for an optimistic local event. Stamped onto the returned
|
|
201
|
+
* event; drives the Tree's event-log retention clock.
|
|
202
|
+
* @returns The lifecycle event, or `undefined` when `name` is not a
|
|
203
|
+
* run-lifecycle event name or the message carries no `run-id`.
|
|
204
|
+
*/
|
|
205
|
+
export const parseRunLifecycle = (
|
|
206
|
+
name: string,
|
|
207
|
+
headers: Record<string, string>,
|
|
208
|
+
serial: string | undefined,
|
|
209
|
+
timestamp: number | undefined,
|
|
210
|
+
): RunLifecycleEvent | undefined => {
|
|
211
|
+
const runId = headers[HEADER_RUN_ID];
|
|
212
|
+
if (!runId) return undefined;
|
|
213
|
+
|
|
214
|
+
const clientId = headers[HEADER_RUN_CLIENT_ID] ?? '';
|
|
215
|
+
const stamped = timestamp === undefined ? {} : { timestamp };
|
|
216
|
+
|
|
217
|
+
if (name === EVENT_RUN_START) {
|
|
218
|
+
const parent = headers[HEADER_PARENT];
|
|
219
|
+
const forkOf = headers[HEADER_FORK_OF];
|
|
220
|
+
const regenerates = headers[HEADER_MSG_REGENERATE];
|
|
221
|
+
return {
|
|
222
|
+
type: 'start',
|
|
223
|
+
runId,
|
|
224
|
+
clientId,
|
|
225
|
+
serial,
|
|
226
|
+
invocationId: headers[HEADER_INVOCATION_ID] ?? '',
|
|
227
|
+
...stamped,
|
|
228
|
+
...(parent !== undefined && { parent }),
|
|
229
|
+
...(forkOf !== undefined && { forkOf }),
|
|
230
|
+
...(regenerates !== undefined && { regenerates }),
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
if (name === EVENT_RUN_SUSPEND) {
|
|
235
|
+
return { type: 'suspend', runId, clientId, serial, invocationId: headers[HEADER_INVOCATION_ID] ?? '', ...stamped };
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
if (name === EVENT_RUN_RESUME) {
|
|
239
|
+
return { type: 'resume', runId, clientId, serial, invocationId: headers[HEADER_INVOCATION_ID] ?? '', ...stamped };
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
if (name === EVENT_RUN_END) {
|
|
243
|
+
// CAST: agent always writes a valid RunEndReason; default to 'complete' for robustness.
|
|
244
|
+
const reason = (headers[HEADER_RUN_REASON] ?? 'complete') as RunEndReason;
|
|
245
|
+
const invocationId = headers[HEADER_INVOCATION_ID] ?? '';
|
|
246
|
+
if (reason === 'error') {
|
|
247
|
+
return {
|
|
248
|
+
type: 'end',
|
|
249
|
+
runId,
|
|
250
|
+
clientId,
|
|
251
|
+
serial,
|
|
252
|
+
invocationId,
|
|
253
|
+
reason,
|
|
254
|
+
...stamped,
|
|
255
|
+
error: buildRunEndError(headers),
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
return { type: 'end', runId, clientId, serial, invocationId, reason, ...stamped };
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
return undefined;
|
|
262
|
+
};
|
|
@@ -1,42 +1,42 @@
|
|
|
1
1
|
// Shared types
|
|
2
2
|
export type {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
ActiveRun,
|
|
4
|
+
AgentSession,
|
|
5
|
+
AgentSessionOptions,
|
|
6
|
+
BranchSelection,
|
|
7
7
|
CancelRequest,
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
ClientSession,
|
|
9
|
+
ClientSessionOptions,
|
|
10
|
+
ConversationNode,
|
|
11
|
+
InputNode,
|
|
12
|
+
LoadConversationOptions,
|
|
12
13
|
MessageNode,
|
|
13
|
-
|
|
14
|
+
OutputEvent,
|
|
15
|
+
PipeOptions,
|
|
16
|
+
Run,
|
|
17
|
+
RunEndParams,
|
|
18
|
+
RunEndReason,
|
|
19
|
+
RunInfo,
|
|
20
|
+
RunLifecycleEvent,
|
|
21
|
+
RunNode,
|
|
22
|
+
RunNodeState,
|
|
23
|
+
RunRuntime,
|
|
24
|
+
RunView,
|
|
14
25
|
SendOptions,
|
|
15
|
-
ServerTransport,
|
|
16
|
-
ServerTransportOptions,
|
|
17
|
-
StreamResponseOptions,
|
|
18
26
|
StreamResult,
|
|
19
27
|
Tree,
|
|
20
|
-
Turn,
|
|
21
|
-
TurnEndReason,
|
|
22
|
-
TurnLifecycleEvent,
|
|
23
28
|
View,
|
|
24
29
|
} from './types.js';
|
|
25
30
|
|
|
26
|
-
//
|
|
27
|
-
|
|
28
|
-
export
|
|
29
|
-
// eslint-disable-next-line @typescript-eslint/no-deprecated
|
|
30
|
-
export type { TreeNode } from './types.js';
|
|
31
|
+
// Invocation
|
|
32
|
+
export type { InvocationData } from './invocation.js';
|
|
33
|
+
export { Invocation } from './invocation.js';
|
|
31
34
|
|
|
32
|
-
//
|
|
33
|
-
export
|
|
35
|
+
// Agent session
|
|
36
|
+
export { createAgentSession } from './agent-session.js';
|
|
34
37
|
|
|
35
|
-
//
|
|
36
|
-
export {
|
|
37
|
-
|
|
38
|
-
// Client transport
|
|
39
|
-
export { createClientTransport } from './client-transport.js';
|
|
38
|
+
// Client session
|
|
39
|
+
export { createClientSession } from './client-session.js';
|
|
40
40
|
|
|
41
41
|
// Header builder
|
|
42
42
|
export { buildTransportHeaders } from './headers.js';
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Helpers for FIFO-bounded `Map`s — Maps used as capacity-limited buffers that
|
|
3
|
+
* must evict their oldest entry when full.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Make room for a new key in a FIFO-bounded map: if `map` is at (or over)
|
|
8
|
+
* `limit` and does not already contain `key`, evict the oldest entry (insertion
|
|
9
|
+
* order) and return its key so the caller can log the eviction. Returns
|
|
10
|
+
* `undefined` when nothing was evicted (the key already exists, the map is
|
|
11
|
+
* below the limit, or it is empty).
|
|
12
|
+
*
|
|
13
|
+
* The caller performs the actual set/append afterwards — this only frees a
|
|
14
|
+
* slot — so it works for maps whose values are replaced and for maps whose
|
|
15
|
+
* values are appended-to lists.
|
|
16
|
+
* @param map - The bounded map to evict from.
|
|
17
|
+
* @param key - The key about to be added; an existing key never evicts.
|
|
18
|
+
* @param limit - The maximum number of entries the map may hold.
|
|
19
|
+
* @returns The evicted key, or `undefined` if nothing was evicted.
|
|
20
|
+
*/
|
|
21
|
+
export const evictOldestIfFull = <K, V>(map: Map<K, V>, key: K, limit: number): K | undefined => {
|
|
22
|
+
if (map.has(key) || map.size < limit) return undefined;
|
|
23
|
+
const oldest = map.keys().next().value;
|
|
24
|
+
if (oldest === undefined) return undefined;
|
|
25
|
+
map.delete(oldest);
|
|
26
|
+
return oldest;
|
|
27
|
+
};
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Invocation — value object wrapping the JSON body that a client sends to
|
|
3
|
+
* an agent's HTTP endpoint to start a run.
|
|
4
|
+
*
|
|
5
|
+
* The data shape is the wire contract; the {@link Invocation} class is a
|
|
6
|
+
* runtime view of that data with the same fields. {@link Invocation.fromJSON}
|
|
7
|
+
* is the entry point used by agent handlers:
|
|
8
|
+
*
|
|
9
|
+
* ```ts
|
|
10
|
+
* const data = (await req.json()) as InvocationData;
|
|
11
|
+
* const invocation = Invocation.fromJSON(data);
|
|
12
|
+
* const run = session.createRun(invocation, { signal: req.signal });
|
|
13
|
+
* await run.start();
|
|
14
|
+
* await run.loadConversation(); // walk channel history into the session tree
|
|
15
|
+
* const messages = run.messages;
|
|
16
|
+
* ```
|
|
17
|
+
*
|
|
18
|
+
* The body carries only what the agent needs out-of-band before the channel
|
|
19
|
+
* is observable: the session/channel name and the `inputEventId` that triggered
|
|
20
|
+
* the invocation. The agent mints the `invocationId` itself (one per HTTP
|
|
21
|
+
* request) and returns it on the HTTP response, so it is not a body field. Run
|
|
22
|
+
* identity also lives on the channel: the agent mints the `runId` for a fresh
|
|
23
|
+
* run and reads the existing `runId` off the triggering input event for a
|
|
24
|
+
* continuation — so the body carries no run-id either. Per-message metadata —
|
|
25
|
+
* `clientId`, `parent`, `forkOf`, continuation status — likewise lives on the
|
|
26
|
+
* channel and is resolved by the agent from the triggering input event, not
|
|
27
|
+
* from the body. The `inputClientId` the agent re-stamps on its own publishes
|
|
28
|
+
* comes from the publisher's Ably `clientId` on the matched input event, not
|
|
29
|
+
* from a body field.
|
|
30
|
+
*/
|
|
31
|
+
|
|
32
|
+
// ---------------------------------------------------------------------------
|
|
33
|
+
// Wire shape
|
|
34
|
+
// ---------------------------------------------------------------------------
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Wire shape of a single invocation — the JSON body sent from the client
|
|
38
|
+
* transport's HTTP POST to the agent endpoint.
|
|
39
|
+
*/
|
|
40
|
+
export interface InvocationData {
|
|
41
|
+
/**
|
|
42
|
+
* Identifier for the specific input event on the channel that triggered
|
|
43
|
+
* this invocation. The agent locates the event via the `event-id`
|
|
44
|
+
* header. Its wire headers carry the run-id for a continuation (absent for
|
|
45
|
+
* a fresh run), so run identity is resolved from the channel, not the body.
|
|
46
|
+
*/
|
|
47
|
+
inputEventId: string;
|
|
48
|
+
/** Logical name of the session (chat) — used as the Ably channel name. */
|
|
49
|
+
sessionName: string;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// ---------------------------------------------------------------------------
|
|
53
|
+
// Runtime view
|
|
54
|
+
// ---------------------------------------------------------------------------
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Runtime view of an {@link InvocationData}. Constructed via
|
|
58
|
+
* {@link Invocation.fromJSON}. Read-only; carries no behaviour beyond
|
|
59
|
+
* exposing its fields.
|
|
60
|
+
*/
|
|
61
|
+
// Spec: AIT-ST13
|
|
62
|
+
export class Invocation {
|
|
63
|
+
/**
|
|
64
|
+
* Identifier for the specific input event on the channel that triggered
|
|
65
|
+
* this invocation. Run identity is resolved from that event's wire headers
|
|
66
|
+
* (or minted), not from the body.
|
|
67
|
+
*/
|
|
68
|
+
readonly inputEventId: string;
|
|
69
|
+
/** Logical name of the session (chat). Used as the Ably channel name. */
|
|
70
|
+
readonly sessionName: string;
|
|
71
|
+
|
|
72
|
+
private constructor(data: InvocationData) {
|
|
73
|
+
this.inputEventId = data.inputEventId;
|
|
74
|
+
this.sessionName = data.sessionName;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Build an Invocation from its JSON wire shape.
|
|
79
|
+
* @param data - Parsed JSON body matching {@link InvocationData}.
|
|
80
|
+
* @returns A new Invocation exposing the same fields.
|
|
81
|
+
*/
|
|
82
|
+
static fromJSON(data: InvocationData): Invocation {
|
|
83
|
+
return new Invocation(data);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Serialise this invocation to its JSON wire shape — the body a client
|
|
88
|
+
* POSTs to the agent's endpoint to wake a run. Round-trips through
|
|
89
|
+
* {@link Invocation.fromJSON}.
|
|
90
|
+
* @returns The {@link InvocationData} carrying this invocation's identity.
|
|
91
|
+
*/
|
|
92
|
+
toJSON(): InvocationData {
|
|
93
|
+
return {
|
|
94
|
+
inputEventId: this.inputEventId,
|
|
95
|
+
sessionName: this.sessionName,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
}
|