@pasko70/pibo 1.9.13 → 1.10.1
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 +183 -183
- package/context/codex-base-prompt.md +148 -148
- package/context/compute-worker.md +23 -23
- package/context/pibo-compaction-prompt.md +100 -100
- package/context/pibo-native-tooling.md +18 -18
- package/context/pibo-system-prompt.md +77 -77
- package/dist/apps/chat/agent-profiles.js +2 -2
- package/dist/apps/chat/agent-store.js +263 -250
- package/dist/apps/chat/chat-request-normalizers.js +17 -0
- package/dist/apps/chat/data/chat-data-mappers.js +2 -0
- package/dist/apps/chat/data/project-service.js +168 -168
- package/dist/apps/chat/data/read-state-service.js +18 -18
- package/dist/apps/chat/data/session-query-service.js +25 -25
- package/dist/apps/chat/data/timeline-query-service.js +19 -19
- package/dist/apps/chat/loop-api.js +181 -0
- package/dist/apps/chat/static-assets.js +854 -854
- package/dist/apps/chat/web-app.js +36 -16
- package/dist/apps/chat/workflow-manual-trigger-runtime.js +149 -46
- package/dist/apps/chat/workflow-persistence.js +255 -255
- package/dist/apps/chat-ui/assets/{dist-BZ2eTC4f.js → dist-3Sts0Afa.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-BHa-kcGl.js → dist-4NlLjLs7.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-yCYNNb5d.js → dist-BA6mhAec.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-D811wJeV.js → dist-BPl-fzRB.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-Dq4GxJi3.js → dist-BPnn9e2B.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-CzE6k3F3.js → dist-BpfBSMzK.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-CnVsqwSG.js → dist-Cvx5M97R.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-WyXdYl-w.js → dist-DnXWNQRm.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-BNMu92bb.js → dist-hU-2oAb6.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-BCB6zezO.js → dist-r31x5Fcc.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-HqTN67dc.js → dist-uF6UXzI7.js} +1 -1
- package/dist/apps/chat-ui/assets/index-CaTGYBOS.js +173 -0
- package/dist/apps/chat-ui/assets/{index-C0x9nEcf.css → index-al8DeEjA.css} +1 -1
- package/dist/apps/chat-ui/index.html +18 -18
- package/dist/apps/chat-ui/manifest.webmanifest +25 -25
- package/dist/apps/chat-ui/sw.js +47 -47
- package/dist/apps/chat-vscode-web/assets/index-CK4SMZuu.js +41 -0
- package/dist/apps/chat-vscode-web/index.html +13 -13
- package/dist/apps/cli-ui/cliSessionsCommand.js +23 -23
- package/dist/apps/context-files-ui/index.html +11 -11
- package/dist/cli-session/localSessionSource.js +34 -12
- package/dist/cli.js +61 -44
- package/dist/compute/cli.js +54 -54
- package/dist/compute/resource-health.js +35 -2
- package/dist/core/events.js +6 -1
- package/dist/core/routed-session.js +97 -5
- package/dist/core/runtime.js +6 -1
- package/dist/core/session-router.js +27 -8
- package/dist/cron/cli.js +15 -15
- package/dist/cron/store.js +49 -49
- package/dist/data/cli.js +23 -23
- package/dist/data/event-log.js +23 -23
- package/dist/data/ingest-service.js +3 -1
- package/dist/data/message-store.js +27 -27
- package/dist/data/navigation-store.js +9 -9
- package/dist/data/observation-store.js +4 -4
- package/dist/data/payload-store.js +17 -17
- package/dist/data/schema.js +433 -433
- package/dist/data/session-store.js +4 -4
- package/dist/data/telemetry-queries.js +54 -54
- package/dist/data/telemetry.js +197 -197
- package/dist/debug/events.js +12 -12
- package/dist/debug/failures.js +6 -6
- package/dist/debug/index.js +231 -227
- package/dist/debug/messages.js +6 -6
- package/dist/debug/pty.js +124 -124
- package/dist/debug/session.js +29 -29
- package/dist/debug/tools.js +5 -5
- package/dist/debug/trace.js +42 -7
- package/dist/debug/web-snapshot-browser-scripts.js +294 -294
- package/dist/debug/web-streaming-browser-library.js +925 -925
- package/dist/debug/web-streaming-browser-scripts.js +232 -232
- package/dist/debug/web-streaming-provider-telemetry.js +4 -4
- package/dist/debug/web.js +93 -93
- package/dist/gateway/cli.js +19 -19
- package/dist/gateway/server.js +4 -2
- package/dist/gateway/web.js +2 -2
- package/dist/index.js +1 -0
- package/dist/loops/accounting.js +19 -0
- package/dist/loops/channel.js +8 -0
- package/dist/loops/cli.js +224 -0
- package/dist/loops/plugin.js +16 -0
- package/dist/loops/prompts.js +86 -0
- package/dist/loops/service.js +446 -0
- package/dist/loops/stopping.js +170 -0
- package/dist/loops/store.js +642 -0
- package/dist/loops/templates.js +232 -0
- package/dist/loops/tools.js +184 -0
- package/dist/loops/types.js +1 -0
- package/dist/mcp/config-command.js +53 -53
- package/dist/mcp/index.js +21 -21
- package/dist/mcp/registry.js +11 -11
- package/dist/pi-packages/cli.js +11 -11
- package/dist/plugins/builtin.js +8 -0
- package/dist/plugins/context-files-store.js +110 -110
- package/dist/plugins/context-files.js +4 -4
- package/dist/plugins/registry.js +23 -12
- package/dist/ralph/cli.js +18 -18
- package/dist/ralph/templates.js +140 -140
- package/dist/reliability/store.js +256 -229
- package/dist/runs/lifecycle.js +59 -0
- package/dist/runs/registry.js +47 -1
- package/dist/runs/tools.js +31 -13
- package/dist/session-ui/terminalRows.js +66 -2
- package/dist/sessions/pibo-data-store.js +16 -16
- package/dist/sessions/sqlite-store.js +53 -53
- package/dist/setup/cli.js +58 -58
- package/dist/shared/trace-async-agent-runs.js +4 -4
- package/dist/shared/trace-event-projection.js +59 -19
- package/dist/shared/trace-nodes.js +5 -0
- package/dist/shared/trace-page-merge.js +15 -0
- package/dist/shared/trace-run-notifications.js +3 -1
- package/dist/signals/projector.js +6 -2
- package/dist/tools/agent-browser-wrapper.js +80 -80
- package/dist/tools/browser-pool.js +50 -0
- package/dist/tools/browser-use-cdp.js +12 -12
- package/dist/tools/browser-use-leases.js +12 -8
- package/dist/tools/browser-use-wrapper.js +762 -762
- package/dist/tools/guides.js +596 -538
- package/dist/tools/index.js +123 -99
- package/dist/tools/registry.js +21 -3
- package/dist/tools/runtime/node-worker-source.js +205 -205
- package/dist/tools/runtime/python-worker-source.js +177 -177
- package/dist/vscode/cli.js +9 -9
- package/dist/web-annotations/cdp.js +900 -900
- package/dist/web-annotations/store.js +96 -96
- package/docs/README.md +23 -23
- package/docs/ops/install-developer-host.md +112 -112
- package/docs/ops/install-user-host.md +96 -96
- package/docs/ops/upgrade-user-to-developer-host.md +69 -69
- package/docs/ops/vscode-extension-release.md +160 -160
- package/package.json +99 -95
- package/skills/builtin/graphify/SKILL.md +52 -52
- package/skills/builtin/loop/SKILL.md +78 -0
- package/skills/builtin/pi-agent-harness/SKILL.md +319 -319
- package/skills/builtin/pi-agent-harness/agents/openai.yaml +4 -4
- package/skills/builtin/pibo-docker-system/SKILL.md +170 -170
- package/skills/builtin/pibo-spec-writing/SKILL.md +330 -330
- package/skills/builtin/prd/SKILL.md +143 -143
- package/skills/builtin/ralph-loop/SKILL.md +361 -359
- package/skills/builtin/ralph-prd-json/SKILL.md +123 -123
- package/skills/builtin/skill-creator/LICENSE.txt +201 -201
- package/skills/builtin/skill-creator/SKILL.md +513 -513
- package/skills/builtin/skill-creator/agents/analyzer.md +274 -274
- package/skills/builtin/skill-creator/agents/comparator.md +202 -202
- package/skills/builtin/skill-creator/agents/grader.md +223 -223
- package/skills/builtin/skill-creator/assets/eval_review.html +146 -146
- package/skills/builtin/skill-creator/eval-viewer/generate_review.py +471 -471
- package/skills/builtin/skill-creator/eval-viewer/viewer.html +1325 -1325
- package/skills/builtin/skill-creator/references/schemas.md +430 -430
- package/skills/builtin/skill-creator/scripts/aggregate_benchmark.py +401 -401
- package/skills/builtin/skill-creator/scripts/generate_report.py +326 -326
- package/skills/builtin/skill-creator/scripts/improve_description.py +247 -247
- package/skills/builtin/skill-creator/scripts/package_skill.py +136 -136
- package/skills/builtin/skill-creator/scripts/quick_validate.py +102 -102
- package/skills/builtin/skill-creator/scripts/run_eval.py +310 -310
- package/skills/builtin/skill-creator/scripts/run_loop.py +328 -328
- package/skills/builtin/skill-creator/scripts/utils.py +47 -47
- package/skills/builtin/web-annotations/SKILL.md +93 -93
- package/src/mcp/LICENSE.mcp-cli +21 -21
- package/dist/apps/chat-ui/assets/index-DwHJfmiF.js +0 -173
- package/dist/apps/chat-vscode-web/assets/index-BAMxIaI_.js +0 -41
- package/dist/apps/vscode-artifacts/latest.vsix +0 -0
- package/dist/apps/vscode-artifacts/pibo-vscode-ext-1.9.13.vsix +0 -0
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { SessionManager, shouldCompact } from "@earendil-works/pi-coding-agent";
|
|
2
|
+
import { PiboSteeringUnavailableError } from "./events.js";
|
|
2
3
|
import { getOpenAiCodexProviderUsageForActiveModel } from "../auth/openai-codex-usage.js";
|
|
3
4
|
import { normalizeSessionErrorDetails, runtimeSessionErrorDetails } from "./session-errors.js";
|
|
4
5
|
import { expandInlineSkills } from "./skill-expansion.js";
|
|
@@ -29,6 +30,31 @@ function isAssistantMessage(message) {
|
|
|
29
30
|
function numberValue(value) {
|
|
30
31
|
return typeof value === "number" && Number.isFinite(value) ? value : undefined;
|
|
31
32
|
}
|
|
33
|
+
export function normalizeAssistantUsageEvent(piboSessionId, message) {
|
|
34
|
+
const assistant = message;
|
|
35
|
+
if (!assistant?.usage || typeof assistant.usage !== "object")
|
|
36
|
+
return undefined;
|
|
37
|
+
const usage = assistant.usage;
|
|
38
|
+
const inputTokens = numberValue(usage.inputTokens) ?? numberValue(usage.input);
|
|
39
|
+
const outputTokens = numberValue(usage.outputTokens) ?? numberValue(usage.output);
|
|
40
|
+
const cacheReadTokens = numberValue(usage.cacheRead);
|
|
41
|
+
const cacheWriteTokens = numberValue(usage.cacheWrite);
|
|
42
|
+
const reportedTotal = numberValue(usage.totalTokens);
|
|
43
|
+
const normalizedTotal = reportedTotal ?? [inputTokens, outputTokens, cacheReadTokens, cacheWriteTokens]
|
|
44
|
+
.filter((value) => value !== undefined)
|
|
45
|
+
.reduce((sum, value) => sum + value, 0);
|
|
46
|
+
if (normalizedTotal <= 0 && inputTokens === undefined && outputTokens === undefined && cacheReadTokens === undefined && cacheWriteTokens === undefined)
|
|
47
|
+
return undefined;
|
|
48
|
+
return {
|
|
49
|
+
type: "assistant_usage",
|
|
50
|
+
piboSessionId,
|
|
51
|
+
...(inputTokens !== undefined ? { inputTokens } : {}),
|
|
52
|
+
...(outputTokens !== undefined ? { outputTokens } : {}),
|
|
53
|
+
...(cacheReadTokens !== undefined ? { cacheReadTokens } : {}),
|
|
54
|
+
...(cacheWriteTokens !== undefined ? { cacheWriteTokens } : {}),
|
|
55
|
+
totalTokens: Math.max(0, normalizedTotal),
|
|
56
|
+
};
|
|
57
|
+
}
|
|
32
58
|
function stringValue(value) {
|
|
33
59
|
return typeof value === "string" && value.length > 0 ? value : undefined;
|
|
34
60
|
}
|
|
@@ -397,6 +423,8 @@ export class RoutedSession {
|
|
|
397
423
|
queue = [];
|
|
398
424
|
processing = false;
|
|
399
425
|
disposed = false;
|
|
426
|
+
disposePromise;
|
|
427
|
+
drainPromise;
|
|
400
428
|
fastMode = false;
|
|
401
429
|
fastModePatchedAgents = new WeakSet();
|
|
402
430
|
activeMessage;
|
|
@@ -511,6 +539,9 @@ export class RoutedSession {
|
|
|
511
539
|
const normalized = normalizePiEvent(this.piboSessionId, event, { contextWindow: numberValue(model?.contextWindow) });
|
|
512
540
|
const candidate = event && typeof event === "object" ? event : undefined;
|
|
513
541
|
const assistantMessageEnded = candidate?.type === "message_end" && isAssistantMessage(candidate.message);
|
|
542
|
+
const usageEvent = assistantMessageEnded ? normalizeAssistantUsageEvent(this.piboSessionId, candidate?.message) : undefined;
|
|
543
|
+
if (usageEvent)
|
|
544
|
+
this.emit(this.withActiveMessage(usageEvent));
|
|
514
545
|
// Pi gets the first chance to recover through its short retry/compaction loop.
|
|
515
546
|
// Keep the final error pending so the routed turn can continue durable recovery.
|
|
516
547
|
if (assistantMessageEnded && normalized?.type === "session_error") {
|
|
@@ -655,7 +686,32 @@ export class RoutedSession {
|
|
|
655
686
|
};
|
|
656
687
|
this.emit(output);
|
|
657
688
|
this.onStateChange?.({ processing: this.processing, queuedMessages: this.queue.length, disposed: this.disposed });
|
|
658
|
-
|
|
689
|
+
this.startDrain();
|
|
690
|
+
return output;
|
|
691
|
+
}
|
|
692
|
+
async steerMessage(event) {
|
|
693
|
+
this.assertActive();
|
|
694
|
+
const activeMessage = this.activeMessage;
|
|
695
|
+
if (!activeMessage || !this.processing || !this.runtime.session.isStreaming) {
|
|
696
|
+
throw new PiboSteeringUnavailableError();
|
|
697
|
+
}
|
|
698
|
+
const session = this.runtime.session;
|
|
699
|
+
const expandedText = expandInlineSkills(event.text, session.resourceLoader.getSkills().skills);
|
|
700
|
+
try {
|
|
701
|
+
await session.steer(expandedText);
|
|
702
|
+
}
|
|
703
|
+
catch (error) {
|
|
704
|
+
throw new PiboSteeringUnavailableError(`The active session could not accept steering: ${errorMessage(error)}`, { cause: error });
|
|
705
|
+
}
|
|
706
|
+
const output = {
|
|
707
|
+
type: "message_steered",
|
|
708
|
+
piboSessionId: this.piboSessionId,
|
|
709
|
+
eventId: event.id,
|
|
710
|
+
activeEventId: activeMessage.id,
|
|
711
|
+
text: event.text,
|
|
712
|
+
source: event.source,
|
|
713
|
+
};
|
|
714
|
+
this.emit(output);
|
|
659
715
|
return output;
|
|
660
716
|
}
|
|
661
717
|
async executeAction(event) {
|
|
@@ -847,9 +903,26 @@ export class RoutedSession {
|
|
|
847
903
|
return await this.runtime.session.compact(customInstructions);
|
|
848
904
|
}
|
|
849
905
|
async dispose() {
|
|
906
|
+
if (this.disposePromise)
|
|
907
|
+
return this.disposePromise;
|
|
908
|
+
this.disposePromise = this.disposeUnsafe();
|
|
909
|
+
return this.disposePromise;
|
|
910
|
+
}
|
|
911
|
+
async disposeUnsafe() {
|
|
850
912
|
if (this.disposed)
|
|
851
913
|
return;
|
|
914
|
+
const activeMessage = this.activeMessage;
|
|
852
915
|
this.notifyMessagesInterrupted(this.activeAndQueuedMessages(), "session disposed");
|
|
916
|
+
if (activeMessage) {
|
|
917
|
+
const error = "Session disposed while a message was active.";
|
|
918
|
+
this.emit({
|
|
919
|
+
type: "session_error",
|
|
920
|
+
piboSessionId: this.piboSessionId,
|
|
921
|
+
eventId: activeMessage.id,
|
|
922
|
+
error,
|
|
923
|
+
errorDetails: runtimeSessionErrorDetails(error),
|
|
924
|
+
});
|
|
925
|
+
}
|
|
853
926
|
this.cancelProviderRecovery();
|
|
854
927
|
this.queue.length = 0;
|
|
855
928
|
this.onStateChange?.({ processing: this.processing, queuedMessages: this.queue.length, disposed: true });
|
|
@@ -860,7 +933,15 @@ export class RoutedSession {
|
|
|
860
933
|
this.recoverySession = undefined;
|
|
861
934
|
}
|
|
862
935
|
this.disposed = true;
|
|
863
|
-
|
|
936
|
+
const abort = this.runtime.session.abort;
|
|
937
|
+
if (abort)
|
|
938
|
+
await Promise.allSettled([abort.call(this.runtime.session)]);
|
|
939
|
+
try {
|
|
940
|
+
await this.drainPromise;
|
|
941
|
+
}
|
|
942
|
+
finally {
|
|
943
|
+
await this.runtime.dispose();
|
|
944
|
+
}
|
|
864
945
|
}
|
|
865
946
|
async kill() {
|
|
866
947
|
this.notifyMessagesInterrupted(this.activeAndQueuedMessages(), "session killed");
|
|
@@ -890,6 +971,16 @@ export class RoutedSession {
|
|
|
890
971
|
}
|
|
891
972
|
return false;
|
|
892
973
|
}
|
|
974
|
+
startDrain() {
|
|
975
|
+
if (this.drainPromise)
|
|
976
|
+
return;
|
|
977
|
+
const drain = this.drain();
|
|
978
|
+
this.drainPromise = drain;
|
|
979
|
+
void drain.finally(() => {
|
|
980
|
+
if (this.drainPromise === drain)
|
|
981
|
+
this.drainPromise = undefined;
|
|
982
|
+
});
|
|
983
|
+
}
|
|
893
984
|
async drain() {
|
|
894
985
|
if (this.processing || this.disposed)
|
|
895
986
|
return;
|
|
@@ -946,7 +1037,7 @@ export class RoutedSession {
|
|
|
946
1037
|
}
|
|
947
1038
|
}
|
|
948
1039
|
catch (error) {
|
|
949
|
-
if (error instanceof PiboProviderRecoveryCancelledError)
|
|
1040
|
+
if (error instanceof PiboProviderRecoveryCancelledError || this.disposed)
|
|
950
1041
|
return;
|
|
951
1042
|
const message = errorMessage(error);
|
|
952
1043
|
this.emit({
|
|
@@ -1002,7 +1093,7 @@ export class RoutedSession {
|
|
|
1002
1093
|
};
|
|
1003
1094
|
this.emit(output);
|
|
1004
1095
|
this.onStateChange?.({ processing: this.processing, queuedMessages: this.queue.length, disposed: this.disposed });
|
|
1005
|
-
|
|
1096
|
+
this.startDrain();
|
|
1006
1097
|
return output;
|
|
1007
1098
|
}
|
|
1008
1099
|
async runAction(event) {
|
|
@@ -1150,7 +1241,8 @@ export class RoutedSession {
|
|
|
1150
1241
|
return output;
|
|
1151
1242
|
}
|
|
1152
1243
|
if (this.activeMessage?.id &&
|
|
1153
|
-
(event.type === "
|
|
1244
|
+
(event.type === "assistant_usage" ||
|
|
1245
|
+
event.type === "tool_call" ||
|
|
1154
1246
|
event.type === "tool_execution_started" ||
|
|
1155
1247
|
event.type === "tool_execution_updated" ||
|
|
1156
1248
|
event.type === "tool_execution_finished" ||
|
package/dist/core/runtime.js
CHANGED
|
@@ -17,6 +17,7 @@ import { createPiboCompactionPromptExtension } from "./compaction-prompt.js";
|
|
|
17
17
|
import { cancelPiboAssistantContextGuardRecovery, createPiboAssistantContextGuardExtension, createPiboAssistantContextGuardRecovery, isPiboAssistantContextGuardRecoveryPending, registerPiboAssistantContextGuardRecovery, } from "./context-guard.js";
|
|
18
18
|
import { getPiPackageRuntimeOptions } from "../pi-packages/runtime.js";
|
|
19
19
|
import { getDefaultPiboWorkspace } from "./workspace.js";
|
|
20
|
+
import { createPiboGoalToolDefinitions, PIBO_GOAL_TOOL_NAMES } from "../loops/tools.js";
|
|
20
21
|
import { DEFAULT_USER_TIMEZONE } from "./user-settings.js";
|
|
21
22
|
import { registerMiniMaxProvider } from "../providers/minimax.js";
|
|
22
23
|
import { registerGlmProvider } from "../providers/glm.js";
|
|
@@ -109,6 +110,8 @@ function getEnabledToolDefinitions(profile, options, subagentRunner, runToolCont
|
|
|
109
110
|
const profileToolDefinitions = profileTools.map((tool) => getToolDefinition(tool, options.toolContext));
|
|
110
111
|
const codexCompatEnabled = profile.toolPackages.codexCompat === true;
|
|
111
112
|
const runControlEnabled = profile.toolPackages.runControl === true;
|
|
113
|
+
const goalControlEnabled = profile.toolPackages.goalControl !== false;
|
|
114
|
+
const goalTools = goalControlEnabled ? createPiboGoalToolDefinitions(options.toolContext ?? {}) : [];
|
|
112
115
|
const runControlBashTool = runControlEnabled && runToolController
|
|
113
116
|
? createBashToolDefinition(options.runtimeCwd, {
|
|
114
117
|
commandPrefix: options.shellCommandPrefix,
|
|
@@ -137,6 +140,7 @@ function getEnabledToolDefinitions(profile, options, subagentRunner, runToolCont
|
|
|
137
140
|
...(runtimeTool ? [runtimeTool] : []),
|
|
138
141
|
...subagentTools,
|
|
139
142
|
...codexCompatTools,
|
|
143
|
+
...goalTools,
|
|
140
144
|
...runTools,
|
|
141
145
|
];
|
|
142
146
|
}
|
|
@@ -155,7 +159,7 @@ function isEnabledRuntimeTool(tool) {
|
|
|
155
159
|
return tool.enabled !== false && isRuntimeTool(tool);
|
|
156
160
|
}
|
|
157
161
|
function isGeneratedPiboTool(name) {
|
|
158
|
-
return name === "runtime" || name.startsWith("pibo_subagent_") || name.startsWith("pibo_run_");
|
|
162
|
+
return name === "runtime" || name.startsWith("pibo_subagent_") || name.startsWith("pibo_run_") || PIBO_GOAL_TOOL_NAMES.includes(name);
|
|
159
163
|
}
|
|
160
164
|
function getBuiltinToolAllowlist(profile, customTools) {
|
|
161
165
|
if (profile.builtinTools === "disabled")
|
|
@@ -282,6 +286,7 @@ export async function createPiboRuntime(options = {}) {
|
|
|
282
286
|
toolContext: {
|
|
283
287
|
piboSessionId: options.sessionContext?.piboSessionId ?? profile.sessionId,
|
|
284
288
|
piboRoomId: options.sessionContext?.piboRoomId,
|
|
289
|
+
profileName: profile.profileName,
|
|
285
290
|
},
|
|
286
291
|
}, options.subagentRunner, options.runToolController, runtimeToolController);
|
|
287
292
|
const modelDefaults = options.modelDefaults ?? loadPiboModelDefaults(runtimeCwd);
|
|
@@ -6,6 +6,7 @@ import { RoutedSession } from "./routed-session.js";
|
|
|
6
6
|
import { runtimeSessionErrorDetails } from "./session-errors.js";
|
|
7
7
|
import { createSubagentToolName } from "../subagents/tool.js";
|
|
8
8
|
import { PiboRunRegistry } from "../runs/registry.js";
|
|
9
|
+
import { PiboRunExecutionTimeoutError } from "../runs/lifecycle.js";
|
|
9
10
|
import { createPiboSignalRegistry } from "../signals/registry.js";
|
|
10
11
|
import { createDefaultPiboReliabilityStore } from "../reliability/store.js";
|
|
11
12
|
import { InMemoryPiboSessionStore, } from "../sessions/store.js";
|
|
@@ -22,13 +23,15 @@ import { createPiboProviderTelemetryExtension } from "./provider-telemetry.js";
|
|
|
22
23
|
import { AsyncTelemetryWriter } from "../data/telemetry-writer.js";
|
|
23
24
|
const DEFAULT_SUBAGENT_REPLY_TIMEOUT_MS = 10 * 60 * 1000;
|
|
24
25
|
const DEFAULT_ROUTED_SESSION_IDLE_TIMEOUT_MS = 30 * 60 * 1000;
|
|
25
|
-
export const
|
|
26
|
+
export const LOOP_RUNTIME_RETRY_DEFAULTS = {
|
|
26
27
|
enabled: true,
|
|
27
28
|
maxRetries: 7,
|
|
28
29
|
baseDelayMs: 2_000,
|
|
29
30
|
};
|
|
31
|
+
/** @deprecated Use LOOP_RUNTIME_RETRY_DEFAULTS. */
|
|
32
|
+
export const RALPH_RUNTIME_RETRY_DEFAULTS = LOOP_RUNTIME_RETRY_DEFAULTS;
|
|
30
33
|
export function resolvePiboSessionRetryDefaults(kind, configured) {
|
|
31
|
-
return configured ?? (kind === "ralph" ?
|
|
34
|
+
return configured ?? (kind === "loop" || kind === "ralph" ? LOOP_RUNTIME_RETRY_DEFAULTS : undefined);
|
|
32
35
|
}
|
|
33
36
|
export function resolvePiboSessionInitialThinkingLevel(session) {
|
|
34
37
|
const value = session.metadata?.initialThinkingLevel;
|
|
@@ -83,6 +86,15 @@ function formatRunReminderMessage(notification) {
|
|
|
83
86
|
toolName: run.toolName,
|
|
84
87
|
summary: run.summary,
|
|
85
88
|
})),
|
|
89
|
+
timedOut: notification.timedOut.map((run) => ({
|
|
90
|
+
runId: run.runId,
|
|
91
|
+
kind: run.kind,
|
|
92
|
+
status: run.status,
|
|
93
|
+
toolName: run.toolName,
|
|
94
|
+
summary: run.summary,
|
|
95
|
+
timeoutMs: run.timeoutMs,
|
|
96
|
+
timeoutPhase: run.timeoutPhase,
|
|
97
|
+
})),
|
|
86
98
|
cancelled: notification.cancelled.map((run) => ({
|
|
87
99
|
runId: run.runId,
|
|
88
100
|
kind: run.kind,
|
|
@@ -97,7 +109,7 @@ function formatRunReminderMessage(notification) {
|
|
|
97
109
|
toolName: run.toolName,
|
|
98
110
|
summary: run.summary,
|
|
99
111
|
})),
|
|
100
|
-
instruction: "Use pibo_run_read for completed or
|
|
112
|
+
instruction: "Use pibo_run_read for completed, failed, or timed_out runs. Use pibo_run_wait, pibo_run_status, pibo_run_cancel, or pibo_run_ack for runs you still need to manage.",
|
|
101
113
|
}),
|
|
102
114
|
"</pibo_run_notification>",
|
|
103
115
|
].join("\n");
|
|
@@ -106,7 +118,7 @@ function isRunReminderServiceMessage(event) {
|
|
|
106
118
|
return event.source === "service" && event.text.startsWith("<pibo_run_notification>");
|
|
107
119
|
}
|
|
108
120
|
function isTerminalRunStatus(status) {
|
|
109
|
-
return status === "completed" || status === "failed" || status === "cancelled";
|
|
121
|
+
return status === "completed" || status === "failed" || status === "timed_out" || status === "cancelled";
|
|
110
122
|
}
|
|
111
123
|
function asJsonObject(value) {
|
|
112
124
|
return value ?? {};
|
|
@@ -210,7 +222,9 @@ export class PiboSessionRouter {
|
|
|
210
222
|
this.clearIdleSessionTimer(event.piboSessionId);
|
|
211
223
|
try {
|
|
212
224
|
if (event.type === "message") {
|
|
213
|
-
return
|
|
225
|
+
return event.delivery === "steer"
|
|
226
|
+
? await session.steerMessage(event)
|
|
227
|
+
: session.enqueueMessage(event);
|
|
214
228
|
}
|
|
215
229
|
if (event.action === "abort") {
|
|
216
230
|
this.signalRegistry.project({ type: "session_interrupted", piboSessionId: event.piboSessionId, reason: "abort action" });
|
|
@@ -665,7 +679,7 @@ export class PiboSessionRouter {
|
|
|
665
679
|
}
|
|
666
680
|
createRunToolController(parentPiboSessionId) {
|
|
667
681
|
return {
|
|
668
|
-
startToolRun: ({ toolName, params, completionPolicy, retryable, maxAttempts, execute }) => {
|
|
682
|
+
startToolRun: ({ toolName, params, completionPolicy, retryable, maxAttempts, timeoutMs, serviceWarning, execute }) => {
|
|
669
683
|
assertGatewayResourceAvailableForWork(`yielded run ${toolName}`);
|
|
670
684
|
const run = this.runRegistry.startToolRun({
|
|
671
685
|
controllerPiboSessionId: parentPiboSessionId,
|
|
@@ -674,6 +688,8 @@ export class PiboSessionRouter {
|
|
|
674
688
|
completionPolicy,
|
|
675
689
|
retryable,
|
|
676
690
|
maxAttempts,
|
|
691
|
+
timeoutMs,
|
|
692
|
+
serviceWarning,
|
|
677
693
|
});
|
|
678
694
|
void (async () => {
|
|
679
695
|
try {
|
|
@@ -683,8 +699,11 @@ export class PiboSessionRouter {
|
|
|
683
699
|
this.scheduleRunReminder(parentPiboSessionId, false);
|
|
684
700
|
}
|
|
685
701
|
catch (error) {
|
|
686
|
-
const
|
|
687
|
-
|
|
702
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
703
|
+
const terminalRun = error instanceof PiboRunExecutionTimeoutError
|
|
704
|
+
? this.runRegistry.timeOut(run.runId, message, error.timeoutPhase)
|
|
705
|
+
: this.runRegistry.fail(run.runId, message);
|
|
706
|
+
if (terminalRun)
|
|
688
707
|
this.scheduleRunReminder(parentPiboSessionId, false);
|
|
689
708
|
}
|
|
690
709
|
})();
|
package/dist/cron/cli.js
CHANGED
|
@@ -2,21 +2,21 @@ import { Command } from "commander";
|
|
|
2
2
|
import { parseFriendlySchedule } from "./schedule.js";
|
|
3
3
|
import { createDefaultPiboCronStore } from "./store.js";
|
|
4
4
|
function printDiscovery() {
|
|
5
|
-
console.log(`pibo cron
|
|
6
|
-
|
|
7
|
-
Manage scheduled Pibo agent jobs.
|
|
8
|
-
|
|
9
|
-
Commands:
|
|
10
|
-
status Show scheduler store status
|
|
11
|
-
list List cron jobs
|
|
12
|
-
add Create a cron job
|
|
13
|
-
edit Update a cron job
|
|
14
|
-
pause Disable a cron job
|
|
15
|
-
resume Enable a cron job and recompute next run
|
|
16
|
-
remove Delete a cron job
|
|
17
|
-
runs List cron runs
|
|
18
|
-
|
|
19
|
-
Next: pibo cron add --help
|
|
5
|
+
console.log(`pibo cron
|
|
6
|
+
|
|
7
|
+
Manage scheduled Pibo agent jobs.
|
|
8
|
+
|
|
9
|
+
Commands:
|
|
10
|
+
status Show scheduler store status
|
|
11
|
+
list List cron jobs
|
|
12
|
+
add Create a cron job
|
|
13
|
+
edit Update a cron job
|
|
14
|
+
pause Disable a cron job
|
|
15
|
+
resume Enable a cron job and recompute next run
|
|
16
|
+
remove Delete a cron job
|
|
17
|
+
runs List cron runs
|
|
18
|
+
|
|
19
|
+
Next: pibo cron add --help
|
|
20
20
|
pibo cron edit --help`);
|
|
21
21
|
}
|
|
22
22
|
function printJson(value) {
|
package/dist/cron/store.js
CHANGED
|
@@ -172,10 +172,10 @@ export class PiboCronStore {
|
|
|
172
172
|
const result = [];
|
|
173
173
|
this.db.exec("BEGIN IMMEDIATE");
|
|
174
174
|
try {
|
|
175
|
-
const rows = this.db.prepare(`
|
|
176
|
-
SELECT * FROM pibo_cron_jobs
|
|
177
|
-
WHERE enabled = 1
|
|
178
|
-
ORDER BY updated_at ASC
|
|
175
|
+
const rows = this.db.prepare(`
|
|
176
|
+
SELECT * FROM pibo_cron_jobs
|
|
177
|
+
WHERE enabled = 1
|
|
178
|
+
ORDER BY updated_at ASC
|
|
179
179
|
`).all();
|
|
180
180
|
for (const row of rows) {
|
|
181
181
|
if (result.length >= limit)
|
|
@@ -242,10 +242,10 @@ export class PiboCronStore {
|
|
|
242
242
|
lastPiboSessionId: input.piboSessionId ?? job.state.lastPiboSessionId,
|
|
243
243
|
consecutiveErrors: input.status === "error" ? (job.state.consecutiveErrors ?? 0) + 1 : 0,
|
|
244
244
|
};
|
|
245
|
-
this.db.prepare(`
|
|
246
|
-
UPDATE pibo_cron_runs
|
|
247
|
-
SET status = ?, pibo_session_id = ?, reason = ?, error = ?, completed_at = ?, updated_at = ?
|
|
248
|
-
WHERE id = ?
|
|
245
|
+
this.db.prepare(`
|
|
246
|
+
UPDATE pibo_cron_runs
|
|
247
|
+
SET status = ?, pibo_session_id = ?, reason = ?, error = ?, completed_at = ?, updated_at = ?
|
|
248
|
+
WHERE id = ?
|
|
249
249
|
`).run(input.status, input.piboSessionId ?? null, input.reason ?? null, input.error ?? null, timestamp, timestamp, input.runId);
|
|
250
250
|
this.db.prepare(`UPDATE pibo_cron_jobs SET enabled = ?, state_json = ?, updated_at = ? WHERE id = ?`).run(enabled ? 1 : 0, JSON.stringify(state), timestamp, job.id);
|
|
251
251
|
if (job.deleteAfterRun && job.schedule.kind === "at" && input.status === "ok") {
|
|
@@ -286,50 +286,50 @@ export class PiboCronStore {
|
|
|
286
286
|
this.createFreshSchema();
|
|
287
287
|
}
|
|
288
288
|
createFreshSchema() {
|
|
289
|
-
this.db.exec(`
|
|
290
|
-
CREATE TABLE IF NOT EXISTS pibo_cron_jobs (
|
|
291
|
-
id TEXT PRIMARY KEY,
|
|
292
|
-
name TEXT NOT NULL,
|
|
293
|
-
description TEXT,
|
|
294
|
-
enabled INTEGER NOT NULL,
|
|
295
|
-
target_json TEXT NOT NULL,
|
|
296
|
-
profile TEXT NOT NULL,
|
|
297
|
-
prompt TEXT NOT NULL,
|
|
298
|
-
schedule_json TEXT NOT NULL,
|
|
299
|
-
schedule_ui_json TEXT,
|
|
300
|
-
delete_after_run INTEGER NOT NULL DEFAULT 0,
|
|
301
|
-
state_json TEXT NOT NULL,
|
|
302
|
-
created_at TEXT NOT NULL,
|
|
303
|
-
updated_at TEXT NOT NULL
|
|
304
|
-
);
|
|
305
|
-
CREATE INDEX IF NOT EXISTS idx_pibo_cron_jobs_enabled ON pibo_cron_jobs(enabled, updated_at DESC);
|
|
306
|
-
|
|
307
|
-
CREATE TABLE IF NOT EXISTS pibo_cron_runs (
|
|
308
|
-
id TEXT PRIMARY KEY,
|
|
309
|
-
job_id TEXT NOT NULL,
|
|
310
|
-
pibo_session_id TEXT,
|
|
311
|
-
status TEXT NOT NULL,
|
|
312
|
-
reason TEXT,
|
|
313
|
-
error TEXT,
|
|
314
|
-
started_at TEXT,
|
|
315
|
-
completed_at TEXT,
|
|
316
|
-
created_at TEXT NOT NULL,
|
|
317
|
-
updated_at TEXT NOT NULL
|
|
318
|
-
);
|
|
319
|
-
CREATE INDEX IF NOT EXISTS idx_pibo_cron_runs_job_created ON pibo_cron_runs(job_id, created_at DESC);
|
|
289
|
+
this.db.exec(`
|
|
290
|
+
CREATE TABLE IF NOT EXISTS pibo_cron_jobs (
|
|
291
|
+
id TEXT PRIMARY KEY,
|
|
292
|
+
name TEXT NOT NULL,
|
|
293
|
+
description TEXT,
|
|
294
|
+
enabled INTEGER NOT NULL,
|
|
295
|
+
target_json TEXT NOT NULL,
|
|
296
|
+
profile TEXT NOT NULL,
|
|
297
|
+
prompt TEXT NOT NULL,
|
|
298
|
+
schedule_json TEXT NOT NULL,
|
|
299
|
+
schedule_ui_json TEXT,
|
|
300
|
+
delete_after_run INTEGER NOT NULL DEFAULT 0,
|
|
301
|
+
state_json TEXT NOT NULL,
|
|
302
|
+
created_at TEXT NOT NULL,
|
|
303
|
+
updated_at TEXT NOT NULL
|
|
304
|
+
);
|
|
305
|
+
CREATE INDEX IF NOT EXISTS idx_pibo_cron_jobs_enabled ON pibo_cron_jobs(enabled, updated_at DESC);
|
|
306
|
+
|
|
307
|
+
CREATE TABLE IF NOT EXISTS pibo_cron_runs (
|
|
308
|
+
id TEXT PRIMARY KEY,
|
|
309
|
+
job_id TEXT NOT NULL,
|
|
310
|
+
pibo_session_id TEXT,
|
|
311
|
+
status TEXT NOT NULL,
|
|
312
|
+
reason TEXT,
|
|
313
|
+
error TEXT,
|
|
314
|
+
started_at TEXT,
|
|
315
|
+
completed_at TEXT,
|
|
316
|
+
created_at TEXT NOT NULL,
|
|
317
|
+
updated_at TEXT NOT NULL
|
|
318
|
+
);
|
|
319
|
+
CREATE INDEX IF NOT EXISTS idx_pibo_cron_runs_job_created ON pibo_cron_runs(job_id, created_at DESC);
|
|
320
320
|
`);
|
|
321
321
|
}
|
|
322
322
|
insertJob(job) {
|
|
323
|
-
this.db.prepare(`
|
|
324
|
-
INSERT INTO pibo_cron_jobs (id, name, description, enabled, target_json, profile, prompt, schedule_json, schedule_ui_json, delete_after_run, state_json, created_at, updated_at)
|
|
325
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
323
|
+
this.db.prepare(`
|
|
324
|
+
INSERT INTO pibo_cron_jobs (id, name, description, enabled, target_json, profile, prompt, schedule_json, schedule_ui_json, delete_after_run, state_json, created_at, updated_at)
|
|
325
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
326
326
|
`).run(job.id, job.name, job.description ?? null, job.enabled ? 1 : 0, targetJson(job.target), job.profile, job.prompt, JSON.stringify(job.schedule), job.scheduleUi ? JSON.stringify(job.scheduleUi) : null, job.deleteAfterRun ? 1 : 0, JSON.stringify(job.state), job.createdAt, job.updatedAt);
|
|
327
327
|
}
|
|
328
328
|
writeJob(job) {
|
|
329
|
-
this.db.prepare(`
|
|
330
|
-
UPDATE pibo_cron_jobs
|
|
331
|
-
SET name = ?, description = ?, enabled = ?, target_json = ?, profile = ?, prompt = ?, schedule_json = ?, schedule_ui_json = ?, delete_after_run = ?, state_json = ?, updated_at = ?
|
|
332
|
-
WHERE id = ?
|
|
329
|
+
this.db.prepare(`
|
|
330
|
+
UPDATE pibo_cron_jobs
|
|
331
|
+
SET name = ?, description = ?, enabled = ?, target_json = ?, profile = ?, prompt = ?, schedule_json = ?, schedule_ui_json = ?, delete_after_run = ?, state_json = ?, updated_at = ?
|
|
332
|
+
WHERE id = ?
|
|
333
333
|
`).run(job.name, job.description ?? null, job.enabled ? 1 : 0, targetJson(job.target), job.profile, job.prompt, JSON.stringify(job.schedule), job.scheduleUi ? JSON.stringify(job.scheduleUi) : null, job.deleteAfterRun ? 1 : 0, JSON.stringify(job.state), job.updatedAt, job.id);
|
|
334
334
|
}
|
|
335
335
|
updateJobStateLocked(id, state, updatedAt) {
|
|
@@ -337,9 +337,9 @@ export class PiboCronStore {
|
|
|
337
337
|
}
|
|
338
338
|
createRunLocked(job, timestamp, status, reason) {
|
|
339
339
|
const run = { id: `crun_${randomUUID()}`, jobId: job.id, status, reason, startedAt: timestamp, createdAt: timestamp, updatedAt: timestamp };
|
|
340
|
-
this.db.prepare(`
|
|
341
|
-
INSERT INTO pibo_cron_runs (id, job_id, pibo_session_id, status, reason, error, started_at, completed_at, created_at, updated_at)
|
|
342
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
340
|
+
this.db.prepare(`
|
|
341
|
+
INSERT INTO pibo_cron_runs (id, job_id, pibo_session_id, status, reason, error, started_at, completed_at, created_at, updated_at)
|
|
342
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
343
343
|
`).run(run.id, run.jobId, null, run.status, run.reason ?? null, null, run.startedAt ?? null, null, run.createdAt, run.updatedAt);
|
|
344
344
|
return run;
|
|
345
345
|
}
|
package/dist/data/cli.js
CHANGED
|
@@ -102,19 +102,19 @@ function migrateSessionsToV2(input) {
|
|
|
102
102
|
"channel", "kind", "profile", "active_model_json", "workspace", "title", "status",
|
|
103
103
|
"metadata_json", "created_at", "updated_at", "last_activity_at",
|
|
104
104
|
];
|
|
105
|
-
target.db.prepare(`
|
|
106
|
-
INSERT INTO sessions (${columns.join(", ")})
|
|
107
|
-
VALUES (${columns.map(() => "?").join(", ")})
|
|
105
|
+
target.db.prepare(`
|
|
106
|
+
INSERT INTO sessions (${columns.join(", ")})
|
|
107
|
+
VALUES (${columns.map(() => "?").join(", ")})
|
|
108
108
|
`).run(row.id, row.pi_session_id, typeof metadata.chatRoomId === "string" ? metadata.chatRoomId : null, rootSessionId, row.parent_id, row.origin_id, row.channel, row.kind, row.profile, row.active_model_json, row.workspace, row.title ?? "Untitled Session", "idle", JSON.stringify(metadata), row.created_at, row.updated_at, row.updated_at);
|
|
109
109
|
report.inserted++;
|
|
110
110
|
}
|
|
111
111
|
else if (row.updated_at > existing.updated_at) {
|
|
112
|
-
target.db.prepare(`
|
|
113
|
-
UPDATE sessions SET
|
|
114
|
-
pi_session_id = ?, root_session_id = ?, parent_id = ?, origin_id = ?,
|
|
115
|
-
channel = ?, kind = ?, profile = ?, active_model_json = ?, workspace = ?, title = ?,
|
|
116
|
-
metadata_json = ?, updated_at = ?, last_activity_at = MAX(last_activity_at, ?)
|
|
117
|
-
WHERE id = ?
|
|
112
|
+
target.db.prepare(`
|
|
113
|
+
UPDATE sessions SET
|
|
114
|
+
pi_session_id = ?, root_session_id = ?, parent_id = ?, origin_id = ?,
|
|
115
|
+
channel = ?, kind = ?, profile = ?, active_model_json = ?, workspace = ?, title = ?,
|
|
116
|
+
metadata_json = ?, updated_at = ?, last_activity_at = MAX(last_activity_at, ?)
|
|
117
|
+
WHERE id = ?
|
|
118
118
|
`).run(row.pi_session_id, rootSessionId, row.parent_id, row.origin_id, row.channel, row.kind, row.profile, row.active_model_json, row.workspace, row.title ?? "Untitled Session", JSON.stringify(metadata), row.updated_at, row.updated_at, row.id);
|
|
119
119
|
report.updated++;
|
|
120
120
|
}
|
|
@@ -166,19 +166,19 @@ function printInventory(stores) {
|
|
|
166
166
|
}
|
|
167
167
|
}
|
|
168
168
|
function printDataHelp() {
|
|
169
|
-
console.log(`pibo data - inspect and maintain Pibo data stores
|
|
170
|
-
|
|
171
|
-
Commands:
|
|
172
|
-
inventory Read-only row counts, sizes, WAL sizes, and integrity checks; legacy-* rows are archived stores
|
|
173
|
-
migrate sessions-to-v2 Import an explicit legacy pibo-sessions.sqlite into pibo.sqlite idempotently
|
|
174
|
-
|
|
175
|
-
Options:
|
|
176
|
-
--json Print machine-readable JSON
|
|
177
|
-
--root DIR Inspect a specific Pibo home directory instead of ~/.pibo
|
|
178
|
-
--to FILE Target pibo.sqlite path for migration or repair
|
|
179
|
-
|
|
180
|
-
Next:
|
|
181
|
-
pibo data inventory --json
|
|
182
|
-
pibo data migrate sessions-to-v2 --from /path/to/pibo-sessions.sqlite --json
|
|
169
|
+
console.log(`pibo data - inspect and maintain Pibo data stores
|
|
170
|
+
|
|
171
|
+
Commands:
|
|
172
|
+
inventory Read-only row counts, sizes, WAL sizes, and integrity checks; legacy-* rows are archived stores
|
|
173
|
+
migrate sessions-to-v2 Import an explicit legacy pibo-sessions.sqlite into pibo.sqlite idempotently
|
|
174
|
+
|
|
175
|
+
Options:
|
|
176
|
+
--json Print machine-readable JSON
|
|
177
|
+
--root DIR Inspect a specific Pibo home directory instead of ~/.pibo
|
|
178
|
+
--to FILE Target pibo.sqlite path for migration or repair
|
|
179
|
+
|
|
180
|
+
Next:
|
|
181
|
+
pibo data inventory --json
|
|
182
|
+
pibo data migrate sessions-to-v2 --from /path/to/pibo-sessions.sqlite --json
|
|
183
183
|
`);
|
|
184
184
|
}
|
package/dist/data/event-log.js
CHANGED
|
@@ -12,29 +12,29 @@ export class PiboEventLogStore {
|
|
|
12
12
|
}
|
|
13
13
|
const createdAt = input.createdAt ?? new Date().toISOString();
|
|
14
14
|
const eventId = input.eventId ?? `evt_${randomUUID()}`;
|
|
15
|
-
const result = this.db.prepare(`
|
|
16
|
-
INSERT OR IGNORE INTO event_log (
|
|
17
|
-
session_id,
|
|
18
|
-
session_sequence,
|
|
19
|
-
room_id,
|
|
20
|
-
topic,
|
|
21
|
-
type,
|
|
22
|
-
source,
|
|
23
|
-
actor_type,
|
|
24
|
-
actor_id,
|
|
25
|
-
turn_id,
|
|
26
|
-
event_id,
|
|
27
|
-
tool_call_id,
|
|
28
|
-
run_id,
|
|
29
|
-
workflow_run_id,
|
|
30
|
-
idempotency_key,
|
|
31
|
-
retention_class,
|
|
32
|
-
payload_ref,
|
|
33
|
-
preview_text,
|
|
34
|
-
attributes_json,
|
|
35
|
-
created_at,
|
|
36
|
-
indexed_at
|
|
37
|
-
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
15
|
+
const result = this.db.prepare(`
|
|
16
|
+
INSERT OR IGNORE INTO event_log (
|
|
17
|
+
session_id,
|
|
18
|
+
session_sequence,
|
|
19
|
+
room_id,
|
|
20
|
+
topic,
|
|
21
|
+
type,
|
|
22
|
+
source,
|
|
23
|
+
actor_type,
|
|
24
|
+
actor_id,
|
|
25
|
+
turn_id,
|
|
26
|
+
event_id,
|
|
27
|
+
tool_call_id,
|
|
28
|
+
run_id,
|
|
29
|
+
workflow_run_id,
|
|
30
|
+
idempotency_key,
|
|
31
|
+
retention_class,
|
|
32
|
+
payload_ref,
|
|
33
|
+
preview_text,
|
|
34
|
+
attributes_json,
|
|
35
|
+
created_at,
|
|
36
|
+
indexed_at
|
|
37
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
38
38
|
`).run(input.sessionId ?? null, input.sessionSequence ?? null, input.roomId ?? null, input.topic, input.type, input.source, input.actorType ?? null, input.actorId ?? null, input.turnId ?? null, eventId, input.toolCallId ?? null, input.runId ?? null, input.workflowRunId ?? null, input.idempotencyKey ?? null, input.retentionClass, input.payloadRef ?? null, input.previewText ?? null, JSON.stringify(input.attributes ?? {}), createdAt, input.indexedAt ?? null);
|
|
39
39
|
if (input.idempotencyKey) {
|
|
40
40
|
const existing = this.findByIdempotencyKey(input.idempotencyKey);
|
|
@@ -303,7 +303,7 @@ function payloadForOutputEvent(event) {
|
|
|
303
303
|
function previewTextForOutputEvent(event) {
|
|
304
304
|
if (event.type === "assistant_message" || event.type === "assistant_delta" || event.type === "thinking_delta" || event.type === "thinking_finished")
|
|
305
305
|
return previewText(event.text ?? "");
|
|
306
|
-
if (event.type === "message_queued" || event.type === "message_started")
|
|
306
|
+
if (event.type === "message_queued" || event.type === "message_steered" || event.type === "message_started")
|
|
307
307
|
return previewText(event.text);
|
|
308
308
|
if (event.type === "tool_call" || event.type === "tool_execution_started" || event.type === "tool_execution_updated" || event.type === "tool_execution_finished")
|
|
309
309
|
return event.toolName;
|
|
@@ -320,6 +320,8 @@ function previewTextForOutputEvent(event) {
|
|
|
320
320
|
function attributesForOutputEvent(event) {
|
|
321
321
|
if (event.type === "message_queued")
|
|
322
322
|
return { inlineText: event.text, source: event.source, queuedMessages: event.queuedMessages };
|
|
323
|
+
if (event.type === "message_steered")
|
|
324
|
+
return { inlineText: event.text, source: event.source, activeEventId: event.activeEventId };
|
|
323
325
|
if (event.type === "assistant_message" || event.type === "assistant_delta")
|
|
324
326
|
return { assistantIndex: event.assistantIndex, contentIndex: event.contentIndex };
|
|
325
327
|
if (event.type === "thinking_started" || event.type === "thinking_delta" || event.type === "thinking_finished")
|