@xopcai/xopc 0.0.168 → 0.0.170
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser-ext/manifest.json +1 -1
- package/dist/extensions/telegram/xopc.extension.json +1 -1
- package/dist/gateway/static/root/assets/{activity-store-DjEDu38T.js → activity-store-CkUp1qvf.js} +1 -1
- package/dist/gateway/static/root/assets/{agent-avatar-dicebear-DVuLzaJi.js → agent-avatar-dicebear-DDuem4HM.js} +1 -1
- package/dist/gateway/static/root/assets/{agents-tF_QTWxn.js → agents-BiaQhiQp.js} +2 -2
- package/dist/gateway/static/root/assets/{api-DwVCuPOb.js → api-BnuPQhJW.js} +1 -1
- package/dist/gateway/static/root/assets/{app-management-settings-panel-spzVBvAu.js → app-management-settings-panel-DdZw8Hi1.js} +1 -1
- package/dist/gateway/static/root/assets/{appearance-settings-CetimI47.js → appearance-settings-BN8Vk2bX.js} +1 -1
- package/dist/gateway/static/root/assets/{apps-page-HDyN6Fjx.js → apps-page-CuL8Q4yF.js} +1 -1
- package/dist/gateway/static/root/assets/{archive-plugin-TOmQ2XKc.js → archive-plugin-C82MaDQj.js} +1 -1
- package/dist/gateway/static/root/assets/{attachment-load-NFNEWVLJ.js → attachment-load-uilrwSdW.js} +1 -1
- package/dist/gateway/static/root/assets/{automation-suggestion-card-B0FnLpSl.js → automation-suggestion-card-CkDZjAmy.js} +1 -1
- package/dist/gateway/static/root/assets/{automations-page-DVevVD6A.js → automations-page-TZOluRNp.js} +1 -1
- package/dist/gateway/static/root/assets/{binary-plugins-Csc4xkR9.js → binary-plugins-B7NTL0_T.js} +1 -1
- package/dist/gateway/static/root/assets/{block-editor-C6Xgrbse.js → block-editor-D_LDNlB-.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-settings-page-CyDDEKxB.js → browser-settings-page-C-l6O68Z.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-workflow-inputs-DaxyAai1.js → browser-workflow-inputs-UFVUzn4v.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-workflows-page-CaX6iIJA.js → browser-workflows-page-CGgC0N92.js} +1 -1
- package/dist/gateway/static/root/assets/{capabilities-settings-panel-EXZv96j1.js → capabilities-settings-panel-BW8c0xPp.js} +6 -6
- package/dist/gateway/static/root/assets/{capability-presets-api-DdCHSzcA.js → capability-presets-api-DUIorGUd.js} +1 -1
- package/dist/gateway/static/root/assets/capability-presets-settings-panel-PTz00nR4.js +1 -0
- package/dist/gateway/static/root/assets/{channel-recipient-api-BOkLI89e.js → channel-recipient-api-BYwSB8c6.js} +1 -1
- package/dist/gateway/static/root/assets/{channels-settings-aCN05KdJ.js → channels-settings-h9CsE0GT.js} +1 -1
- package/dist/gateway/static/root/assets/channels-status-swr-C058Mcfr.js +1 -0
- package/dist/gateway/static/root/assets/{chunk-KS7C4IRE-uQ0fehio.js → chunk-KS7C4IRE-BMhrPKJC.js} +2 -2
- package/dist/gateway/static/root/assets/{connector-logo-Mp40HWsb.js → connector-logo-CsbegNqi.js} +1 -1
- package/dist/gateway/static/root/assets/{connectors-page-i0cu5rg5.js → connectors-page-BWALafGW.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-BtzUJ0d7.js → desktop-pet-CkT98fPT.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-settings-Dg0Duj8B.js → desktop-pet-settings-DkbIzdA3.js} +1 -1
- package/dist/gateway/static/root/assets/{directory-picker-path-field-9f0k1wZq.js → directory-picker-path-field-dBQvj1sG.js} +1 -1
- package/dist/gateway/static/root/assets/{dreaming-settings-rdW7dsGP.js → dreaming-settings-DkdnKMZx.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-debug-page-C9zUnn-z.js → extension-debug-page-BfxoIiNo.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-Cy5rfU0h.js → extension-page-EIJ3wIb7.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-BjIquAw6.js → extension-settings-page-DBBec51N.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-config-api-AQQmI6SW.js → gateway-config-api-4_u53Ufq.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-settings-CYNmbqHj.js → gateway-settings-v9kJM59H.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-startup-retry-qnEmj-vL.js → gateway-startup-retry-CXITih5d.js} +1 -1
- package/dist/gateway/static/root/assets/{goal-create-dialog-CkXaDfN3.js → goal-create-dialog-y2Y3p7_k.js} +1 -1
- package/dist/gateway/static/root/assets/{goal-detail-page-FqDa5bfO.js → goal-detail-page-DuzL-alv.js} +3 -3
- package/dist/gateway/static/root/assets/{goals-config-api-CaVGtM6n.js → goals-config-api-D54YQPon.js} +1 -1
- package/dist/gateway/static/root/assets/{goals-page-B-uBRGN6.js → goals-page-OeLtfKI2.js} +1 -1
- package/dist/gateway/static/root/assets/{goals-settings-C9J3MX0F.js → goals-settings-DDezXaVi.js} +1 -1
- package/dist/gateway/static/root/assets/{heartbeat-settings-C0qFLyew.js → heartbeat-settings-CRsIUeZN.js} +1 -1
- package/dist/gateway/static/root/assets/image-generation-api-CY6cQUHL.js +1 -0
- package/dist/gateway/static/root/assets/index-Dfq2laZe.js +212 -0
- package/dist/gateway/static/root/assets/index-o4uaOGKT.css +1 -0
- package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-BAZlRZMd.js → keyboard-shortcuts-settings-D9k7EDdY.js} +1 -1
- package/dist/gateway/static/root/assets/{local-app-workbench-page-DkJUQRyC.js → local-app-workbench-page-3ssYIEK6.js} +1 -1
- package/dist/gateway/static/root/assets/{local-apps-page-PcQABi7F.js → local-apps-page-DbaiBolh.js} +1 -1
- package/dist/gateway/static/root/assets/{locale-store-tnRLWdx2.js → locale-store-Dqp9H2Uf.js} +1 -1
- package/dist/gateway/static/root/assets/{logs-page-B-nXM29t.js → logs-page-DoCY0Mm9.js} +1 -1
- package/dist/gateway/static/root/assets/{markdown-split-B6W1H0Fj.js → markdown-split-BGlQR-Be.js} +1 -1
- package/dist/gateway/static/root/assets/{media-plugins-B-r9Tj74.js → media-plugins-BpaeV6f_.js} +1 -1
- package/dist/gateway/static/root/assets/{messages-B1EG4gdu.js → messages-KEk-hTFt.js} +2 -2
- package/dist/gateway/static/root/assets/notes-page-Cd2HpciM.js +1 -0
- package/dist/gateway/static/root/assets/{notes-workbench-Be97S0Im.js → notes-workbench-CatZNAPc.js} +2 -2
- package/dist/gateway/static/root/assets/{page-tabs-BmUWVWO9.js → page-tabs-DyimBUp_.js} +1 -1
- package/dist/gateway/static/root/assets/{preview-open-alternatives-a76A8p5R.js → preview-open-alternatives-BKZulEYr.js} +1 -1
- package/dist/gateway/static/root/assets/{product-open-page-BWhYrt-U.js → product-open-page-Bjz9BxBY.js} +1 -1
- package/dist/gateway/static/root/assets/project-detail-page-DJUOgqm4.js +1 -0
- package/dist/gateway/static/root/assets/{projects-page-D1MNrLcy.js → projects-page-BQQAD_nu.js} +1 -1
- package/dist/gateway/static/root/assets/{remote-access-hub-GTuiqlJO.js → remote-access-hub-fIGXTTnA.js} +1 -1
- package/dist/gateway/static/root/assets/{save-bar-controls-_ZMLDSUw.js → save-bar-controls-BPTqb2_r.js} +1 -1
- package/dist/gateway/static/root/assets/{schedule-field-D4ErObRc.js → schedule-field-YN0D81Dk.js} +1 -1
- package/dist/gateway/static/root/assets/{schema-form-PqNSGlcH.js → schema-form-BmY5PSS2.js} +1 -1
- package/dist/gateway/static/root/assets/{sessions-page-Ct0MVjNv.js → sessions-page-BuU-8FCe.js} +1 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-DlKoeZm3.js +1 -0
- package/dist/gateway/static/root/assets/{settings-form-section-BCKaoLhJ.js → settings-form-section-B-RhgD_p.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-loading-skeleton-Dn95fked.js → settings-loading-skeleton-DkPupX2B.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-C8MPUl2Q.js → settings-page-2QBMvaxj.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-layout-Bigc8-GR.js → settings-page-layout-CtrW-LD6.js} +1 -1
- package/dist/gateway/static/root/assets/{setup-status-panel-DFTcAHsd.js → setup-status-panel-BSUcDFnb.js} +1 -1
- package/dist/gateway/static/root/assets/{share-preview-page-xAjqaV4y.js → share-preview-page-BezIW1n9.js} +1 -1
- package/dist/gateway/static/root/assets/{shares-settings-D2uvC_aM.js → shares-settings-Bk2-SwGJ.js} +1 -1
- package/dist/gateway/static/root/assets/skill-reload-api-e_Fx1kVC.js +1 -0
- package/dist/gateway/static/root/assets/{skills-page-6dr3RRVW.js → skills-page-D_cCADfj.js} +1 -1
- package/dist/gateway/static/root/assets/{system-settings-panel-BJJQulg9.js → system-settings-panel-WAFhKyAu.js} +1 -1
- package/dist/gateway/static/root/assets/{theme-store-H9T49Iar.js → theme-store-BiC0gIBa.js} +1 -1
- package/dist/gateway/static/root/assets/{time-picker-DsuPUbRE.js → time-picker-fqRXpNJV.js} +1 -1
- package/dist/gateway/static/root/assets/{typed-models-lib-Djk3F3EL.js → typed-models-lib-WAQO3F_8.js} +1 -1
- package/dist/gateway/static/root/assets/{use-channel-catalog-UACJTyH0.js → use-channel-catalog-CKlfsSeU.js} +1 -1
- package/dist/gateway/static/root/assets/{user-context-page-BC585kHK.js → user-context-page-9Ov4htPW.js} +1 -1
- package/dist/gateway/static/root/assets/{voice-api-key-field-CvocOFat.js → voice-api-key-field-BAFHF0_v.js} +1 -1
- package/dist/gateway/static/root/assets/{work-discovery-page-DiMn6nrT.js → work-discovery-page-DGN2FxWv.js} +1 -1
- package/dist/gateway/static/root/assets/{work-item-detail-page-CFBlQbPy.js → work-item-detail-page-HmyWSgUo.js} +1 -1
- package/dist/gateway/static/root/assets/work-page-D3iKVjFq.js +1 -0
- package/dist/gateway/static/root/assets/{workflow-run-setup-panel-DbQwWPjv.js → workflow-run-setup-panel-1OP4HyvS.js} +1 -1
- package/dist/gateway/static/root/assets/workflows-page-B5L4SFw4.js +11 -0
- package/dist/gateway/static/root/index.html +8 -8
- package/dist/package.js +1 -1
- package/dist/src/agent/service/process-direct-one-shot.js +2 -1
- package/dist/src/agent/service/process-direct-streaming.js +2 -1
- package/dist/src/agent/workflow/builtins/index.js +2 -2
- package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
- package/dist/src/cli/commands/onboard/model.d.ts +2 -0
- package/dist/src/cli/commands/onboard/model.js +16 -3
- package/dist/src/config/schema.d.ts +2 -4
- package/dist/src/config/schema.js +1 -2
- package/dist/src/gateway/heartbeat/service.js +1 -1
- package/dist/src/gateway/hono/routes/composer-history.d.ts +3 -0
- package/dist/src/gateway/hono/routes/composer-history.js +28 -0
- package/dist/src/gateway/hono/routes/index.js +2 -0
- package/dist/src/gateway/hono/routes/sessions.js +13 -2
- package/dist/src/gateway/service/sessions-api.js +2 -2
- package/dist/src/heartbeat/index.js +1 -1
- package/dist/src/session/client-history.d.ts +2 -0
- package/dist/src/session/client-history.js +2 -0
- package/dist/src/session/reset-policy.js +3 -5
- package/dist/src/session/store.d.ts +1 -0
- package/dist/src/session/store.js +19 -8
- package/dist/src/storage/sqlite/composer-input-history-repository.d.ts +12 -0
- package/dist/src/storage/sqlite/composer-input-history-repository.js +42 -0
- package/dist/src/storage/sqlite/index.d.ts +2 -1
- package/dist/src/storage/sqlite/index.js +3 -2
- package/dist/src/storage/sqlite/migrations/059_composer_input_history.sql +8 -0
- package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
- package/dist/src/storage/sqlite/migrations/runner.js +3 -3
- package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
- package/dist/src/storage/sqlite/schema.js +1 -1
- package/dist/src/storage/sqlite/transcript-repository.d.ts +4 -3
- package/dist/src/storage/sqlite/transcript-repository.js +31 -22
- package/dist/src/tui/backends/embedded-backend.d.ts +3 -1
- package/dist/src/tui/backends/embedded-backend.js +7 -0
- package/dist/src/tui/backends/gateway-sse-backend.d.ts +3 -1
- package/dist/src/tui/backends/gateway-sse-backend.js +13 -0
- package/dist/src/tui/components/custom-editor.d.ts +1 -0
- package/dist/src/tui/components/custom-editor.js +6 -0
- package/dist/src/tui/tui-backend.d.ts +9 -0
- package/dist/src/tui/tui-submit.d.ts +1 -0
- package/dist/src/tui/tui-submit.js +1 -1
- package/dist/src/tui/tui.js +58 -1
- package/dist/src/workflows/domain/result.d.ts +4 -15
- package/dist/src/workflows/engine/workflow-engine.js +5 -14
- package/dist/src/workflows/runtime/graph-workflow-runtime.js +7 -11
- package/dist/src/workflows/service/workflow-run-service.js +1 -1
- package/dist/src/workflows/service/workflow-session-bridge.js +1 -1
- package/dist/src/workflows/store/run-index-store.js +1 -6
- package/package.json +1 -1
- package/dist/gateway/static/root/assets/capability-presets-settings-panel-o08SXqM4.js +0 -2
- package/dist/gateway/static/root/assets/channels-status-swr-ZrqadU60.js +0 -1
- package/dist/gateway/static/root/assets/index-DchbD-qM.js +0 -199
- package/dist/gateway/static/root/assets/index-DfE2j0g8.css +0 -1
- package/dist/gateway/static/root/assets/notes-page-BNECY6Oy.js +0 -1
- package/dist/gateway/static/root/assets/project-detail-page-md0ANZ-f.js +0 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-QOUph2Oq.js +0 -1
- package/dist/gateway/static/root/assets/skill-reload-api-DYtfQXB-.js +0 -1
- package/dist/gateway/static/root/assets/work-page-CLJLKqsf.js +0 -1
- package/dist/gateway/static/root/assets/workflows-page-BJOhlABF.js +0 -11
|
@@ -31,7 +31,7 @@ function ensureXopcDatabaseSchema(db) {
|
|
|
31
31
|
bootstrapFreshDatabase(db);
|
|
32
32
|
currentVersion = 11;
|
|
33
33
|
}
|
|
34
|
-
applyPendingMigrations(db, { targetVersion:
|
|
34
|
+
applyPendingMigrations(db, { targetVersion: 59 });
|
|
35
35
|
}
|
|
36
36
|
//#endregion
|
|
37
37
|
export { SCHEMA_META_SCHEMA_VERSION_KEY, XOPC_DB_BASELINE_SCHEMA_VERSION, XOPC_DB_SCHEMA_VERSION, ensureSchemaMetaTable, ensureXopcDatabaseSchema, readSchemaVersion, readSchemaVersionForTest, setSchemaVersion };
|
|
@@ -8,6 +8,7 @@ export declare function appendTranscriptEntry(sessionKey: string, row: Transcrip
|
|
|
8
8
|
tokenDelta?: number;
|
|
9
9
|
}): TranscriptEntryRow;
|
|
10
10
|
export declare function loadTranscriptRowsForSession(sessionKey: string): TranscriptStoredRow[];
|
|
11
|
+
export declare function loadTranscriptHistoryRowsForSession(sessionKey: string): TranscriptStoredRow[];
|
|
11
12
|
export declare function loadTranscriptRows(sessionId: string): TranscriptStoredRow[];
|
|
12
13
|
export declare function loadLlmMessagesForSession(sessionKey: string): AgentMessage[];
|
|
13
14
|
export declare function replaceTranscriptRows(sessionKey: string, rows: TranscriptStoredRow[], opts?: {
|
|
@@ -17,10 +18,10 @@ export declare function loadCheckpointRows(sessionKey: string, checkpointId: str
|
|
|
17
18
|
export declare function paginateTranscriptMessages(sessionKey: string, options?: {
|
|
18
19
|
offset?: number;
|
|
19
20
|
limit?: number;
|
|
20
|
-
|
|
21
|
-
/** 0-based exclusive end index (legacy cursor from gateway UI). */
|
|
22
|
-
beforeEndIndex?: number;
|
|
21
|
+
beforeIndex?: number;
|
|
23
22
|
includeContext?: boolean;
|
|
23
|
+
/** Include reset/rollover transcripts for read-only conversation history. */
|
|
24
|
+
includeArchived?: boolean;
|
|
24
25
|
}): {
|
|
25
26
|
rows: TranscriptStoredRow[];
|
|
26
27
|
messages: AgentMessage[];
|
|
@@ -63,6 +63,15 @@ function loadTranscriptRowsForSession(sessionKey) {
|
|
|
63
63
|
if (!sessionId) return [];
|
|
64
64
|
return loadTranscriptRows(sessionId);
|
|
65
65
|
}
|
|
66
|
+
function loadTranscriptHistoryRowsForSession(sessionKey) {
|
|
67
|
+
if (!getCurrentSessionId(sessionKey)) return [];
|
|
68
|
+
return getSqliteDatabase().prepare(`SELECT e.entry_id, e.session_id, e.seq, e.entry_kind, e.role, e.payload_json, e.created_at
|
|
69
|
+
FROM transcript_entries e
|
|
70
|
+
JOIN transcripts t ON t.session_id = e.session_id
|
|
71
|
+
WHERE t.session_key = ?
|
|
72
|
+
AND (t.status = 'active' OR t.archive_reason IN ('reset', 'stale'))
|
|
73
|
+
ORDER BY t.created_at ASC, t.rowid ASC, e.seq ASC`).all(sessionKey).map(transcriptEntryRowToStoredRow);
|
|
74
|
+
}
|
|
66
75
|
function loadTranscriptRows(sessionId) {
|
|
67
76
|
return getSqliteDatabase().prepare(`SELECT entry_id, session_id, seq, entry_kind, role, payload_json, created_at
|
|
68
77
|
FROM transcript_entries
|
|
@@ -121,36 +130,36 @@ function paginateTranscriptMessages(sessionKey, options = {}) {
|
|
|
121
130
|
const db = getSqliteDatabase();
|
|
122
131
|
const kinds = options.includeContext ? ["message", "context"] : ["message"];
|
|
123
132
|
const kindPlaceholders = kinds.map(() => "?").join(", ");
|
|
124
|
-
const
|
|
125
|
-
|
|
133
|
+
const includeArchived = options.includeArchived === true;
|
|
134
|
+
const transcriptWhere = includeArchived ? `t.session_key = ? AND (t.status = 'active' OR t.archive_reason IN ('reset', 'stale'))` : "e.session_id = ?";
|
|
135
|
+
const transcriptArg = includeArchived ? sessionKey : sessionId;
|
|
136
|
+
const total = db.prepare(`SELECT COUNT(*) AS total
|
|
137
|
+
FROM transcript_entries e
|
|
138
|
+
JOIN transcripts t ON t.session_id = e.session_id
|
|
139
|
+
WHERE ${transcriptWhere} AND e.entry_kind IN (${kindPlaceholders})`).get(transcriptArg, ...kinds).total;
|
|
126
140
|
const limit = Math.min(200, Math.max(1, Math.trunc(options.limit ?? 50)));
|
|
127
141
|
const offset = Math.max(0, Math.trunc(options.offset ?? 0));
|
|
128
142
|
let rows;
|
|
129
|
-
if (options.
|
|
130
|
-
const endExclusive = Math.min(total, Math.max(0, Math.trunc(options.
|
|
143
|
+
if (options.beforeIndex !== void 0 && Number.isFinite(options.beforeIndex)) {
|
|
144
|
+
const endExclusive = Math.min(total, Math.max(0, Math.trunc(options.beforeIndex)));
|
|
131
145
|
const startInclusive = Math.max(0, endExclusive - limit);
|
|
132
146
|
rows = db.prepare(`SELECT entry_id, session_id, seq, entry_kind, role, payload_json, created_at
|
|
133
147
|
FROM (
|
|
134
|
-
SELECT entry_id, session_id, seq, entry_kind, role, payload_json, created_at,
|
|
135
|
-
ROW_NUMBER() OVER (ORDER BY seq ASC) - 1 AS idx
|
|
136
|
-
FROM transcript_entries
|
|
137
|
-
|
|
148
|
+
SELECT e.entry_id, e.session_id, e.seq, e.entry_kind, e.role, e.payload_json, e.created_at,
|
|
149
|
+
ROW_NUMBER() OVER (ORDER BY t.created_at ASC, t.rowid ASC, e.seq ASC) - 1 AS idx
|
|
150
|
+
FROM transcript_entries e
|
|
151
|
+
JOIN transcripts t ON t.session_id = e.session_id
|
|
152
|
+
WHERE ${transcriptWhere} AND e.entry_kind IN (${kindPlaceholders})
|
|
138
153
|
)
|
|
139
154
|
WHERE idx >= ? AND idx < ?
|
|
140
|
-
ORDER BY
|
|
141
|
-
} else if (options.beforeSeq !== void 0 && Number.isFinite(options.beforeSeq)) {
|
|
142
|
-
rows = db.prepare(`SELECT entry_id, session_id, seq, entry_kind, role, payload_json, created_at
|
|
143
|
-
FROM transcript_entries
|
|
144
|
-
WHERE session_id = ? AND entry_kind IN (${kindPlaceholders}) AND seq < ?
|
|
145
|
-
ORDER BY seq DESC
|
|
146
|
-
LIMIT ?`).all(sessionId, ...kinds, options.beforeSeq, limit);
|
|
147
|
-
rows.reverse();
|
|
155
|
+
ORDER BY idx ASC`).all(transcriptArg, ...kinds, startInclusive, endExclusive);
|
|
148
156
|
} else {
|
|
149
|
-
rows = db.prepare(`SELECT entry_id, session_id, seq, entry_kind, role, payload_json, created_at
|
|
150
|
-
FROM transcript_entries
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
157
|
+
rows = db.prepare(`SELECT e.entry_id, e.session_id, e.seq, e.entry_kind, e.role, e.payload_json, e.created_at
|
|
158
|
+
FROM transcript_entries e
|
|
159
|
+
JOIN transcripts t ON t.session_id = e.session_id
|
|
160
|
+
WHERE ${transcriptWhere} AND e.entry_kind IN (${kindPlaceholders})
|
|
161
|
+
ORDER BY t.created_at DESC, t.rowid DESC, e.seq DESC
|
|
162
|
+
LIMIT ? OFFSET ?`).all(transcriptArg, ...kinds, limit, offset);
|
|
154
163
|
rows.reverse();
|
|
155
164
|
}
|
|
156
165
|
const storedRows = rows.map(transcriptEntryRowToStoredRow);
|
|
@@ -244,4 +253,4 @@ function restoreCompactionCheckpoint(sessionKey, checkpointId) {
|
|
|
244
253
|
});
|
|
245
254
|
}
|
|
246
255
|
//#endregion
|
|
247
|
-
export { appendTranscriptEntry, captureCompactionCheckpoint, getCompactionCheckpointDetail, listCompactionCheckpoints, loadCheckpointRows, loadLlmMessagesForSession, loadTranscriptRows, loadTranscriptRowsForSession, paginateTranscriptMessages, replaceTranscriptRows, restoreCompactionCheckpoint };
|
|
256
|
+
export { appendTranscriptEntry, captureCompactionCheckpoint, getCompactionCheckpointDetail, listCompactionCheckpoints, loadCheckpointRows, loadLlmMessagesForSession, loadTranscriptHistoryRowsForSession, loadTranscriptRows, loadTranscriptRowsForSession, paginateTranscriptMessages, replaceTranscriptRows, restoreCompactionCheckpoint };
|
|
@@ -2,7 +2,7 @@ import type { ExtensionRegistryImpl } from '../../extensions/loader.js';
|
|
|
2
2
|
import { type SessionTimelineItem } from '../../session/transcript-outline.js';
|
|
3
3
|
import { type Config } from '../../config/schema.js';
|
|
4
4
|
import type { ExportFormat } from '../../session/types.js';
|
|
5
|
-
import type { ChatSendOptions, HistoryMessage, TuiBackend, TuiCompactionResult, TuiEvent, TuiModelChoice, TuiShareRequest, TuiShareResult, TuiSessionStats, TuiSessionItem, TuiTranscriptTreeEntry, TuiAgentInfo, TuiWorkspaceFileSearchEntry, TuiWorkflowRunStartRequest, TuiWorkflowRunStartResult, TuiStartupProjectResult } from '../tui-backend.js';
|
|
5
|
+
import type { ChatSendOptions, HistoryMessage, TuiBackend, TuiCompactionResult, TuiComposerHistoryItem, TuiEvent, TuiModelChoice, TuiShareRequest, TuiShareResult, TuiSessionStats, TuiSessionItem, TuiTranscriptTreeEntry, TuiAgentInfo, TuiWorkspaceFileSearchEntry, TuiWorkflowRunStartRequest, TuiWorkflowRunStartResult, TuiStartupProjectResult } from '../tui-backend.js';
|
|
6
6
|
import type { SessionInfo } from '../tui-types.js';
|
|
7
7
|
interface EmbeddedBackendOptions {
|
|
8
8
|
config?: Config;
|
|
@@ -33,6 +33,8 @@ export declare class EmbeddedBackend implements TuiBackend {
|
|
|
33
33
|
onDisconnected?: (reason: string) => void;
|
|
34
34
|
constructor(opts?: EmbeddedBackendOptions);
|
|
35
35
|
get connectionLabel(): string;
|
|
36
|
+
getComposerInputHistory(): Promise<TuiComposerHistoryItem[]>;
|
|
37
|
+
recordComposerInputHistory(text: string): Promise<TuiComposerHistoryItem>;
|
|
36
38
|
start(): void;
|
|
37
39
|
private ensureAgent;
|
|
38
40
|
private createAgent;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { createLogger } from "../../utils/logger/index.js";
|
|
2
2
|
import { init_logger } from "../../utils/logger.js";
|
|
3
3
|
import { openXopcDatabase } from "../../storage/sqlite/connection.js";
|
|
4
|
+
import { appendComposerInputHistory, listComposerInputHistory } from "../../storage/sqlite/composer-input-history-repository.js";
|
|
4
5
|
import { init_agent_session_key, resolveAgentIdFromSessionKey } from "../../routing/agent-session-key.js";
|
|
5
6
|
import { getSessionMetadata } from "../../storage/sqlite/session-repository.js";
|
|
6
7
|
import "../../storage/sqlite/index.js";
|
|
@@ -77,6 +78,12 @@ var EmbeddedBackend = class {
|
|
|
77
78
|
get connectionLabel() {
|
|
78
79
|
return "local embedded";
|
|
79
80
|
}
|
|
81
|
+
async getComposerInputHistory() {
|
|
82
|
+
return listComposerInputHistory();
|
|
83
|
+
}
|
|
84
|
+
async recordComposerInputHistory(text) {
|
|
85
|
+
return appendComposerInputHistory(text).item;
|
|
86
|
+
}
|
|
80
87
|
start() {
|
|
81
88
|
if (this.running) return;
|
|
82
89
|
this.running = true;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ExportFormat } from '../../session/types.js';
|
|
2
2
|
import type { SessionTimelineItem } from '../../session/transcript-outline.js';
|
|
3
|
-
import type { ChatSendOptions, HistoryMessage, TuiBackend, TuiCompactionResult, TuiEvent, TuiModelChoice, TuiShareRequest, TuiShareResult, TuiSessionStats, TuiSessionItem, TuiStartupResources, TuiTranscriptTreeEntry, TuiAgentInfo, TuiWorkspaceFileSearchEntry, TuiWorkflowRunStartRequest, TuiWorkflowRunStartResult, TuiStartupProjectResult } from '../tui-backend.js';
|
|
3
|
+
import type { ChatSendOptions, HistoryMessage, TuiBackend, TuiCompactionResult, TuiComposerHistoryItem, TuiEvent, TuiModelChoice, TuiShareRequest, TuiShareResult, TuiSessionStats, TuiSessionItem, TuiStartupResources, TuiTranscriptTreeEntry, TuiAgentInfo, TuiWorkspaceFileSearchEntry, TuiWorkflowRunStartRequest, TuiWorkflowRunStartResult, TuiStartupProjectResult } from '../tui-backend.js';
|
|
4
4
|
import type { SessionInfo } from '../tui-types.js';
|
|
5
5
|
import type { ReviewContext } from '../../review/review-git.js';
|
|
6
6
|
import { type GatewayCredential } from '../../gateway/credential.js';
|
|
@@ -33,6 +33,8 @@ export declare class GatewaySseBackend implements TuiBackend {
|
|
|
33
33
|
start(): void;
|
|
34
34
|
stop(): void;
|
|
35
35
|
getActiveSignal(): AbortSignal | undefined;
|
|
36
|
+
getComposerInputHistory(): Promise<TuiComposerHistoryItem[]>;
|
|
37
|
+
recordComposerInputHistory(text: string): Promise<TuiComposerHistoryItem>;
|
|
36
38
|
sendChat(opts: ChatSendOptions): Promise<{
|
|
37
39
|
runId: string;
|
|
38
40
|
}>;
|
|
@@ -80,6 +80,19 @@ var GatewaySseBackend = class {
|
|
|
80
80
|
const signal = this.chatAbort?.signal;
|
|
81
81
|
return signal && !signal.aborted ? signal : void 0;
|
|
82
82
|
}
|
|
83
|
+
async getComposerInputHistory() {
|
|
84
|
+
const res = await gatewayFetch(this.baseUrl, "/api/composer-history", this.credential);
|
|
85
|
+
if (!res.ok) throw new Error(`Failed to load composer history (${res.status})`);
|
|
86
|
+
return (await res.json()).items ?? [];
|
|
87
|
+
}
|
|
88
|
+
async recordComposerInputHistory(text) {
|
|
89
|
+
const res = await gatewayFetch(this.baseUrl, "/api/composer-history", this.credential, {
|
|
90
|
+
method: "POST",
|
|
91
|
+
body: JSON.stringify({ text })
|
|
92
|
+
});
|
|
93
|
+
if (!res.ok) throw new Error(`Failed to save composer history (${res.status})`);
|
|
94
|
+
return (await res.json()).item;
|
|
95
|
+
}
|
|
83
96
|
async sendChat(opts) {
|
|
84
97
|
this.chatAbort?.abort();
|
|
85
98
|
this.chatAbort = new AbortController();
|
|
@@ -13,5 +13,6 @@ export declare class CustomEditor extends Editor {
|
|
|
13
13
|
onExtensionShortcut?: (data: string) => boolean;
|
|
14
14
|
constructor(tui: TUI, theme: EditorTheme, keybindings: KeybindingsManager, options?: EditorOptions);
|
|
15
15
|
onAction(action: XopcTuiAppKeybinding, handler: () => void): void;
|
|
16
|
+
replaceHistory(itemsNewestFirst: string[]): void;
|
|
16
17
|
handleInput(data: string): void;
|
|
17
18
|
}
|
|
@@ -18,6 +18,12 @@ var CustomEditor = class extends Editor {
|
|
|
18
18
|
onAction(action, handler) {
|
|
19
19
|
this.actionHandlers.set(action, handler);
|
|
20
20
|
}
|
|
21
|
+
replaceHistory(itemsNewestFirst) {
|
|
22
|
+
const internals = this;
|
|
23
|
+
internals.history = itemsNewestFirst.slice(0, 100);
|
|
24
|
+
internals.historyIndex = -1;
|
|
25
|
+
internals.historyDraft = "";
|
|
26
|
+
}
|
|
21
27
|
handleInput(data) {
|
|
22
28
|
if (this.onExtensionShortcut?.(data)) return;
|
|
23
29
|
if (this.keybindings.matches(data, "app.clipboard.pasteImage")) {
|
|
@@ -25,6 +25,11 @@ export interface TuiEvent {
|
|
|
25
25
|
data: unknown;
|
|
26
26
|
source?: TuiEventSource;
|
|
27
27
|
}
|
|
28
|
+
export interface TuiComposerHistoryItem {
|
|
29
|
+
id: number;
|
|
30
|
+
text: string;
|
|
31
|
+
createdAt: number;
|
|
32
|
+
}
|
|
28
33
|
/** Minimal session list item. */
|
|
29
34
|
export interface TuiSessionItem {
|
|
30
35
|
key: string;
|
|
@@ -180,6 +185,10 @@ export interface TuiBackend {
|
|
|
180
185
|
stop(): void;
|
|
181
186
|
/** Current active chat abort signal, if a run is in progress. */
|
|
182
187
|
getActiveSignal?(): AbortSignal | undefined;
|
|
188
|
+
/** Global composer history, shared across sessions and clients. */
|
|
189
|
+
getComposerInputHistory(): Promise<TuiComposerHistoryItem[]>;
|
|
190
|
+
/** Persist one submitted chat input. */
|
|
191
|
+
recordComposerInputHistory(text: string): Promise<TuiComposerHistoryItem>;
|
|
183
192
|
/** Send a chat message, returns the run id. */
|
|
184
193
|
sendChat(opts: ChatSendOptions): Promise<{
|
|
185
194
|
runId: string;
|
|
@@ -7,6 +7,7 @@ export declare function createEditorSubmitHandler(params: {
|
|
|
7
7
|
setText: (value: string) => void;
|
|
8
8
|
addToHistory: (value: string) => void;
|
|
9
9
|
};
|
|
10
|
+
recordChatHistory?: (value: string) => void;
|
|
10
11
|
handleCommand: (value: string) => void | Promise<void>;
|
|
11
12
|
sendMessage: (value: string) => void | Promise<void>;
|
|
12
13
|
handleBangLine: (value: string) => void | Promise<void>;
|
|
@@ -36,7 +36,7 @@ function createEditorSubmitHandler(params) {
|
|
|
36
36
|
params.handleBangLine(raw);
|
|
37
37
|
return;
|
|
38
38
|
}
|
|
39
|
-
params.editor.addToHistory(
|
|
39
|
+
if (rawTrimmed) (params.recordChatHistory ?? params.editor.addToHistory)(rawTrimmed);
|
|
40
40
|
if (value.startsWith("/")) {
|
|
41
41
|
params.handleCommand(value);
|
|
42
42
|
return;
|
package/dist/src/tui/tui.js
CHANGED
|
@@ -360,6 +360,7 @@ async function runTui(opts) {
|
|
|
360
360
|
paddingX: tuiSettings.editorPaddingX,
|
|
361
361
|
autocompleteMaxVisible: tuiSettings.autocompleteMaxVisible
|
|
362
362
|
});
|
|
363
|
+
let composerHistoryTexts = [];
|
|
363
364
|
let editor = defaultEditor;
|
|
364
365
|
let editorComponentFactory;
|
|
365
366
|
const editorContainer = new Container();
|
|
@@ -421,6 +422,7 @@ async function runTui(opts) {
|
|
|
421
422
|
nextEditor.setAutocompleteProvider?.(extensionRuntime.autocompleteProvider);
|
|
422
423
|
copyDefaultEditorAppHandlers(nextEditor);
|
|
423
424
|
editor = nextEditor;
|
|
425
|
+
for (const text of composerHistoryTexts.slice().reverse()) editor.addToHistory?.(text);
|
|
424
426
|
} else {
|
|
425
427
|
defaultEditor.setText(currentText);
|
|
426
428
|
editor = defaultEditor;
|
|
@@ -1762,12 +1764,48 @@ async function runTui(opts) {
|
|
|
1762
1764
|
updateFooter();
|
|
1763
1765
|
tui.requestRender();
|
|
1764
1766
|
};
|
|
1767
|
+
let composerHistory = [];
|
|
1768
|
+
let composerHistoryWriteQueue = Promise.resolve();
|
|
1769
|
+
const applyComposerHistory = (next) => {
|
|
1770
|
+
composerHistory = next.slice(0, 100);
|
|
1771
|
+
composerHistoryTexts = composerHistory.map((item) => item.text);
|
|
1772
|
+
if (editor === defaultEditor) {
|
|
1773
|
+
defaultEditor.replaceHistory(composerHistory.map((item) => item.text));
|
|
1774
|
+
return;
|
|
1775
|
+
}
|
|
1776
|
+
for (const item of composerHistory.slice().reverse()) editor.addToHistory?.(item.text);
|
|
1777
|
+
};
|
|
1778
|
+
const refreshComposerHistory = async () => {
|
|
1779
|
+
try {
|
|
1780
|
+
await composerHistoryWriteQueue;
|
|
1781
|
+
applyComposerHistory(await client.getComposerInputHistory());
|
|
1782
|
+
} catch {}
|
|
1783
|
+
};
|
|
1784
|
+
const recordChatHistory = (value) => {
|
|
1785
|
+
const text = value.trim();
|
|
1786
|
+
if (!text) return;
|
|
1787
|
+
editor.addToHistory?.(text);
|
|
1788
|
+
if (composerHistory[0]?.text !== text) {
|
|
1789
|
+
composerHistory = [{
|
|
1790
|
+
id: 0,
|
|
1791
|
+
text,
|
|
1792
|
+
createdAt: Date.now()
|
|
1793
|
+
}, ...composerHistory].slice(0, 100);
|
|
1794
|
+
composerHistoryTexts = composerHistory.map((item) => item.text);
|
|
1795
|
+
}
|
|
1796
|
+
composerHistoryWriteQueue = composerHistoryWriteQueue.then(async () => {
|
|
1797
|
+
const item = await client.recordComposerInputHistory(text);
|
|
1798
|
+
const optimisticIndex = composerHistory.findIndex((entry) => entry.id === 0 && entry.text === item.text);
|
|
1799
|
+
if (optimisticIndex >= 0) composerHistory[optimisticIndex] = item;
|
|
1800
|
+
}).catch(() => {});
|
|
1801
|
+
};
|
|
1765
1802
|
const submitBurst = createSubmitBurstCoalescer({
|
|
1766
1803
|
submit: createEditorSubmitHandler({
|
|
1767
1804
|
editor: {
|
|
1768
1805
|
setText: (value) => editor.setText(value),
|
|
1769
1806
|
addToHistory: (value) => editor.addToHistory?.(value)
|
|
1770
1807
|
},
|
|
1808
|
+
recordChatHistory: (value) => recordChatHistory(value),
|
|
1771
1809
|
handleCommand,
|
|
1772
1810
|
sendMessage,
|
|
1773
1811
|
handleBangLine: runLocalShellLine,
|
|
@@ -1798,7 +1836,7 @@ async function runTui(opts) {
|
|
|
1798
1836
|
tui.requestRender();
|
|
1799
1837
|
return;
|
|
1800
1838
|
}
|
|
1801
|
-
|
|
1839
|
+
recordChatHistory(text);
|
|
1802
1840
|
state.messageFollowUpQueue.push(text);
|
|
1803
1841
|
editor.setText("");
|
|
1804
1842
|
chatLog.addSystem(theme.dim(`Queued follow-up (${state.messageFollowUpQueue.length} in queue). ${tuiSettings.followUpMode === "all" ? "All queued messages send together when this reply finishes." : "Next sends when this reply finishes."}`));
|
|
@@ -2052,6 +2090,23 @@ async function runTui(opts) {
|
|
|
2052
2090
|
};
|
|
2053
2091
|
client.onEvent = (evt) => {
|
|
2054
2092
|
const data = evt.data ?? {};
|
|
2093
|
+
if (evt.event === "composer-history.appended") {
|
|
2094
|
+
const item = data;
|
|
2095
|
+
if (typeof item.text === "string" && typeof item.id === "number") {
|
|
2096
|
+
const optimisticIndex = composerHistory.findIndex((entry) => entry.id === 0 && entry.text === item.text);
|
|
2097
|
+
if (optimisticIndex >= 0) composerHistory[optimisticIndex] = item;
|
|
2098
|
+
else if (composerHistory[0]?.text !== item.text) {
|
|
2099
|
+
composerHistory = [item, ...composerHistory].slice(0, 100);
|
|
2100
|
+
composerHistoryTexts = composerHistory.map((entry) => entry.text);
|
|
2101
|
+
editor.addToHistory?.(item.text);
|
|
2102
|
+
} else composerHistory[0] = item;
|
|
2103
|
+
}
|
|
2104
|
+
return;
|
|
2105
|
+
}
|
|
2106
|
+
if (evt.event === "composer-history.cleared") {
|
|
2107
|
+
applyComposerHistory([]);
|
|
2108
|
+
return;
|
|
2109
|
+
}
|
|
2055
2110
|
if (evt.event === "workflow.run.updated" && handleWorkflowRunUpdated(data)) return;
|
|
2056
2111
|
dispatchAgentEvent(evt.event, data, state, chatLog, tui, setActivityStatus, touchStreamingActivity, onAgentRunEnded, (message) => sessionSnapshot.appendMessage("assistant", assistantMessagePlainText(message)), evt.source);
|
|
2057
2112
|
};
|
|
@@ -2061,6 +2116,7 @@ async function runTui(opts) {
|
|
|
2061
2116
|
setConnectionStatus(isLocalMode ? "local ready" : "gateway connected");
|
|
2062
2117
|
touchStreamingActivity();
|
|
2063
2118
|
(async () => {
|
|
2119
|
+
await refreshComposerHistory();
|
|
2064
2120
|
if (opts.openSessionPickerOnStart && !startupSessionPickerOpened) {
|
|
2065
2121
|
startupSessionPickerOpened = true;
|
|
2066
2122
|
await openSessionPickerOverlay(pickerSvc, {
|
|
@@ -2125,6 +2181,7 @@ async function runTui(opts) {
|
|
|
2125
2181
|
setConnectionStatus(`event gap: expected ${info.expected}, got ${info.received}`);
|
|
2126
2182
|
if (state.activeRunId) recoverActiveRunFromHistory("broadcast event gap");
|
|
2127
2183
|
else loadSessionHistory({ merge: true });
|
|
2184
|
+
refreshComposerHistory();
|
|
2128
2185
|
tui.requestRender();
|
|
2129
2186
|
};
|
|
2130
2187
|
const sigintHandler = () => handleCtrlC();
|
|
@@ -1,18 +1,12 @@
|
|
|
1
1
|
export interface WorkflowResultEnvelope {
|
|
2
2
|
title?: string;
|
|
3
3
|
summary: string;
|
|
4
|
-
sections
|
|
4
|
+
sections?: WorkflowResultSection[];
|
|
5
5
|
actions?: WorkflowNextAction[];
|
|
6
6
|
artifacts?: WorkflowArtifactRef[];
|
|
7
7
|
followUps?: WorkflowFollowUp[];
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
/** Product-level outcome contract for reusable workflow deliverables. */
|
|
11
|
-
export interface WorkflowOutcome {
|
|
12
|
-
summary: string;
|
|
13
|
-
artifacts?: WorkflowArtifactRef[];
|
|
14
|
-
followUps?: WorkflowFollowUp[];
|
|
15
|
-
structuredOutput?: unknown;
|
|
8
|
+
/** Machine-readable workflow output. It is intentionally not rendered as user-facing content. */
|
|
9
|
+
data?: unknown;
|
|
16
10
|
}
|
|
17
11
|
export interface WorkflowFollowUp {
|
|
18
12
|
id: string;
|
|
@@ -20,7 +14,7 @@ export interface WorkflowFollowUp {
|
|
|
20
14
|
prompt?: string;
|
|
21
15
|
priority?: 'low' | 'medium' | 'high';
|
|
22
16
|
}
|
|
23
|
-
export type WorkflowResultSection = WorkflowTextSection | WorkflowFindingsSection | WorkflowRisksSection | WorkflowQuestionsSection
|
|
17
|
+
export type WorkflowResultSection = WorkflowTextSection | WorkflowFindingsSection | WorkflowRisksSection | WorkflowQuestionsSection;
|
|
24
18
|
export interface WorkflowTextSection {
|
|
25
19
|
kind: 'text';
|
|
26
20
|
title: string;
|
|
@@ -41,11 +35,6 @@ export interface WorkflowQuestionsSection {
|
|
|
41
35
|
title: string;
|
|
42
36
|
items: string[];
|
|
43
37
|
}
|
|
44
|
-
export interface WorkflowJsonSection {
|
|
45
|
-
kind: 'json';
|
|
46
|
-
title: string;
|
|
47
|
-
value: unknown;
|
|
48
|
-
}
|
|
49
38
|
export interface WorkflowFinding {
|
|
50
39
|
title: string;
|
|
51
40
|
severity?: WorkflowSeverity;
|
|
@@ -177,7 +177,7 @@ var WorkflowEngine = class {
|
|
|
177
177
|
await eventQueue;
|
|
178
178
|
if (currentPhaseId) await appendEvent("phase_completed", { phaseId: currentPhaseId });
|
|
179
179
|
const result = requireWorkflowResultEnvelope(runtimeResult.result);
|
|
180
|
-
assertWorkflowOutput(definition, result);
|
|
180
|
+
assertWorkflowOutput(definition, result.data === void 0 ? result.summary : result.data);
|
|
181
181
|
await appendEvent("run_completed", { result });
|
|
182
182
|
await this.callHooks((hook) => hook.afterRun?.({
|
|
183
183
|
runId,
|
|
@@ -622,16 +622,7 @@ function groupReplayTargetsByPhase(targets) {
|
|
|
622
622
|
function buildReplayResultEnvelope(options, results) {
|
|
623
623
|
return {
|
|
624
624
|
summary: `Replay completed for ${results.filter((item) => item.status === "done").length}/${results.length} target${results.length === 1 ? "" : "s"}.`,
|
|
625
|
-
|
|
626
|
-
kind: "json",
|
|
627
|
-
title: "Replay targets",
|
|
628
|
-
value: {
|
|
629
|
-
sourceRunId: options.sourceRunId,
|
|
630
|
-
scope: options.replayScope,
|
|
631
|
-
targets: results
|
|
632
|
-
}
|
|
633
|
-
}],
|
|
634
|
-
structuredOutput: { replay: {
|
|
625
|
+
data: { replay: {
|
|
635
626
|
sourceRunId: options.sourceRunId,
|
|
636
627
|
scope: options.replayScope,
|
|
637
628
|
targets: results
|
|
@@ -669,6 +660,7 @@ function normalizeCompletedAgentStatus(status) {
|
|
|
669
660
|
function previewWorkflowValue(value) {
|
|
670
661
|
if (value === null || value === void 0) return;
|
|
671
662
|
if (typeof value === "string") return truncate(value, 300);
|
|
663
|
+
if (isWorkflowResultEnvelope(value)) return truncate(value.summary, 1200);
|
|
672
664
|
try {
|
|
673
665
|
return truncate(JSON.stringify(value), 300);
|
|
674
666
|
} catch {
|
|
@@ -687,12 +679,11 @@ function assertWorkflowOutput(definition, value) {
|
|
|
687
679
|
}
|
|
688
680
|
function isWorkflowResultEnvelope(value) {
|
|
689
681
|
if (!value || typeof value !== "object" || Array.isArray(value)) return false;
|
|
690
|
-
|
|
691
|
-
return typeof record.summary === "string" && Array.isArray(record.sections);
|
|
682
|
+
return typeof value.summary === "string";
|
|
692
683
|
}
|
|
693
684
|
function requireWorkflowResultEnvelope(value) {
|
|
694
685
|
if (isWorkflowResultEnvelope(value)) return value;
|
|
695
|
-
throw new WorkflowEngineRunError("result_validation_failed", "Workflow output node must return a result envelope with summary
|
|
686
|
+
throw new WorkflowEngineRunError("result_validation_failed", "Workflow output node must return a result envelope with summary.", false);
|
|
696
687
|
}
|
|
697
688
|
function toWorkflowRunError(err, wasAborted, abortReason) {
|
|
698
689
|
if (err instanceof WorkflowEngineRunError) return {
|
|
@@ -95,15 +95,10 @@ var GraphWorkflowRuntime = class {
|
|
|
95
95
|
};
|
|
96
96
|
} else if (node.kind === "merge") value = node.config.mode === "array" ? predecessors.map((entry) => entry.value) : Object.fromEntries(predecessors.map((entry) => [entry.id, entry.value]));
|
|
97
97
|
else {
|
|
98
|
-
const
|
|
98
|
+
const outputData = predecessors.length === 1 ? predecessors[0].value : Object.fromEntries(predecessors.map((entry) => [entry.id, entry.value]));
|
|
99
99
|
value = {
|
|
100
|
-
summary: node.config.summary ? renderTemplate(node.config.summary, options.args, outputs, predecessors, options.goal) :
|
|
101
|
-
|
|
102
|
-
kind: "json",
|
|
103
|
-
title: node.config.title ?? "Workflow result",
|
|
104
|
-
value: structuredOutput
|
|
105
|
-
}],
|
|
106
|
-
structuredOutput
|
|
100
|
+
summary: node.config.summary ? renderTemplate(node.config.summary, options.args, outputs, predecessors, options.goal) : renderResultContent(outputData),
|
|
101
|
+
...typeof outputData === "string" ? {} : { data: outputData }
|
|
107
102
|
};
|
|
108
103
|
}
|
|
109
104
|
outputs.set(node.id, value);
|
|
@@ -276,16 +271,17 @@ function createLimiter(limit) {
|
|
|
276
271
|
}
|
|
277
272
|
};
|
|
278
273
|
}
|
|
279
|
-
function
|
|
280
|
-
if (typeof value === "string") return value.
|
|
274
|
+
function renderResultContent(value) {
|
|
275
|
+
if (typeof value === "string") return value.trim();
|
|
281
276
|
if (value && typeof value === "object") {
|
|
282
277
|
const record = value;
|
|
283
278
|
for (const key of [
|
|
279
|
+
"content",
|
|
284
280
|
"summary",
|
|
285
281
|
"executiveSummary",
|
|
286
282
|
"result",
|
|
287
283
|
"answer"
|
|
288
|
-
]) if (typeof record[key] === "string") return record[key].
|
|
284
|
+
]) if (typeof record[key] === "string") return record[key].trim();
|
|
289
285
|
}
|
|
290
286
|
return "Workflow completed.";
|
|
291
287
|
}
|
|
@@ -4,8 +4,8 @@ import { publishAutomationProductEvent } from "../../automations/product-events.
|
|
|
4
4
|
import { GoalService } from "../../goals/goal-service.js";
|
|
5
5
|
import "../../goals/index.js";
|
|
6
6
|
import { DelegateSubagentRunner } from "../../agent/workflow/subagent-runner.js";
|
|
7
|
-
import { preflightWorkflowConnectors } from "../../connectors/workflow-preflight.js";
|
|
8
7
|
import { resolveModelRef } from "../../config/agent-typed-models.js";
|
|
8
|
+
import { preflightWorkflowConnectors } from "../../connectors/workflow-preflight.js";
|
|
9
9
|
import { CatalogWorkflowDefinitionRegistry } from "../registry/catalog-workflow-definition-registry.js";
|
|
10
10
|
import { validateWorkflowJsonSchema } from "../domain/schema-validation.js";
|
|
11
11
|
import { isTerminalWorkflowRunStatus } from "../domain/run.js";
|
|
@@ -160,7 +160,7 @@ var WorkflowSessionBridge = class {
|
|
|
160
160
|
const projectId = view.run.metadata?.projectId?.trim();
|
|
161
161
|
const agentId = view.run.metadata?.agentId?.trim();
|
|
162
162
|
if (!projectId || !agentId) return;
|
|
163
|
-
const resultText = view.run.result?.summary
|
|
163
|
+
const resultText = view.run.result?.summary.trim() || renderWorkflowText(runViewToSnapshot(view), view.run.status === "succeeded", { showResultPreviews: true });
|
|
164
164
|
upsertMemoryRecord({
|
|
165
165
|
id: `workflow-run:${view.run.id}`,
|
|
166
166
|
providerId: "workflow-run",
|
|
@@ -19,12 +19,7 @@ function rowToSummary(row) {
|
|
|
19
19
|
function resultPreview(view) {
|
|
20
20
|
const result = view.run.result;
|
|
21
21
|
if (result == null) return null;
|
|
22
|
-
|
|
23
|
-
try {
|
|
24
|
-
return JSON.stringify(result).slice(0, 500);
|
|
25
|
-
} catch {
|
|
26
|
-
return null;
|
|
27
|
-
}
|
|
22
|
+
return result.summary.slice(0, 500);
|
|
28
23
|
}
|
|
29
24
|
function parentSessionKey(view) {
|
|
30
25
|
if (view.run.source.kind === "chat") return view.run.source.sessionKey;
|
package/package.json
CHANGED