@tangle-network/agent-provider-cli-bridge 1.1.2 → 2.0.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 +4 -3
- package/dist/capability-discovery.js +2 -0
- package/dist/context-transfer.js +3 -0
- package/dist/index.js +46 -4
- package/dist/retained-environment.d.ts +3 -0
- package/dist/retained-environment.js +8 -6
- package/dist/retained-execution.js +7 -3
- package/dist/retained-run-state.d.ts +2 -2
- package/dist/retained-run-state.js +7 -3
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -49,7 +49,7 @@ The lookup returns the server-issued digest only when all five planned coordinat
|
|
|
49
49
|
|
|
50
50
|
## Which call adds a turn
|
|
51
51
|
|
|
52
|
-
|
|
52
|
+
Creation, ordinary reconstruction and accepted transfer attachment have different admission authority.
|
|
53
53
|
|
|
54
54
|
In the process that created the environment, `environment.dispatch()`, `environment.stream()`, and `session.prompt()` all add a turn.
|
|
55
55
|
Passing the same `sessionId` continues the same CLI conversation.
|
|
@@ -58,10 +58,11 @@ After `provider.get(environmentId)` reconstructs the environment, only `session.
|
|
|
58
58
|
It requires the `nativeContinuation` capability, which the provider publishes only for the Pi harness today, and only when the running Bridge proves the same contract.
|
|
59
59
|
The reconstructed environment deliberately refuses every other way to start work: `environment.stream()` and `environment.dispatch()` throw "a reconstructed cli-bridge environment can only control an existing run", and `session.prompt()` throws "a reconstructed cli-bridge session cannot start another turn".
|
|
60
60
|
A reconstructed environment for any other harness therefore controls its existing runs (status, cursor replay, result, cancellation, and interaction responses) but adds no turn.
|
|
61
|
-
|
|
61
|
+
|
|
62
|
+
When the exact deployed route confirms `contextTransfer.attach`, `provider.get(environmentId, { contextTransfer: request })` instead attaches the accepted transfer's first turn. The request must carry its exact profile. The adapter looks up the canonical operation, requires an available matching receipt for that environment, and returns it as `environment.contextTransferReceipt`. The resulting `dispatch`, `stream` and `session.prompt` accept only that request and its destination identities. They do not allocate another environment or replace a missing one. Changed context or profile fails before dispatch; a missing or uncertain receipt refuses attachment. Destroying this reconstructed handle closes its readers without canceling the accepted destination's runs.
|
|
62
63
|
|
|
63
64
|
The capability document keeps `sessions.continue: true` on a reconstructed environment because the Agent Interface couples that flag to `retainedControl`: a document that reports `sessions.continue: false` while keeping retained run control fails `AgentEnvironmentCapabilitiesSchema` with "retained control requires exact run, result, event, cancellation, replay, detach, turn, and session identity together".
|
|
64
|
-
`nativeContinuation`
|
|
65
|
+
`nativeContinuation` states whether an ordinary reconstructed environment supports `continueNative`. It does not authorize the first turn of a separate transfer.
|
|
65
66
|
|
|
66
67
|
A runtime caller continues a retained run with `RetainedRunHandle.continueNative`, not with `startRetainedRunInEnvironment`.
|
|
67
68
|
`startRetainedRunInEnvironment` requires `provider.list` for its ownership proof, and this provider exposes no `list`; it then calls `environment.dispatch()`, which a reconstructed environment refuses.
|
|
@@ -82,6 +82,8 @@ export function narrowCliBridgeCapabilities(adapter, reported, selectedBackend,
|
|
|
82
82
|
freshSession: true,
|
|
83
83
|
requestIdempotency: true,
|
|
84
84
|
lookup: true,
|
|
85
|
+
...(adapter.contextTransfer.attach === true && reported.contextTransfer.attach === true
|
|
86
|
+
? { attach: true } : {}),
|
|
85
87
|
}
|
|
86
88
|
: undefined;
|
|
87
89
|
const sessions = {
|
package/dist/context-transfer.js
CHANGED
|
@@ -9,6 +9,9 @@ export function createCliBridgeContextTransfer(options) {
|
|
|
9
9
|
}
|
|
10
10
|
export async function transferCliBridgeContext(options, request, signal) {
|
|
11
11
|
const exact = ContextTransferRequestSchema.parse(request);
|
|
12
|
+
if (exact.workspace?.snapshot !== undefined) {
|
|
13
|
+
throw new Error("CLI Bridge provider does not support portable workspace snapshots");
|
|
14
|
+
}
|
|
12
15
|
const transport = createCliBridgeTransport(options);
|
|
13
16
|
try {
|
|
14
17
|
const response = await transport.fetch(`${trimSlash(options.baseUrl)}/v1/context-transfers`, {
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { agentEnvironmentCreateInputDigest, createAgentEnvironmentWithIdempotency, } from "@tangle-network/agent-interface/environment-provider";
|
|
2
|
-
import { harnessTypeSchema, harnessSystemPromptIntents, snapshotAgentProfile, WorkspaceRequestSchema, workspaceCwdPathForBase, } from "@tangle-network/agent-interface";
|
|
1
|
+
import { agentEnvironmentCreateInputDigest, createAgentEnvironmentWithIdempotency, AgentEnvironmentGetOptionsSchema, } from "@tangle-network/agent-interface/environment-provider";
|
|
2
|
+
import { harnessTypeSchema, harnessSystemPromptIntents, snapshotAgentProfile, deepFreeze, ContextTransferReceiptSchema, WorkspaceRequestSchema, workspaceCwdPathForBase, } from "@tangle-network/agent-interface";
|
|
3
3
|
import { createCliBridgeEnvironment, } from "./retained-environment.js";
|
|
4
4
|
import { lookupExactCliBridgeRun, } from "./retained-control.js";
|
|
5
5
|
import { cachedCliBridgeCapabilityDiscovery, narrowCliBridgeCapabilities, } from "./capability-discovery.js";
|
|
6
6
|
import { supportsCliBridgeNativeInteractions, } from "./retained-native.js";
|
|
7
|
-
import { createCliBridgeContextTransfer, lookupCliBridgeContextByEnvironment, } from "./context-transfer.js";
|
|
7
|
+
import { createCliBridgeContextTransfer, lookupCliBridgeContextByEnvironment, lookupCliBridgeContext, } from "./context-transfer.js";
|
|
8
8
|
import { assertCliBridgeProviderOptions, } from "./provider-options.js";
|
|
9
9
|
import { narrowedCliBridgeObservation } from "./observation.js";
|
|
10
10
|
import { cliBridgeEnvironmentId, optionalCliBridgeEnvironmentRoute, } from "./environment-identity.js";
|
|
@@ -13,6 +13,9 @@ export { safeEndpointFromBaseUrl } from "./observation.js";
|
|
|
13
13
|
export { closeExactCliBridgeSession } from "./retained-control.js";
|
|
14
14
|
export function createCliBridgeProvider(options) {
|
|
15
15
|
assertCliBridgeProviderOptions(options);
|
|
16
|
+
if (options.capabilities?.create?.workspaceSnapshot === true) {
|
|
17
|
+
throw new Error("CLI Bridge provider does not support portable workspace snapshots");
|
|
18
|
+
}
|
|
16
19
|
const name = options.name ?? "cli-bridge";
|
|
17
20
|
const createRecords = new Map();
|
|
18
21
|
const configuredBackend = selectedBackendFromRoute(options.defaultModel);
|
|
@@ -55,6 +58,9 @@ export function createCliBridgeProvider(options) {
|
|
|
55
58
|
});
|
|
56
59
|
};
|
|
57
60
|
const createEnvironment = async (input) => {
|
|
61
|
+
if (input.workspace?.snapshot !== undefined) {
|
|
62
|
+
throw new Error("CLI Bridge provider does not support portable workspace snapshots");
|
|
63
|
+
}
|
|
58
64
|
if (input.runtimeAttachments !== undefined) {
|
|
59
65
|
throw new Error("CLI Bridge provider does not support runtime MCP attachments");
|
|
60
66
|
}
|
|
@@ -111,9 +117,44 @@ export function createCliBridgeProvider(options) {
|
|
|
111
117
|
if (id.length === 0 || id.trim() !== id) {
|
|
112
118
|
throw new Error("cli-bridge environment id must be non-empty and have no outer whitespace");
|
|
113
119
|
}
|
|
120
|
+
const operation = AgentEnvironmentGetOptionsSchema.parse(getOptions ?? {});
|
|
121
|
+
operation.signal?.throwIfAborted();
|
|
122
|
+
const accepted = operation.contextTransfer;
|
|
123
|
+
if (accepted !== undefined) {
|
|
124
|
+
if (accepted.profile === undefined)
|
|
125
|
+
throw new Error("CLI Bridge attachment requires the accepted exact profile");
|
|
126
|
+
if (accepted.workspace?.snapshot !== undefined)
|
|
127
|
+
throw new Error("CLI Bridge provider does not support portable workspace snapshots");
|
|
128
|
+
const destination = accepted.plan.destination;
|
|
129
|
+
if (destination.provider !== name || (destination.environmentId !== undefined && destination.environmentId !== id)) {
|
|
130
|
+
throw new Error("CLI Bridge attachment targets another provider or environment");
|
|
131
|
+
}
|
|
132
|
+
const backend = destination.runner;
|
|
133
|
+
const environmentInput = { profile: snapshotAgentProfile(accepted.profile), backend,
|
|
134
|
+
...(accepted.workspace === undefined ? {} : { workspace: accepted.workspace }),
|
|
135
|
+
...(accepted.resources === undefined ? {} : { resources: accepted.resources }),
|
|
136
|
+
idempotencyKey: accepted.operationId };
|
|
137
|
+
const model = resolveBridgeModel({ ...options, defaultModel: undefined }, environmentInput, { model: destination.model ?? accepted.profile.model?.default ?? backend }, accepted.profile);
|
|
138
|
+
const attachedOptions = { ...options, defaultModel: model };
|
|
139
|
+
const capabilities = await resolveCapabilities(backend, model, true, true);
|
|
140
|
+
if (capabilities.contextTransfer?.attach !== true)
|
|
141
|
+
throw new Error("CLI Bridge context transfer attachment is unsupported by the selected deployment");
|
|
142
|
+
const transfer = await lookupCliBridgeContext(options, accepted, operation.signal);
|
|
143
|
+
if (transfer === undefined || (transfer.status !== "accepted" && transfer.status !== "replayed") || transfer.environmentId !== id) {
|
|
144
|
+
throw new Error("CLI Bridge attachment requires an available exact transfer receipt");
|
|
145
|
+
}
|
|
146
|
+
operation.signal?.throwIfAborted();
|
|
147
|
+
return createCliBridgeEnvironment({
|
|
148
|
+
options: attachedOptions, providerName: name, environmentId: id, environmentInput,
|
|
149
|
+
allowDispatch: true, cancelRunsOnDestroy: false, capabilities,
|
|
150
|
+
selectedBackend: backend, selectedModel: model,
|
|
151
|
+
acceptedContextTransfer: accepted,
|
|
152
|
+
contextTransferReceipt: deepFreeze(ContextTransferReceiptSchema.parse(transfer)),
|
|
153
|
+
});
|
|
154
|
+
}
|
|
114
155
|
const ownedRoute = optionalCliBridgeEnvironmentRoute(id);
|
|
115
156
|
const transfer = ownedRoute === undefined
|
|
116
|
-
? await lookupCliBridgeContextByEnvironment(options, id,
|
|
157
|
+
? await lookupCliBridgeContextByEnvironment(options, id, operation.signal)
|
|
117
158
|
: undefined;
|
|
118
159
|
const backend = ownedRoute?.backend ?? transfer?.destination.runner;
|
|
119
160
|
const destinationModel = transfer?.destination.model;
|
|
@@ -204,6 +245,7 @@ export function defaultCliBridgeCapabilities(harness) {
|
|
|
204
245
|
freshSession: true,
|
|
205
246
|
requestIdempotency: true,
|
|
206
247
|
lookup: true,
|
|
248
|
+
attach: true,
|
|
207
249
|
},
|
|
208
250
|
...(harness === "pi"
|
|
209
251
|
? {
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import type { AgentEnvironment, AgentEnvironmentCapabilities, AgentEnvironmentCreation, CreateAgentEnvironmentInput } from "@tangle-network/agent-interface/environment-provider";
|
|
2
|
+
import type { ContextTransferRequest, ContextTransferReceipt } from "@tangle-network/agent-interface";
|
|
2
3
|
import type { CliBridgeProviderOptions } from "./provider-options.js";
|
|
3
4
|
export interface CreateCliBridgeEnvironmentArgs {
|
|
5
|
+
readonly acceptedContextTransfer?: ContextTransferRequest;
|
|
6
|
+
readonly contextTransferReceipt?: ContextTransferReceipt;
|
|
4
7
|
readonly options: CliBridgeProviderOptions;
|
|
5
8
|
readonly providerName: string;
|
|
6
9
|
readonly environmentInput: CreateAgentEnvironmentInput;
|
|
@@ -41,11 +41,11 @@ export function createCliBridgeEnvironment(args) {
|
|
|
41
41
|
throw new Error("cli-bridge environment is destroyed");
|
|
42
42
|
assertCliBridgeTurnAllowed(args.allowDispatch, "environment.stream()");
|
|
43
43
|
if (args.selectedModel !== undefined &&
|
|
44
|
-
args.capabilities.retainedControl !== undefined) {
|
|
44
|
+
(args.capabilities.retainedControl !== undefined || args.acceptedContextTransfer !== undefined)) {
|
|
45
45
|
assertCliBridgeTurnModel(options, environmentInput, turn, args.selectedModel);
|
|
46
46
|
}
|
|
47
47
|
assertCliBridgeRequestedInteractions(args.capabilities, turn.interactions);
|
|
48
|
-
const prepared = prepareCliBridgeRun(options, environmentInput, turn, providerName, environmentId, useNativeInteractions);
|
|
48
|
+
const prepared = prepareCliBridgeRun(options, environmentInput, turn, providerName, environmentId, useNativeInteractions, args.acceptedContextTransfer);
|
|
49
49
|
// A streamed run reports usage across its events, so the totals are summed
|
|
50
50
|
// here and recorded as one execution's measurement.
|
|
51
51
|
let streamedUsage;
|
|
@@ -60,6 +60,7 @@ export function createCliBridgeEnvironment(args) {
|
|
|
60
60
|
provider: providerName,
|
|
61
61
|
...(args.creation === undefined ? {} : { creation: args.creation }),
|
|
62
62
|
capabilities: args.capabilities,
|
|
63
|
+
...(args.contextTransferReceipt === undefined ? {} : { contextTransferReceipt: args.contextTransferReceipt }),
|
|
63
64
|
...(environmentInput.name ? { name: environmentInput.name } : {}),
|
|
64
65
|
status: async (statusOptions) => {
|
|
65
66
|
statusOptions?.signal?.throwIfAborted();
|
|
@@ -71,11 +72,11 @@ export function createCliBridgeEnvironment(args) {
|
|
|
71
72
|
throw new Error("cli-bridge environment is destroyed");
|
|
72
73
|
assertCliBridgeTurnAllowed(args.allowDispatch, "environment.dispatch()");
|
|
73
74
|
if (args.selectedModel !== undefined &&
|
|
74
|
-
args.capabilities.retainedControl !== undefined) {
|
|
75
|
+
(args.capabilities.retainedControl !== undefined || args.acceptedContextTransfer !== undefined)) {
|
|
75
76
|
assertCliBridgeTurnModel(options, environmentInput, turn, args.selectedModel);
|
|
76
77
|
}
|
|
77
78
|
assertCliBridgeRequestedInteractions(args.capabilities, turn.interactions);
|
|
78
|
-
const prepared = prepareCliBridgeRun(options, environmentInput, turn, providerName, environmentId, useNativeInteractions);
|
|
79
|
+
const prepared = prepareCliBridgeRun(options, environmentInput, turn, providerName, environmentId, useNativeInteractions, args.acceptedContextTransfer);
|
|
79
80
|
return dispatchCliBridgeTurn(options, environmentInput, prepared, transport, providerName, runs, sessions, nativeSessions, useNativeInteractions);
|
|
80
81
|
},
|
|
81
82
|
session(id, sessionOptions) {
|
|
@@ -99,6 +100,7 @@ export function createCliBridgeEnvironment(args) {
|
|
|
99
100
|
interactionsEnabled: respondToInteraction !== undefined,
|
|
100
101
|
useNativeInteractions,
|
|
101
102
|
selectedModel: args.selectedModel,
|
|
103
|
+
acceptedContextTransfer: args.acceptedContextTransfer,
|
|
102
104
|
});
|
|
103
105
|
},
|
|
104
106
|
...(respondToInteraction ? { respondToInteraction } : {}),
|
|
@@ -243,14 +245,14 @@ function createCliBridgeSession(args) {
|
|
|
243
245
|
throw new Error(`cli-bridge session "${args.id}" cannot prompt session "${input.sessionId}"`);
|
|
244
246
|
}
|
|
245
247
|
if (args.selectedModel !== undefined &&
|
|
246
|
-
args.capabilities.retainedControl !== undefined) {
|
|
248
|
+
(args.capabilities.retainedControl !== undefined || args.acceptedContextTransfer !== undefined)) {
|
|
247
249
|
assertCliBridgeTurnModel(args.options, args.environmentInput, input, args.selectedModel);
|
|
248
250
|
}
|
|
249
251
|
assertCliBridgeRequestedInteractions(args.capabilities, input.interactions);
|
|
250
252
|
const prepared = prepareCliBridgeRun(args.options, args.environmentInput, {
|
|
251
253
|
...input,
|
|
252
254
|
sessionId: args.id,
|
|
253
|
-
}, args.providerName, args.environmentId, args.useNativeInteractions);
|
|
255
|
+
}, args.providerName, args.environmentId, args.useNativeInteractions, args.acceptedContextTransfer);
|
|
254
256
|
const result = await collectCliBridgeTurnResult(streamTrackedCliBridgeTurn(args.options, args.environmentInput, args.providerName, prepared, args.transport, args.runs, args.sessions, args.readers, args.nativeSessions, args.useNativeInteractions), prepared.run, args.options, args.transport, input.signal);
|
|
255
257
|
args.usageLog.record(prepared.run.executionId, result.usage);
|
|
256
258
|
return { ...result, sessionId: args.id };
|
|
@@ -33,6 +33,7 @@ export async function* streamTrackedCliBridgeTurn(options, environmentInput, pro
|
|
|
33
33
|
let admitted = false;
|
|
34
34
|
let admissionValidated = false;
|
|
35
35
|
try {
|
|
36
|
+
await confirmCliBridgeContextTransfer(options, originalTurn, run, signal);
|
|
36
37
|
if (useNativeInteractions) {
|
|
37
38
|
await beginCliBridgeNativeTurn(options, providerName, environmentInput, turn, run, transport, nativeSessions, signal, () => {
|
|
38
39
|
admitted = true;
|
|
@@ -51,7 +52,6 @@ export async function* streamTrackedCliBridgeTurn(options, environmentInput, pro
|
|
|
51
52
|
yield event;
|
|
52
53
|
}
|
|
53
54
|
}
|
|
54
|
-
await confirmCliBridgeContextTransfer(options, originalTurn, run, signal);
|
|
55
55
|
drained = true;
|
|
56
56
|
if (runs.get(run.id) === run)
|
|
57
57
|
runs.delete(run.id);
|
|
@@ -112,6 +112,7 @@ export async function dispatchCliBridgeTurn(options, environmentInput, prepared,
|
|
|
112
112
|
let accepted = false;
|
|
113
113
|
let responseBody;
|
|
114
114
|
try {
|
|
115
|
+
await confirmCliBridgeContextTransfer(options, prepared.turn, run, signal);
|
|
115
116
|
if (useNativeInteractions) {
|
|
116
117
|
await beginCliBridgeNativeTurn(options, providerName, environmentInput, prepared.turn, run, transport, nativeSessions, signal, () => {
|
|
117
118
|
accepted = true;
|
|
@@ -146,7 +147,6 @@ export async function dispatchCliBridgeTurn(options, environmentInput, prepared,
|
|
|
146
147
|
}
|
|
147
148
|
const controlRef = exactControlRefForRun(run, providerName);
|
|
148
149
|
run.controlRef = controlRef;
|
|
149
|
-
await confirmCliBridgeContextTransfer(options, prepared.turn, run, signal);
|
|
150
150
|
if (responseBody) {
|
|
151
151
|
await detachCliBridgeReader(responseBody);
|
|
152
152
|
responseBody = undefined;
|
|
@@ -202,7 +202,11 @@ async function confirmCliBridgeContextTransfer(options, turn, run, signal) {
|
|
|
202
202
|
const transfer = await lookupCliBridgeContext(options, turn.contextTransfer, signal);
|
|
203
203
|
if (transfer === undefined ||
|
|
204
204
|
(transfer.status !== "accepted" && transfer.status !== "replayed")) {
|
|
205
|
-
throw new
|
|
205
|
+
throw new CliBridgeRequestRejectedError(409, "cli-bridge did not confirm admitted portable context");
|
|
206
|
+
}
|
|
207
|
+
if (transfer.environmentId !== run.environmentId || transfer.sessionId !== run.sessionId ||
|
|
208
|
+
transfer.runId !== run.id || transfer.executionId !== run.executionId) {
|
|
209
|
+
throw new CliBridgeRequestRejectedError(409, "cli-bridge portable context belongs to another environment or run");
|
|
206
210
|
}
|
|
207
211
|
run.contextTransferReceipt = transfer;
|
|
208
212
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type AgentExactRunControlRef, type AgentRunControlRef, type Sha256Digest } from "@tangle-network/agent-interface";
|
|
1
|
+
import { type ContextTransferRequest, type AgentExactRunControlRef, type AgentRunControlRef, type Sha256Digest } from "@tangle-network/agent-interface";
|
|
2
2
|
import type { AgentTurnInput, CreateAgentEnvironmentInput } from "@tangle-network/agent-interface/environment-provider";
|
|
3
3
|
import type { ContextTransferReceipt } from "@tangle-network/agent-interface";
|
|
4
4
|
import type { CliBridgeProviderOptions } from "./provider-options.js";
|
|
@@ -37,7 +37,7 @@ export declare function runFromControlRef(controlRef: AgentExactRunControlRef):
|
|
|
37
37
|
export declare function assertRunMatchesControlRef(run: CliBridgeRun, controlRef: AgentExactRunControlRef): void;
|
|
38
38
|
/** Advance one session object to the exact run returned by native continuation. */
|
|
39
39
|
export declare function advanceCliBridgeRun(run: CliBridgeRun, controlRef: AgentExactRunControlRef, providerName: string, runs: Map<string, CliBridgeRun>): void;
|
|
40
|
-
export declare function prepareCliBridgeRun(options: CliBridgeProviderOptions, environmentInput: CreateAgentEnvironmentInput, originalTurn: AgentTurnInput, providerName: string, environmentId: string, requireStableIdentity?: boolean): PreparedCliBridgeRun;
|
|
40
|
+
export declare function prepareCliBridgeRun(options: CliBridgeProviderOptions, environmentInput: CreateAgentEnvironmentInput, originalTurn: AgentTurnInput, providerName: string, environmentId: string, requireStableIdentity?: boolean, acceptedContextTransfer?: ContextTransferRequest): PreparedCliBridgeRun;
|
|
41
41
|
export declare function bindCliBridgeRun(prepared: CliBridgeRun, runs: Map<string, CliBridgeRun>): CliBridgeRun | undefined;
|
|
42
42
|
export declare function restoreCliBridgeRun(run: CliBridgeRun, previous: CliBridgeRun | undefined, runs: Map<string, CliBridgeRun>): void;
|
|
43
43
|
export declare function bindCliBridgeSession(run: CliBridgeRun, sessions: Map<string, CliBridgeSessionState>): CliBridgeRun | undefined;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AgentExactRunControlRefSchema, AgentTurnInputSchema, } from "@tangle-network/agent-interface";
|
|
1
|
+
import { AgentExactRunControlRefSchema, AgentTurnInputSchema, canonicalAgentProfileDigest, } from "@tangle-network/agent-interface";
|
|
2
2
|
import { assertCliBridgeRunId, cliBridgeRunId, toChatCompletionsBody, } from "./wire.js";
|
|
3
3
|
export function exactControlRefForRun(run, providerName) {
|
|
4
4
|
if (!run.sessionId || !run.requestDigest) {
|
|
@@ -70,8 +70,12 @@ export function advanceCliBridgeRun(run, controlRef, providerName, runs) {
|
|
|
70
70
|
run.controlRef = Object.freeze(AgentExactRunControlRefSchema.parse(controlRef));
|
|
71
71
|
runs.set(run.id, run);
|
|
72
72
|
}
|
|
73
|
-
export function prepareCliBridgeRun(options, environmentInput, originalTurn, providerName, environmentId, requireStableIdentity = false) {
|
|
73
|
+
export function prepareCliBridgeRun(options, environmentInput, originalTurn, providerName, environmentId, requireStableIdentity = false, acceptedContextTransfer) {
|
|
74
74
|
const validatedTurn = AgentTurnInputSchema.parse(originalTurn);
|
|
75
|
+
if (acceptedContextTransfer !== undefined && (validatedTurn.contextTransfer?.requestDigest !== acceptedContextTransfer.requestDigest ||
|
|
76
|
+
(validatedTurn.profile !== undefined && canonicalAgentProfileDigest(validatedTurn.profile) !== acceptedContextTransfer.plan.destination.profileDigest))) {
|
|
77
|
+
throw new Error("CLI Bridge turn conflicts with its accepted context transfer");
|
|
78
|
+
}
|
|
75
79
|
if (requireStableIdentity &&
|
|
76
80
|
(validatedTurn.turnId === undefined || validatedTurn.executionId === undefined)) {
|
|
77
81
|
throw new Error("native cli-bridge turns require stable turnId and executionId");
|
|
@@ -83,7 +87,7 @@ export function prepareCliBridgeRun(options, environmentInput, originalTurn, pro
|
|
|
83
87
|
const executionId = validatedTurn.executionId ?? destination?.executionId ?? runId;
|
|
84
88
|
if (destination !== undefined &&
|
|
85
89
|
(destination.provider !== providerName ||
|
|
86
|
-
destination.environmentId !== environmentId ||
|
|
90
|
+
(destination.environmentId !== undefined && destination.environmentId !== environmentId) ||
|
|
87
91
|
destination.sessionId !== sessionId ||
|
|
88
92
|
destination.executionId !== executionId)) {
|
|
89
93
|
throw new Error("cli-bridge context transfer targets another destination");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tangle-network/agent-provider-cli-bridge",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "AgentEnvironmentProvider adapter for cli-bridge retained sessions and one-shot turns",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -64,10 +64,11 @@
|
|
|
64
64
|
"LICENSE"
|
|
65
65
|
],
|
|
66
66
|
"dependencies": {
|
|
67
|
-
"@tangle-network/agent-interface": "^
|
|
67
|
+
"@tangle-network/agent-interface": "^5.0.0",
|
|
68
68
|
"undici": "8.11.2"
|
|
69
69
|
},
|
|
70
70
|
"devDependencies": {
|
|
71
|
+
"@tangle-network/agent-provider-testkit": "0.12.0",
|
|
71
72
|
"@types/node": "26.6.3",
|
|
72
73
|
"typescript": "7.0.2",
|
|
73
74
|
"vitest": "5.0.2"
|