@xopcai/xopc 0.0.87 → 0.0.89
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 +8 -1
- package/README.zh-CN.md +8 -1
- package/dist/browser-ext/manifest.json +1 -1
- package/dist/extensions/telegram/xopc.extension.json +1 -1
- package/dist/gateway/static/root/assets/agents-B6PJB07W.js +222 -0
- package/dist/gateway/static/root/assets/apps-page-BOr0B1wv.js +1 -0
- package/dist/gateway/static/root/assets/channels-settings-BelUKggl.js +1 -0
- package/dist/gateway/static/root/assets/{channels-status-swr-BSHqqCF1.js → channels-status-swr-DaHGkRF1.js} +1 -1
- package/dist/gateway/static/root/assets/cron-api-CjOg-BIj.js +1 -0
- package/dist/gateway/static/root/assets/cron-page-DhoZmZXb.js +1 -0
- package/dist/gateway/static/root/assets/{dist-Cmjp2APP.js → dist-6LecgDx5.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-debug-page-CFa9z_1N.js → extension-debug-page-CtuKJ9tE.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-BI8eaTPq.js → extension-page-ykzjOkR5.js} +1 -1
- package/dist/gateway/static/root/assets/extension-settings-page-Ce2qrdpO.js +1 -0
- package/dist/gateway/static/root/assets/{fetch-DRqwef_Q.js → fetch-C9FFJjuH.js} +1 -1
- package/dist/gateway/static/root/assets/{field-primitives-BiNHBo2Y.js → field-primitives-BFcrNeTU.js} +1 -1
- package/dist/gateway/static/root/assets/{heartbeat-config-api-ZRb8qhuz.js → heartbeat-config-api-CEg4Vr9R.js} +1 -1
- package/dist/gateway/static/root/assets/{index-Cu7bKuUi.js → index-CZfy9oxs.js} +85 -85
- package/dist/gateway/static/root/assets/index-CiN1cQiQ.css +1 -0
- package/dist/gateway/static/root/assets/logs-page-BwWLfqvd.js +1 -0
- package/dist/gateway/static/root/assets/sessions-page-DV5WN8uk.js +1 -0
- package/dist/gateway/static/root/assets/{settings-form-section-DiqqVs6m.js → settings-form-section-BqdzA28u.js} +1 -1
- package/dist/gateway/static/root/assets/settings-page-CfOBRbPX.js +3 -0
- package/dist/gateway/static/root/assets/{share-preview-page-n1Gprylk.js → share-preview-page-Di5Bzh4g.js} +1 -1
- package/dist/gateway/static/root/assets/skills-page-D0H5Kaxg.js +2 -0
- package/dist/gateway/static/root/assets/{theme-store-CZOh1nT3.js → theme-store-CNqbmTNV.js} +1 -1
- package/dist/gateway/static/root/assets/url-aYn-Rj1C.js +7 -0
- package/dist/gateway/static/root/assets/{utils-CkWBfxs4.js → utils-BWm2tG2w.js} +1 -1
- package/dist/gateway/static/root/assets/voice-api-key-field-X2UfnHeq.js +1 -0
- package/dist/gateway/static/root/assets/workflows-page-BOPpO3NG.js +27 -0
- package/dist/gateway/static/root/index.html +5 -5
- package/dist/package.js +1 -1
- package/dist/src/agent/agent-manager.d.ts +2 -0
- package/dist/src/agent/agent-manager.js +1 -0
- package/dist/src/agent/agent-manager.js.map +1 -1
- package/dist/src/agent/child-agent-factory.d.ts +15 -0
- package/dist/src/agent/child-agent-factory.js +35 -2
- package/dist/src/agent/child-agent-factory.js.map +1 -1
- package/dist/src/agent/client-error-format.d.ts +20 -0
- package/dist/src/agent/client-error-format.js +97 -0
- package/dist/src/agent/client-error-format.js.map +1 -0
- package/dist/src/agent/embedded/run-turn.js +23 -4
- package/dist/src/agent/embedded/run-turn.js.map +1 -1
- package/dist/src/agent/goals/goal-locale.d.ts +1 -1
- package/dist/src/agent/inbound/turn-dispatcher.js +1 -1
- package/dist/src/agent/inbound/turn-dispatcher.js.map +1 -1
- package/dist/src/agent/orchestration/llm-turn-retry.d.ts +2 -0
- package/dist/src/agent/orchestration/llm-turn-retry.js +9 -1
- package/dist/src/agent/orchestration/llm-turn-retry.js.map +1 -1
- package/dist/src/agent/service/process-direct-streaming.js +19 -3
- package/dist/src/agent/service/process-direct-streaming.js.map +1 -1
- package/dist/src/agent/service/webchat-tts.d.ts +1 -2
- package/dist/src/agent/service/webchat-tts.js +1 -1
- package/dist/src/agent/service/webchat-tts.js.map +1 -1
- package/dist/src/agent/service.js +2 -1
- package/dist/src/agent/service.js.map +1 -1
- package/dist/src/agent/service.types.d.ts +3 -1
- package/dist/src/agent/tools/cronjob-tool.js +2 -1
- package/dist/src/agent/tools/cronjob-tool.js.map +1 -1
- package/dist/src/agent/tools/factory.d.ts +3 -0
- package/dist/src/agent/tools/factory.js +2 -23
- package/dist/src/agent/tools/factory.js.map +1 -1
- package/dist/src/agent/tools/workflow-tool.d.ts +6 -28
- package/dist/src/agent/tools/workflow-tool.js +61 -213
- package/dist/src/agent/tools/workflow-tool.js.map +1 -1
- package/dist/src/agent/workflow/agent-progress.d.ts +5 -0
- package/dist/src/agent/workflow/agent-progress.js +65 -0
- package/dist/src/agent/workflow/agent-progress.js.map +1 -0
- package/dist/src/agent/workflow/builtins/audit-repo.d.ts +1 -1
- package/dist/src/agent/workflow/builtins/audit-repo.js +14 -0
- package/dist/src/agent/workflow/builtins/audit-repo.js.map +1 -1
- package/dist/src/agent/workflow/builtins/debug-incident.d.ts +1 -1
- package/dist/src/agent/workflow/builtins/debug-incident.js +14 -0
- package/dist/src/agent/workflow/builtins/debug-incident.js.map +1 -1
- package/dist/src/agent/workflow/builtins/implementation-plan.d.ts +12 -0
- package/dist/src/agent/workflow/builtins/implementation-plan.js +175 -0
- package/dist/src/agent/workflow/builtins/implementation-plan.js.map +1 -0
- package/dist/src/agent/workflow/builtins/index.d.ts +3 -1
- package/dist/src/agent/workflow/builtins/index.js +11 -1
- package/dist/src/agent/workflow/builtins/index.js.map +1 -1
- package/dist/src/agent/workflow/builtins/multi-perspective-review.d.ts +1 -1
- package/dist/src/agent/workflow/builtins/multi-perspective-review.js +14 -0
- package/dist/src/agent/workflow/builtins/multi-perspective-review.js.map +1 -1
- package/dist/src/agent/workflow/builtins/pr-review.d.ts +1 -1
- package/dist/src/agent/workflow/builtins/pr-review.js +14 -0
- package/dist/src/agent/workflow/builtins/pr-review.js.map +1 -1
- package/dist/src/agent/workflow/builtins/release-check.d.ts +11 -0
- package/dist/src/agent/workflow/builtins/release-check.js +165 -0
- package/dist/src/agent/workflow/builtins/release-check.js.map +1 -0
- package/dist/src/agent/workflow/builtins/research.d.ts +1 -1
- package/dist/src/agent/workflow/builtins/research.js +14 -0
- package/dist/src/agent/workflow/builtins/research.js.map +1 -1
- package/dist/src/agent/workflow/index.d.ts +2 -1
- package/dist/src/agent/workflow/index.js +3 -2
- package/dist/src/agent/workflow/meta-locale.d.ts +12 -0
- package/dist/src/agent/workflow/meta-locale.js +62 -0
- package/dist/src/agent/workflow/meta-locale.js.map +1 -0
- package/dist/src/agent/workflow/parser.js +3 -0
- package/dist/src/agent/workflow/parser.js.map +1 -1
- package/dist/src/agent/workflow/runtime.d.ts +2 -2
- package/dist/src/agent/workflow/runtime.js +21 -14
- package/dist/src/agent/workflow/runtime.js.map +1 -1
- package/dist/src/agent/workflow/snapshot.js +2 -12
- package/dist/src/agent/workflow/snapshot.js.map +1 -1
- package/dist/src/agent/workflow/step-labels.d.ts +8 -0
- package/dist/src/agent/workflow/step-labels.js +48 -0
- package/dist/src/agent/workflow/step-labels.js.map +1 -0
- package/dist/src/agent/workflow/subagent-runner.js +46 -1
- package/dist/src/agent/workflow/subagent-runner.js.map +1 -1
- package/dist/src/agent/workflow/types.d.ts +74 -1
- package/dist/src/agent/workflow/workflow-child-tools.d.ts +4 -0
- package/dist/src/agent/workflow/workflow-child-tools.js +21 -0
- package/dist/src/agent/workflow/workflow-child-tools.js.map +1 -0
- package/dist/src/auth/credentials.d.ts +19 -2
- package/dist/src/auth/credentials.js +47 -13
- package/dist/src/auth/credentials.js.map +1 -1
- package/dist/src/auth/oauth/types.d.ts +16 -0
- package/dist/src/cli/commands/auth.js +6 -0
- package/dist/src/cli/commands/auth.js.map +1 -1
- package/dist/src/cli/commands/gateway/lifecycle.js +1 -1
- package/dist/src/cli/commands/onboard/model.js +6 -0
- package/dist/src/cli/commands/onboard/model.js.map +1 -1
- package/dist/src/config/agent-typed-models.d.ts +18 -0
- package/dist/src/config/agent-typed-models.js +53 -0
- package/dist/src/config/agent-typed-models.js.map +1 -0
- package/dist/src/config/index.js +2 -2
- package/dist/src/config/schema.d.ts +52 -0
- package/dist/src/config/schema.js +39 -3
- package/dist/src/config/schema.js.map +1 -1
- package/dist/src/config/voice.d.ts +3 -28
- package/dist/src/config/voice.js +27 -261
- package/dist/src/config/voice.js.map +1 -1
- package/dist/src/cron/executor.d.ts +2 -0
- package/dist/src/cron/executor.js +59 -5
- package/dist/src/cron/executor.js.map +1 -1
- package/dist/src/cron/job-content.js +2 -1
- package/dist/src/cron/job-content.js.map +1 -1
- package/dist/src/cron/types.d.ts +21 -1
- package/dist/src/cron/validation.d.ts +76 -0
- package/dist/src/cron/validation.js +26 -1
- package/dist/src/cron/validation.js.map +1 -1
- package/dist/src/gateway/agents-admin.d.ts +9 -0
- package/dist/src/gateway/agents-admin.js +16 -0
- package/dist/src/gateway/agents-admin.js.map +1 -1
- package/dist/src/gateway/config-tools-web.js +3 -2
- package/dist/src/gateway/config-tools-web.js.map +1 -1
- package/dist/src/gateway/gateway-workflow-host.types.d.ts +17 -0
- package/dist/src/gateway/gateway-workflow-host.types.js +1 -0
- package/dist/src/gateway/hono/lib/agent-model.d.ts +7 -0
- package/dist/src/gateway/hono/lib/agent-model.js +36 -1
- package/dist/src/gateway/hono/lib/agent-model.js.map +1 -1
- package/dist/src/gateway/hono/lib/config-payload.js +28 -5
- package/dist/src/gateway/hono/lib/config-payload.js.map +1 -1
- package/dist/src/gateway/hono/lib/mask-secret-length.d.ts +6 -0
- package/dist/src/gateway/hono/lib/mask-secret-length.js +16 -0
- package/dist/src/gateway/hono/lib/mask-secret-length.js.map +1 -0
- package/dist/src/gateway/hono/lib/safe-providers-config.d.ts +1 -1
- package/dist/src/gateway/hono/lib/safe-providers-config.js +2 -1
- package/dist/src/gateway/hono/lib/safe-providers-config.js.map +1 -1
- package/dist/src/gateway/hono/lib/safe-voice-config.js +2 -1
- package/dist/src/gateway/hono/lib/safe-voice-config.js.map +1 -1
- package/dist/src/gateway/hono/oauth-async.js +40 -15
- package/dist/src/gateway/hono/oauth-async.js.map +1 -1
- package/dist/src/gateway/hono/oauth.js +31 -6
- package/dist/src/gateway/hono/oauth.js.map +1 -1
- package/dist/src/gateway/hono/routes/agents.js +1 -1
- package/dist/src/gateway/hono/routes/config-patch/agents.js +8 -2
- package/dist/src/gateway/hono/routes/config-patch/agents.js.map +1 -1
- package/dist/src/gateway/hono/routes/config-patch/gateway.js +3 -2
- package/dist/src/gateway/hono/routes/config-patch/gateway.js.map +1 -1
- package/dist/src/gateway/hono/routes/config-patch/misc.js +7 -2
- package/dist/src/gateway/hono/routes/config-patch/misc.js.map +1 -1
- package/dist/src/gateway/hono/routes/config.js +59 -0
- package/dist/src/gateway/hono/routes/config.js.map +1 -1
- package/dist/src/gateway/hono/routes/lazy-bundles.js +8 -0
- package/dist/src/gateway/hono/routes/lazy-bundles.js.map +1 -1
- package/dist/src/gateway/hono/routes/models.js +84 -15
- package/dist/src/gateway/hono/routes/models.js.map +1 -1
- package/dist/src/gateway/hono/routes/voice.js +75 -0
- package/dist/src/gateway/hono/routes/voice.js.map +1 -1
- package/dist/src/gateway/hono/routes/workflows.d.ts +3 -0
- package/dist/src/gateway/hono/routes/workflows.js +226 -0
- package/dist/src/gateway/hono/routes/workflows.js.map +1 -0
- package/dist/src/gateway/service/run-gateway-agent.js +2 -20
- package/dist/src/gateway/service/run-gateway-agent.js.map +1 -1
- package/dist/src/gateway/service.d.ts +8 -0
- package/dist/src/gateway/service.js +28 -2
- package/dist/src/gateway/service.js.map +1 -1
- package/dist/src/mcp/channel-bridge.js +1 -1
- package/dist/src/providers/index.d.ts +8 -0
- package/dist/src/providers/index.js +51 -12
- package/dist/src/providers/index.js.map +1 -1
- package/dist/src/share/site-share-config.d.ts +3 -2
- package/dist/src/share/site-share-config.js.map +1 -1
- package/dist/src/tui/tui-agent-events.js +2 -1
- package/dist/src/tui/tui-agent-events.js.map +1 -1
- package/dist/src/voice/metadata/builtin.d.ts +2 -0
- package/dist/src/voice/metadata/builtin.js +420 -0
- package/dist/src/voice/metadata/builtin.js.map +1 -0
- package/dist/src/voice/metadata/index.d.ts +4 -0
- package/dist/src/voice/metadata/index.js +3 -0
- package/dist/src/voice/metadata/registry.d.ts +5 -0
- package/dist/src/voice/metadata/registry.js +34 -0
- package/dist/src/voice/metadata/registry.js.map +1 -0
- package/dist/src/voice/metadata/types.d.ts +41 -0
- package/dist/src/voice/metadata/types.js +1 -0
- package/dist/src/voice/stt/list-providers.d.ts +3 -3
- package/dist/src/voice/stt/list-providers.js +41 -6
- package/dist/src/voice/stt/list-providers.js.map +1 -1
- package/dist/src/voice/tts/list-providers.d.ts +3 -3
- package/dist/src/voice/tts/list-providers.js +41 -6
- package/dist/src/voice/tts/list-providers.js.map +1 -1
- package/dist/src/workflows/domain/command.d.ts +19 -0
- package/dist/src/workflows/domain/command.js +1 -0
- package/dist/src/workflows/domain/definition-utils.d.ts +14 -0
- package/dist/src/workflows/domain/definition-utils.js +50 -0
- package/dist/src/workflows/domain/definition-utils.js.map +1 -0
- package/dist/src/workflows/domain/definition.d.ts +62 -0
- package/dist/src/workflows/domain/definition.js +1 -0
- package/dist/src/workflows/domain/event.d.ts +67 -0
- package/dist/src/workflows/domain/event.js +1 -0
- package/dist/src/workflows/domain/index.d.ts +7 -0
- package/dist/src/workflows/domain/index.js +4 -0
- package/dist/src/workflows/domain/result.d.ts +65 -0
- package/dist/src/workflows/domain/result.js +1 -0
- package/dist/src/workflows/domain/run.d.ts +177 -0
- package/dist/src/workflows/domain/run.js +14 -0
- package/dist/src/workflows/domain/run.js.map +1 -0
- package/dist/src/workflows/domain/validation.d.ts +19 -0
- package/dist/src/workflows/domain/validation.js +66 -0
- package/dist/src/workflows/domain/validation.js.map +1 -0
- package/dist/src/workflows/engine/index.d.ts +2 -0
- package/dist/src/workflows/engine/index.js +3 -0
- package/dist/src/workflows/engine/projector.d.ts +3 -0
- package/dist/src/workflows/engine/projector.js +205 -0
- package/dist/src/workflows/engine/projector.js.map +1 -0
- package/dist/src/workflows/engine/workflow-engine.d.ts +32 -0
- package/dist/src/workflows/engine/workflow-engine.js +189 -0
- package/dist/src/workflows/engine/workflow-engine.js.map +1 -0
- package/dist/src/workflows/index.d.ts +10 -0
- package/dist/src/workflows/index.js +18 -0
- package/dist/src/workflows/runtime/index.d.ts +1 -0
- package/dist/src/workflows/runtime/index.js +4 -0
- package/dist/src/workflows/runtime/script-runtime.d.ts +3 -0
- package/dist/src/workflows/runtime/script-runtime.js +3 -0
- package/dist/src/workflows/service/run-view-to-snapshot.d.ts +4 -0
- package/dist/src/workflows/service/run-view-to-snapshot.js +61 -0
- package/dist/src/workflows/service/run-view-to-snapshot.js.map +1 -0
- package/dist/src/workflows/service/workflow-run-service.d.ts +36 -0
- package/dist/src/workflows/service/workflow-run-service.js +279 -0
- package/dist/src/workflows/service/workflow-run-service.js.map +1 -0
- package/dist/src/workflows/service/workflow-run-service.types.d.ts +47 -0
- package/dist/src/workflows/service/workflow-run-service.types.js +1 -0
- package/dist/src/workflows/service/workflow-session-bridge.d.ts +29 -0
- package/dist/src/workflows/service/workflow-session-bridge.js +177 -0
- package/dist/src/workflows/service/workflow-session-bridge.js.map +1 -0
- package/dist/src/workflows/service/workflow-session-key.d.ts +3 -0
- package/dist/src/workflows/service/workflow-session-key.js +21 -0
- package/dist/src/workflows/service/workflow-session-key.js.map +1 -0
- package/dist/src/workflows/store/event-store.d.ts +17 -0
- package/dist/src/workflows/store/event-store.js +83 -0
- package/dist/src/workflows/store/event-store.js.map +1 -0
- package/dist/src/workflows/store/paths.d.ts +7 -0
- package/dist/src/workflows/store/paths.js +26 -0
- package/dist/src/workflows/store/paths.js.map +1 -0
- package/dist/src/workflows/store/run-store.d.ts +13 -0
- package/dist/src/workflows/store/run-store.js +69 -0
- package/dist/src/workflows/store/run-store.js.map +1 -0
- package/package.json +5 -5
- package/dist/gateway/static/root/assets/agents-BEAbXpuP.js +0 -222
- package/dist/gateway/static/root/assets/apps-page-Dg8R-Szf.js +0 -1
- package/dist/gateway/static/root/assets/channels-settings-yohw9YSu.js +0 -1
- package/dist/gateway/static/root/assets/cron-api-0h_QT8U3.js +0 -1
- package/dist/gateway/static/root/assets/cron-page-BkfKFfFk.js +0 -1
- package/dist/gateway/static/root/assets/extension-settings-page-x4BB7q1X.js +0 -1
- package/dist/gateway/static/root/assets/index-a5gWIdZQ.css +0 -1
- package/dist/gateway/static/root/assets/logs-page-BFZ8GgCv.js +0 -1
- package/dist/gateway/static/root/assets/sessions-page-CD7AfB-2.js +0 -1
- package/dist/gateway/static/root/assets/settings-page-BBOjEQW3.js +0 -3
- package/dist/gateway/static/root/assets/skills-page-CcN_gj--.js +0 -2
- package/dist/gateway/static/root/assets/url-Dd8Q7kZZ.js +0 -3
- package/dist/gateway/static/root/assets/voice-api-key-field-O6awz9hi.js +0 -1
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import { appendPiTranscriptContextEntry, appendPiTranscriptMessage } from "../../session/parity/jsonl-transcript-io.js";
|
|
2
|
+
import { renderWorkflowText } from "../../agent/workflow/snapshot.js";
|
|
3
|
+
import "../../session/types.js";
|
|
4
|
+
import { isTerminalWorkflowRunStatus } from "../domain/run.js";
|
|
5
|
+
import "../domain/index.js";
|
|
6
|
+
import { runViewToSnapshot } from "./run-view-to-snapshot.js";
|
|
7
|
+
import { buildWorkflowRunSessionKey } from "./workflow-session-key.js";
|
|
8
|
+
import { randomUUID } from "node:crypto";
|
|
9
|
+
//#region src/workflows/service/workflow-session-bridge.ts
|
|
10
|
+
const WORKFLOW_SESSION_TYPE = "workflow";
|
|
11
|
+
const WORKFLOW_RUN_LINK_CONTEXT_KIND = "workflow-run-link";
|
|
12
|
+
var WorkflowSessionBridge = class {
|
|
13
|
+
terminalPersistedRunIds = /* @__PURE__ */ new Set();
|
|
14
|
+
constructor(gateway) {
|
|
15
|
+
this.gateway = gateway;
|
|
16
|
+
}
|
|
17
|
+
async prepareRunSession(params) {
|
|
18
|
+
const sessionKey = buildWorkflowRunSessionKey(params.agentId, params.runId);
|
|
19
|
+
const goalText = formatWorkflowGoalUserMessage(params.definitionId, params.goal);
|
|
20
|
+
const sessionName = truncateSessionName(params.goal.trim() || params.definitionTitle || params.definitionId);
|
|
21
|
+
const store = this.gateway.sessionIndexInstance.getStore();
|
|
22
|
+
await store.resolveTranscriptPath(sessionKey);
|
|
23
|
+
await store.updateMetadata(sessionKey, {
|
|
24
|
+
sessionType: WORKFLOW_SESSION_TYPE,
|
|
25
|
+
name: sessionName,
|
|
26
|
+
tags: ["workflow", params.definitionId],
|
|
27
|
+
customData: {
|
|
28
|
+
workflowRunId: params.runId,
|
|
29
|
+
workflowDefinitionId: params.definitionId,
|
|
30
|
+
workflowGoal: params.goal,
|
|
31
|
+
...params.parentSessionKey ? { parentSessionKey: params.parentSessionKey } : {}
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
const { absPath } = await store.resolveTranscriptPath(sessionKey);
|
|
35
|
+
await appendPiTranscriptMessage({
|
|
36
|
+
absPath,
|
|
37
|
+
cwd: process.cwd(),
|
|
38
|
+
sessionKey,
|
|
39
|
+
message: {
|
|
40
|
+
role: "user",
|
|
41
|
+
content: [{
|
|
42
|
+
type: "text",
|
|
43
|
+
text: goalText
|
|
44
|
+
}],
|
|
45
|
+
timestamp: Date.now()
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
if (params.parentSessionKey?.trim()) await this.writeParentRunLink({
|
|
49
|
+
parentSessionKey: params.parentSessionKey.trim(),
|
|
50
|
+
runId: params.runId,
|
|
51
|
+
workflowSessionKey: sessionKey,
|
|
52
|
+
definitionId: params.definitionId,
|
|
53
|
+
goal: params.goal,
|
|
54
|
+
status: "running"
|
|
55
|
+
});
|
|
56
|
+
this.gateway.emit("session.updated", {
|
|
57
|
+
key: sessionKey,
|
|
58
|
+
name: sessionName
|
|
59
|
+
});
|
|
60
|
+
return { sessionKey };
|
|
61
|
+
}
|
|
62
|
+
async handleRunViewUpdated(view) {
|
|
63
|
+
const runId = view.run.id;
|
|
64
|
+
const sessionKey = view.run.metadata?.sessionKey?.trim();
|
|
65
|
+
if (!sessionKey || !isTerminalWorkflowRunStatus(view.run.status)) return;
|
|
66
|
+
if (this.terminalPersistedRunIds.has(runId)) return;
|
|
67
|
+
this.terminalPersistedRunIds.add(runId);
|
|
68
|
+
await this.persistTerminalTranscript(sessionKey, view);
|
|
69
|
+
const parentSessionKey = readParentSessionKey(view);
|
|
70
|
+
if (parentSessionKey) await this.writeParentRunLink({
|
|
71
|
+
parentSessionKey,
|
|
72
|
+
runId,
|
|
73
|
+
workflowSessionKey: sessionKey,
|
|
74
|
+
definitionId: view.run.definitionId,
|
|
75
|
+
goal: view.run.goal,
|
|
76
|
+
status: view.run.status
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
async persistTerminalTranscript(sessionKey, view) {
|
|
80
|
+
const store = this.gateway.sessionIndexInstance.getStore();
|
|
81
|
+
const { absPath } = await store.resolveTranscriptPath(sessionKey);
|
|
82
|
+
const snapshot = runViewToSnapshot(view);
|
|
83
|
+
const toolCallId = randomUUID();
|
|
84
|
+
const envelope = {
|
|
85
|
+
content: [{
|
|
86
|
+
type: "text",
|
|
87
|
+
text: renderWorkflowText(snapshot, view.run.status === "succeeded", { showResultPreviews: true })
|
|
88
|
+
}],
|
|
89
|
+
details: snapshot
|
|
90
|
+
};
|
|
91
|
+
const isError = view.run.status === "failed" || view.run.status === "timeout";
|
|
92
|
+
await appendPiTranscriptMessage({
|
|
93
|
+
absPath,
|
|
94
|
+
cwd: process.cwd(),
|
|
95
|
+
sessionKey,
|
|
96
|
+
message: {
|
|
97
|
+
role: "assistant",
|
|
98
|
+
content: [{
|
|
99
|
+
type: "toolCall",
|
|
100
|
+
id: toolCallId,
|
|
101
|
+
name: "workflow",
|
|
102
|
+
arguments: { name: view.run.definitionId }
|
|
103
|
+
}],
|
|
104
|
+
timestamp: Date.now()
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
await appendPiTranscriptMessage({
|
|
108
|
+
absPath,
|
|
109
|
+
cwd: process.cwd(),
|
|
110
|
+
sessionKey,
|
|
111
|
+
message: {
|
|
112
|
+
role: "toolResult",
|
|
113
|
+
toolCallId,
|
|
114
|
+
content: [{
|
|
115
|
+
type: "text",
|
|
116
|
+
text: JSON.stringify(envelope)
|
|
117
|
+
}],
|
|
118
|
+
details: snapshot,
|
|
119
|
+
isError,
|
|
120
|
+
timestamp: Date.now()
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
await store.updateMetadata(sessionKey, { status: "active" });
|
|
124
|
+
}
|
|
125
|
+
async writeParentRunLink(params) {
|
|
126
|
+
const { absPath } = await this.gateway.sessionIndexInstance.getStore().resolveTranscriptPath(params.parentSessionKey);
|
|
127
|
+
const text = formatParentRunLinkText(params);
|
|
128
|
+
await appendPiTranscriptContextEntry({
|
|
129
|
+
absPath,
|
|
130
|
+
cwd: process.cwd(),
|
|
131
|
+
sessionKey: params.parentSessionKey,
|
|
132
|
+
entry: {
|
|
133
|
+
kind: "context",
|
|
134
|
+
id: `workflow-run-link:${params.runId}`,
|
|
135
|
+
text,
|
|
136
|
+
data: {
|
|
137
|
+
kind: WORKFLOW_RUN_LINK_CONTEXT_KIND,
|
|
138
|
+
runId: params.runId,
|
|
139
|
+
workflowSessionKey: params.workflowSessionKey,
|
|
140
|
+
definitionId: params.definitionId,
|
|
141
|
+
goal: params.goal,
|
|
142
|
+
status: params.status
|
|
143
|
+
},
|
|
144
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
};
|
|
149
|
+
function formatWorkflowGoalUserMessage(definitionId, goal) {
|
|
150
|
+
const trimmedGoal = goal.trim();
|
|
151
|
+
if (trimmedGoal) return `Run workflow \`${definitionId}\`:\n\n${trimmedGoal}`;
|
|
152
|
+
return `Run workflow \`${definitionId}\``;
|
|
153
|
+
}
|
|
154
|
+
function truncateSessionName(name) {
|
|
155
|
+
const trimmed = name.trim();
|
|
156
|
+
if (trimmed.length <= 80) return trimmed;
|
|
157
|
+
return `${trimmed.slice(0, 77)}…`;
|
|
158
|
+
}
|
|
159
|
+
function readParentSessionKey(view) {
|
|
160
|
+
if (view.run.source.kind === "chat") {
|
|
161
|
+
const originKey = view.run.source.sessionKey?.trim();
|
|
162
|
+
if (originKey) return originKey;
|
|
163
|
+
}
|
|
164
|
+
const customParent = view.run.metadata?.origin?.sessionKey?.trim();
|
|
165
|
+
if (customParent && view.run.metadata?.triggerSource === "chat") return customParent;
|
|
166
|
+
return null;
|
|
167
|
+
}
|
|
168
|
+
function formatParentRunLinkText(params) {
|
|
169
|
+
const label = params.goal.trim() || params.definitionId;
|
|
170
|
+
if (params.status === "running" || params.status === "queued") return `Workflow \`${params.definitionId}\` is running: ${label}`;
|
|
171
|
+
if (params.status === "succeeded") return `Workflow \`${params.definitionId}\` completed: ${label}`;
|
|
172
|
+
return `Workflow \`${params.definitionId}\` finished (${params.status}): ${label}`;
|
|
173
|
+
}
|
|
174
|
+
//#endregion
|
|
175
|
+
export { WORKFLOW_RUN_LINK_CONTEXT_KIND, WORKFLOW_SESSION_TYPE, WorkflowSessionBridge, formatParentRunLinkText };
|
|
176
|
+
|
|
177
|
+
//# sourceMappingURL=workflow-session-bridge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workflow-session-bridge.js","names":[],"sources":["../../../../src/workflows/service/workflow-session-bridge.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto';\n\nimport type { GatewayWorkflowHost } from '../../gateway/gateway-workflow-host.types.js';\nimport { renderWorkflowText } from '../../agent/workflow/snapshot.js';\nimport {\n appendPiTranscriptContextEntry,\n appendPiTranscriptMessage,\n} from '../../session/parity/jsonl-transcript-io.js';\nimport { SessionStatus } from '../../session/types.js';\nimport type { WorkflowRunView } from '../domain/index.js';\nimport { isTerminalWorkflowRunStatus } from '../domain/index.js';\n\nimport { runViewToSnapshot } from './run-view-to-snapshot.js';\nimport { buildWorkflowRunSessionKey } from './workflow-session-key.js';\n\nexport const WORKFLOW_SESSION_TYPE = 'workflow';\nexport const WORKFLOW_RUN_LINK_CONTEXT_KIND = 'workflow-run-link';\n\nexport interface PrepareWorkflowRunSessionParams {\n runId: string;\n agentId: string;\n definitionId: string;\n definitionTitle: string;\n goal: string;\n parentSessionKey?: string;\n}\n\nexport interface PrepareWorkflowRunSessionResult {\n sessionKey: string;\n}\n\nexport class WorkflowSessionBridge {\n private readonly terminalPersistedRunIds = new Set<string>();\n\n constructor(private readonly gateway: GatewayWorkflowHost) {}\n\n async prepareRunSession(params: PrepareWorkflowRunSessionParams): Promise<PrepareWorkflowRunSessionResult> {\n const sessionKey = buildWorkflowRunSessionKey(params.agentId, params.runId);\n const goalText = formatWorkflowGoalUserMessage(params.definitionId, params.goal);\n const sessionName = truncateSessionName(params.goal.trim() || params.definitionTitle || params.definitionId);\n\n const store = this.gateway.sessionIndexInstance.getStore();\n await store.resolveTranscriptPath(sessionKey);\n await store.updateMetadata(sessionKey, {\n sessionType: WORKFLOW_SESSION_TYPE,\n name: sessionName,\n tags: ['workflow', params.definitionId],\n customData: {\n workflowRunId: params.runId,\n workflowDefinitionId: params.definitionId,\n workflowGoal: params.goal,\n ...(params.parentSessionKey ? { parentSessionKey: params.parentSessionKey } : {}),\n },\n });\n\n const { absPath } = await store.resolveTranscriptPath(sessionKey);\n await appendPiTranscriptMessage({\n absPath,\n cwd: process.cwd(),\n sessionKey,\n message: {\n role: 'user',\n content: [{ type: 'text', text: goalText }],\n timestamp: Date.now(),\n },\n });\n\n if (params.parentSessionKey?.trim()) {\n await this.writeParentRunLink({\n parentSessionKey: params.parentSessionKey.trim(),\n runId: params.runId,\n workflowSessionKey: sessionKey,\n definitionId: params.definitionId,\n goal: params.goal,\n status: 'running',\n });\n }\n\n this.gateway.emit('session.updated', { key: sessionKey, name: sessionName });\n return { sessionKey };\n }\n\n async handleRunViewUpdated(view: WorkflowRunView): Promise<void> {\n const runId = view.run.id;\n const sessionKey = view.run.metadata?.sessionKey?.trim();\n if (!sessionKey || !isTerminalWorkflowRunStatus(view.run.status)) {\n return;\n }\n if (this.terminalPersistedRunIds.has(runId)) {\n return;\n }\n this.terminalPersistedRunIds.add(runId);\n\n await this.persistTerminalTranscript(sessionKey, view);\n\n const parentSessionKey = readParentSessionKey(view);\n if (parentSessionKey) {\n await this.writeParentRunLink({\n parentSessionKey,\n runId,\n workflowSessionKey: sessionKey,\n definitionId: view.run.definitionId,\n goal: view.run.goal,\n status: view.run.status,\n });\n }\n }\n\n private async persistTerminalTranscript(sessionKey: string, view: WorkflowRunView): Promise<void> {\n const store = this.gateway.sessionIndexInstance.getStore();\n const { absPath } = await store.resolveTranscriptPath(sessionKey);\n const snapshot = runViewToSnapshot(view);\n const toolCallId = randomUUID();\n const completed = view.run.status === 'succeeded';\n const resultText = renderWorkflowText(snapshot, completed, { showResultPreviews: true });\n const envelope = {\n content: [{ type: 'text', text: resultText }],\n details: snapshot,\n };\n const isError = view.run.status === 'failed' || view.run.status === 'timeout';\n\n await appendPiTranscriptMessage({\n absPath,\n cwd: process.cwd(),\n sessionKey,\n message: {\n role: 'assistant',\n content: [\n {\n type: 'toolCall',\n id: toolCallId,\n name: 'workflow',\n arguments: { name: view.run.definitionId },\n },\n ],\n timestamp: Date.now(),\n } as unknown as Parameters<typeof appendPiTranscriptMessage>[0]['message'],\n });\n\n await appendPiTranscriptMessage({\n absPath,\n cwd: process.cwd(),\n sessionKey,\n message: {\n role: 'toolResult',\n toolCallId,\n content: [{ type: 'text', text: JSON.stringify(envelope) }],\n details: snapshot,\n isError,\n timestamp: Date.now(),\n } as Parameters<typeof appendPiTranscriptMessage>[0]['message'],\n });\n\n await store.updateMetadata(sessionKey, {\n status: SessionStatus.ACTIVE,\n });\n }\n\n private async writeParentRunLink(params: {\n parentSessionKey: string;\n runId: string;\n workflowSessionKey: string;\n definitionId: string;\n goal: string;\n status: WorkflowRunView['run']['status'];\n }): Promise<void> {\n const store = this.gateway.sessionIndexInstance.getStore();\n const { absPath } = await store.resolveTranscriptPath(params.parentSessionKey);\n const text = formatParentRunLinkText(params);\n await appendPiTranscriptContextEntry({\n absPath,\n cwd: process.cwd(),\n sessionKey: params.parentSessionKey,\n entry: {\n kind: 'context',\n id: `workflow-run-link:${params.runId}`,\n text,\n data: {\n kind: WORKFLOW_RUN_LINK_CONTEXT_KIND,\n runId: params.runId,\n workflowSessionKey: params.workflowSessionKey,\n definitionId: params.definitionId,\n goal: params.goal,\n status: params.status,\n },\n createdAt: new Date().toISOString(),\n },\n });\n }\n}\n\nfunction formatWorkflowGoalUserMessage(definitionId: string, goal: string): string {\n const trimmedGoal = goal.trim();\n if (trimmedGoal) {\n return `Run workflow \\`${definitionId}\\`:\\n\\n${trimmedGoal}`;\n }\n return `Run workflow \\`${definitionId}\\``;\n}\n\nfunction truncateSessionName(name: string): string {\n const trimmed = name.trim();\n if (trimmed.length <= 80) return trimmed;\n return `${trimmed.slice(0, 77)}…`;\n}\n\nfunction readParentSessionKey(view: WorkflowRunView): string | null {\n if (view.run.source.kind === 'chat') {\n const originKey = view.run.source.sessionKey?.trim();\n if (originKey) return originKey;\n }\n const customParent = view.run.metadata?.origin?.sessionKey?.trim();\n if (customParent && view.run.metadata?.triggerSource === 'chat') {\n return customParent;\n }\n return null;\n}\n\nexport function formatParentRunLinkText(params: {\n definitionId: string;\n goal: string;\n status: WorkflowRunView['run']['status'];\n}): string {\n const label = params.goal.trim() || params.definitionId;\n if (params.status === 'running' || params.status === 'queued') {\n return `Workflow \\`${params.definitionId}\\` is running: ${label}`;\n }\n if (params.status === 'succeeded') {\n return `Workflow \\`${params.definitionId}\\` completed: ${label}`;\n }\n return `Workflow \\`${params.definitionId}\\` finished (${params.status}): ${label}`;\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
/** Stable webchat session key for one workflow run (`agent:{id}:webchat:…:direct:wf_{runId}`). */
|
|
2
|
+
export declare function buildWorkflowRunSessionKey(agentId: string, runId: string): string;
|
|
3
|
+
export declare function readWorkflowRunIdFromSessionCustomData(customData: Record<string, unknown> | undefined): string | null;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { buildSessionKey, init_session_key } from "../../routing/session-key.js";
|
|
2
|
+
//#region src/workflows/service/workflow-session-key.ts
|
|
3
|
+
init_session_key();
|
|
4
|
+
/** Stable webchat session key for one workflow run (`agent:{id}:webchat:…:direct:wf_{runId}`). */
|
|
5
|
+
function buildWorkflowRunSessionKey(agentId, runId) {
|
|
6
|
+
return buildSessionKey({
|
|
7
|
+
agentId,
|
|
8
|
+
source: "webchat",
|
|
9
|
+
accountId: "default",
|
|
10
|
+
peerKind: "direct",
|
|
11
|
+
peerId: `wf_${runId}`
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
function readWorkflowRunIdFromSessionCustomData(customData) {
|
|
15
|
+
const raw = customData?.workflowRunId;
|
|
16
|
+
return typeof raw === "string" && raw.trim() ? raw.trim() : null;
|
|
17
|
+
}
|
|
18
|
+
//#endregion
|
|
19
|
+
export { buildWorkflowRunSessionKey, readWorkflowRunIdFromSessionCustomData };
|
|
20
|
+
|
|
21
|
+
//# sourceMappingURL=workflow-session-key.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workflow-session-key.js","names":[],"sources":["../../../../src/workflows/service/workflow-session-key.ts"],"sourcesContent":["import { buildSessionKey } from '../../routing/session-key.js';\n\n/** Stable webchat session key for one workflow run (`agent:{id}:webchat:…:direct:wf_{runId}`). */\nexport function buildWorkflowRunSessionKey(agentId: string, runId: string): string {\n return buildSessionKey({\n agentId,\n source: 'webchat',\n accountId: 'default',\n peerKind: 'direct',\n peerId: `wf_${runId}`,\n });\n}\n\nexport function readWorkflowRunIdFromSessionCustomData(\n customData: Record<string, unknown> | undefined,\n): string | null {\n const raw = customData?.workflowRunId;\n return typeof raw === 'string' && raw.trim() ? raw.trim() : null;\n}\n"],"mappings":";;kBAA+D;;AAG/D,SAAgB,2BAA2B,SAAiB,OAAuB;AACjF,QAAO,gBAAgB;EACrB;EACA,QAAQ;EACR,WAAW;EACX,UAAU;EACV,QAAQ,MAAM;EACf,CAAC;;AAGJ,SAAgB,uCACd,YACe;CACf,MAAM,MAAM,YAAY;AACxB,QAAO,OAAO,QAAQ,YAAY,IAAI,MAAM,GAAG,IAAI,MAAM,GAAG"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { Config } from '../../config/schema.js';
|
|
2
|
+
import type { WorkflowEventEnvelope, WorkflowEventPayload, WorkflowEventType } from '../domain/event.js';
|
|
3
|
+
export interface AppendWorkflowEventInput<T extends WorkflowEventPayload = WorkflowEventPayload> {
|
|
4
|
+
runId: string;
|
|
5
|
+
type: WorkflowEventType;
|
|
6
|
+
payload: T;
|
|
7
|
+
createdAtMs?: number;
|
|
8
|
+
}
|
|
9
|
+
export declare class WorkflowEventStore {
|
|
10
|
+
private readonly config;
|
|
11
|
+
private readonly agentId;
|
|
12
|
+
constructor(config: Config, agentId: string);
|
|
13
|
+
append<T extends WorkflowEventPayload>(input: AppendWorkflowEventInput<T>): Promise<WorkflowEventEnvelope<T>>;
|
|
14
|
+
readRunEvents(runId: string): Promise<WorkflowEventEnvelope[]>;
|
|
15
|
+
listRunIds(): Promise<string[]>;
|
|
16
|
+
}
|
|
17
|
+
export declare function createWorkflowEventStore(config: Config, agentId: string): WorkflowEventStore;
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { createLogger } from "../../utils/logger/index.js";
|
|
2
|
+
import { init_logger } from "../../utils/logger.js";
|
|
3
|
+
import { resolveWorkflowRunEventsPath, resolveWorkflowRunsDir } from "./paths.js";
|
|
4
|
+
import { dirname } from "node:path";
|
|
5
|
+
import { randomUUID } from "node:crypto";
|
|
6
|
+
import { appendFile, mkdir, readFile, readdir } from "node:fs/promises";
|
|
7
|
+
//#region src/workflows/store/event-store.ts
|
|
8
|
+
init_logger();
|
|
9
|
+
const log = createLogger("WorkflowEventStore");
|
|
10
|
+
var WorkflowEventStore = class {
|
|
11
|
+
constructor(config, agentId) {
|
|
12
|
+
this.config = config;
|
|
13
|
+
this.agentId = agentId;
|
|
14
|
+
}
|
|
15
|
+
async append(input) {
|
|
16
|
+
const eventsPath = resolveWorkflowRunEventsPath(this.config, this.agentId, input.runId);
|
|
17
|
+
await mkdir(dirname(eventsPath), { recursive: true });
|
|
18
|
+
const previousEvents = await this.readRunEvents(input.runId);
|
|
19
|
+
const event = {
|
|
20
|
+
id: randomUUID(),
|
|
21
|
+
runId: input.runId,
|
|
22
|
+
sequence: previousEvents.length + 1,
|
|
23
|
+
type: input.type,
|
|
24
|
+
payload: input.payload,
|
|
25
|
+
createdAtMs: input.createdAtMs ?? Date.now()
|
|
26
|
+
};
|
|
27
|
+
await appendFile(eventsPath, `${JSON.stringify(event)}\n`, "utf8");
|
|
28
|
+
return event;
|
|
29
|
+
}
|
|
30
|
+
async readRunEvents(runId) {
|
|
31
|
+
const eventsPath = resolveWorkflowRunEventsPath(this.config, this.agentId, runId);
|
|
32
|
+
let content;
|
|
33
|
+
try {
|
|
34
|
+
content = await readFile(eventsPath, "utf8");
|
|
35
|
+
} catch (err) {
|
|
36
|
+
if ((err && typeof err === "object" && "code" in err ? String(err.code) : "") === "ENOENT") return [];
|
|
37
|
+
log.warn({
|
|
38
|
+
err,
|
|
39
|
+
runId,
|
|
40
|
+
eventsPath
|
|
41
|
+
}, "Workflow events read failed");
|
|
42
|
+
return [];
|
|
43
|
+
}
|
|
44
|
+
const events = [];
|
|
45
|
+
for (const line of content.split("\n")) {
|
|
46
|
+
if (!line.trim()) continue;
|
|
47
|
+
try {
|
|
48
|
+
const event = JSON.parse(line);
|
|
49
|
+
if (event.runId === runId && Number.isFinite(event.sequence)) events.push(event);
|
|
50
|
+
} catch (err) {
|
|
51
|
+
log.warn({
|
|
52
|
+
err,
|
|
53
|
+
runId,
|
|
54
|
+
linePreview: line.slice(0, 160)
|
|
55
|
+
}, "Workflow event line parse failed");
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
events.sort((left, right) => left.sequence - right.sequence);
|
|
59
|
+
return events;
|
|
60
|
+
}
|
|
61
|
+
async listRunIds() {
|
|
62
|
+
const runsDir = resolveWorkflowRunsDir(this.config, this.agentId);
|
|
63
|
+
let entries;
|
|
64
|
+
try {
|
|
65
|
+
entries = await readdir(runsDir);
|
|
66
|
+
} catch (err) {
|
|
67
|
+
if ((err && typeof err === "object" && "code" in err ? String(err.code) : "") === "ENOENT") return [];
|
|
68
|
+
log.warn({
|
|
69
|
+
err,
|
|
70
|
+
runsDir
|
|
71
|
+
}, "Workflow runs directory read failed");
|
|
72
|
+
return [];
|
|
73
|
+
}
|
|
74
|
+
return entries.filter((entry) => !entry.startsWith(".") && !entry.includes("/") && !entry.includes("\\"));
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
function createWorkflowEventStore(config, agentId) {
|
|
78
|
+
return new WorkflowEventStore(config, agentId);
|
|
79
|
+
}
|
|
80
|
+
//#endregion
|
|
81
|
+
export { WorkflowEventStore, createWorkflowEventStore };
|
|
82
|
+
|
|
83
|
+
//# sourceMappingURL=event-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event-store.js","names":[],"sources":["../../../../src/workflows/store/event-store.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto';\nimport { appendFile, mkdir, readFile, readdir } from 'node:fs/promises';\nimport { dirname } from 'node:path';\n\nimport type { Config } from '../../config/schema.js';\nimport { createLogger } from '../../utils/logger.js';\nimport type { WorkflowEventEnvelope, WorkflowEventPayload, WorkflowEventType } from '../domain/event.js';\n\nimport { resolveWorkflowRunEventsPath, resolveWorkflowRunsDir } from './paths.js';\n\nconst log = createLogger('WorkflowEventStore');\n\nexport interface AppendWorkflowEventInput<T extends WorkflowEventPayload = WorkflowEventPayload> {\n runId: string;\n type: WorkflowEventType;\n payload: T;\n createdAtMs?: number;\n}\n\nexport class WorkflowEventStore {\n constructor(\n private readonly config: Config,\n private readonly agentId: string,\n ) {}\n\n async append<T extends WorkflowEventPayload>(input: AppendWorkflowEventInput<T>): Promise<WorkflowEventEnvelope<T>> {\n const eventsPath = resolveWorkflowRunEventsPath(this.config, this.agentId, input.runId);\n await mkdir(dirname(eventsPath), { recursive: true });\n const previousEvents = await this.readRunEvents(input.runId);\n const event: WorkflowEventEnvelope<T> = {\n id: randomUUID(),\n runId: input.runId,\n sequence: previousEvents.length + 1,\n type: input.type,\n payload: input.payload,\n createdAtMs: input.createdAtMs ?? Date.now(),\n };\n\n await appendFile(eventsPath, `${JSON.stringify(event)}\\n`, 'utf8');\n return event;\n }\n\n async readRunEvents(runId: string): Promise<WorkflowEventEnvelope[]> {\n const eventsPath = resolveWorkflowRunEventsPath(this.config, this.agentId, runId);\n let content: string;\n try {\n content = await readFile(eventsPath, 'utf8');\n } catch (err) {\n const code = err && typeof err === 'object' && 'code' in err ? String((err as NodeJS.ErrnoException).code) : '';\n if (code === 'ENOENT') {\n return [];\n }\n log.warn({ err, runId, eventsPath }, 'Workflow events read failed');\n return [];\n }\n\n const events: WorkflowEventEnvelope[] = [];\n for (const line of content.split('\\n')) {\n if (!line.trim()) {\n continue;\n }\n try {\n const event = JSON.parse(line) as WorkflowEventEnvelope;\n if (event.runId === runId && Number.isFinite(event.sequence)) {\n events.push(event);\n }\n } catch (err) {\n log.warn({ err, runId, linePreview: line.slice(0, 160) }, 'Workflow event line parse failed');\n }\n }\n\n events.sort((left, right) => left.sequence - right.sequence);\n return events;\n }\n\n async listRunIds(): Promise<string[]> {\n const runsDir = resolveWorkflowRunsDir(this.config, this.agentId);\n let entries: string[];\n try {\n entries = await readdir(runsDir);\n } catch (err) {\n const code = err && typeof err === 'object' && 'code' in err ? String((err as NodeJS.ErrnoException).code) : '';\n if (code === 'ENOENT') {\n return [];\n }\n log.warn({ err, runsDir }, 'Workflow runs directory read failed');\n return [];\n }\n\n return entries.filter((entry) => !entry.startsWith('.') && !entry.includes('/') && !entry.includes('\\\\'));\n }\n}\n\nexport function createWorkflowEventStore(config: Config, agentId: string): WorkflowEventStore {\n return new WorkflowEventStore(config, agentId);\n}\n"],"mappings":";;;;;;;aAKqD;AAKrD,MAAM,MAAM,aAAa,qBAAqB;AAS9C,IAAa,qBAAb,MAAgC;CAC9B,YACE,QACA,SACA;AAFiB,OAAA,SAAA;AACA,OAAA,UAAA;;CAGnB,MAAM,OAAuC,OAAuE;EAClH,MAAM,aAAa,6BAA6B,KAAK,QAAQ,KAAK,SAAS,MAAM,MAAM;AACvF,QAAM,MAAM,QAAQ,WAAW,EAAE,EAAE,WAAW,MAAM,CAAC;EACrD,MAAM,iBAAiB,MAAM,KAAK,cAAc,MAAM,MAAM;EAC5D,MAAM,QAAkC;GACtC,IAAI,YAAY;GAChB,OAAO,MAAM;GACb,UAAU,eAAe,SAAS;GAClC,MAAM,MAAM;GACZ,SAAS,MAAM;GACf,aAAa,MAAM,eAAe,KAAK,KAAK;GAC7C;AAED,QAAM,WAAW,YAAY,GAAG,KAAK,UAAU,MAAM,CAAC,KAAK,OAAO;AAClE,SAAO;;CAGT,MAAM,cAAc,OAAiD;EACnE,MAAM,aAAa,6BAA6B,KAAK,QAAQ,KAAK,SAAS,MAAM;EACjF,IAAI;AACJ,MAAI;AACF,aAAU,MAAM,SAAS,YAAY,OAAO;WACrC,KAAK;AAEZ,QADa,OAAO,OAAO,QAAQ,YAAY,UAAU,MAAM,OAAQ,IAA8B,KAAK,GAAG,QAChG,SACX,QAAO,EAAE;AAEX,OAAI,KAAK;IAAE;IAAK;IAAO;IAAY,EAAE,8BAA8B;AACnE,UAAO,EAAE;;EAGX,MAAM,SAAkC,EAAE;AAC1C,OAAK,MAAM,QAAQ,QAAQ,MAAM,KAAK,EAAE;AACtC,OAAI,CAAC,KAAK,MAAM,CACd;AAEF,OAAI;IACF,MAAM,QAAQ,KAAK,MAAM,KAAK;AAC9B,QAAI,MAAM,UAAU,SAAS,OAAO,SAAS,MAAM,SAAS,CAC1D,QAAO,KAAK,MAAM;YAEb,KAAK;AACZ,QAAI,KAAK;KAAE;KAAK;KAAO,aAAa,KAAK,MAAM,GAAG,IAAI;KAAE,EAAE,mCAAmC;;;AAIjG,SAAO,MAAM,MAAM,UAAU,KAAK,WAAW,MAAM,SAAS;AAC5D,SAAO;;CAGT,MAAM,aAAgC;EACpC,MAAM,UAAU,uBAAuB,KAAK,QAAQ,KAAK,QAAQ;EACjE,IAAI;AACJ,MAAI;AACF,aAAU,MAAM,QAAQ,QAAQ;WACzB,KAAK;AAEZ,QADa,OAAO,OAAO,QAAQ,YAAY,UAAU,MAAM,OAAQ,IAA8B,KAAK,GAAG,QAChG,SACX,QAAO,EAAE;AAEX,OAAI,KAAK;IAAE;IAAK;IAAS,EAAE,sCAAsC;AACjE,UAAO,EAAE;;AAGX,SAAO,QAAQ,QAAQ,UAAU,CAAC,MAAM,WAAW,IAAI,IAAI,CAAC,MAAM,SAAS,IAAI,IAAI,CAAC,MAAM,SAAS,KAAK,CAAC;;;AAI7G,SAAgB,yBAAyB,QAAgB,SAAqC;AAC5F,QAAO,IAAI,mBAAmB,QAAQ,QAAQ"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Config } from '../../config/schema.js';
|
|
2
|
+
export declare function resolveWorkflowRootDir(config: Config, agentId: string): string;
|
|
3
|
+
export declare function resolveWorkflowRunsDir(config: Config, agentId: string): string;
|
|
4
|
+
export declare function resolveWorkflowRunDir(config: Config, agentId: string, runId: string): string;
|
|
5
|
+
export declare function resolveWorkflowRunEventsPath(config: Config, agentId: string, runId: string): string;
|
|
6
|
+
export declare function resolveWorkflowRunViewPath(config: Config, agentId: string, runId: string): string;
|
|
7
|
+
export declare function resolveWorkflowRunArtifactsDir(config: Config, agentId: string, runId: string): string;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { init_paths, resolveAgentHomeDir } from "../../config/paths.js";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
//#region src/workflows/store/paths.ts
|
|
4
|
+
init_paths();
|
|
5
|
+
function resolveWorkflowRootDir(config, agentId) {
|
|
6
|
+
return join(resolveAgentHomeDir(config, agentId), "workflows");
|
|
7
|
+
}
|
|
8
|
+
function resolveWorkflowRunsDir(config, agentId) {
|
|
9
|
+
return join(resolveWorkflowRootDir(config, agentId), "runs");
|
|
10
|
+
}
|
|
11
|
+
function resolveWorkflowRunDir(config, agentId, runId) {
|
|
12
|
+
return join(resolveWorkflowRunsDir(config, agentId), runId);
|
|
13
|
+
}
|
|
14
|
+
function resolveWorkflowRunEventsPath(config, agentId, runId) {
|
|
15
|
+
return join(resolveWorkflowRunDir(config, agentId, runId), "events.jsonl");
|
|
16
|
+
}
|
|
17
|
+
function resolveWorkflowRunViewPath(config, agentId, runId) {
|
|
18
|
+
return join(resolveWorkflowRunDir(config, agentId, runId), "view.json");
|
|
19
|
+
}
|
|
20
|
+
function resolveWorkflowRunArtifactsDir(config, agentId, runId) {
|
|
21
|
+
return join(resolveWorkflowRunDir(config, agentId, runId), "artifacts");
|
|
22
|
+
}
|
|
23
|
+
//#endregion
|
|
24
|
+
export { resolveWorkflowRootDir, resolveWorkflowRunArtifactsDir, resolveWorkflowRunDir, resolveWorkflowRunEventsPath, resolveWorkflowRunViewPath, resolveWorkflowRunsDir };
|
|
25
|
+
|
|
26
|
+
//# sourceMappingURL=paths.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.js","names":[],"sources":["../../../../src/workflows/store/paths.ts"],"sourcesContent":["import { join } from 'node:path';\n\nimport type { Config } from '../../config/schema.js';\nimport { resolveAgentHomeDir } from '../../config/paths.js';\n\nexport function resolveWorkflowRootDir(config: Config, agentId: string): string {\n return join(resolveAgentHomeDir(config, agentId), 'workflows');\n}\n\nexport function resolveWorkflowRunsDir(config: Config, agentId: string): string {\n return join(resolveWorkflowRootDir(config, agentId), 'runs');\n}\n\nexport function resolveWorkflowRunDir(config: Config, agentId: string, runId: string): string {\n return join(resolveWorkflowRunsDir(config, agentId), runId);\n}\n\nexport function resolveWorkflowRunEventsPath(config: Config, agentId: string, runId: string): string {\n return join(resolveWorkflowRunDir(config, agentId, runId), 'events.jsonl');\n}\n\nexport function resolveWorkflowRunViewPath(config: Config, agentId: string, runId: string): string {\n return join(resolveWorkflowRunDir(config, agentId, runId), 'view.json');\n}\n\nexport function resolveWorkflowRunArtifactsDir(config: Config, agentId: string, runId: string): string {\n return join(resolveWorkflowRunDir(config, agentId, runId), 'artifacts');\n}\n"],"mappings":";;;YAG4D;AAE5D,SAAgB,uBAAuB,QAAgB,SAAyB;AAC9E,QAAO,KAAK,oBAAoB,QAAQ,QAAQ,EAAE,YAAY;;AAGhE,SAAgB,uBAAuB,QAAgB,SAAyB;AAC9E,QAAO,KAAK,uBAAuB,QAAQ,QAAQ,EAAE,OAAO;;AAG9D,SAAgB,sBAAsB,QAAgB,SAAiB,OAAuB;AAC5F,QAAO,KAAK,uBAAuB,QAAQ,QAAQ,EAAE,MAAM;;AAG7D,SAAgB,6BAA6B,QAAgB,SAAiB,OAAuB;AACnG,QAAO,KAAK,sBAAsB,QAAQ,SAAS,MAAM,EAAE,eAAe;;AAG5E,SAAgB,2BAA2B,QAAgB,SAAiB,OAAuB;AACjG,QAAO,KAAK,sBAAsB,QAAQ,SAAS,MAAM,EAAE,YAAY;;AAGzE,SAAgB,+BAA+B,QAAgB,SAAiB,OAAuB;AACrG,QAAO,KAAK,sBAAsB,QAAQ,SAAS,MAAM,EAAE,YAAY"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Config } from '../../config/schema.js';
|
|
2
|
+
import type { WorkflowRunSummary, WorkflowRunView } from '../domain/run.js';
|
|
3
|
+
import { WorkflowEventStore } from './event-store.js';
|
|
4
|
+
export declare class WorkflowRunStore {
|
|
5
|
+
private readonly config;
|
|
6
|
+
private readonly agentId;
|
|
7
|
+
private readonly eventStore;
|
|
8
|
+
constructor(config: Config, agentId: string, eventStore?: WorkflowEventStore);
|
|
9
|
+
rebuildRunView(runId: string): Promise<WorkflowRunView | null>;
|
|
10
|
+
readRunView(runId: string): Promise<WorkflowRunView | null>;
|
|
11
|
+
listRunSummaries(limit?: number): Promise<WorkflowRunSummary[]>;
|
|
12
|
+
}
|
|
13
|
+
export declare function createWorkflowRunStore(config: Config, agentId: string): WorkflowRunStore;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { createLogger } from "../../utils/logger/index.js";
|
|
2
|
+
import { init_logger } from "../../utils/logger.js";
|
|
3
|
+
import { init_write_file_atomic, writeTextAtomic } from "../../infra/write-file-atomic.js";
|
|
4
|
+
import { projectWorkflowRunView } from "../engine/projector.js";
|
|
5
|
+
import { resolveWorkflowRunViewPath } from "./paths.js";
|
|
6
|
+
import { WorkflowEventStore } from "./event-store.js";
|
|
7
|
+
import { readFile } from "node:fs/promises";
|
|
8
|
+
//#region src/workflows/store/run-store.ts
|
|
9
|
+
init_write_file_atomic();
|
|
10
|
+
init_logger();
|
|
11
|
+
const log = createLogger("WorkflowRunStore");
|
|
12
|
+
var WorkflowRunStore = class {
|
|
13
|
+
eventStore;
|
|
14
|
+
constructor(config, agentId, eventStore) {
|
|
15
|
+
this.config = config;
|
|
16
|
+
this.agentId = agentId;
|
|
17
|
+
this.eventStore = eventStore ?? new WorkflowEventStore(config, agentId);
|
|
18
|
+
}
|
|
19
|
+
async rebuildRunView(runId) {
|
|
20
|
+
const view = projectWorkflowRunView(await this.eventStore.readRunEvents(runId));
|
|
21
|
+
if (!view) return null;
|
|
22
|
+
await writeTextAtomic(resolveWorkflowRunViewPath(this.config, this.agentId, runId), `${JSON.stringify(view, null, 2)}\n`);
|
|
23
|
+
return view;
|
|
24
|
+
}
|
|
25
|
+
async readRunView(runId) {
|
|
26
|
+
const viewPath = resolveWorkflowRunViewPath(this.config, this.agentId, runId);
|
|
27
|
+
try {
|
|
28
|
+
const content = await readFile(viewPath, "utf8");
|
|
29
|
+
return JSON.parse(content);
|
|
30
|
+
} catch (err) {
|
|
31
|
+
if ((err && typeof err === "object" && "code" in err ? String(err.code) : "") !== "ENOENT") log.debug({
|
|
32
|
+
err,
|
|
33
|
+
runId,
|
|
34
|
+
viewPath
|
|
35
|
+
}, "Workflow run view read failed; rebuilding from events");
|
|
36
|
+
return this.rebuildRunView(runId);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
async listRunSummaries(limit = 50) {
|
|
40
|
+
const safeLimit = Math.min(500, Math.max(1, Math.floor(limit)));
|
|
41
|
+
const runIds = await this.eventStore.listRunIds();
|
|
42
|
+
const summaries = [];
|
|
43
|
+
for (const runId of runIds) {
|
|
44
|
+
const view = await this.readRunView(runId);
|
|
45
|
+
if (!view) continue;
|
|
46
|
+
summaries.push({
|
|
47
|
+
id: view.run.id,
|
|
48
|
+
definitionId: view.run.definitionId,
|
|
49
|
+
title: view.run.title,
|
|
50
|
+
status: view.run.status,
|
|
51
|
+
source: view.run.source,
|
|
52
|
+
metadata: view.run.metadata,
|
|
53
|
+
createdAtMs: view.run.createdAtMs,
|
|
54
|
+
startedAtMs: view.run.startedAtMs,
|
|
55
|
+
completedAtMs: view.run.completedAtMs,
|
|
56
|
+
metrics: view.run.metrics
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
summaries.sort((left, right) => right.createdAtMs - left.createdAtMs);
|
|
60
|
+
return summaries.slice(0, safeLimit);
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
function createWorkflowRunStore(config, agentId) {
|
|
64
|
+
return new WorkflowRunStore(config, agentId);
|
|
65
|
+
}
|
|
66
|
+
//#endregion
|
|
67
|
+
export { WorkflowRunStore, createWorkflowRunStore };
|
|
68
|
+
|
|
69
|
+
//# sourceMappingURL=run-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-store.js","names":[],"sources":["../../../../src/workflows/store/run-store.ts"],"sourcesContent":["import { readFile } from 'node:fs/promises';\n\nimport type { Config } from '../../config/schema.js';\nimport { writeTextAtomic } from '../../infra/write-file-atomic.js';\nimport { createLogger } from '../../utils/logger.js';\nimport { projectWorkflowRunView } from '../engine/projector.js';\nimport type { WorkflowRunSummary, WorkflowRunView } from '../domain/run.js';\n\nimport { WorkflowEventStore } from './event-store.js';\nimport { resolveWorkflowRunViewPath } from './paths.js';\n\nconst log = createLogger('WorkflowRunStore');\n\nexport class WorkflowRunStore {\n private readonly eventStore: WorkflowEventStore;\n\n constructor(\n private readonly config: Config,\n private readonly agentId: string,\n eventStore?: WorkflowEventStore,\n ) {\n this.eventStore = eventStore ?? new WorkflowEventStore(config, agentId);\n }\n\n async rebuildRunView(runId: string): Promise<WorkflowRunView | null> {\n const events = await this.eventStore.readRunEvents(runId);\n const view = projectWorkflowRunView(events);\n if (!view) {\n return null;\n }\n\n const viewPath = resolveWorkflowRunViewPath(this.config, this.agentId, runId);\n await writeTextAtomic(viewPath, `${JSON.stringify(view, null, 2)}\\n`);\n return view;\n }\n\n async readRunView(runId: string): Promise<WorkflowRunView | null> {\n const viewPath = resolveWorkflowRunViewPath(this.config, this.agentId, runId);\n try {\n const content = await readFile(viewPath, 'utf8');\n return JSON.parse(content) as WorkflowRunView;\n } catch (err) {\n const code = err && typeof err === 'object' && 'code' in err ? String((err as NodeJS.ErrnoException).code) : '';\n if (code !== 'ENOENT') {\n log.debug({ err, runId, viewPath }, 'Workflow run view read failed; rebuilding from events');\n }\n return this.rebuildRunView(runId);\n }\n }\n\n async listRunSummaries(limit = 50): Promise<WorkflowRunSummary[]> {\n const safeLimit = Math.min(500, Math.max(1, Math.floor(limit)));\n const runIds = await this.eventStore.listRunIds();\n const summaries: WorkflowRunSummary[] = [];\n for (const runId of runIds) {\n const view = await this.readRunView(runId);\n if (!view) {\n continue;\n }\n summaries.push({\n id: view.run.id,\n definitionId: view.run.definitionId,\n title: view.run.title,\n status: view.run.status,\n source: view.run.source,\n metadata: view.run.metadata,\n createdAtMs: view.run.createdAtMs,\n startedAtMs: view.run.startedAtMs,\n completedAtMs: view.run.completedAtMs,\n metrics: view.run.metrics,\n });\n }\n\n summaries.sort((left, right) => right.createdAtMs - left.createdAtMs);\n return summaries.slice(0, safeLimit);\n }\n}\n\nexport function createWorkflowRunStore(config: Config, agentId: string): WorkflowRunStore {\n return new WorkflowRunStore(config, agentId);\n}\n"],"mappings":";;;;;;;;wBAGmE;aACd;AAOrD,MAAM,MAAM,aAAa,mBAAmB;AAE5C,IAAa,mBAAb,MAA8B;CAC5B;CAEA,YACE,QACA,SACA,YACA;AAHiB,OAAA,SAAA;AACA,OAAA,UAAA;AAGjB,OAAK,aAAa,cAAc,IAAI,mBAAmB,QAAQ,QAAQ;;CAGzE,MAAM,eAAe,OAAgD;EAEnE,MAAM,OAAO,uBAAuB,MADf,KAAK,WAAW,cAAc,MAAM,CACd;AAC3C,MAAI,CAAC,KACH,QAAO;AAIT,QAAM,gBADW,2BAA2B,KAAK,QAAQ,KAAK,SAAS,MACzC,EAAE,GAAG,KAAK,UAAU,MAAM,MAAM,EAAE,CAAC,IAAI;AACrE,SAAO;;CAGT,MAAM,YAAY,OAAgD;EAChE,MAAM,WAAW,2BAA2B,KAAK,QAAQ,KAAK,SAAS,MAAM;AAC7E,MAAI;GACF,MAAM,UAAU,MAAM,SAAS,UAAU,OAAO;AAChD,UAAO,KAAK,MAAM,QAAQ;WACnB,KAAK;AAEZ,QADa,OAAO,OAAO,QAAQ,YAAY,UAAU,MAAM,OAAQ,IAA8B,KAAK,GAAG,QAChG,SACX,KAAI,MAAM;IAAE;IAAK;IAAO;IAAU,EAAE,wDAAwD;AAE9F,UAAO,KAAK,eAAe,MAAM;;;CAIrC,MAAM,iBAAiB,QAAQ,IAAmC;EAChE,MAAM,YAAY,KAAK,IAAI,KAAK,KAAK,IAAI,GAAG,KAAK,MAAM,MAAM,CAAC,CAAC;EAC/D,MAAM,SAAS,MAAM,KAAK,WAAW,YAAY;EACjD,MAAM,YAAkC,EAAE;AAC1C,OAAK,MAAM,SAAS,QAAQ;GAC1B,MAAM,OAAO,MAAM,KAAK,YAAY,MAAM;AAC1C,OAAI,CAAC,KACH;AAEF,aAAU,KAAK;IACb,IAAI,KAAK,IAAI;IACb,cAAc,KAAK,IAAI;IACvB,OAAO,KAAK,IAAI;IAChB,QAAQ,KAAK,IAAI;IACjB,QAAQ,KAAK,IAAI;IACjB,UAAU,KAAK,IAAI;IACnB,aAAa,KAAK,IAAI;IACtB,aAAa,KAAK,IAAI;IACtB,eAAe,KAAK,IAAI;IACxB,SAAS,KAAK,IAAI;IACnB,CAAC;;AAGJ,YAAU,MAAM,MAAM,UAAU,MAAM,cAAc,KAAK,YAAY;AACrE,SAAO,UAAU,MAAM,GAAG,UAAU;;;AAIxC,SAAgB,uBAAuB,QAAgB,SAAmC;AACxF,QAAO,IAAI,iBAAiB,QAAQ,QAAQ"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xopcai/xopc",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.89",
|
|
4
4
|
"description": "The OPC workstation that grows with you: AI assistant for One Person Companies — CLI, gateway, multi-channel (Telegram/WeChat), 20+ LLM providers via pi-ai, extensions and skills.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/src/index.js",
|
|
@@ -54,10 +54,10 @@
|
|
|
54
54
|
"node": ">=22.0.0"
|
|
55
55
|
},
|
|
56
56
|
"dependencies": {
|
|
57
|
-
"@earendil-works/pi-agent-core": "^0.78.
|
|
58
|
-
"@earendil-works/pi-ai": "^0.78.
|
|
59
|
-
"@earendil-works/pi-coding-agent": "0.78.
|
|
60
|
-
"@earendil-works/pi-tui": "^0.78.
|
|
57
|
+
"@earendil-works/pi-agent-core": "^0.78.1",
|
|
58
|
+
"@earendil-works/pi-ai": "^0.78.1",
|
|
59
|
+
"@earendil-works/pi-coding-agent": "^0.78.1",
|
|
60
|
+
"@earendil-works/pi-tui": "^0.78.1",
|
|
61
61
|
"@grammyjs/runner": "^2.0.3",
|
|
62
62
|
"@hono/node-server": "^2.0.4",
|
|
63
63
|
"@inquirer/prompts": "^8.5.0",
|