@pasko70/pibo 1.16.6 → 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/dist/agent-runtime/auth.js +28 -0
- package/dist/agent-runtime/capabilities.js +221 -0
- package/dist/agent-runtime/context-build.js +313 -0
- package/dist/agent-runtime/contract.js +45 -0
- package/dist/agent-runtime/errors.js +57 -0
- package/dist/agent-runtime/events.js +1 -0
- package/dist/agent-runtime/history.js +1 -0
- package/dist/agent-runtime/profile-validation.js +109 -0
- package/dist/agent-runtime/registry.js +608 -0
- package/dist/agent-runtime/resource-files.js +87 -0
- package/dist/agent-runtime/resource-service.js +635 -0
- package/dist/agent-runtime/resources.js +1 -0
- package/dist/agent-runtime/routed-session.js +931 -0
- package/dist/agent-runtime/testing/contract.js +51 -0
- package/dist/agent-runtime/testing/fake-adapter.js +192 -0
- package/dist/agent-runtime/types.js +3 -0
- package/dist/agent-runtimes/codex-native/adapter.js +905 -0
- package/dist/agent-runtimes/codex-native/auth.js +476 -0
- package/dist/agent-runtimes/codex-native/client.js +734 -0
- package/dist/agent-runtimes/codex-native/config.js +152 -0
- package/dist/agent-runtimes/codex-native/history.js +283 -0
- package/dist/agent-runtimes/codex-native/mcp-stdio-launcher.js +89 -0
- package/dist/agent-runtimes/codex-native/models.js +581 -0
- package/dist/agent-runtimes/codex-native/process.js +459 -0
- package/dist/agent-runtimes/codex-native/protocol-types.js +1 -0
- package/dist/agent-runtimes/codex-native/protocol-version.js +7 -0
- package/dist/agent-runtimes/codex-native/redaction.js +31 -0
- package/dist/agent-runtimes/codex-native/requests.js +378 -0
- package/dist/agent-runtimes/codex-native/resource-delivery.js +445 -0
- package/dist/agent-runtimes/codex-native/thread.js +388 -0
- package/dist/agent-runtimes/codex-native/turn.js +849 -0
- package/dist/agent-runtimes/pi/adapter.js +653 -0
- package/dist/agent-runtimes/pi/auth.js +455 -0
- package/dist/agent-runtimes/pi/history.js +640 -0
- package/dist/agent-runtimes/pi/model-catalog.js +87 -0
- package/dist/agent-runtimes/pi/routed-session.js +1464 -0
- package/dist/agent-runtimes/pi/runtime.js +534 -0
- package/dist/agent-runtimes/pi/tool-compiler.js +69 -0
- package/dist/apps/chat/agent-profiles.js +40 -23
- package/dist/apps/chat/agent-store.js +111 -64
- package/dist/apps/chat/chat-api-routes.js +1 -1
- package/dist/apps/chat/chat-request-normalizers.js +47 -0
- package/dist/apps/chat/data/chat-data-mappers.js +25 -9
- package/dist/apps/chat/data/history-query-service.js +108 -0
- package/dist/apps/chat/data/session-query-service.js +24 -3
- package/dist/apps/chat/data/timeline-query-service.js +3 -3
- package/dist/apps/chat/model-catalog.js +1 -55
- package/dist/apps/chat/provider-auth-actions.js +171 -23
- package/dist/apps/chat/stream.js +12 -0
- package/dist/apps/chat/trace-v2.js +1 -0
- package/dist/apps/chat/trace.js +126 -415
- package/dist/apps/chat/web-app.js +582 -157
- package/dist/apps/chat-ui/assets/{dist-BTLtT_Vf.js → dist-9v2ZXT6V.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-CMk1aPug.js → dist-B1LVAytl.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-CcwA_IWN.js → dist-C6LPDFXU.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-DKOthbxr.js → dist-DVtXxfHc.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-ls2I6BIw.js → dist-DW4Qrfbd.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-D1rAtRWs.js → dist-DmbsHdMC.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-C1JQRskW.js → dist-DyvwuSFO.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-DfpaylQ-.js → dist-I26VB0QO.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-D10bTFD5.js → dist-RtHbJRPV.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-5KpmmBBZ.js → dist-sZgJkWZb.js} +1 -1
- package/dist/apps/chat-ui/assets/index-BPbNvcZe.css +1 -0
- package/dist/apps/chat-ui/assets/index-CIOf2uL2.js +237 -0
- package/dist/apps/chat-ui/index.html +2 -2
- package/dist/apps/chat-vscode-web/assets/index-1ivRyjFs.js +41 -0
- package/dist/apps/chat-vscode-web/index.html +1 -1
- package/dist/apps/vscode-artifacts/latest.vsix +0 -0
- package/dist/apps/vscode-artifacts/pibo-vscode-ext-2.0.0.vsix +0 -0
- package/dist/auth/login-actions.js +5 -251
- package/dist/cli-session/localSessionSource.js +8 -1
- package/dist/core/context-build.js +124 -20
- package/dist/core/default-profile.js +8 -0
- package/dist/core/profiles.js +30 -3
- package/dist/core/routed-session.js +5 -1446
- package/dist/core/runtime.js +5 -561
- package/dist/core/session-router.js +637 -83
- package/dist/data/cli.js +20 -3
- package/dist/data/schema.js +104 -1
- package/dist/data/session-store.js +24 -1
- package/dist/debug/events.js +25 -10
- package/dist/debug/failures.js +23 -3
- package/dist/debug/index.js +24 -6
- package/dist/debug/messages.js +87 -7
- package/dist/debug/persisted-payloads.js +31 -0
- package/dist/debug/pty.js +7 -6
- package/dist/debug/runtime-binding.js +29 -0
- package/dist/debug/session.js +137 -0
- package/dist/debug/summary.js +12 -0
- package/dist/debug/telemetry.js +28 -0
- package/dist/debug/tools.js +12 -2
- package/dist/debug/trace.js +154 -76
- package/dist/gateway/server.js +87 -2
- package/dist/gateway/tool.js +5 -5
- package/dist/index.js +21 -2
- package/dist/loops/tools.js +13 -12
- package/dist/mcp/agent-context.js +13 -4
- package/dist/mcp/client.js +10 -6
- package/dist/mcp/config.js +5 -2
- package/dist/mcp/runtime-session.js +166 -0
- package/dist/plugins/builtin.js +191 -53
- package/dist/plugins/codex-native.js +29 -0
- package/dist/plugins/registry.js +66 -2
- package/dist/runs/tools.js +26 -25
- package/dist/session-ui/terminalRows.js +2 -2
- package/dist/sessions/pibo-data-store.js +125 -16
- package/dist/sessions/runtime-binding.js +107 -0
- package/dist/sessions/sqlite-store.js +239 -18
- package/dist/sessions/store.js +86 -7
- package/dist/shared/trace-engine.js +18 -9
- package/dist/shared/trace-event-projection.js +29 -11
- package/dist/shared/{trace-transcript.js → trace-history.js} +193 -195
- package/dist/shared/trace-order.js +9 -4
- package/dist/shared/trace-page-merge.js +1 -1
- package/dist/signals/projector.js +20 -2
- package/dist/signals/registry.js +11 -0
- package/dist/subagents/tool.js +8 -6
- package/dist/tools/codex-browser.js +20 -19
- package/dist/tools/codex-compat.js +10 -9
- package/dist/tools/codex-image-generation.js +8 -6
- package/dist/tools/contract.js +45 -0
- package/dist/tools/credential-registry.js +182 -0
- package/dist/tools/mcp-bridge.js +511 -0
- package/dist/tools/payload-writer.js +17 -0
- package/dist/tools/runtime/tool.js +10 -9
- package/dist/tools/schema.js +9 -0
- package/dist/tools/session-service.js +193 -0
- package/dist/tools/session-tool-set.js +85 -0
- package/dist/web-annotations/tools.js +17 -16
- package/docs/README.md +11 -0
- package/package.json +3 -2
- package/skills/builtin/pibo-agent-runtime-adapter/SKILL.md +183 -0
- package/skills/builtin/pibo-agent-runtime-adapter/evals/README.md +10 -0
- package/skills/builtin/pibo-agent-runtime-adapter/evals/evals.json +45 -0
- package/skills/builtin/pibo-agent-runtime-adapter/evals/fixtures/orion-full-harness.md +60 -0
- package/skills/builtin/pibo-agent-runtime-adapter/evals/fixtures/relay-partial-harness.md +52 -0
- package/skills/builtin/pibo-agent-runtime-adapter/references/capabilities-and-designer.md +194 -0
- package/skills/builtin/pibo-agent-runtime-adapter/references/history-debug-and-security.md +213 -0
- package/skills/builtin/pibo-agent-runtime-adapter/references/interfaces-and-registration.md +214 -0
- package/skills/builtin/pibo-agent-runtime-adapter/references/lifecycle-bindings-and-events.md +193 -0
- package/skills/builtin/pibo-agent-runtime-adapter/references/portable-delivery-and-native-behavior.md +226 -0
- package/skills/builtin/pibo-agent-runtime-adapter/references/testing-migration-and-validation.md +256 -0
- package/dist/apps/chat-ui/assets/index-C2YI0xfw.js +0 -237
- package/dist/apps/chat-ui/assets/index-E0RmuCkY.css +0 -1
- package/dist/apps/chat-vscode-web/assets/index-D-tSsXLG.js +0 -41
package/dist/plugins/registry.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { normalizeToolProfile } from "../core/profiles.js";
|
|
2
3
|
import { listInstalledCliToolAgentContexts } from "../tools/registry.js";
|
|
3
4
|
import { listPiPackages } from "../pi-packages/store.js";
|
|
5
|
+
import { AgentRuntimeAdapterRegistry } from "../agent-runtime/registry.js";
|
|
4
6
|
function getWebAppRoutes(app) {
|
|
5
7
|
return [
|
|
6
8
|
{ label: "mountPath", prefix: app.mountPath },
|
|
@@ -18,7 +20,20 @@ function validateWebRoute(appName, label, prefix) {
|
|
|
18
20
|
function webRoutesOverlap(left, right) {
|
|
19
21
|
return left === right || left === "/" || right === "/" || left.startsWith(`${right}/`) || right.startsWith(`${left}/`);
|
|
20
22
|
}
|
|
23
|
+
function toolIsPortable(tool) {
|
|
24
|
+
if (tool.definition)
|
|
25
|
+
return tool.definition.portable !== false;
|
|
26
|
+
if (!tool.createDefinition)
|
|
27
|
+
return true;
|
|
28
|
+
try {
|
|
29
|
+
return tool.createDefinition({}).portable !== false;
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
21
35
|
export class PiboPluginRegistry {
|
|
36
|
+
agentRuntimes = new AgentRuntimeAdapterRegistry();
|
|
22
37
|
tools = new Map();
|
|
23
38
|
subagents = new Map();
|
|
24
39
|
skills = new Map();
|
|
@@ -52,8 +67,51 @@ export class PiboPluginRegistry {
|
|
|
52
67
|
this.pluginNames.set(plugin.id, plugin.name ?? plugin.id);
|
|
53
68
|
plugin.register(this.createApi(plugin.id));
|
|
54
69
|
}
|
|
70
|
+
registerAgentRuntimeDriver(driver) {
|
|
71
|
+
this.agentRuntimes.registerDriver(driver);
|
|
72
|
+
}
|
|
73
|
+
registerAgentRuntimeInstance(instance) {
|
|
74
|
+
return this.agentRuntimes.registerInstance(instance);
|
|
75
|
+
}
|
|
76
|
+
getAgentRuntimeAdapter(instanceId) {
|
|
77
|
+
return this.agentRuntimes.getInstance(instanceId);
|
|
78
|
+
}
|
|
79
|
+
requireAgentRuntimeAdapter(instanceId) {
|
|
80
|
+
return this.agentRuntimes.requireInstance(instanceId);
|
|
81
|
+
}
|
|
82
|
+
openAgentRuntimeSession(instanceId, input) {
|
|
83
|
+
return this.agentRuntimes.openSession(instanceId, input);
|
|
84
|
+
}
|
|
85
|
+
getAgentRuntimeInstanceIds() {
|
|
86
|
+
return this.agentRuntimes.getInstanceIds();
|
|
87
|
+
}
|
|
88
|
+
inspectAgentRuntimeInstances() {
|
|
89
|
+
return this.agentRuntimes.inspectInstances();
|
|
90
|
+
}
|
|
91
|
+
getAgentRuntimeAuthStatus(runtimeInstanceId) {
|
|
92
|
+
return this.agentRuntimes.getAuthStatus(runtimeInstanceId);
|
|
93
|
+
}
|
|
94
|
+
startAgentRuntimeAuth(runtimeInstanceId, input) {
|
|
95
|
+
return this.agentRuntimes.startAuth(runtimeInstanceId, input);
|
|
96
|
+
}
|
|
97
|
+
completeAgentRuntimeAuth(runtimeInstanceId, input) {
|
|
98
|
+
return this.agentRuntimes.completeAuth(runtimeInstanceId, input);
|
|
99
|
+
}
|
|
100
|
+
cancelAgentRuntimeAuth(runtimeInstanceId, input) {
|
|
101
|
+
return this.agentRuntimes.cancelAuth(runtimeInstanceId, input);
|
|
102
|
+
}
|
|
103
|
+
logoutAgentRuntimeAuth(runtimeInstanceId, input) {
|
|
104
|
+
return this.agentRuntimes.logoutAuth(runtimeInstanceId, input);
|
|
105
|
+
}
|
|
106
|
+
disposeAgentRuntimeAuth() {
|
|
107
|
+
return this.agentRuntimes.disposeAuth();
|
|
108
|
+
}
|
|
109
|
+
validateAgentRuntimeProfile(profile, workspace) {
|
|
110
|
+
return this.agentRuntimes.validateProfile({ profile, workspace });
|
|
111
|
+
}
|
|
55
112
|
registerTool(tool) {
|
|
56
|
-
|
|
113
|
+
const normalized = normalizeToolProfile(tool);
|
|
114
|
+
this.addUnique(this.tools, normalized.name, normalized, "tool");
|
|
57
115
|
}
|
|
58
116
|
registerTools(tools) {
|
|
59
117
|
for (const tool of tools) {
|
|
@@ -187,6 +245,8 @@ export class PiboPluginRegistry {
|
|
|
187
245
|
name: profile.name,
|
|
188
246
|
description: profile.description,
|
|
189
247
|
aliases: [...(profile.aliases ?? [])],
|
|
248
|
+
runtimeInstanceId: sessionContext.runtimeInstanceId,
|
|
249
|
+
runtimeOptions: structuredClone(sessionContext.runtimeOptions),
|
|
190
250
|
nativeTools: sessionContext.tools.filter((tool) => tool.enabled !== false).map((tool) => tool.name),
|
|
191
251
|
skills: sessionContext.skills.filter((skill) => skill.enabled !== false).map((skill) => skill.name),
|
|
192
252
|
contextFiles: sessionContext.contextFiles.filter((contextFile) => contextFile.enabled !== false).map(contextFileKey),
|
|
@@ -212,11 +272,13 @@ export class PiboPluginRegistry {
|
|
|
212
272
|
}
|
|
213
273
|
getCapabilityCatalog() {
|
|
214
274
|
return {
|
|
275
|
+
agentRuntimes: this.agentRuntimes.getInstanceInfos(),
|
|
215
276
|
nativeTools: [...this.tools.values()].map((tool) => ({
|
|
216
277
|
name: tool.name,
|
|
217
278
|
description: tool.description,
|
|
218
279
|
yieldable: tool.yieldable !== false,
|
|
219
280
|
hasDefinition: tool.definition !== undefined || tool.createDefinition !== undefined,
|
|
281
|
+
portable: toolIsPortable(tool),
|
|
220
282
|
pluginId: tool.pluginId,
|
|
221
283
|
pluginName: tool.pluginId ? this.pluginNames.get(tool.pluginId) : undefined,
|
|
222
284
|
...(tool.providerTool ? { providerTool: tool.providerTool } : {}),
|
|
@@ -248,7 +310,7 @@ export class PiboPluginRegistry {
|
|
|
248
310
|
packages: [
|
|
249
311
|
{
|
|
250
312
|
name: "pibo-run-control",
|
|
251
|
-
description: "Expose pibo_run_*
|
|
313
|
+
description: "Expose pibo_run_* for Pibo-managed tools and subagents; private harness-native tools require explicit runtime capability.",
|
|
252
314
|
toolNames: [
|
|
253
315
|
"pibo_run_start",
|
|
254
316
|
"pibo_run_list",
|
|
@@ -350,6 +412,8 @@ export class PiboPluginRegistry {
|
|
|
350
412
|
pluginId: pkg.pluginId ?? pluginId,
|
|
351
413
|
});
|
|
352
414
|
return {
|
|
415
|
+
registerAgentRuntimeDriver: (driver) => this.registerAgentRuntimeDriver(driver),
|
|
416
|
+
registerAgentRuntimeInstance: (instance) => this.registerAgentRuntimeInstance(instance),
|
|
353
417
|
registerTool: (tool) => this.registerTool(withPluginToolContext(tool)),
|
|
354
418
|
registerTools: (tools) => this.registerTools(tools.map(withPluginToolContext)),
|
|
355
419
|
registerSubagent: (subagent) => this.registerSubagent(subagent),
|
package/dist/runs/tools.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { Type } from "typebox";
|
|
2
|
+
import { piboStringEnum } from "../tools/schema.js";
|
|
3
|
+
import { definePiboTool } from "../tools/contract.js";
|
|
3
4
|
import { foregroundServiceWarning, hasMeaningfulTimeoutOutput, isConfiguredTimeoutError, PiboRunExecutionTimeoutError, resolveRunTimeoutMs } from "./lifecycle.js";
|
|
4
5
|
import { PiboRunResourceLimitError, prepareYieldedRunExecution } from "./resource-isolation.js";
|
|
5
6
|
function resultText(prefix, value) {
|
|
@@ -29,16 +30,16 @@ function requireTool(tools, name) {
|
|
|
29
30
|
export function createRunToolDefinitions(yieldableTools, controller) {
|
|
30
31
|
const toolNames = yieldableTools.map((tool) => tool.name);
|
|
31
32
|
return [
|
|
32
|
-
|
|
33
|
+
definePiboTool({
|
|
33
34
|
name: "pibo_run_start",
|
|
34
|
-
|
|
35
|
+
title: "Pibo Run Start",
|
|
35
36
|
description: "Start a yieldable tool as a yielded run. The run records its configured timeout and classifies lifetime expiry separately from command failure. Use detached only for intentional fire-and-forget work.",
|
|
36
37
|
promptSnippet: "Use pibo_run_start to run a yieldable tool in the background. It returns a runId. Use pibo_run_read for completed results and pibo_run_wait/status/list/cancel/ack to manage runs.",
|
|
37
38
|
executionMode: "parallel",
|
|
38
|
-
|
|
39
|
-
toolName:
|
|
39
|
+
inputSchema: Type.Object({
|
|
40
|
+
toolName: piboStringEnum(toolNames, { description: "Yieldable tool name to start" }),
|
|
40
41
|
arguments: Type.Any({ description: "Arguments object for the selected tool" }),
|
|
41
|
-
completionPolicy: Type.Optional(
|
|
42
|
+
completionPolicy: Type.Optional(piboStringEnum(["tracked", "detached"], {
|
|
42
43
|
description: "tracked reminds this agent about completion; detached is fire-and-forget and creates no automatic reminders.",
|
|
43
44
|
default: "tracked",
|
|
44
45
|
})),
|
|
@@ -87,13 +88,13 @@ export function createRunToolDefinitions(yieldableTools, controller) {
|
|
|
87
88
|
};
|
|
88
89
|
},
|
|
89
90
|
}),
|
|
90
|
-
|
|
91
|
+
definePiboTool({
|
|
91
92
|
name: "pibo_run_list",
|
|
92
|
-
|
|
93
|
+
title: "Pibo Run List",
|
|
93
94
|
description: "List yielded runs owned by this agent session.",
|
|
94
95
|
promptSnippet: "Use pibo_run_list to inspect yielded runs owned by this session.",
|
|
95
96
|
executionMode: "parallel",
|
|
96
|
-
|
|
97
|
+
inputSchema: Type.Object({
|
|
97
98
|
includeConsumed: Type.Optional(Type.Boolean({ description: "Include already read, cancelled, or acknowledged runs" })),
|
|
98
99
|
includeDetached: Type.Optional(Type.Boolean({ description: "Include fire-and-forget detached runs" })),
|
|
99
100
|
}),
|
|
@@ -108,13 +109,13 @@ export function createRunToolDefinitions(yieldableTools, controller) {
|
|
|
108
109
|
};
|
|
109
110
|
},
|
|
110
111
|
}),
|
|
111
|
-
|
|
112
|
+
definePiboTool({
|
|
112
113
|
name: "pibo_run_status",
|
|
113
|
-
|
|
114
|
+
title: "Pibo Run Status",
|
|
114
115
|
description: "Read compact status for one yielded run.",
|
|
115
116
|
promptSnippet: "Use pibo_run_status to inspect one yielded run without reading its full result.",
|
|
116
117
|
executionMode: "parallel",
|
|
117
|
-
|
|
118
|
+
inputSchema: Type.Object({
|
|
118
119
|
runId: Type.String({ description: "Run id returned by pibo_run_start" }),
|
|
119
120
|
}),
|
|
120
121
|
async execute(_toolCallId, params) {
|
|
@@ -125,13 +126,13 @@ export function createRunToolDefinitions(yieldableTools, controller) {
|
|
|
125
126
|
};
|
|
126
127
|
},
|
|
127
128
|
}),
|
|
128
|
-
|
|
129
|
+
definePiboTool({
|
|
129
130
|
name: "pibo_run_wait",
|
|
130
|
-
|
|
131
|
+
title: "Pibo Run Wait",
|
|
131
132
|
description: "Wait a bounded time for a yielded run. Timeout is normal and does not mean failure.",
|
|
132
133
|
promptSnippet: "Use pibo_run_wait when blocked on a run. Timeout is normal; call again or continue other work.",
|
|
133
134
|
executionMode: "parallel",
|
|
134
|
-
|
|
135
|
+
inputSchema: Type.Object({
|
|
135
136
|
runId: Type.String({ description: "Run id returned by pibo_run_start" }),
|
|
136
137
|
timeoutMs: Type.Optional(Type.Number({ description: "Maximum wait time in milliseconds, clamped to 300000" })),
|
|
137
138
|
}),
|
|
@@ -150,13 +151,13 @@ export function createRunToolDefinitions(yieldableTools, controller) {
|
|
|
150
151
|
};
|
|
151
152
|
},
|
|
152
153
|
}),
|
|
153
|
-
|
|
154
|
+
definePiboTool({
|
|
154
155
|
name: "pibo_run_read",
|
|
155
|
-
|
|
156
|
+
title: "Pibo Run Read",
|
|
156
157
|
description: "Read the terminal result, timeout reason, or error for a yielded run.",
|
|
157
158
|
promptSnippet: "Use pibo_run_read to retrieve a completed, failed, or timed_out run result. Reading terminal tracked runs consumes reminders.",
|
|
158
159
|
executionMode: "parallel",
|
|
159
|
-
|
|
160
|
+
inputSchema: Type.Object({
|
|
160
161
|
runId: Type.String({ description: "Run id returned by pibo_run_start" }),
|
|
161
162
|
}),
|
|
162
163
|
async execute(_toolCallId, params) {
|
|
@@ -168,13 +169,13 @@ export function createRunToolDefinitions(yieldableTools, controller) {
|
|
|
168
169
|
};
|
|
169
170
|
},
|
|
170
171
|
}),
|
|
171
|
-
|
|
172
|
+
definePiboTool({
|
|
172
173
|
name: "pibo_run_cancel",
|
|
173
|
-
|
|
174
|
+
title: "Pibo Run Cancel",
|
|
174
175
|
description: "Cancel a yielded run if possible and suppress future reminders.",
|
|
175
176
|
promptSnippet: "Use pibo_run_cancel when a yielded run is no longer needed.",
|
|
176
177
|
executionMode: "parallel",
|
|
177
|
-
|
|
178
|
+
inputSchema: Type.Object({
|
|
178
179
|
runId: Type.String({ description: "Run id returned by pibo_run_start" }),
|
|
179
180
|
}),
|
|
180
181
|
async execute(_toolCallId, params) {
|
|
@@ -185,13 +186,13 @@ export function createRunToolDefinitions(yieldableTools, controller) {
|
|
|
185
186
|
};
|
|
186
187
|
},
|
|
187
188
|
}),
|
|
188
|
-
|
|
189
|
+
definePiboTool({
|
|
189
190
|
name: "pibo_run_ack",
|
|
190
|
-
|
|
191
|
+
title: "Pibo Run Ack",
|
|
191
192
|
description: "Acknowledge a yielded run update and suppress reminders for its current state.",
|
|
192
193
|
promptSnippet: "Use pibo_run_ack when you intentionally do not need to read a completed result or do not need more reminders for the current running state.",
|
|
193
194
|
executionMode: "parallel",
|
|
194
|
-
|
|
195
|
+
inputSchema: Type.Object({
|
|
195
196
|
runId: Type.String({ description: "Run id returned by pibo_run_start" }),
|
|
196
197
|
}),
|
|
197
198
|
async execute(_toolCallId, params) {
|
|
@@ -226,8 +226,8 @@ function createAssistantMessageRow(node) {
|
|
|
226
226
|
lines: [],
|
|
227
227
|
sourceNodeIds: [node.id],
|
|
228
228
|
startedAt: node.startedAt,
|
|
229
|
-
completedAt: node.source === "transcript" ? node.completedAt : undefined,
|
|
230
|
-
durationMs: node.source === "transcript" ? node.durationMs : undefined,
|
|
229
|
+
completedAt: node.source === "transcript" || node.source === "product-history" ? node.completedAt : undefined,
|
|
230
|
+
durationMs: node.source === "transcript" || node.source === "product-history" ? node.durationMs : undefined,
|
|
231
231
|
output: stringValue(node.output) || stringValue(node.summary) || "",
|
|
232
232
|
error: node.error,
|
|
233
233
|
payloadRefs: node.payloadRefs,
|
|
@@ -1,6 +1,26 @@
|
|
|
1
1
|
import { ChatDataIngestService } from "../data/ingest-service.js";
|
|
2
2
|
import { PiboDataStore } from "../data/pibo-store.js";
|
|
3
3
|
import { createPiboSession, matchesFindInput, } from "./store.js";
|
|
4
|
+
import { createLegacyPiRuntimeSessionBinding, nextRuntimeSessionBinding, RuntimeSessionBindingConflictError, } from "./runtime-binding.js";
|
|
5
|
+
const SESSION_SELECT = `
|
|
6
|
+
SELECT
|
|
7
|
+
s.*,
|
|
8
|
+
b.pibo_session_id AS binding_pibo_session_id,
|
|
9
|
+
b.runtime_instance_id AS binding_runtime_instance_id,
|
|
10
|
+
b.runtime_adapter_id AS binding_runtime_adapter_id,
|
|
11
|
+
b.native_session_id AS binding_native_session_id,
|
|
12
|
+
b.binding_state AS binding_state,
|
|
13
|
+
b.protocol AS binding_protocol,
|
|
14
|
+
b.protocol_version AS binding_protocol_version,
|
|
15
|
+
b.adapter_version AS binding_adapter_version,
|
|
16
|
+
b.locator_json AS binding_locator_json,
|
|
17
|
+
b.metadata_json AS binding_metadata_json,
|
|
18
|
+
b.revision AS binding_revision,
|
|
19
|
+
b.created_at AS binding_created_at,
|
|
20
|
+
b.updated_at AS binding_updated_at
|
|
21
|
+
FROM sessions s
|
|
22
|
+
LEFT JOIN session_runtime_bindings b ON b.pibo_session_id = s.id
|
|
23
|
+
`;
|
|
4
24
|
export class PiboDataSessionStore {
|
|
5
25
|
dataStore;
|
|
6
26
|
db;
|
|
@@ -17,15 +37,15 @@ export class PiboDataSessionStore {
|
|
|
17
37
|
this.db = this.dataStore.db;
|
|
18
38
|
}
|
|
19
39
|
get(id) {
|
|
20
|
-
const row = this.db.prepare(
|
|
40
|
+
const row = this.db.prepare(`${SESSION_SELECT} WHERE s.id = ? AND s.deleted_at IS NULL`).get(id);
|
|
21
41
|
return row ? sessionFromRow(row) : undefined;
|
|
22
42
|
}
|
|
23
43
|
list() {
|
|
24
|
-
return this.db.prepare(
|
|
44
|
+
return this.db.prepare(`${SESSION_SELECT} WHERE s.deleted_at IS NULL ORDER BY s.updated_at DESC`).all().map(sessionFromRow);
|
|
25
45
|
}
|
|
26
46
|
create(input) {
|
|
27
47
|
const session = createPiboSession(input);
|
|
28
|
-
this.insertSession(session);
|
|
48
|
+
this.dataStore.transaction(() => this.insertSession(session));
|
|
29
49
|
const created = this.get(session.id);
|
|
30
50
|
if (!created)
|
|
31
51
|
throw new Error(`Failed to create Pibo session "${session.id}"`);
|
|
@@ -68,7 +88,7 @@ export class PiboDataSessionStore {
|
|
|
68
88
|
updated_at = ?,
|
|
69
89
|
last_activity_at = MAX(last_activity_at, ?)
|
|
70
90
|
WHERE id = ? AND deleted_at IS NULL
|
|
71
|
-
`).run(updated.piSessionId, rootSessionId(updated), updated.parentId ?? null, updated.originId ?? null, updated.profile, updated.activeModel ? JSON.stringify(updated.activeModel) : null, updated.workspace ?? null, updated.title ?? "Untitled Session", JSON.stringify(updated.metadata ?? {}), updated.updatedAt, updated.updatedAt, id);
|
|
91
|
+
`).run(updated.piSessionId || null, rootSessionId(updated), updated.parentId ?? null, updated.originId ?? null, updated.profile, updated.activeModel ? JSON.stringify(updated.activeModel) : null, updated.workspace ?? null, updated.title ?? "Untitled Session", JSON.stringify(updated.metadata ?? {}), updated.updatedAt, updated.updatedAt, id);
|
|
72
92
|
return this.get(id);
|
|
73
93
|
}
|
|
74
94
|
delete(id) {
|
|
@@ -76,50 +96,90 @@ export class PiboDataSessionStore {
|
|
|
76
96
|
return Number(result.changes ?? 0) > 0;
|
|
77
97
|
}
|
|
78
98
|
find(input) {
|
|
79
|
-
const clauses = ["deleted_at IS NULL"];
|
|
99
|
+
const clauses = ["s.deleted_at IS NULL"];
|
|
80
100
|
const values = [];
|
|
81
101
|
if (input.ids !== undefined) {
|
|
82
102
|
if (input.ids.length === 0)
|
|
83
103
|
return [];
|
|
84
|
-
clauses.push(`id IN (${input.ids.map(() => "?").join(", ")})`);
|
|
104
|
+
clauses.push(`s.id IN (${input.ids.map(() => "?").join(", ")})`);
|
|
85
105
|
values.push(...input.ids);
|
|
86
106
|
}
|
|
87
107
|
if (input.channel !== undefined) {
|
|
88
|
-
clauses.push("channel = ?");
|
|
108
|
+
clauses.push("s.channel = ?");
|
|
89
109
|
values.push(input.channel);
|
|
90
110
|
}
|
|
91
111
|
if (input.kind !== undefined) {
|
|
92
|
-
clauses.push("kind = ?");
|
|
112
|
+
clauses.push("s.kind = ?");
|
|
93
113
|
values.push(input.kind);
|
|
94
114
|
}
|
|
95
115
|
if (input.parentId !== undefined) {
|
|
96
116
|
if (input.parentId === null)
|
|
97
|
-
clauses.push("parent_id IS NULL");
|
|
117
|
+
clauses.push("s.parent_id IS NULL");
|
|
98
118
|
else {
|
|
99
|
-
clauses.push("parent_id = ?");
|
|
119
|
+
clauses.push("s.parent_id = ?");
|
|
100
120
|
values.push(input.parentId);
|
|
101
121
|
}
|
|
102
122
|
}
|
|
103
123
|
if (input.originId !== undefined) {
|
|
104
|
-
clauses.push("origin_id = ?");
|
|
124
|
+
clauses.push("s.origin_id = ?");
|
|
105
125
|
values.push(input.originId);
|
|
106
126
|
}
|
|
107
127
|
if (input.profile !== undefined) {
|
|
108
|
-
clauses.push("profile = ?");
|
|
128
|
+
clauses.push("s.profile = ?");
|
|
109
129
|
values.push(input.profile);
|
|
110
130
|
}
|
|
111
131
|
if (input.activeModel !== undefined) {
|
|
112
132
|
if (input.activeModel === null)
|
|
113
|
-
clauses.push("active_model_json IS NULL");
|
|
133
|
+
clauses.push("s.active_model_json IS NULL");
|
|
114
134
|
else
|
|
115
|
-
clauses.push("active_model_json IS NOT NULL");
|
|
135
|
+
clauses.push("s.active_model_json IS NOT NULL");
|
|
116
136
|
}
|
|
117
|
-
const rows = this.db.prepare(
|
|
137
|
+
const rows = this.db.prepare(`${SESSION_SELECT} WHERE ${clauses.join(" AND ")} ORDER BY s.updated_at DESC`).all(...values);
|
|
118
138
|
return rows.map(sessionFromRow).filter((session) => matchesFindInput(session, input));
|
|
119
139
|
}
|
|
140
|
+
getRuntimeBinding(id) {
|
|
141
|
+
const session = this.get(id);
|
|
142
|
+
return session?.runtimeBinding ? structuredClone(session.runtimeBinding) : undefined;
|
|
143
|
+
}
|
|
144
|
+
updateRuntimeBinding(id, binding, options = {}) {
|
|
145
|
+
return this.dataStore.transaction(() => {
|
|
146
|
+
const current = this.getRuntimeBinding(id);
|
|
147
|
+
if (!current)
|
|
148
|
+
return undefined;
|
|
149
|
+
const currentRevision = current.revision ?? 1;
|
|
150
|
+
const updated = nextRuntimeSessionBinding(current, { ...structuredClone(binding), piboSessionId: id }, options);
|
|
151
|
+
const result = this.db.prepare(`
|
|
152
|
+
UPDATE session_runtime_bindings SET
|
|
153
|
+
runtime_instance_id = ?,
|
|
154
|
+
runtime_adapter_id = ?,
|
|
155
|
+
native_session_id = ?,
|
|
156
|
+
binding_state = ?,
|
|
157
|
+
protocol = ?,
|
|
158
|
+
protocol_version = ?,
|
|
159
|
+
adapter_version = ?,
|
|
160
|
+
locator_json = ?,
|
|
161
|
+
metadata_json = ?,
|
|
162
|
+
revision = ?,
|
|
163
|
+
updated_at = ?
|
|
164
|
+
WHERE pibo_session_id = ? AND revision = ?
|
|
165
|
+
`).run(updated.runtimeInstanceId, updated.adapterId, updated.nativeSessionId ?? null, updated.state, updated.protocol ?? null, updated.protocolVersion ?? null, updated.adapterVersion ?? null, updated.locator ? JSON.stringify(updated.locator) : null, JSON.stringify(updated.metadata ?? {}), updated.revision, updated.updatedAt, id, currentRevision);
|
|
166
|
+
if (Number(result.changes ?? 0) === 0) {
|
|
167
|
+
const actual = this.getRuntimeBinding(id);
|
|
168
|
+
throw new RuntimeSessionBindingConflictError(id, currentRevision, actual?.revision ?? 0);
|
|
169
|
+
}
|
|
170
|
+
this.db.prepare(`
|
|
171
|
+
UPDATE sessions SET pi_session_id = ?, updated_at = ?, last_activity_at = MAX(last_activity_at, ?)
|
|
172
|
+
WHERE id = ? AND deleted_at IS NULL
|
|
173
|
+
`).run(updated.adapterId === "pi" ? updated.nativeSessionId ?? null : null, updated.updatedAt, updated.updatedAt, id);
|
|
174
|
+
return this.getRuntimeBinding(id);
|
|
175
|
+
});
|
|
176
|
+
}
|
|
120
177
|
getTelemetryStore() {
|
|
121
178
|
return this.dataStore.telemetry;
|
|
122
179
|
}
|
|
180
|
+
getPayloadStore() {
|
|
181
|
+
return this.dataStore.payloads;
|
|
182
|
+
}
|
|
123
183
|
recoverInterruptedRuntimeState(input = {}) {
|
|
124
184
|
const at = input.at ?? new Date().toISOString();
|
|
125
185
|
const runsBySession = groupRunsByController(input.recoveredRuns ?? []);
|
|
@@ -196,7 +256,30 @@ export class PiboDataSessionStore {
|
|
|
196
256
|
];
|
|
197
257
|
this.db.prepare(`
|
|
198
258
|
INSERT INTO sessions (${columns.join(", ")}) VALUES (${columns.map(() => "?").join(", ")})
|
|
199
|
-
`).run(session.id, session.piSessionId, roomIdFromMetadata(session.metadata), rootSessionId(session), session.parentId ?? null, session.originId ?? null, session.channel, session.kind, session.profile, session.activeModel ? JSON.stringify(session.activeModel) : null, session.workspace ?? null, session.title ?? "Untitled Session", previewText(session.title ?? "") ?? null, "idle", JSON.stringify(session.metadata ?? {}), session.createdAt, session.updatedAt, session.updatedAt);
|
|
259
|
+
`).run(session.id, session.piSessionId || null, roomIdFromMetadata(session.metadata), rootSessionId(session), session.parentId ?? null, session.originId ?? null, session.channel, session.kind, session.profile, session.activeModel ? JSON.stringify(session.activeModel) : null, session.workspace ?? null, session.title ?? "Untitled Session", previewText(session.title ?? "") ?? null, "idle", JSON.stringify(session.metadata ?? {}), session.createdAt, session.updatedAt, session.updatedAt);
|
|
260
|
+
this.upsertRuntimeBinding(session.runtimeBinding ?? createLegacyPiRuntimeSessionBinding(session.id, session.piSessionId, session.createdAt));
|
|
261
|
+
}
|
|
262
|
+
upsertRuntimeBinding(binding) {
|
|
263
|
+
this.db.prepare(`
|
|
264
|
+
INSERT INTO session_runtime_bindings (
|
|
265
|
+
pibo_session_id, runtime_instance_id, runtime_adapter_id, native_session_id,
|
|
266
|
+
binding_state, protocol, protocol_version, adapter_version, locator_json,
|
|
267
|
+
metadata_json, revision, created_at, updated_at
|
|
268
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
269
|
+
ON CONFLICT(pibo_session_id) DO UPDATE SET
|
|
270
|
+
runtime_instance_id = excluded.runtime_instance_id,
|
|
271
|
+
runtime_adapter_id = excluded.runtime_adapter_id,
|
|
272
|
+
native_session_id = excluded.native_session_id,
|
|
273
|
+
binding_state = excluded.binding_state,
|
|
274
|
+
protocol = excluded.protocol,
|
|
275
|
+
protocol_version = excluded.protocol_version,
|
|
276
|
+
adapter_version = excluded.adapter_version,
|
|
277
|
+
locator_json = excluded.locator_json,
|
|
278
|
+
metadata_json = excluded.metadata_json,
|
|
279
|
+
revision = excluded.revision,
|
|
280
|
+
created_at = excluded.created_at,
|
|
281
|
+
updated_at = excluded.updated_at
|
|
282
|
+
`).run(binding.piboSessionId, binding.runtimeInstanceId, binding.adapterId, binding.nativeSessionId ?? null, binding.state, binding.protocol ?? null, binding.protocolVersion ?? null, binding.adapterVersion ?? null, binding.locator ? JSON.stringify(binding.locator) : null, JSON.stringify(binding.metadata ?? {}), binding.revision ?? 1, binding.createdAt ?? new Date().toISOString(), binding.updatedAt ?? binding.createdAt ?? new Date().toISOString());
|
|
200
283
|
}
|
|
201
284
|
}
|
|
202
285
|
export function createDefaultPiboDataSessionStore() {
|
|
@@ -255,6 +338,7 @@ function sessionFromRow(row) {
|
|
|
255
338
|
return {
|
|
256
339
|
id: row.id,
|
|
257
340
|
piSessionId: row.pi_session_id ?? "",
|
|
341
|
+
runtimeBinding: runtimeBindingFromRow(row),
|
|
258
342
|
channel: row.channel,
|
|
259
343
|
kind: row.kind,
|
|
260
344
|
profile: row.profile,
|
|
@@ -268,6 +352,31 @@ function sessionFromRow(row) {
|
|
|
268
352
|
updatedAt: row.updated_at,
|
|
269
353
|
};
|
|
270
354
|
}
|
|
355
|
+
function runtimeBindingFromRow(row) {
|
|
356
|
+
if (!row.binding_runtime_instance_id || !row.binding_runtime_adapter_id || !row.binding_state) {
|
|
357
|
+
return createLegacyPiRuntimeSessionBinding(row.id, row.pi_session_id ?? undefined, row.created_at);
|
|
358
|
+
}
|
|
359
|
+
return {
|
|
360
|
+
piboSessionId: row.binding_pibo_session_id ?? row.id,
|
|
361
|
+
runtimeInstanceId: row.binding_runtime_instance_id,
|
|
362
|
+
adapterId: row.binding_runtime_adapter_id,
|
|
363
|
+
nativeSessionId: row.binding_native_session_id ?? undefined,
|
|
364
|
+
state: isRuntimeBindingState(row.binding_state) ? row.binding_state : "error",
|
|
365
|
+
protocol: row.binding_protocol ?? undefined,
|
|
366
|
+
protocolVersion: row.binding_protocol_version ?? undefined,
|
|
367
|
+
adapterVersion: row.binding_adapter_version ?? undefined,
|
|
368
|
+
locator: row.binding_locator_json
|
|
369
|
+
? parseJsonObject(row.binding_locator_json)
|
|
370
|
+
: undefined,
|
|
371
|
+
metadata: parseJsonObject(row.binding_metadata_json),
|
|
372
|
+
revision: row.binding_revision ?? 1,
|
|
373
|
+
createdAt: row.binding_created_at ?? row.created_at,
|
|
374
|
+
updatedAt: row.binding_updated_at ?? row.updated_at,
|
|
375
|
+
};
|
|
376
|
+
}
|
|
377
|
+
function isRuntimeBindingState(value) {
|
|
378
|
+
return value === "unbound" || value === "bound" || value === "missing" || value === "error";
|
|
379
|
+
}
|
|
271
380
|
function parseJsonObject(json) {
|
|
272
381
|
if (!json)
|
|
273
382
|
return {};
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { DEFAULT_AGENT_RUNTIME_INSTANCE_ID } from "../core/profiles.js";
|
|
2
|
+
export class RuntimeSessionBindingConflictError extends Error {
|
|
3
|
+
piboSessionId;
|
|
4
|
+
expectedRevision;
|
|
5
|
+
actualRevision;
|
|
6
|
+
constructor(piboSessionId, expectedRevision, actualRevision) {
|
|
7
|
+
super(`Runtime binding for Pibo session "${piboSessionId}" changed concurrently (expected revision ${expectedRevision}, actual revision ${actualRevision}).`);
|
|
8
|
+
this.piboSessionId = piboSessionId;
|
|
9
|
+
this.expectedRevision = expectedRevision;
|
|
10
|
+
this.actualRevision = actualRevision;
|
|
11
|
+
this.name = "RuntimeSessionBindingConflictError";
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
export class RuntimeSessionBindingTransitionError extends Error {
|
|
15
|
+
piboSessionId;
|
|
16
|
+
constructor(piboSessionId, message) {
|
|
17
|
+
super(`Invalid runtime binding transition for Pibo session "${piboSessionId}": ${message}`);
|
|
18
|
+
this.piboSessionId = piboSessionId;
|
|
19
|
+
this.name = "RuntimeSessionBindingTransitionError";
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
export function createInitialRuntimeSessionBinding(piboSessionId, input, now = new Date().toISOString()) {
|
|
23
|
+
if (!input.runtimeInstanceId.trim()) {
|
|
24
|
+
throw new RuntimeSessionBindingTransitionError(piboSessionId, "runtime instance id is required");
|
|
25
|
+
}
|
|
26
|
+
if (!input.adapterId.trim()) {
|
|
27
|
+
throw new RuntimeSessionBindingTransitionError(piboSessionId, "runtime adapter id is required");
|
|
28
|
+
}
|
|
29
|
+
const nativeSessionId = normalizedOptionalString(input.nativeSessionId);
|
|
30
|
+
if ((input.state === "bound" || input.state === "missing") && !nativeSessionId) {
|
|
31
|
+
throw new RuntimeSessionBindingTransitionError(piboSessionId, `${input.state} state requires a native session id`);
|
|
32
|
+
}
|
|
33
|
+
return {
|
|
34
|
+
piboSessionId,
|
|
35
|
+
runtimeInstanceId: input.runtimeInstanceId,
|
|
36
|
+
adapterId: input.adapterId,
|
|
37
|
+
nativeSessionId,
|
|
38
|
+
state: input.state ?? "unbound",
|
|
39
|
+
protocol: normalizedOptionalString(input.protocol),
|
|
40
|
+
protocolVersion: normalizedOptionalString(input.protocolVersion),
|
|
41
|
+
adapterVersion: normalizedOptionalString(input.adapterVersion),
|
|
42
|
+
locator: input.locator ? structuredClone(input.locator) : undefined,
|
|
43
|
+
metadata: input.metadata ? structuredClone(input.metadata) : {},
|
|
44
|
+
revision: 1,
|
|
45
|
+
createdAt: now,
|
|
46
|
+
updatedAt: now,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
export function createLegacyPiRuntimeSessionBinding(piboSessionId, piSessionId, now = new Date().toISOString()) {
|
|
50
|
+
const nativeSessionId = normalizedOptionalString(piSessionId);
|
|
51
|
+
return createInitialRuntimeSessionBinding(piboSessionId, {
|
|
52
|
+
runtimeInstanceId: DEFAULT_AGENT_RUNTIME_INSTANCE_ID,
|
|
53
|
+
adapterId: "pi",
|
|
54
|
+
nativeSessionId,
|
|
55
|
+
state: nativeSessionId ? "bound" : "unbound",
|
|
56
|
+
protocol: "pi-sdk",
|
|
57
|
+
}, now);
|
|
58
|
+
}
|
|
59
|
+
export function nextRuntimeSessionBinding(current, next, options = {}, now = new Date().toISOString()) {
|
|
60
|
+
const currentRevision = current.revision ?? 1;
|
|
61
|
+
if (options.expectedRevision !== undefined && currentRevision !== options.expectedRevision) {
|
|
62
|
+
throw new RuntimeSessionBindingConflictError(current.piboSessionId, options.expectedRevision, currentRevision);
|
|
63
|
+
}
|
|
64
|
+
assertRuntimeSessionBindingTransition(current, next, options);
|
|
65
|
+
return {
|
|
66
|
+
...structuredClone(next),
|
|
67
|
+
piboSessionId: current.piboSessionId,
|
|
68
|
+
revision: currentRevision + 1,
|
|
69
|
+
createdAt: current.createdAt ?? now,
|
|
70
|
+
updatedAt: now,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
export function assertRuntimeSessionBindingTransition(current, next, options = {}) {
|
|
74
|
+
const mode = options.mode ?? "normal";
|
|
75
|
+
if (!next.runtimeInstanceId.trim()) {
|
|
76
|
+
throw new RuntimeSessionBindingTransitionError(current.piboSessionId, "runtime instance id is required");
|
|
77
|
+
}
|
|
78
|
+
if (!next.adapterId.trim()) {
|
|
79
|
+
throw new RuntimeSessionBindingTransitionError(current.piboSessionId, "runtime adapter id is required");
|
|
80
|
+
}
|
|
81
|
+
if ((current.runtimeInstanceId !== next.runtimeInstanceId || current.adapterId !== next.adapterId)
|
|
82
|
+
&& mode !== "rebind") {
|
|
83
|
+
throw new RuntimeSessionBindingTransitionError(current.piboSessionId, "changing the runtime instance or adapter requires rebind mode");
|
|
84
|
+
}
|
|
85
|
+
if (current.state === "unbound" && next.state === "bound" && options.expectedRevision === undefined) {
|
|
86
|
+
throw new RuntimeSessionBindingTransitionError(current.piboSessionId, "unbound to bound requires an expected revision");
|
|
87
|
+
}
|
|
88
|
+
if ((current.state === "missing" || current.state === "error") && next.state === "bound" && mode === "normal") {
|
|
89
|
+
throw new RuntimeSessionBindingTransitionError(current.piboSessionId, `${current.state} to bound requires repair or rebind mode`);
|
|
90
|
+
}
|
|
91
|
+
if (current.state === "bound" && next.state === "unbound" && mode !== "rebind") {
|
|
92
|
+
throw new RuntimeSessionBindingTransitionError(current.piboSessionId, "bound to unbound requires rebind mode");
|
|
93
|
+
}
|
|
94
|
+
if (current.state === "bound"
|
|
95
|
+
&& next.state === "bound"
|
|
96
|
+
&& current.nativeSessionId !== next.nativeSessionId
|
|
97
|
+
&& mode !== "rebind") {
|
|
98
|
+
throw new RuntimeSessionBindingTransitionError(current.piboSessionId, "changing a bound native session id requires rebind mode");
|
|
99
|
+
}
|
|
100
|
+
if ((next.state === "bound" || next.state === "missing") && !normalizedOptionalString(next.nativeSessionId)) {
|
|
101
|
+
throw new RuntimeSessionBindingTransitionError(current.piboSessionId, `${next.state} state requires a native session id`);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
function normalizedOptionalString(value) {
|
|
105
|
+
const normalized = value?.trim();
|
|
106
|
+
return normalized ? normalized : undefined;
|
|
107
|
+
}
|