@tangle-network/agent-provider-cli-bridge 0.8.1 → 0.9.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/capability-discovery.js +12 -3
- package/dist/index.js +18 -6
- package/dist/retained-environment.js +15 -1
- package/dist/retained-native.d.ts +7 -1
- package/dist/retained-native.js +197 -1
- package/dist/retained-run-state.d.ts +5 -3
- package/dist/retained-run-state.js +22 -0
- package/package.json +2 -2
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { AgentEnvironmentCapabilitiesSchema, } from "@tangle-network/agent-interface/environment-provider";
|
|
2
|
-
import { supportsCliBridgeNativeInteractions } from "./retained-native.js";
|
|
2
|
+
import { supportsCliBridgeNativeContinuation, supportsCliBridgeNativeInteractions, } from "./retained-native.js";
|
|
3
3
|
import { createCliBridgeTransport, requestHeaders, trimSlash, } from "./transport.js";
|
|
4
4
|
/** Read the retained contract from the exact Bridge model route. */
|
|
5
5
|
export async function discoverCliBridgeCapabilities(options, model) {
|
|
@@ -60,13 +60,21 @@ export function narrowCliBridgeCapabilities(adapter, reported, selectedBackend,
|
|
|
60
60
|
detach: adapter.streaming.detach && reported.streaming.detach,
|
|
61
61
|
turnIdempotency: adapter.streaming.turnIdempotency && reported.streaming.turnIdempotency,
|
|
62
62
|
};
|
|
63
|
+
const nativeContinuation = supportsCliBridgeNativeContinuation(adapter) &&
|
|
64
|
+
supportsCliBridgeNativeContinuation(reported)
|
|
65
|
+
? { atomicBoundary: true, requestIdempotency: true }
|
|
66
|
+
: undefined;
|
|
63
67
|
const sessions = {
|
|
64
|
-
continue:
|
|
68
|
+
continue: nativeContinuation !== undefined &&
|
|
69
|
+
adapter.sessions.continue &&
|
|
70
|
+
reported.sessions.continue,
|
|
65
71
|
// The Bridge can list and inspect sessions, but this adapter exposes neither method.
|
|
66
72
|
list: false,
|
|
67
73
|
messages: false,
|
|
68
74
|
};
|
|
69
|
-
const retainedControl =
|
|
75
|
+
const retainedControl = sessions.continue &&
|
|
76
|
+
supportsRetainedControl(adapter) &&
|
|
77
|
+
supportsRetainedControl(reported)
|
|
70
78
|
? {
|
|
71
79
|
exactRunIdentity: true,
|
|
72
80
|
resultIdentity: true,
|
|
@@ -111,6 +119,7 @@ export function narrowCliBridgeCapabilities(adapter, reported, selectedBackend,
|
|
|
111
119
|
streaming,
|
|
112
120
|
sessions,
|
|
113
121
|
...(retainedControl === undefined ? {} : { retainedControl }),
|
|
122
|
+
...(nativeContinuation === undefined ? {} : { nativeContinuation }),
|
|
114
123
|
...(interactions === undefined ? {} : { interactions }),
|
|
115
124
|
// Remote workspace support cannot create absent adapter methods.
|
|
116
125
|
workspace: {
|
package/dist/index.js
CHANGED
|
@@ -148,13 +148,25 @@ export function defaultCliBridgeCapabilities(harness) {
|
|
|
148
148
|
validation: false,
|
|
149
149
|
},
|
|
150
150
|
streaming: { live: true, replay: true, detach: true, turnIdempotency: true },
|
|
151
|
-
sessions: {
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
eventIdentity: true,
|
|
156
|
-
cancellationIdempotency: true,
|
|
151
|
+
sessions: {
|
|
152
|
+
continue: harness === "pi",
|
|
153
|
+
list: false,
|
|
154
|
+
messages: false,
|
|
157
155
|
},
|
|
156
|
+
...(harness === "pi"
|
|
157
|
+
? {
|
|
158
|
+
retainedControl: {
|
|
159
|
+
exactRunIdentity: true,
|
|
160
|
+
resultIdentity: true,
|
|
161
|
+
eventIdentity: true,
|
|
162
|
+
cancellationIdempotency: true,
|
|
163
|
+
},
|
|
164
|
+
nativeContinuation: {
|
|
165
|
+
atomicBoundary: true,
|
|
166
|
+
requestIdempotency: true,
|
|
167
|
+
},
|
|
168
|
+
}
|
|
169
|
+
: {}),
|
|
158
170
|
...(harness === "pi"
|
|
159
171
|
? {
|
|
160
172
|
interactions: {
|
|
@@ -2,7 +2,7 @@ import { agentSessionStatusFromRun, cancelCliBridgeRun, cancelExactCliBridgeRun,
|
|
|
2
2
|
import { addTokenUsage, collectCliBridgeTurnResult, dispatchCliBridgeTurn, streamCliBridgeSessionEvents, streamTrackedCliBridgeTurn, } from "./retained-execution.js";
|
|
3
3
|
import { createExecutionUsageLog, observeCliBridgeEnvironment, } from "./observation.js";
|
|
4
4
|
import { cliBridgeInteractionResponder } from "./interaction-response.js";
|
|
5
|
-
import { assertCliBridgeRequestedInteractions, assertCliBridgeNativeTurnModel, supportsCliBridgeNativeInteractions, } from "./retained-native.js";
|
|
5
|
+
import { assertCliBridgeRequestedInteractions, assertCliBridgeNativeTurnModel, continueCliBridgeNative, readCliBridgeNativeContextBoundary, supportsCliBridgeNativeContinuation, supportsCliBridgeNativeInteractions, } from "./retained-native.js";
|
|
6
6
|
import { assertRunMatchesControlRef, exactControlRefForSession, prepareCliBridgeRun, runFromControlRef, } from "./retained-run-state.js";
|
|
7
7
|
import { createCliBridgeTransport } from "./transport.js";
|
|
8
8
|
export function createCliBridgeEnvironment(args) {
|
|
@@ -253,6 +253,20 @@ function createCliBridgeSession(args) {
|
|
|
253
253
|
const run = requireCurrentRun();
|
|
254
254
|
return cancelExactCliBridgeRun(args.options, args.transport, run, request, cancelOptions?.signal);
|
|
255
255
|
},
|
|
256
|
+
...(supportsCliBridgeNativeContinuation(args.capabilities)
|
|
257
|
+
? {
|
|
258
|
+
async contextBoundary(boundaryOptions) {
|
|
259
|
+
return readCliBridgeNativeContextBoundary(args.options, args.providerName, args.transport, requireCurrentRun(), boundaryOptions?.signal);
|
|
260
|
+
},
|
|
261
|
+
async continueNative(request, continuationOptions) {
|
|
262
|
+
const result = await continueCliBridgeNative(args.options, args.providerName, args.transport, requireCurrentRun(), request, continuationOptions, args.runs);
|
|
263
|
+
if ("result" in result && result.result.usage !== undefined) {
|
|
264
|
+
args.usageLog.record(result.controlRef.executionId, result.result.usage);
|
|
265
|
+
}
|
|
266
|
+
return result;
|
|
267
|
+
},
|
|
268
|
+
}
|
|
269
|
+
: {}),
|
|
256
270
|
...(respondToInteraction ? { respondToInteraction } : {}),
|
|
257
271
|
};
|
|
258
272
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { AgentEnvironmentCapabilities, AgentTurnInput, CreateAgentEnvironmentInput } from "@tangle-network/agent-interface/environment-provider";
|
|
2
|
-
import { type Sha256Digest, type RequestedInteractions } from "@tangle-network/agent-interface";
|
|
2
|
+
import { type AgentNativeContextContinuationOptions, type AgentNativeContextContinuationResult, type Sha256Digest, type NativeContextBoundaryProof, type NativeContextContinuationRequest, type RequestedInteractions } from "@tangle-network/agent-interface";
|
|
3
3
|
import type { CliBridgeProviderOptions } from "./provider-options.js";
|
|
4
4
|
import type { CliBridgeRun } from "./retained-run-state.js";
|
|
5
5
|
import type { CliBridgeTransport } from "./transport.js";
|
|
@@ -12,10 +12,16 @@ export interface CliBridgeNativeSession {
|
|
|
12
12
|
export type CliBridgeNativeSessionCache = Map<string, Promise<CliBridgeNativeSession>>;
|
|
13
13
|
/** Interactions are valid only for the native retained Pi contract. */
|
|
14
14
|
export declare function supportsCliBridgeNativeInteractions(capabilities: AgentEnvironmentCapabilities, selectedBackend?: string): boolean;
|
|
15
|
+
/** Native continuation is exposed only when the Bridge proves both guarantees. */
|
|
16
|
+
export declare function supportsCliBridgeNativeContinuation(capabilities: AgentEnvironmentCapabilities): boolean;
|
|
15
17
|
/** Reject posture the selected environment did not advertise before transport use. */
|
|
16
18
|
export declare function assertCliBridgeRequestedInteractions(capabilities: AgentEnvironmentCapabilities, requested: RequestedInteractions | undefined): void;
|
|
17
19
|
/** Keep capability discovery and every native turn on one exact model route. */
|
|
18
20
|
export declare function assertCliBridgeNativeTurnModel(options: CliBridgeProviderOptions, environmentInput: CreateAgentEnvironmentInput, turn: AgentTurnInput, selectedModel: string | undefined): void;
|
|
21
|
+
/** Read the Bridge-owned exact boundary for the current retained run. */
|
|
22
|
+
export declare function readCliBridgeNativeContextBoundary(options: CliBridgeProviderOptions, providerName: string, transport: CliBridgeTransport, run: CliBridgeRun, signal?: AbortSignal): Promise<NativeContextBoundaryProof | null>;
|
|
23
|
+
/** Send one canonical same-session continuation and advance the live run identity. */
|
|
24
|
+
export declare function continueCliBridgeNative(options: CliBridgeProviderOptions, providerName: string, transport: CliBridgeTransport, run: CliBridgeRun, request: NativeContextContinuationRequest, continuationOptions: AgentNativeContextContinuationOptions, runs: Map<string, CliBridgeRun>): Promise<AgentNativeContextContinuationResult>;
|
|
19
25
|
/**
|
|
20
26
|
* Create or reuse the server's retained native session for one external id.
|
|
21
27
|
*
|
package/dist/retained-native.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import { AgentExactRunControlRefSchema, RequestedInteractionsSchema, canonicalCandidateDigest, } from "@tangle-network/agent-interface";
|
|
1
|
+
import { AgentNativeContextContinuationResultSchema, AgentExactRunControlRefSchema, NativeContextBoundaryProofSchema, NativeContextContinuationRequestSchema, RequestedInteractionsSchema, agentNativeContextContinuationResultMatchesRequest, canonicalCandidateDigest, nativeContextContinuationTurnDigest, } from "@tangle-network/agent-interface";
|
|
2
2
|
import { CliBridgeRequestRejectedError } from "./retained-stream.js";
|
|
3
|
+
import { advanceCliBridgeRun, exactControlRefForRun, } from "./retained-run-state.js";
|
|
3
4
|
import { requestHeaders, trimSlash, } from "./transport.js";
|
|
4
5
|
import { inlineProfile, safeJson, resolveBridgeModel, toRetainedSessionBody, toRetainedTurnBody, } from "./wire.js";
|
|
6
|
+
const MAX_NATIVE_CONTINUATION_RESPONSE_BYTES = 1_048_576;
|
|
5
7
|
/** Interactions are valid only for the native retained Pi contract. */
|
|
6
8
|
export function supportsCliBridgeNativeInteractions(capabilities, selectedBackend) {
|
|
7
9
|
const interactions = capabilities.interactions;
|
|
@@ -18,6 +20,12 @@ export function supportsCliBridgeNativeInteractions(capabilities, selectedBacken
|
|
|
18
20
|
retainedControl.eventIdentity &&
|
|
19
21
|
retainedControl.cancellationIdempotency);
|
|
20
22
|
}
|
|
23
|
+
/** Native continuation is exposed only when the Bridge proves both guarantees. */
|
|
24
|
+
export function supportsCliBridgeNativeContinuation(capabilities) {
|
|
25
|
+
return Boolean(capabilities.sessions.continue &&
|
|
26
|
+
capabilities.nativeContinuation?.atomicBoundary === true &&
|
|
27
|
+
capabilities.nativeContinuation.requestIdempotency === true);
|
|
28
|
+
}
|
|
21
29
|
/** Reject posture the selected environment did not advertise before transport use. */
|
|
22
30
|
export function assertCliBridgeRequestedInteractions(capabilities, requested) {
|
|
23
31
|
if (requested === undefined)
|
|
@@ -49,6 +57,194 @@ function piInteractionCapabilitiesMatch(interactions) {
|
|
|
49
57
|
interactions.replay === true &&
|
|
50
58
|
interactions.responseIdempotency === true);
|
|
51
59
|
}
|
|
60
|
+
/** Read the Bridge-owned exact boundary for the current retained run. */
|
|
61
|
+
export async function readCliBridgeNativeContextBoundary(options, providerName, transport, run, signal) {
|
|
62
|
+
const controlRef = currentCliBridgeControlRef(run, providerName);
|
|
63
|
+
const response = await transport.fetch(`${trimSlash(options.baseUrl)}/v1/sessions/${encodeURIComponent(controlRef.sessionId)}`, {
|
|
64
|
+
method: "GET",
|
|
65
|
+
headers: requestHeaders(options),
|
|
66
|
+
...(signal ? { signal } : {}),
|
|
67
|
+
});
|
|
68
|
+
const responseText = await readBoundedResponseText(response, signal);
|
|
69
|
+
if (!response.ok) {
|
|
70
|
+
throw new CliBridgeRequestRejectedError(response.status, responseText);
|
|
71
|
+
}
|
|
72
|
+
const parsed = safeJson(responseText);
|
|
73
|
+
if (!parsed) {
|
|
74
|
+
throw new Error("cli-bridge native session boundary response is not a JSON object");
|
|
75
|
+
}
|
|
76
|
+
if (parsed.id !== undefined && parsed.id !== controlRef.sessionId) {
|
|
77
|
+
throw new Error("cli-bridge native session boundary response targets another session");
|
|
78
|
+
}
|
|
79
|
+
if (parsed.context_boundary === null)
|
|
80
|
+
return null;
|
|
81
|
+
const proof = NativeContextBoundaryProofSchema.safeParse(parsed.context_boundary);
|
|
82
|
+
if (!proof.success) {
|
|
83
|
+
throw new Error("cli-bridge native session returned an invalid context boundary", {
|
|
84
|
+
cause: proof.error,
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
assertBoundaryControlRef(proof.data, controlRef);
|
|
88
|
+
return proof.data;
|
|
89
|
+
}
|
|
90
|
+
/** Send one canonical same-session continuation and advance the live run identity. */
|
|
91
|
+
export async function continueCliBridgeNative(options, providerName, transport, run, request, continuationOptions, runs) {
|
|
92
|
+
const exactRequest = NativeContextContinuationRequestSchema.parse(request);
|
|
93
|
+
const current = currentCliBridgeControlRef(run, providerName);
|
|
94
|
+
if (!sameControlRef(current, exactRequest.run)) {
|
|
95
|
+
throw new Error("cli-bridge native continuation targets another retained run");
|
|
96
|
+
}
|
|
97
|
+
if (nativeContextContinuationTurnDigest(continuationOptions.turn) !==
|
|
98
|
+
exactRequest.turnDigest) {
|
|
99
|
+
throw new Error("cli-bridge native continuation turn does not match its request digest");
|
|
100
|
+
}
|
|
101
|
+
const operation = continuationSignal(continuationOptions);
|
|
102
|
+
try {
|
|
103
|
+
operation.signal?.throwIfAborted();
|
|
104
|
+
const response = await transport.fetch(`${trimSlash(options.baseUrl)}/v1/sessions/${encodeURIComponent(exactRequest.run.sessionId)}/continue`, {
|
|
105
|
+
method: "POST",
|
|
106
|
+
headers: requestHeaders(options),
|
|
107
|
+
body: JSON.stringify({ request: exactRequest, turn: continuationOptions.turn }),
|
|
108
|
+
...(operation.signal ? { signal: operation.signal } : {}),
|
|
109
|
+
});
|
|
110
|
+
const responseText = await readBoundedResponseText(response, operation.signal);
|
|
111
|
+
const outcome = parseNativeContinuationResult(responseText);
|
|
112
|
+
assertContinuationAcknowledgementBinding(exactRequest, outcome);
|
|
113
|
+
if (outcome.acknowledgement.status === "accepted" ||
|
|
114
|
+
outcome.acknowledgement.status === "replayed") {
|
|
115
|
+
if (!agentNativeContextContinuationResultMatchesRequest(exactRequest, outcome)) {
|
|
116
|
+
throw new Error("cli-bridge native continuation returned an acknowledgement for another request");
|
|
117
|
+
}
|
|
118
|
+
if (!response.ok) {
|
|
119
|
+
throw new Error(`cli-bridge native continuation returned HTTP ${response.status} for an accepted result`);
|
|
120
|
+
}
|
|
121
|
+
if (!("controlRef" in outcome)) {
|
|
122
|
+
throw new Error("cli-bridge native continuation omitted its current control reference");
|
|
123
|
+
}
|
|
124
|
+
advanceCliBridgeRun(run, outcome.controlRef, providerName, runs);
|
|
125
|
+
}
|
|
126
|
+
return outcome;
|
|
127
|
+
}
|
|
128
|
+
finally {
|
|
129
|
+
operation.dispose();
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
function currentCliBridgeControlRef(run, providerName) {
|
|
133
|
+
if (run.controlRef !== undefined) {
|
|
134
|
+
const controlRef = AgentExactRunControlRefSchema.parse(run.controlRef);
|
|
135
|
+
if (!sameControlRef(controlRef, exactControlRefForRun(run, providerName))) {
|
|
136
|
+
throw new Error("cli-bridge retained run has a conflicting control reference");
|
|
137
|
+
}
|
|
138
|
+
return controlRef;
|
|
139
|
+
}
|
|
140
|
+
const controlRef = exactControlRefForRun(run, providerName);
|
|
141
|
+
run.controlRef = controlRef;
|
|
142
|
+
return controlRef;
|
|
143
|
+
}
|
|
144
|
+
function sameControlRef(left, right) {
|
|
145
|
+
return left.runId === right.runId &&
|
|
146
|
+
left.provider === right.provider &&
|
|
147
|
+
left.environmentId === right.environmentId &&
|
|
148
|
+
left.sessionId === right.sessionId &&
|
|
149
|
+
left.executionId === right.executionId &&
|
|
150
|
+
left.requestDigest === right.requestDigest;
|
|
151
|
+
}
|
|
152
|
+
function assertBoundaryControlRef(proof, controlRef) {
|
|
153
|
+
if (proof.runId !== controlRef.runId ||
|
|
154
|
+
proof.provider !== controlRef.provider ||
|
|
155
|
+
proof.environmentId !== controlRef.environmentId ||
|
|
156
|
+
proof.sessionId !== controlRef.sessionId ||
|
|
157
|
+
proof.executionId !== controlRef.executionId ||
|
|
158
|
+
proof.requestDigest !== controlRef.requestDigest) {
|
|
159
|
+
throw new Error("cli-bridge native session boundary does not bind to the retained run");
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
function parseNativeContinuationResult(value) {
|
|
163
|
+
const parsed = safeJson(value);
|
|
164
|
+
try {
|
|
165
|
+
return AgentNativeContextContinuationResultSchema.parse(parsed);
|
|
166
|
+
}
|
|
167
|
+
catch (error) {
|
|
168
|
+
throw new Error("cli-bridge native continuation returned an invalid result", {
|
|
169
|
+
cause: error,
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
function assertContinuationAcknowledgementBinding(request, outcome) {
|
|
174
|
+
const acknowledgement = outcome.acknowledgement;
|
|
175
|
+
if (acknowledgement.operationId !== request.operationId ||
|
|
176
|
+
acknowledgement.requestDigest !== request.requestDigest ||
|
|
177
|
+
acknowledgement.historyMessagesSent !== 0) {
|
|
178
|
+
throw new Error("cli-bridge native continuation acknowledgement is not bound to the request");
|
|
179
|
+
}
|
|
180
|
+
if (acknowledgement.actualBoundary !== undefined) {
|
|
181
|
+
assertBoundaryControlRef(acknowledgement.actualBoundary, request.run);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
function continuationSignal(options) {
|
|
185
|
+
const timeoutMs = options.timeoutMs;
|
|
186
|
+
if (timeoutMs !== undefined &&
|
|
187
|
+
(!Number.isSafeInteger(timeoutMs) || timeoutMs < 0 || timeoutMs > 2_147_483_647)) {
|
|
188
|
+
throw new Error("native continuation timeoutMs must be an integer from 0 through 2147483647");
|
|
189
|
+
}
|
|
190
|
+
if (timeoutMs === undefined) {
|
|
191
|
+
return { signal: options.signal, dispose: () => { } };
|
|
192
|
+
}
|
|
193
|
+
const controller = new AbortController();
|
|
194
|
+
const timer = setTimeout(() => {
|
|
195
|
+
controller.abort(new DOMException("native continuation timed out", "TimeoutError"));
|
|
196
|
+
}, timeoutMs);
|
|
197
|
+
const signal = options.signal === undefined
|
|
198
|
+
? controller.signal
|
|
199
|
+
: AbortSignal.any([options.signal, controller.signal]);
|
|
200
|
+
return {
|
|
201
|
+
signal,
|
|
202
|
+
dispose: () => clearTimeout(timer),
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
async function readBoundedResponseText(response, signal) {
|
|
206
|
+
const contentLength = response.headers.get("content-length");
|
|
207
|
+
if (contentLength !== null) {
|
|
208
|
+
const parsedLength = Number(contentLength);
|
|
209
|
+
if (Number.isSafeInteger(parsedLength) &&
|
|
210
|
+
parsedLength > MAX_NATIVE_CONTINUATION_RESPONSE_BYTES) {
|
|
211
|
+
throw new Error("cli-bridge native continuation response exceeds its byte limit");
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
if (response.body === null) {
|
|
215
|
+
signal?.throwIfAborted();
|
|
216
|
+
const text = await response.text();
|
|
217
|
+
if (new TextEncoder().encode(text).byteLength > MAX_NATIVE_CONTINUATION_RESPONSE_BYTES) {
|
|
218
|
+
throw new Error("cli-bridge native continuation response exceeds its byte limit");
|
|
219
|
+
}
|
|
220
|
+
return text;
|
|
221
|
+
}
|
|
222
|
+
const iterator = response.body[Symbol.asyncIterator]();
|
|
223
|
+
const decoder = new TextDecoder();
|
|
224
|
+
let bytes = 0;
|
|
225
|
+
let text = "";
|
|
226
|
+
let complete = false;
|
|
227
|
+
try {
|
|
228
|
+
while (true) {
|
|
229
|
+
signal?.throwIfAborted();
|
|
230
|
+
const next = await iterator.next();
|
|
231
|
+
if (next.done)
|
|
232
|
+
break;
|
|
233
|
+
bytes += next.value.byteLength;
|
|
234
|
+
if (bytes > MAX_NATIVE_CONTINUATION_RESPONSE_BYTES) {
|
|
235
|
+
throw new Error("cli-bridge native continuation response exceeds its byte limit");
|
|
236
|
+
}
|
|
237
|
+
text += decoder.decode(next.value, { stream: true });
|
|
238
|
+
}
|
|
239
|
+
complete = true;
|
|
240
|
+
return text + decoder.decode();
|
|
241
|
+
}
|
|
242
|
+
finally {
|
|
243
|
+
if (!complete) {
|
|
244
|
+
await iterator.return?.();
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
}
|
|
52
248
|
/**
|
|
53
249
|
* Create or reuse the server's retained native session for one external id.
|
|
54
250
|
*
|
|
@@ -2,11 +2,11 @@ import { type AgentExactRunControlRef, type AgentRunControlRef, type Sha256Diges
|
|
|
2
2
|
import type { AgentTurnInput, CreateAgentEnvironmentInput } from "@tangle-network/agent-interface/environment-provider";
|
|
3
3
|
import type { CliBridgeProviderOptions } from "./provider-options.js";
|
|
4
4
|
export interface CliBridgeRun {
|
|
5
|
-
|
|
5
|
+
id: string;
|
|
6
6
|
readonly environmentId: string;
|
|
7
7
|
readonly sessionId?: string;
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
executionId: string;
|
|
9
|
+
turnId: string;
|
|
10
10
|
readonly requestBody: string;
|
|
11
11
|
readonly readers: Set<AbortController>;
|
|
12
12
|
requestDigest?: Sha256Digest;
|
|
@@ -31,6 +31,8 @@ export declare function exactControlRefForRun(run: CliBridgeRun, providerName: s
|
|
|
31
31
|
export declare function exactControlRefForSession(value: AgentRunControlRef, providerName: string, environmentId: string, sessionId: string): AgentExactRunControlRef;
|
|
32
32
|
export declare function runFromControlRef(controlRef: AgentExactRunControlRef): CliBridgeRun;
|
|
33
33
|
export declare function assertRunMatchesControlRef(run: CliBridgeRun, controlRef: AgentExactRunControlRef): void;
|
|
34
|
+
/** Advance one session object to the exact run returned by native continuation. */
|
|
35
|
+
export declare function advanceCliBridgeRun(run: CliBridgeRun, controlRef: AgentExactRunControlRef, providerName: string, runs: Map<string, CliBridgeRun>): void;
|
|
34
36
|
export declare function prepareCliBridgeRun(options: CliBridgeProviderOptions, environmentInput: CreateAgentEnvironmentInput, originalTurn: AgentTurnInput, environmentId: string, requireSession: boolean): PreparedCliBridgeRun;
|
|
35
37
|
export declare function bindCliBridgeRun(prepared: CliBridgeRun, runs: Map<string, CliBridgeRun>): CliBridgeRun | undefined;
|
|
36
38
|
export declare function restoreCliBridgeRun(run: CliBridgeRun, previous: CliBridgeRun | undefined, runs: Map<string, CliBridgeRun>): void;
|
|
@@ -45,6 +45,28 @@ export function assertRunMatchesControlRef(run, controlRef) {
|
|
|
45
45
|
}
|
|
46
46
|
run.controlRef = controlRef;
|
|
47
47
|
}
|
|
48
|
+
/** Advance one session object to the exact run returned by native continuation. */
|
|
49
|
+
export function advanceCliBridgeRun(run, controlRef, providerName, runs) {
|
|
50
|
+
if (controlRef.provider !== providerName ||
|
|
51
|
+
controlRef.environmentId !== run.environmentId ||
|
|
52
|
+
controlRef.sessionId !== run.sessionId) {
|
|
53
|
+
throw new Error("cli-bridge native continuation returned a run for another session");
|
|
54
|
+
}
|
|
55
|
+
const existing = runs.get(controlRef.runId);
|
|
56
|
+
if (existing !== undefined && existing !== run) {
|
|
57
|
+
throw new Error("cli-bridge native continuation returned a run already owned by another session");
|
|
58
|
+
}
|
|
59
|
+
const previousId = run.id;
|
|
60
|
+
if (runs.get(previousId) === run && previousId !== controlRef.runId) {
|
|
61
|
+
runs.delete(previousId);
|
|
62
|
+
}
|
|
63
|
+
run.id = controlRef.runId;
|
|
64
|
+
run.executionId = controlRef.executionId;
|
|
65
|
+
run.turnId = controlRef.executionId;
|
|
66
|
+
run.requestDigest = controlRef.requestDigest;
|
|
67
|
+
run.controlRef = Object.freeze(AgentExactRunControlRefSchema.parse(controlRef));
|
|
68
|
+
runs.set(run.id, run);
|
|
69
|
+
}
|
|
48
70
|
export function prepareCliBridgeRun(options, environmentInput, originalTurn, environmentId, requireSession) {
|
|
49
71
|
if (requireSession &&
|
|
50
72
|
(originalTurn.turnId === undefined || originalTurn.executionId === undefined)) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tangle-network/agent-provider-cli-bridge",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"description": "AgentEnvironmentProvider adapter for cli-bridge retained sessions and one-shot turns",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
"LICENSE"
|
|
60
60
|
],
|
|
61
61
|
"dependencies": {
|
|
62
|
-
"@tangle-network/agent-interface": "^1.0
|
|
62
|
+
"@tangle-network/agent-interface": "^1.3.0",
|
|
63
63
|
"undici": "7.29.0"
|
|
64
64
|
},
|
|
65
65
|
"devDependencies": {
|