@grackle-ai/adapter-sdk 0.132.1 → 0.133.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/dist/adapter.d.ts +14 -10
- package/dist/adapter.d.ts.map +1 -1
- package/dist/adapter.js.map +1 -1
- package/dist/ahp-host-transport.d.ts +124 -0
- package/dist/ahp-host-transport.d.ts.map +1 -0
- package/dist/ahp-host-transport.js +413 -0
- package/dist/ahp-host-transport.js.map +1 -0
- package/dist/connect.d.ts +34 -8
- package/dist/connect.d.ts.map +1 -1
- package/dist/connect.js +79 -35
- package/dist/connect.js.map +1 -1
- package/dist/host-transport.d.ts +15 -27
- package/dist/host-transport.d.ts.map +1 -1
- package/dist/host-transport.js +15 -12
- package/dist/host-transport.js.map +1 -1
- package/dist/index.d.ts +3 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -4
- package/dist/index.js.map +1 -1
- package/dist/shared-operations.js +1 -1
- package/dist/shared-operations.js.map +1 -1
- package/package.json +4 -6
- package/dist/grpc-host-transport.d.ts +0 -77
- package/dist/grpc-host-transport.d.ts.map +0 -1
- package/dist/grpc-host-transport.js +0 -168
- package/dist/grpc-host-transport.js.map +0 -1
package/dist/adapter.d.ts
CHANGED
|
@@ -1,21 +1,25 @@
|
|
|
1
|
-
import type { Client } from "@connectrpc/connect";
|
|
2
|
-
import type { powerline } from "@grackle-ai/common";
|
|
3
1
|
import type { AdapterLogger } from "./logger.js";
|
|
4
2
|
import type { IHostTransport } from "./host-transport.js";
|
|
5
|
-
/**
|
|
6
|
-
export type PowerLineClient = Client<typeof powerline.GracklePowerLine>;
|
|
7
|
-
/** An active connection to a PowerLine, including the gRPC client and port info. */
|
|
3
|
+
/** An active connection to a PowerLine. */
|
|
8
4
|
export interface PowerLineConnection {
|
|
9
|
-
client: PowerLineClient;
|
|
10
5
|
environmentId: string;
|
|
11
6
|
port: number;
|
|
12
7
|
/**
|
|
13
|
-
* Transport-agnostic host interface
|
|
14
|
-
*
|
|
15
|
-
* instead of touching `client` directly so the HR8d wire-flip is a
|
|
16
|
-
* swap of one `IHostTransport` impl for another.
|
|
8
|
+
* Transport-agnostic host interface. Constructed when the connection is
|
|
9
|
+
* established and used for all session-level operations.
|
|
17
10
|
*/
|
|
18
11
|
transport: IHostTransport;
|
|
12
|
+
/**
|
|
13
|
+
* Send a liveness probe to the PowerLine. Resolves on success; rejects on
|
|
14
|
+
* any transport-layer error.
|
|
15
|
+
*/
|
|
16
|
+
ping(): Promise<void>;
|
|
17
|
+
/**
|
|
18
|
+
* Tear down the underlying transport (WebSocket + pending RPCs). Idempotent.
|
|
19
|
+
* Adapters MUST call this from `disconnect()` to avoid socket leaks —
|
|
20
|
+
* under HR8d the AHP transport is persistent and only closes here.
|
|
21
|
+
*/
|
|
22
|
+
close(): Promise<void>;
|
|
19
23
|
}
|
|
20
24
|
/** Progress event emitted during environment provisioning. */
|
|
21
25
|
export interface ProvisionEvent {
|
package/dist/adapter.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAGjD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE1D,2CAA2C;AAC3C,MAAM,WAAW,mBAAmB;IAClC,aAAa,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;IACb;;;OAGG;IACH,SAAS,EAAE,cAAc,CAAC;IAC1B;;;OAGG;IACH,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACtB;;;;OAIG;IACH,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED,8DAA8D;AAC9D,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,6DAA6D;AAC7D,MAAM,WAAW,qBAAqB;IACpC,2CAA2C;IAC3C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,uCAAuC;IACvC,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,qEAAqE;AACrE,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IAEb,0DAA0D;IAC1D,SAAS,CACP,aAAa,EAAE,MAAM,EACrB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,cAAc,EAAE,MAAM,GACrB,cAAc,CAAC,cAAc,CAAC,CAAC;IAClC,+EAA+E;IAC/E,OAAO,CACL,aAAa,EAAE,MAAM,EACrB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,cAAc,EAAE,MAAM,GACrB,OAAO,CAAC,mBAAmB,CAAC,CAAC;IAChC,uFAAuF;IACvF,UAAU,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACjD,gFAAgF;IAChF,IAAI,CAAC,aAAa,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5E,gEAAgE;IAChE,OAAO,CAAC,aAAa,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/E,0DAA0D;IAC1D,WAAW,CAAC,UAAU,EAAE,mBAAmB,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/D,gGAAgG;IAChG,SAAS,CAAC,CACR,aAAa,EAAE,MAAM,EACrB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,cAAc,EAAE,MAAM,GACrB,cAAc,CAAC,cAAc,CAAC,CAAC;CACnC;AAED;;;;;;GAMG;AACH,wBAAuB,oBAAoB,CACzC,aAAa,EAAE,MAAM,EACrB,OAAO,EAAE,kBAAkB,EAC3B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,cAAc,EAAE,MAAM,EACtB,YAAY,EAAE,OAAO,EACrB,KAAK,GAAE,OAAe,EACtB,MAAM,GAAE,aAA6B,GACpC,cAAc,CAAC,cAAc,CAAC,CAgBhC"}
|
package/dist/adapter.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adapter.js","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"adapter.js","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAwErD;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,SAAS,CAAC,CAAC,oBAAoB,CACzC,aAAqB,EACrB,OAA2B,EAC3B,MAA+B,EAC/B,cAAsB,EACtB,YAAqB,EACrB,QAAiB,KAAK,EACtB,SAAwB,aAAa;IAErC,IAAI,WAAW,GAAG,KAAK,CAAC;IACxB,IAAI,CAAC,KAAK,IAAI,YAAY,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;QAChD,IAAI,CAAC;YACH,KAAK,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,aAAa,EAAE,MAAM,EAAE,cAAc,CAAC,CAAC;YAChE,WAAW,GAAG,IAAI,CAAC;QACrB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,GAAG,YAAY,iBAAiB,EAAE,CAAC;gBACrC,MAAM,GAAG,CAAC;YACZ,CAAC;YACD,MAAM,CAAC,IAAI,CAAC,EAAE,aAAa,EAAE,GAAG,EAAE,EAAE,kDAAkD,CAAC,CAAC;QAC1F,CAAC;IACH,CAAC;IACD,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,KAAK,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,aAAa,EAAE,MAAM,EAAE,cAAc,CAAC,CAAC;IAClE,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AHP-backed implementation of {@link IHostTransport} (AHP HR8d / #1336).
|
|
3
|
+
*
|
|
4
|
+
* Owns one `AhpClientSocket` per `PowerLineConnection` and routes
|
|
5
|
+
* inbound `action` notifications to per-session queues via the
|
|
6
|
+
* {@link reverseMapAction} reverse mapper. Downstream consumers in
|
|
7
|
+
* `@grackle-ai/core` continue to read `envelope.event` (the synthesized
|
|
8
|
+
* AgentEventFields), so no consumer code changes — only the wire format does.
|
|
9
|
+
*
|
|
10
|
+
* Wire-protocol summary (per #1336):
|
|
11
|
+
*
|
|
12
|
+
* - `createSession` (spawn) → AHP `createSession` + `subscribe`
|
|
13
|
+
* - `createSession` (reanimate) → same, with `config.resumeFromRuntimeSessionId`
|
|
14
|
+
* - `dispatchInput` → AHP `dispatchAction` notification with `SessionTurnStartedAction`
|
|
15
|
+
* - `dispose` (kill) → AHP `disposeSession`
|
|
16
|
+
* - `listSessions` → AHP `listSessions`
|
|
17
|
+
* - `authenticate` → AHP `authenticate`
|
|
18
|
+
*
|
|
19
|
+
* Drain semantics (Option E): PowerLine replays parked events as `action`
|
|
20
|
+
* notifications immediately after the `subscribe` response, so the consumer
|
|
21
|
+
* receives them via the same stream — no separate `drainBuffered` RPC.
|
|
22
|
+
*
|
|
23
|
+
* @module ahp-host-transport
|
|
24
|
+
*/
|
|
25
|
+
import type { AhpNotification } from "@grackle-ai/ahp";
|
|
26
|
+
import { AhpClientSocket } from "@grackle-ai/ahp-transport";
|
|
27
|
+
import type { AuthenticateParams, CreateSessionParams, CreateSessionResult, HostSessionInfo, IHostTransport, ReanimateParams, ServerActionEnvelope } from "./host-transport.js";
|
|
28
|
+
/**
|
|
29
|
+
* AHP-backed {@link IHostTransport} for a single environment.
|
|
30
|
+
*
|
|
31
|
+
* Lifecycle: one instance per `PowerLineConnection`. Owns one
|
|
32
|
+
* `AhpClientSocket`; multiplexes session subscriptions over it.
|
|
33
|
+
*
|
|
34
|
+
* Construct via {@link createAhpHostTransport} (in `./connect.ts`) which
|
|
35
|
+
* handles the `socket.open()` handshake. Tests can construct directly with
|
|
36
|
+
* a pre-opened socket.
|
|
37
|
+
*/
|
|
38
|
+
export declare class AhpHostTransport implements IHostTransport {
|
|
39
|
+
private readonly socket;
|
|
40
|
+
private readonly sessions;
|
|
41
|
+
private nextClientSeq;
|
|
42
|
+
/**
|
|
43
|
+
* Construct an AhpHostTransport over a pre-opened `AhpClientSocket`.
|
|
44
|
+
* The socket MUST already have completed its `initialize` handshake.
|
|
45
|
+
*
|
|
46
|
+
* @param socket - The AHP client socket, opened and connected.
|
|
47
|
+
*/
|
|
48
|
+
constructor(socket: AhpClientSocket);
|
|
49
|
+
/**
|
|
50
|
+
* Notification handler that must be supplied to `AhpClientSocket` at
|
|
51
|
+
* construction time (the socket's `onNotification` option). This is a
|
|
52
|
+
* static-bound method so it can be passed to the socket constructor.
|
|
53
|
+
*
|
|
54
|
+
* Routes inbound `action` notifications to the appropriate per-session
|
|
55
|
+
* queue, running the reverse mapper to synthesize `AgentEventFields` and
|
|
56
|
+
* wrapping each into a `ServerActionEnvelope`. Other notification methods
|
|
57
|
+
* are ignored (no consumers in the wire-only scope of HR8d).
|
|
58
|
+
*
|
|
59
|
+
* @param notif - The AHP notification from the wire.
|
|
60
|
+
*/
|
|
61
|
+
handleNotification(notif: AhpNotification): void;
|
|
62
|
+
/**
|
|
63
|
+
* Create a new session via AHP `createSession` + `subscribe`.
|
|
64
|
+
*
|
|
65
|
+
* Returns synchronously with the session URI and the live envelope stream.
|
|
66
|
+
* The actual AHP requests fire in the background; failures push an error
|
|
67
|
+
* sentinel into the stream and close it (mirroring how gRPC stream errors
|
|
68
|
+
* surface during iteration).
|
|
69
|
+
*/
|
|
70
|
+
createSession(params: CreateSessionParams): CreateSessionResult;
|
|
71
|
+
/**
|
|
72
|
+
* Reanimate a suspended session. Maps to AHP `createSession` with a
|
|
73
|
+
* `config.resumeFromRuntimeSessionId` hint that PowerLine interprets as
|
|
74
|
+
* "spawn a continuation runtime from this prior runtime session."
|
|
75
|
+
*/
|
|
76
|
+
reanimate(params: ReanimateParams): AsyncIterable<ServerActionEnvelope>;
|
|
77
|
+
/** Send input text by dispatching a `SessionTurnStartedAction`. */
|
|
78
|
+
dispatchInput(sessionUri: string, text: string): Promise<void>;
|
|
79
|
+
/**
|
|
80
|
+
* Deliver runtime credentials.
|
|
81
|
+
*
|
|
82
|
+
* AHP `authenticate` is OAuth-shaped (single `{ resource, token }`) and
|
|
83
|
+
* Grackle's HR6 authenticate delivers multiple typed tokens (env-var or
|
|
84
|
+
* file-backed) for one provider. HR8d preserves the AHP-spec wire method
|
|
85
|
+
* by fanning Grackle's tokens out into N `authenticate` calls. Each call:
|
|
86
|
+
*
|
|
87
|
+
* - `resource`: `grackle://provider/{provider}/{name}` — encodes the
|
|
88
|
+
* Grackle-side identity. PowerLine recognizes the `grackle://` scheme
|
|
89
|
+
* and decodes it.
|
|
90
|
+
* - `token`: JSON-encoded `{ type, envVar?, filePath?, value }` — carries
|
|
91
|
+
* the delivery instructions inside the AHP token field.
|
|
92
|
+
*
|
|
93
|
+
* On-spec method, abused field semantics. The contortion is documented in
|
|
94
|
+
* #1336 and bounded to this single command.
|
|
95
|
+
*/
|
|
96
|
+
authenticate(params: AuthenticateParams): Promise<void>;
|
|
97
|
+
/**
|
|
98
|
+
* Dispose a session via AHP `disposeSession`.
|
|
99
|
+
*
|
|
100
|
+
* AHP's `DisposeSessionParams` doesn't carry a `reason` field; the optional
|
|
101
|
+
* `reason` argument is logged client-side but not delivered to PowerLine.
|
|
102
|
+
* Acceptable for HR8d — `reason` was informational in the gRPC path too.
|
|
103
|
+
*/
|
|
104
|
+
dispose(sessionUri: string, _reason?: string): Promise<void>;
|
|
105
|
+
/** List active sessions via AHP `listSessions`. */
|
|
106
|
+
listSessions(): Promise<HostSessionInfo[]>;
|
|
107
|
+
private getOrCreateSession;
|
|
108
|
+
private closeSession;
|
|
109
|
+
private runSpawnFlow;
|
|
110
|
+
private surfaceErrorAndClose;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Helper to wire {@link AhpHostTransport}'s notification handler into an
|
|
114
|
+
* `AhpClientSocket` at construction time. The transport's
|
|
115
|
+
* {@link AhpHostTransport.handleNotification} method must be bound to the
|
|
116
|
+
* socket BEFORE `socket.open()` so the first inbound `action` notifications
|
|
117
|
+
* are routed correctly.
|
|
118
|
+
*
|
|
119
|
+
* @param transport - The transport whose handler should be bound.
|
|
120
|
+
* @returns A function suitable for passing as `onNotification` to
|
|
121
|
+
* `AhpClientSocket`'s constructor options.
|
|
122
|
+
*/
|
|
123
|
+
export declare function bindNotificationHandler(transport: AhpHostTransport): (n: AhpNotification) => void;
|
|
124
|
+
//# sourceMappingURL=ahp-host-transport.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ahp-host-transport.d.ts","sourceRoot":"","sources":["../src/ahp-host-transport.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,KAAK,EAMV,eAAe,EAChB,MAAM,iBAAiB,CAAC;AAQzB,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAE5D,OAAO,KAAK,EACV,kBAAkB,EAClB,mBAAmB,EACnB,mBAAmB,EACnB,eAAe,EACf,cAAc,EACd,eAAe,EACf,oBAAoB,EACrB,MAAM,qBAAqB,CAAC;AA+F7B;;;;;;;;;GASG;AACH,qBAAa,gBAAiB,YAAW,cAAc;IACrD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAkB;IACzC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAsC;IAC/D,OAAO,CAAC,aAAa,CAAa;IAElC;;;;;OAKG;gBACgB,MAAM,EAAE,eAAe;IAI1C;;;;;;;;;;;OAWG;IACI,kBAAkB,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI;IAiBvD;;;;;;;OAOG;IACI,aAAa,CAAC,MAAM,EAAE,mBAAmB,GAAG,mBAAmB;IAStE;;;;OAIG;IACI,SAAS,CAAC,MAAM,EAAE,eAAe,GAAG,aAAa,CAAC,oBAAoB,CAAC;IA2B9E,mEAAmE;IACtD,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAc3E;;;;;;;;;;;;;;;;OAgBG;IACU,YAAY,CAAC,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;IAuBpE;;;;;;OAMG;IACU,OAAO,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IASzE,mDAAmD;IACtC,YAAY,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC;IAevD,OAAO,CAAC,kBAAkB;IAS1B,OAAO,CAAC,YAAY;YASN,YAAY;IAmD1B,OAAO,CAAC,oBAAoB;CAS7B;AAsDD;;;;;;;;;;GAUG;AACH,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,gBAAgB,GAAG,CAAC,CAAC,EAAE,eAAe,KAAK,IAAI,CAEjG"}
|
|
@@ -0,0 +1,413 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AHP-backed implementation of {@link IHostTransport} (AHP HR8d / #1336).
|
|
3
|
+
*
|
|
4
|
+
* Owns one `AhpClientSocket` per `PowerLineConnection` and routes
|
|
5
|
+
* inbound `action` notifications to per-session queues via the
|
|
6
|
+
* {@link reverseMapAction} reverse mapper. Downstream consumers in
|
|
7
|
+
* `@grackle-ai/core` continue to read `envelope.event` (the synthesized
|
|
8
|
+
* AgentEventFields), so no consumer code changes — only the wire format does.
|
|
9
|
+
*
|
|
10
|
+
* Wire-protocol summary (per #1336):
|
|
11
|
+
*
|
|
12
|
+
* - `createSession` (spawn) → AHP `createSession` + `subscribe`
|
|
13
|
+
* - `createSession` (reanimate) → same, with `config.resumeFromRuntimeSessionId`
|
|
14
|
+
* - `dispatchInput` → AHP `dispatchAction` notification with `SessionTurnStartedAction`
|
|
15
|
+
* - `dispose` (kill) → AHP `disposeSession`
|
|
16
|
+
* - `listSessions` → AHP `listSessions`
|
|
17
|
+
* - `authenticate` → AHP `authenticate`
|
|
18
|
+
*
|
|
19
|
+
* Drain semantics (Option E): PowerLine replays parked events as `action`
|
|
20
|
+
* notifications immediately after the `subscribe` response, so the consumer
|
|
21
|
+
* receives them via the same stream — no separate `drainBuffered` RPC.
|
|
22
|
+
*
|
|
23
|
+
* @module ahp-host-transport
|
|
24
|
+
*/
|
|
25
|
+
import { ActionType } from "@grackle-ai/ahp";
|
|
26
|
+
import { newReverseMapperContext, reverseMapAction, } from "@grackle-ai/common";
|
|
27
|
+
const ROOT_CHANNEL = "ahp-root://";
|
|
28
|
+
const SESSION_CHANNEL_PREFIX = "ahp-session:/";
|
|
29
|
+
/** Build the AHP session channel URI for a Grackle session id. */
|
|
30
|
+
function sessionChannel(sessionId) {
|
|
31
|
+
return `${SESSION_CHANNEL_PREFIX}${sessionId}`;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Accept either a plain Grackle session id (e.g. `"sess-1"`) or an
|
|
35
|
+
* already-formed AHP session URI (`"ahp-session:/sess-1"`) and return the
|
|
36
|
+
* URI form. `IHostTransport`'s `dispatchInput` / `dispose` historically
|
|
37
|
+
* pass a session id; this helper keeps the boundary forgiving.
|
|
38
|
+
*/
|
|
39
|
+
function toSessionChannel(sessionIdOrUri) {
|
|
40
|
+
return sessionIdOrUri.startsWith(SESSION_CHANNEL_PREFIX)
|
|
41
|
+
? sessionIdOrUri
|
|
42
|
+
: sessionChannel(sessionIdOrUri);
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Minimal push/pull queue specialized for per-session envelope streaming.
|
|
46
|
+
* Mirrors `packages/runtime-sdk/src/async-queue.ts:1-48`; inlined here to
|
|
47
|
+
* avoid a new dep edge on runtime-sdk.
|
|
48
|
+
*
|
|
49
|
+
* @internal
|
|
50
|
+
*/
|
|
51
|
+
class EnvelopeQueue {
|
|
52
|
+
buffer = [];
|
|
53
|
+
waiters = [];
|
|
54
|
+
closedFlag = false;
|
|
55
|
+
push(item) {
|
|
56
|
+
if (this.closedFlag) {
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
const waiter = this.waiters.shift();
|
|
60
|
+
if (waiter !== undefined) {
|
|
61
|
+
waiter(item);
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
this.buffer.push(item);
|
|
65
|
+
}
|
|
66
|
+
async shift() {
|
|
67
|
+
const buffered = this.buffer.shift();
|
|
68
|
+
if (buffered !== undefined) {
|
|
69
|
+
return buffered;
|
|
70
|
+
}
|
|
71
|
+
if (this.closedFlag) {
|
|
72
|
+
return undefined;
|
|
73
|
+
}
|
|
74
|
+
return new Promise((resolve) => {
|
|
75
|
+
this.waiters.push(resolve);
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
close() {
|
|
79
|
+
if (this.closedFlag) {
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
this.closedFlag = true;
|
|
83
|
+
for (const waiter of this.waiters) {
|
|
84
|
+
waiter(undefined);
|
|
85
|
+
}
|
|
86
|
+
this.waiters.length = 0;
|
|
87
|
+
}
|
|
88
|
+
get closed() {
|
|
89
|
+
return this.closedFlag;
|
|
90
|
+
}
|
|
91
|
+
async *[Symbol.asyncIterator]() {
|
|
92
|
+
while (true) {
|
|
93
|
+
const item = await this.shift();
|
|
94
|
+
if (item === undefined) {
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
yield item;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* AHP-backed {@link IHostTransport} for a single environment.
|
|
103
|
+
*
|
|
104
|
+
* Lifecycle: one instance per `PowerLineConnection`. Owns one
|
|
105
|
+
* `AhpClientSocket`; multiplexes session subscriptions over it.
|
|
106
|
+
*
|
|
107
|
+
* Construct via {@link createAhpHostTransport} (in `./connect.ts`) which
|
|
108
|
+
* handles the `socket.open()` handshake. Tests can construct directly with
|
|
109
|
+
* a pre-opened socket.
|
|
110
|
+
*/
|
|
111
|
+
export class AhpHostTransport {
|
|
112
|
+
socket;
|
|
113
|
+
sessions = new Map();
|
|
114
|
+
nextClientSeq = 0;
|
|
115
|
+
/**
|
|
116
|
+
* Construct an AhpHostTransport over a pre-opened `AhpClientSocket`.
|
|
117
|
+
* The socket MUST already have completed its `initialize` handshake.
|
|
118
|
+
*
|
|
119
|
+
* @param socket - The AHP client socket, opened and connected.
|
|
120
|
+
*/
|
|
121
|
+
constructor(socket) {
|
|
122
|
+
this.socket = socket;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Notification handler that must be supplied to `AhpClientSocket` at
|
|
126
|
+
* construction time (the socket's `onNotification` option). This is a
|
|
127
|
+
* static-bound method so it can be passed to the socket constructor.
|
|
128
|
+
*
|
|
129
|
+
* Routes inbound `action` notifications to the appropriate per-session
|
|
130
|
+
* queue, running the reverse mapper to synthesize `AgentEventFields` and
|
|
131
|
+
* wrapping each into a `ServerActionEnvelope`. Other notification methods
|
|
132
|
+
* are ignored (no consumers in the wire-only scope of HR8d).
|
|
133
|
+
*
|
|
134
|
+
* @param notif - The AHP notification from the wire.
|
|
135
|
+
*/
|
|
136
|
+
handleNotification(notif) {
|
|
137
|
+
if (notif.method !== "action") {
|
|
138
|
+
// Other notifications (root/sessionAdded, auth/required, otlp/*, etc.)
|
|
139
|
+
// are not consumed by Grackle's downstream pipeline; drop silently.
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
const envelope = notif.params;
|
|
143
|
+
const session = this.sessions.get(envelope.channel);
|
|
144
|
+
if (session === undefined) {
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
const result = reverseMapAction(envelope, session.context);
|
|
148
|
+
for (const event of result.events) {
|
|
149
|
+
session.queue.push({ event, actions: [envelope.action] });
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Create a new session via AHP `createSession` + `subscribe`.
|
|
154
|
+
*
|
|
155
|
+
* Returns synchronously with the session URI and the live envelope stream.
|
|
156
|
+
* The actual AHP requests fire in the background; failures push an error
|
|
157
|
+
* sentinel into the stream and close it (mirroring how gRPC stream errors
|
|
158
|
+
* surface during iteration).
|
|
159
|
+
*/
|
|
160
|
+
createSession(params) {
|
|
161
|
+
const channel = sessionChannel(params.sessionId);
|
|
162
|
+
const session = this.getOrCreateSession(channel);
|
|
163
|
+
void this.runSpawnFlow(channel, params, undefined).catch((err) => {
|
|
164
|
+
this.surfaceErrorAndClose(session, channel, err);
|
|
165
|
+
});
|
|
166
|
+
return { sessionUri: channel, stream: session.queue };
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Reanimate a suspended session. Maps to AHP `createSession` with a
|
|
170
|
+
* `config.resumeFromRuntimeSessionId` hint that PowerLine interprets as
|
|
171
|
+
* "spawn a continuation runtime from this prior runtime session."
|
|
172
|
+
*/
|
|
173
|
+
reanimate(params) {
|
|
174
|
+
const channel = sessionChannel(params.sessionId);
|
|
175
|
+
const session = this.getOrCreateSession(channel);
|
|
176
|
+
const reanimateConfig = {
|
|
177
|
+
sessionId: params.sessionId,
|
|
178
|
+
runtime: params.runtime,
|
|
179
|
+
// Reanimate doesn't have prompt/model/etc.; use empty defaults — the
|
|
180
|
+
// PowerLine handler ignores them when resumeFromRuntimeSessionId is set.
|
|
181
|
+
prompt: "",
|
|
182
|
+
model: "",
|
|
183
|
+
maxTurns: 0,
|
|
184
|
+
branch: "",
|
|
185
|
+
workingDirectory: "",
|
|
186
|
+
systemContext: "",
|
|
187
|
+
taskId: "",
|
|
188
|
+
mcpServersJson: "",
|
|
189
|
+
mcpUrl: "",
|
|
190
|
+
mcpToken: "",
|
|
191
|
+
};
|
|
192
|
+
void this.runSpawnFlow(channel, reanimateConfig, params.runtimeSessionId).catch((err) => {
|
|
193
|
+
this.surfaceErrorAndClose(session, channel, err);
|
|
194
|
+
});
|
|
195
|
+
return session.queue;
|
|
196
|
+
}
|
|
197
|
+
/** Send input text by dispatching a `SessionTurnStartedAction`. */
|
|
198
|
+
async dispatchInput(sessionUri, text) {
|
|
199
|
+
this.nextClientSeq += 1;
|
|
200
|
+
const action = {
|
|
201
|
+
type: ActionType.SessionTurnStarted,
|
|
202
|
+
turnId: `turn-input-${String(this.nextClientSeq)}`,
|
|
203
|
+
userMessage: { text },
|
|
204
|
+
};
|
|
205
|
+
this.socket.notify("dispatchAction", {
|
|
206
|
+
channel: toSessionChannel(sessionUri),
|
|
207
|
+
clientSeq: this.nextClientSeq,
|
|
208
|
+
action,
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Deliver runtime credentials.
|
|
213
|
+
*
|
|
214
|
+
* AHP `authenticate` is OAuth-shaped (single `{ resource, token }`) and
|
|
215
|
+
* Grackle's HR6 authenticate delivers multiple typed tokens (env-var or
|
|
216
|
+
* file-backed) for one provider. HR8d preserves the AHP-spec wire method
|
|
217
|
+
* by fanning Grackle's tokens out into N `authenticate` calls. Each call:
|
|
218
|
+
*
|
|
219
|
+
* - `resource`: `grackle://provider/{provider}/{name}` — encodes the
|
|
220
|
+
* Grackle-side identity. PowerLine recognizes the `grackle://` scheme
|
|
221
|
+
* and decodes it.
|
|
222
|
+
* - `token`: JSON-encoded `{ type, envVar?, filePath?, value }` — carries
|
|
223
|
+
* the delivery instructions inside the AHP token field.
|
|
224
|
+
*
|
|
225
|
+
* On-spec method, abused field semantics. The contortion is documented in
|
|
226
|
+
* #1336 and bounded to this single command.
|
|
227
|
+
*/
|
|
228
|
+
async authenticate(params) {
|
|
229
|
+
const settlements = await Promise.allSettled(params.tokens.map((t) => this.socket.request("authenticate", {
|
|
230
|
+
channel: ROOT_CHANNEL,
|
|
231
|
+
resource: `grackle://provider/${params.provider}/${t.name}`,
|
|
232
|
+
token: JSON.stringify({
|
|
233
|
+
type: t.type,
|
|
234
|
+
envVar: t.envVar,
|
|
235
|
+
filePath: t.filePath,
|
|
236
|
+
value: t.value,
|
|
237
|
+
}),
|
|
238
|
+
})));
|
|
239
|
+
// Surface the first failure (if any) so the caller can log it — matches
|
|
240
|
+
// the prior gRPC-path "best-effort, log and continue" semantics.
|
|
241
|
+
const rejection = settlements.find((s) => s.status === "rejected");
|
|
242
|
+
if (rejection !== undefined && rejection.status === "rejected") {
|
|
243
|
+
throw rejection.reason;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Dispose a session via AHP `disposeSession`.
|
|
248
|
+
*
|
|
249
|
+
* AHP's `DisposeSessionParams` doesn't carry a `reason` field; the optional
|
|
250
|
+
* `reason` argument is logged client-side but not delivered to PowerLine.
|
|
251
|
+
* Acceptable for HR8d — `reason` was informational in the gRPC path too.
|
|
252
|
+
*/
|
|
253
|
+
async dispose(sessionUri, _reason) {
|
|
254
|
+
const channel = toSessionChannel(sessionUri);
|
|
255
|
+
try {
|
|
256
|
+
await this.socket.request("disposeSession", { channel });
|
|
257
|
+
}
|
|
258
|
+
finally {
|
|
259
|
+
this.closeSession(channel);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
/** List active sessions via AHP `listSessions`. */
|
|
263
|
+
async listSessions() {
|
|
264
|
+
const result = (await this.socket.request("listSessions", {
|
|
265
|
+
channel: ROOT_CHANNEL,
|
|
266
|
+
}));
|
|
267
|
+
return result.items.map((s) => ({
|
|
268
|
+
sessionId: s.resource.replace(/^ahp-session:\//, ""),
|
|
269
|
+
runtime: s.provider,
|
|
270
|
+
// SessionStatus is a bitset enum; preserve the numeric value as string
|
|
271
|
+
// so existing consumers (which treat status as opaque) still work.
|
|
272
|
+
status: String(s.status),
|
|
273
|
+
}));
|
|
274
|
+
}
|
|
275
|
+
// ─── Internals ────────────────────────────────────────────────────
|
|
276
|
+
getOrCreateSession(channel) {
|
|
277
|
+
let session = this.sessions.get(channel);
|
|
278
|
+
if (session === undefined) {
|
|
279
|
+
session = { queue: new EnvelopeQueue(), context: newReverseMapperContext() };
|
|
280
|
+
this.sessions.set(channel, session);
|
|
281
|
+
}
|
|
282
|
+
return session;
|
|
283
|
+
}
|
|
284
|
+
closeSession(channel) {
|
|
285
|
+
const session = this.sessions.get(channel);
|
|
286
|
+
if (session === undefined) {
|
|
287
|
+
return;
|
|
288
|
+
}
|
|
289
|
+
session.queue.close();
|
|
290
|
+
this.sessions.delete(channel);
|
|
291
|
+
}
|
|
292
|
+
async runSpawnFlow(channel, params, resumeFromRuntimeSessionId) {
|
|
293
|
+
const config = {
|
|
294
|
+
// Grackle-specific session config — PowerLine handler validates this shape.
|
|
295
|
+
prompt: params.prompt,
|
|
296
|
+
model: params.model,
|
|
297
|
+
maxTurns: params.maxTurns,
|
|
298
|
+
branch: params.branch,
|
|
299
|
+
workingDirectory: params.workingDirectory,
|
|
300
|
+
systemContext: params.systemContext,
|
|
301
|
+
taskId: params.taskId,
|
|
302
|
+
mcpServersJson: params.mcpServersJson,
|
|
303
|
+
mcpUrl: params.mcpUrl,
|
|
304
|
+
mcpToken: params.mcpToken,
|
|
305
|
+
...(params.workspaceId !== undefined ? { workspaceId: params.workspaceId } : {}),
|
|
306
|
+
...(params.useWorktrees !== undefined ? { useWorktrees: params.useWorktrees } : {}),
|
|
307
|
+
...(params.pipe !== undefined && params.pipe !== "" ? { pipe: params.pipe } : {}),
|
|
308
|
+
...(params.scriptContent !== undefined && params.scriptContent !== ""
|
|
309
|
+
? { scriptContent: params.scriptContent }
|
|
310
|
+
: {}),
|
|
311
|
+
...(resumeFromRuntimeSessionId !== undefined ? { resumeFromRuntimeSessionId } : {}),
|
|
312
|
+
};
|
|
313
|
+
const ahpParams = {
|
|
314
|
+
channel,
|
|
315
|
+
provider: params.runtime,
|
|
316
|
+
config,
|
|
317
|
+
};
|
|
318
|
+
const isReanimate = resumeFromRuntimeSessionId !== undefined;
|
|
319
|
+
try {
|
|
320
|
+
await this.socket.request("createSession", ahpParams);
|
|
321
|
+
}
|
|
322
|
+
catch (err) {
|
|
323
|
+
// Reanimate path: if the channel is already live on PowerLine (env was
|
|
324
|
+
// never actually torn down — happens with the local adapter whose
|
|
325
|
+
// `stop()` is a no-op), the server returns "Session already active".
|
|
326
|
+
// For reanimate that's success: the underlying runtime never died, we
|
|
327
|
+
// just need to re-subscribe to its action stream.
|
|
328
|
+
if (isReanimate && isSessionAlreadyActiveError(err)) {
|
|
329
|
+
// intentional fall-through to subscribe()
|
|
330
|
+
}
|
|
331
|
+
else {
|
|
332
|
+
throw err;
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
await this.socket.request("subscribe", { channel });
|
|
336
|
+
// After subscribe resolves, PowerLine starts firing action notifications
|
|
337
|
+
// (including any replayed parked events) — the handleNotification handler
|
|
338
|
+
// routes them to the session's queue.
|
|
339
|
+
}
|
|
340
|
+
surfaceErrorAndClose(session, channel, err) {
|
|
341
|
+
// Synthesize an error event so the downstream pipeline sees the failure
|
|
342
|
+
// through the same channel it sees normal events.
|
|
343
|
+
const message = formatTransportError(err);
|
|
344
|
+
const errorEvent = { type: "error", content: message };
|
|
345
|
+
session.queue.push({ event: errorEvent, actions: [] });
|
|
346
|
+
session.queue.push({ event: { type: "status", content: "failed" }, actions: [] });
|
|
347
|
+
this.closeSession(channel);
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
/**
|
|
351
|
+
* True if `err` is the JSON-RPC "Session already active" error PowerLine
|
|
352
|
+
* returns when `createSession` targets a channel whose underlying session
|
|
353
|
+
* is still live in the registry. Tested with both message-prefix and
|
|
354
|
+
* code+message-shape since the error can arrive as a rejected
|
|
355
|
+
* `TransportError` or a raw JSON-RPC error object depending on the
|
|
356
|
+
* `request()` path.
|
|
357
|
+
*/
|
|
358
|
+
function isSessionAlreadyActiveError(err) {
|
|
359
|
+
const message = err instanceof Error
|
|
360
|
+
? err.message
|
|
361
|
+
: err !== null &&
|
|
362
|
+
typeof err === "object" &&
|
|
363
|
+
typeof err.message === "string"
|
|
364
|
+
? err.message
|
|
365
|
+
: "";
|
|
366
|
+
return message.startsWith("Session already active");
|
|
367
|
+
}
|
|
368
|
+
/**
|
|
369
|
+
* Stringify an unknown error into a readable message for the synthesized
|
|
370
|
+
* `type: "error"` event surfaced into the downstream pipeline.
|
|
371
|
+
*
|
|
372
|
+
* Handles four shapes:
|
|
373
|
+
* - `Error` (and subclasses, including `TransportError` from
|
|
374
|
+
* `@grackle-ai/ahp-transport`): use `.message`.
|
|
375
|
+
* - JSON-RPC error object `{ code, message }` (what `request()` rejects with
|
|
376
|
+
* on a server-returned error): use `.message`, prefix with code if present.
|
|
377
|
+
* Without this branch, `String(err)` returns `"[object Object]"` and the
|
|
378
|
+
* UI renders an opaque "Error: [object Object]" with no diagnostic value.
|
|
379
|
+
* - String: pass through.
|
|
380
|
+
* - Anything else: best-effort `String(err)`.
|
|
381
|
+
*/
|
|
382
|
+
function formatTransportError(err) {
|
|
383
|
+
if (err instanceof Error) {
|
|
384
|
+
return err.message;
|
|
385
|
+
}
|
|
386
|
+
if (typeof err === "string") {
|
|
387
|
+
return err;
|
|
388
|
+
}
|
|
389
|
+
if (err !== null && typeof err === "object") {
|
|
390
|
+
const obj = err;
|
|
391
|
+
if (typeof obj.message === "string" && obj.message.length > 0) {
|
|
392
|
+
return typeof obj.code === "number" || typeof obj.code === "string"
|
|
393
|
+
? `JSON-RPC error ${String(obj.code)}: ${obj.message}`
|
|
394
|
+
: obj.message;
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
return String(err);
|
|
398
|
+
}
|
|
399
|
+
/**
|
|
400
|
+
* Helper to wire {@link AhpHostTransport}'s notification handler into an
|
|
401
|
+
* `AhpClientSocket` at construction time. The transport's
|
|
402
|
+
* {@link AhpHostTransport.handleNotification} method must be bound to the
|
|
403
|
+
* socket BEFORE `socket.open()` so the first inbound `action` notifications
|
|
404
|
+
* are routed correctly.
|
|
405
|
+
*
|
|
406
|
+
* @param transport - The transport whose handler should be bound.
|
|
407
|
+
* @returns A function suitable for passing as `onNotification` to
|
|
408
|
+
* `AhpClientSocket`'s constructor options.
|
|
409
|
+
*/
|
|
410
|
+
export function bindNotificationHandler(transport) {
|
|
411
|
+
return (n) => transport.handleNotification(n);
|
|
412
|
+
}
|
|
413
|
+
//# sourceMappingURL=ahp-host-transport.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ahp-host-transport.js","sourceRoot":"","sources":["../src/ahp-host-transport.ts"],"names":[],"mappings":"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"}
|
package/dist/connect.d.ts
CHANGED
|
@@ -1,16 +1,42 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { AhpClientSocket } from "@grackle-ai/ahp-transport";
|
|
2
|
+
import type { PowerLineConnection } from "./adapter.js";
|
|
3
|
+
import { AhpHostTransport } from "./ahp-host-transport.js";
|
|
2
4
|
import type { AdapterLogger } from "./logger.js";
|
|
3
5
|
/**
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
6
|
+
* Construct an opened {@link AhpHostTransport} for a single PowerLine.
|
|
7
|
+
*
|
|
8
|
+
* Opens an `AhpClientSocket` to `${baseUrl}/ahp`, awaits the AHP
|
|
9
|
+
* `initialize` handshake, and returns the transport ready for use.
|
|
10
|
+
*
|
|
11
|
+
* `InMemoryClientIdStore` is used by default — Grackle's adapter
|
|
12
|
+
* connections are ephemeral (one per provision; reconnect creates a fresh
|
|
13
|
+
* one). Persistent `clientId` across server restarts is not required for
|
|
14
|
+
* HR8d. A future optimization (HR8a-followup #1344) would persist for
|
|
15
|
+
* reconnect-RPC replay efficiency.
|
|
16
|
+
*
|
|
17
|
+
* @param baseUrl - Origin URL of the PowerLine (e.g. `ws://127.0.0.1:7433`).
|
|
18
|
+
* The helper appends `/ahp` to form the WebSocket URL.
|
|
19
|
+
* @param powerlineToken - Bearer token sent on the HTTP upgrade.
|
|
20
|
+
* @param environmentId - Used as the `clientIdKey` to namespace the
|
|
21
|
+
* persisted clientId within the store.
|
|
22
|
+
* @param logger - Optional logger for state transitions.
|
|
23
|
+
* @returns The opened transport.
|
|
7
24
|
*/
|
|
8
|
-
export declare function
|
|
25
|
+
export declare function createAhpHostTransport(baseUrl: string, powerlineToken: string, environmentId: string, logger?: AdapterLogger): Promise<{
|
|
26
|
+
transport: AhpHostTransport;
|
|
27
|
+
socket: AhpClientSocket;
|
|
28
|
+
}>;
|
|
9
29
|
/**
|
|
10
|
-
* Connect to a PowerLine through a local tunnel port, retrying until the
|
|
11
|
-
*
|
|
30
|
+
* Connect to a PowerLine through a local tunnel port, retrying until the AHP
|
|
31
|
+
* `ping` succeeds.
|
|
32
|
+
*
|
|
33
|
+
* @param environmentId - Stable identifier for the environment.
|
|
34
|
+
* @param localPort - Local TCP port the tunnel forwards to the PowerLine.
|
|
35
|
+
* @param powerlineToken - Bearer token for the PowerLine.
|
|
36
|
+
* @param logger - Optional logger.
|
|
37
|
+
* @returns A {@link PowerLineConnection} ready for session operations.
|
|
12
38
|
*/
|
|
13
|
-
export declare function connectThroughTunnel(environmentId: string, localPort: number, powerlineToken: string, logger?: AdapterLogger
|
|
39
|
+
export declare function connectThroughTunnel(environmentId: string, localPort: number, powerlineToken: string, logger?: AdapterLogger): Promise<PowerLineConnection>;
|
|
14
40
|
/** Single-shot TCP port prober used by {@link waitForLocalPort}. */
|
|
15
41
|
export interface PortProber {
|
|
16
42
|
/** Attempt a single TCP connection to `host:port`, returning `true` if it succeeds. */
|