@xopcai/xopc 0.0.166 → 0.0.168
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/feishu/src/outbound/media-load.js +1 -1
- package/dist/extensions/telegram/xopc.extension.json +1 -1
- package/dist/gateway/static/root/assets/{activity-store-DkALQFJT.js → activity-store-DjEDu38T.js} +1 -1
- package/dist/gateway/static/root/assets/{agent-avatar-dicebear-Tr2hgn4j.js → agent-avatar-dicebear-DVuLzaJi.js} +1 -1
- package/dist/gateway/static/root/assets/agents-tF_QTWxn.js +2 -0
- package/dist/gateway/static/root/assets/{api-DPIXEcIq.js → api-DwVCuPOb.js} +1 -1
- package/dist/gateway/static/root/assets/{app-management-settings-panel-D7Nrbhez.js → app-management-settings-panel-spzVBvAu.js} +1 -1
- package/dist/gateway/static/root/assets/{appearance-settings-DNNbABFj.js → appearance-settings-CetimI47.js} +1 -1
- package/dist/gateway/static/root/assets/{apps-page-0zXIeywq.js → apps-page-HDyN6Fjx.js} +1 -1
- package/dist/gateway/static/root/assets/{archive-plugin-CizqFy4G.js → archive-plugin-TOmQ2XKc.js} +1 -1
- package/dist/gateway/static/root/assets/{attachment-load-DU8KjTua.js → attachment-load-NFNEWVLJ.js} +1 -1
- package/dist/gateway/static/root/assets/{automation-suggestion-card-3pqyIveW.js → automation-suggestion-card-B0FnLpSl.js} +1 -1
- package/dist/gateway/static/root/assets/{automations-page-DSz3xDsi.js → automations-page-DVevVD6A.js} +1 -1
- package/dist/gateway/static/root/assets/{binary-plugins-CipUnsOr.js → binary-plugins-Csc4xkR9.js} +1 -1
- package/dist/gateway/static/root/assets/{block-editor-XoEq6qiv.js → block-editor-C6Xgrbse.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-settings-page-COYvq3y5.js → browser-settings-page-CyDDEKxB.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-workflow-inputs-DRH995XI.js → browser-workflow-inputs-DaxyAai1.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-workflows-page-65edjhpz.js → browser-workflows-page-CaX6iIJA.js} +1 -1
- package/dist/gateway/static/root/assets/capabilities-settings-panel-EXZv96j1.js +7 -0
- package/dist/gateway/static/root/assets/capability-presets-api-DdCHSzcA.js +1 -0
- package/dist/gateway/static/root/assets/capability-presets-settings-panel-o08SXqM4.js +2 -0
- package/dist/gateway/static/root/assets/{channel-recipient-api-B5rLegwk.js → channel-recipient-api-BOkLI89e.js} +1 -1
- package/dist/gateway/static/root/assets/{channels-settings-D8nH0mve.js → channels-settings-aCN05KdJ.js} +1 -1
- package/dist/gateway/static/root/assets/channels-status-swr-ZrqadU60.js +1 -0
- package/dist/gateway/static/root/assets/{connector-logo-n4Hg41iD.js → connector-logo-Mp40HWsb.js} +1 -1
- package/dist/gateway/static/root/assets/{connectors-page-jvRWZn3Y.js → connectors-page-i0cu5rg5.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-D4OzBOwm.js → desktop-pet-BtzUJ0d7.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-settings-CDGezbaf.js → desktop-pet-settings-Dg0Duj8B.js} +1 -1
- package/dist/gateway/static/root/assets/{directory-picker-path-field-DmL4AUXQ.js → directory-picker-path-field-9f0k1wZq.js} +1 -1
- package/dist/gateway/static/root/assets/{dreaming-settings-ClUcBKnd.js → dreaming-settings-rdW7dsGP.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-debug-page-DsV_KUDM.js → extension-debug-page-C9zUnn-z.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-DJv_G1jY.js → extension-page-Cy5rfU0h.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-DUAlJ4CU.js → extension-settings-page-BjIquAw6.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-config-api-SVYgzqv7.js → gateway-config-api-AQQmI6SW.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-settings-YL6f2C_F.js → gateway-settings-CYNmbqHj.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-startup-retry-ulwTJovP.js → gateway-startup-retry-qnEmj-vL.js} +1 -1
- package/dist/gateway/static/root/assets/{goal-create-dialog-CJJe-4Co.js → goal-create-dialog-CkXaDfN3.js} +1 -1
- package/dist/gateway/static/root/assets/{goal-detail-page-Da9VMWRd.js → goal-detail-page-FqDa5bfO.js} +1 -1
- package/dist/gateway/static/root/assets/{goals-config-api-st_Itxa9.js → goals-config-api-CaVGtM6n.js} +1 -1
- package/dist/gateway/static/root/assets/{goals-page-B6pC7PYZ.js → goals-page-B-uBRGN6.js} +1 -1
- package/dist/gateway/static/root/assets/{goals-settings-BEZePZ5m.js → goals-settings-C9J3MX0F.js} +1 -1
- package/dist/gateway/static/root/assets/{heartbeat-settings-DpeD9GQ9.js → heartbeat-settings-C0qFLyew.js} +1 -1
- package/dist/gateway/static/root/assets/{index-BhQMnKH1.js → index-DchbD-qM.js} +9 -9
- package/dist/gateway/static/root/assets/index-DfE2j0g8.css +1 -0
- package/dist/gateway/static/root/assets/keyboard-shortcuts-settings-BAZlRZMd.js +1 -0
- package/dist/gateway/static/root/assets/{local-app-workbench-page-Ctia6lSG.js → local-app-workbench-page-DkJUQRyC.js} +1 -1
- package/dist/gateway/static/root/assets/{local-apps-page-DWF9rpWQ.js → local-apps-page-PcQABi7F.js} +1 -1
- package/dist/gateway/static/root/assets/locale-store-tnRLWdx2.js +1 -0
- package/dist/gateway/static/root/assets/{logs-page-D3gL6vHX.js → logs-page-B-nXM29t.js} +1 -1
- package/dist/gateway/static/root/assets/{markdown-split-BuduJ0Ev.js → markdown-split-B6W1H0Fj.js} +1 -1
- package/dist/gateway/static/root/assets/{media-plugins-CLASZjhT.js → media-plugins-B-r9Tj74.js} +1 -1
- package/dist/gateway/static/root/assets/{messages-C96Zjb0V.js → messages-B1EG4gdu.js} +2 -4
- package/dist/gateway/static/root/assets/{notes-page-ve3XiBDF.js → notes-page-BNECY6Oy.js} +1 -1
- package/dist/gateway/static/root/assets/{notes-workbench-oHU532lp.js → notes-workbench-Be97S0Im.js} +2 -2
- package/dist/gateway/static/root/assets/{page-tabs-DU85jn98.js → page-tabs-BmUWVWO9.js} +1 -1
- package/dist/gateway/static/root/assets/{preview-open-alternatives-CtchTuRQ.js → preview-open-alternatives-a76A8p5R.js} +1 -1
- package/dist/gateway/static/root/assets/{product-open-page-DFT6Fx6y.js → product-open-page-BWhYrt-U.js} +1 -1
- package/dist/gateway/static/root/assets/{project-detail-page-Ceu0NoC1.js → project-detail-page-md0ANZ-f.js} +1 -1
- package/dist/gateway/static/root/assets/{projects-page-CdpqOmO8.js → projects-page-D1MNrLcy.js} +1 -1
- package/dist/gateway/static/root/assets/{remote-access-hub-D1NKLyiR.js → remote-access-hub-GTuiqlJO.js} +1 -1
- package/dist/gateway/static/root/assets/{save-bar-controls-CmcrHpMc.js → save-bar-controls-_ZMLDSUw.js} +1 -1
- package/dist/gateway/static/root/assets/{schedule-field-DmIkP6JV.js → schedule-field-D4ErObRc.js} +1 -1
- package/dist/gateway/static/root/assets/{schema-form-Dkk9blN0.js → schema-form-PqNSGlcH.js} +1 -1
- package/dist/gateway/static/root/assets/{sessions-page-CMj_JaOk.js → sessions-page-Ct0MVjNv.js} +1 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-QOUph2Oq.js +1 -0
- package/dist/gateway/static/root/assets/{settings-form-section-CuQzWvg5.js → settings-form-section-BCKaoLhJ.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-loading-skeleton-C5FNbyej.js → settings-loading-skeleton-Dn95fked.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-a-A2yTGE.js → settings-page-C8MPUl2Q.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-layout-MuXpamWD.js → settings-page-layout-Bigc8-GR.js} +1 -1
- package/dist/gateway/static/root/assets/{setup-status-panel-BUdh8FKY.js → setup-status-panel-DFTcAHsd.js} +1 -1
- package/dist/gateway/static/root/assets/{share-preview-page-BfzzmTgg.js → share-preview-page-xAjqaV4y.js} +1 -1
- package/dist/gateway/static/root/assets/{shares-settings-8a9qnLF8.js → shares-settings-D2uvC_aM.js} +1 -1
- package/dist/gateway/static/root/assets/skill-reload-api-DYtfQXB-.js +1 -0
- package/dist/gateway/static/root/assets/{skills-page-CmHj-CKY.js → skills-page-6dr3RRVW.js} +1 -1
- package/dist/gateway/static/root/assets/{system-settings-panel-CyhRkWMi.js → system-settings-panel-BJJQulg9.js} +1 -1
- package/dist/gateway/static/root/assets/{theme-store-D37XLD_C.js → theme-store-H9T49Iar.js} +1 -1
- package/dist/gateway/static/root/assets/{time-picker-WEPp3HrB.js → time-picker-DsuPUbRE.js} +1 -1
- package/dist/gateway/static/root/assets/{typed-models-lib-Bi1uoxFR.js → typed-models-lib-Djk3F3EL.js} +1 -1
- package/dist/gateway/static/root/assets/{use-channel-catalog-DBh0dOC9.js → use-channel-catalog-UACJTyH0.js} +1 -1
- package/dist/gateway/static/root/assets/{user-context-page-BObEyiim.js → user-context-page-BC585kHK.js} +1 -1
- package/dist/gateway/static/root/assets/{voice-api-key-field-Gvgodhec.js → voice-api-key-field-CvocOFat.js} +1 -1
- package/dist/gateway/static/root/assets/{work-discovery-page-BHnjvGH1.js → work-discovery-page-DiMn6nrT.js} +1 -1
- package/dist/gateway/static/root/assets/{work-item-detail-page-CQ8ybkxx.js → work-item-detail-page-CFBlQbPy.js} +1 -1
- package/dist/gateway/static/root/assets/{work-page-D_U_En23.js → work-page-CLJLKqsf.js} +1 -1
- package/dist/gateway/static/root/assets/{workflow-run-setup-panel-B-Sk6gFn.js → workflow-run-setup-panel-DbQwWPjv.js} +1 -1
- package/dist/gateway/static/root/assets/{workflows-page-DT0pzfkz.js → workflows-page-BJOhlABF.js} +1 -1
- package/dist/gateway/static/root/index.html +8 -8
- package/dist/package.js +1 -1
- package/dist/src/agent/agent-manager.js +12 -5
- package/dist/src/agent/image/generation/custom-openai-images-provider.d.ts +7 -0
- package/dist/src/agent/image/generation/custom-openai-images-provider.js +81 -0
- package/dist/src/agent/image/generation/{openai-compatible-image-provider.d.ts → openai-images-provider.d.ts} +10 -31
- package/dist/src/agent/image/generation/{openai-compatible-image-provider.js → openai-images-provider.js} +36 -23
- package/dist/src/agent/image/generation/provider-registry.d.ts +2 -0
- package/dist/src/agent/image/generation/provider-registry.js +50 -4
- package/dist/src/agent/image/generation/providers/openai.js +2 -2
- package/dist/src/agent/image/generation/runtime.js +5 -1
- package/dist/src/agent/image/generation/types.d.ts +11 -0
- package/dist/src/agent/models/manager.d.ts +5 -0
- package/dist/src/agent/models/manager.js +8 -0
- package/dist/src/agent/prompt/sections/messaging-runtime.js +1 -1
- package/dist/src/agent/prompt/sections/tooling.js +1 -1
- package/dist/src/agent/tools/communication.js +25 -7
- package/dist/src/channels/plugin-registry.js +6 -1
- package/dist/src/cli/commands/channels.js +1 -1
- package/dist/src/cli/commands/connectors.js +1 -1
- package/dist/src/cli/commands/doctor/checks/image-providers.d.ts +2 -0
- package/dist/src/cli/commands/doctor/checks/image-providers.js +68 -0
- package/dist/src/cli/commands/doctor/flow.js +2 -0
- package/dist/src/cli/commands/extension-marketplace.js +1 -1
- package/dist/src/cli/commands/models.js +1 -1
- package/dist/src/cli/commands/onboard.js +1 -1
- package/dist/src/config/index.js +2 -2
- package/dist/src/config/models-json.d.ts +325 -0
- package/dist/src/config/models-json.js +139 -4
- package/dist/src/extensions/sdk/index.js +1 -1
- package/dist/src/gateway/custom-image-providers.d.ts +89 -0
- package/dist/src/gateway/custom-image-providers.js +59 -0
- package/dist/src/gateway/hono/routes/models.js +182 -1
- package/dist/src/gateway/hono/routes/workflows.js +1 -1
- package/dist/src/gateway/image-generation-setup.js +7 -1
- package/dist/src/gateway/service/config-coordinator.js +2 -0
- package/dist/src/gateway/service.js +2 -2
- package/dist/src/media-shared/http/index.d.ts +1 -1
- package/dist/src/media-shared/http/index.js +2 -2
- package/dist/src/media-shared/http/provider-http.d.ts +2 -0
- package/dist/src/media-shared/http/provider-http.js +43 -4
- package/dist/src/providers/model-reference-auditor.d.ts +1 -0
- package/dist/src/providers/model-reference-auditor.js +23 -13
- package/dist/src/session/patch-metadata.d.ts +2 -0
- package/dist/src/session/patch-metadata.js +2 -0
- package/dist/src/tui/backends/embedded-backend.d.ts +2 -0
- package/dist/src/tui/backends/embedded-backend.js +46 -9
- package/dist/src/tui/backends/gateway-sse-backend.js +10 -3
- package/dist/src/tui/tui-backend.d.ts +2 -0
- package/dist/src/tui/tui-empty-session-cleanup.d.ts +11 -0
- package/dist/src/tui/tui-empty-session-cleanup.js +37 -0
- package/dist/src/tui/tui.js +43 -16
- package/dist/src/workflows/service/workflow-run-service.js +1 -1
- package/package.json +2 -2
- package/dist/gateway/static/root/assets/agents-DZ69tC4K.js +0 -2
- package/dist/gateway/static/root/assets/capabilities-settings-panel-LOQyfdsM.js +0 -2
- package/dist/gateway/static/root/assets/capability-presets-api-XL4h7dCK.js +0 -1
- package/dist/gateway/static/root/assets/capability-presets-settings-panel-KPJFkt1h.js +0 -2
- package/dist/gateway/static/root/assets/channels-status-swr-DZZq0upi.js +0 -1
- package/dist/gateway/static/root/assets/index-BXtJvaQl.css +0 -1
- package/dist/gateway/static/root/assets/keyboard-shortcuts-settings-fhssr2-J.js +0 -1
- package/dist/gateway/static/root/assets/locale-store-C_ax27uc.js +0 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-DR9Q2ZyF.js +0 -1
- package/dist/gateway/static/root/assets/skill-reload-api-da5gLCer.js +0 -1
|
@@ -49,7 +49,8 @@ async function postJsonRequest(url, options) {
|
|
|
49
49
|
init: {
|
|
50
50
|
method: "POST",
|
|
51
51
|
headers,
|
|
52
|
-
body: JSON.stringify(options.body)
|
|
52
|
+
body: JSON.stringify(options.body),
|
|
53
|
+
redirect: "error"
|
|
53
54
|
}
|
|
54
55
|
});
|
|
55
56
|
await assertOkOrThrowProviderError(response, options.label);
|
|
@@ -62,7 +63,8 @@ async function postMultipartRequest(url, options) {
|
|
|
62
63
|
init: {
|
|
63
64
|
method: "POST",
|
|
64
65
|
headers,
|
|
65
|
-
body: options.body
|
|
66
|
+
body: options.body,
|
|
67
|
+
redirect: "error"
|
|
66
68
|
}
|
|
67
69
|
});
|
|
68
70
|
await assertOkOrThrowProviderError(response, options.label);
|
|
@@ -75,12 +77,49 @@ async function getJsonRequest(url, options) {
|
|
|
75
77
|
...options,
|
|
76
78
|
init: {
|
|
77
79
|
method: "GET",
|
|
78
|
-
headers
|
|
80
|
+
headers,
|
|
81
|
+
redirect: "error"
|
|
79
82
|
}
|
|
80
83
|
});
|
|
81
84
|
await assertOkOrThrowProviderError(response, options.label);
|
|
82
85
|
return response;
|
|
83
86
|
}
|
|
87
|
+
/** Read and parse a JSON response without allowing an unbounded body allocation. */
|
|
88
|
+
async function readJsonResponseLimited(response, maxBytes) {
|
|
89
|
+
if (!Number.isSafeInteger(maxBytes) || maxBytes <= 0) throw new Error("JSON response byte limit must be a positive safe integer.");
|
|
90
|
+
const declaredLength = Number.parseInt(response.headers.get("content-length") ?? "", 10);
|
|
91
|
+
if (Number.isFinite(declaredLength) && declaredLength > maxBytes) throw new Error(`Provider JSON response exceeds ${maxBytes} bytes.`);
|
|
92
|
+
const reader = response.body?.getReader();
|
|
93
|
+
if (!reader) throw new Error("Provider returned an empty JSON response.");
|
|
94
|
+
const chunks = [];
|
|
95
|
+
let total = 0;
|
|
96
|
+
try {
|
|
97
|
+
while (true) {
|
|
98
|
+
const { value, done } = await reader.read();
|
|
99
|
+
if (done) break;
|
|
100
|
+
if (!value?.byteLength) continue;
|
|
101
|
+
total += value.byteLength;
|
|
102
|
+
if (total > maxBytes) {
|
|
103
|
+
await reader.cancel().catch(() => {});
|
|
104
|
+
throw new Error(`Provider JSON response exceeds ${maxBytes} bytes.`);
|
|
105
|
+
}
|
|
106
|
+
chunks.push(value);
|
|
107
|
+
}
|
|
108
|
+
} finally {
|
|
109
|
+
reader.releaseLock();
|
|
110
|
+
}
|
|
111
|
+
const body = new Uint8Array(total);
|
|
112
|
+
let offset = 0;
|
|
113
|
+
for (const chunk of chunks) {
|
|
114
|
+
body.set(chunk, offset);
|
|
115
|
+
offset += chunk.byteLength;
|
|
116
|
+
}
|
|
117
|
+
try {
|
|
118
|
+
return JSON.parse(new TextDecoder().decode(body));
|
|
119
|
+
} catch {
|
|
120
|
+
throw new Error("Provider returned invalid JSON.");
|
|
121
|
+
}
|
|
122
|
+
}
|
|
84
123
|
/**
|
|
85
124
|
* Normalize a base URL: trim trailing slash, force http(s) scheme.
|
|
86
125
|
*/
|
|
@@ -107,4 +146,4 @@ async function waitProviderOperationPollInterval(intervalMs, signal) {
|
|
|
107
146
|
await setTimeout$1(intervalMs, void 0, { signal });
|
|
108
147
|
}
|
|
109
148
|
//#endregion
|
|
110
|
-
export { createProviderOperationDeadline, fetchWithTimeoutGuarded, getJsonRequest, normalizeBaseUrl, postJsonRequest, postMultipartRequest, waitProviderOperationPollInterval };
|
|
149
|
+
export { createProviderOperationDeadline, fetchWithTimeoutGuarded, getJsonRequest, normalizeBaseUrl, postJsonRequest, postMultipartRequest, readJsonResponseLimited, waitProviderOperationPollInterval };
|
|
@@ -11,4 +11,5 @@ export interface ModelReferenceHealth {
|
|
|
11
11
|
export declare function auditModelReferences(config: Config, sessionConfigs?: ReadonlyMap<string, SessionAgentConfig>, deps?: {
|
|
12
12
|
registry?: ModelRegistry;
|
|
13
13
|
catalog?: ModelCatalogSnapshot;
|
|
14
|
+
resolveImageGenerationModel?: (ref: string) => boolean;
|
|
14
15
|
}): ModelReferenceHealth[];
|
|
@@ -1,22 +1,25 @@
|
|
|
1
1
|
import { getModelCatalogStore, init_model_catalog_store } from "./model-catalog-store.js";
|
|
2
2
|
import { getModelRegistry, init_model_registry } from "./model-registry.js";
|
|
3
|
+
import { parseImageGenerationModelRef } from "../agent/image/generation/model-ref.js";
|
|
4
|
+
import { getImageGenerationProvider } from "../agent/image/generation/provider-registry.js";
|
|
3
5
|
//#region src/providers/model-reference-auditor.ts
|
|
4
6
|
init_model_catalog_store();
|
|
5
7
|
init_model_registry();
|
|
6
8
|
function asRecord(value) {
|
|
7
9
|
return value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
|
|
8
10
|
}
|
|
9
|
-
function addRef(out, value, location) {
|
|
11
|
+
function addRef(out, value, location, kind = "text") {
|
|
10
12
|
if (typeof value === "string" && value.trim()) out.push({
|
|
11
13
|
ref: value.trim(),
|
|
12
|
-
location
|
|
14
|
+
location,
|
|
15
|
+
kind
|
|
13
16
|
});
|
|
14
17
|
}
|
|
15
|
-
function collectToolModel(out, value, location) {
|
|
18
|
+
function collectToolModel(out, value, location, kind = "text") {
|
|
16
19
|
const model = asRecord(value);
|
|
17
20
|
if (!model) return;
|
|
18
|
-
addRef(out, model.primary, `${location}.primary
|
|
19
|
-
if (Array.isArray(model.fallbacks)) model.fallbacks.forEach((ref, index) => addRef(out, ref, `${location}.fallbacks[${index}]
|
|
21
|
+
addRef(out, model.primary, `${location}.primary`, kind);
|
|
22
|
+
if (Array.isArray(model.fallbacks)) model.fallbacks.forEach((ref, index) => addRef(out, ref, `${location}.fallbacks[${index}]`, kind));
|
|
20
23
|
}
|
|
21
24
|
function collectModelPolicy(out, value, location) {
|
|
22
25
|
const policy = asRecord(value);
|
|
@@ -29,7 +32,7 @@ function collectModelPolicy(out, value, location) {
|
|
|
29
32
|
if (Array.isArray(role.fallbacks)) role.fallbacks.forEach((ref, index) => addRef(out, ref, `${location}.roles.${roleId}.fallbacks[${index}]`));
|
|
30
33
|
}
|
|
31
34
|
collectToolModel(out, policy.imageModel, `${location}.imageModel`);
|
|
32
|
-
collectToolModel(out, policy.imageGenerationModel, `${location}.imageGenerationModel
|
|
35
|
+
collectToolModel(out, policy.imageGenerationModel, `${location}.imageGenerationModel`, "image-generation");
|
|
33
36
|
}
|
|
34
37
|
function collectReferences(config, sessionConfigs) {
|
|
35
38
|
const out = [];
|
|
@@ -47,22 +50,29 @@ function suggestedRef(ref, catalog) {
|
|
|
47
50
|
const first = source.models.find((model) => model.availability === "available");
|
|
48
51
|
return first ? `${providerId}/${first.id}` : void 0;
|
|
49
52
|
}
|
|
53
|
+
function hasImageGenerationModel(ref) {
|
|
54
|
+
const parsed = parseImageGenerationModelRef(ref);
|
|
55
|
+
if (!parsed) return false;
|
|
56
|
+
return getImageGenerationProvider(parsed.provider)?.models.includes(parsed.model) ?? false;
|
|
57
|
+
}
|
|
50
58
|
function auditModelReferences(config, sessionConfigs = /* @__PURE__ */ new Map(), deps = {}) {
|
|
51
59
|
const registry = deps.registry ?? getModelRegistry();
|
|
52
60
|
const catalog = deps.catalog ?? getModelCatalogStore().load();
|
|
61
|
+
const resolveImageGenerationModel = deps.resolveImageGenerationModel ?? hasImageGenerationModel;
|
|
53
62
|
const grouped = /* @__PURE__ */ new Map();
|
|
54
63
|
for (const reference of collectReferences(config, sessionConfigs)) {
|
|
55
|
-
const
|
|
56
|
-
|
|
57
|
-
grouped.set(reference.ref,
|
|
64
|
+
const references = grouped.get(reference.ref) ?? [];
|
|
65
|
+
references.push(reference);
|
|
66
|
+
grouped.set(reference.ref, references);
|
|
58
67
|
}
|
|
59
|
-
return [...grouped.entries()].map(([ref,
|
|
60
|
-
const availability = registry.resolve(ref) ? "available" : "unavailable";
|
|
61
|
-
const
|
|
68
|
+
return [...grouped.entries()].map(([ref, references]) => {
|
|
69
|
+
const availability = references.every((reference) => reference.kind === "image-generation" ? resolveImageGenerationModel(ref) : Boolean(registry.resolve(ref))) ? "available" : "unavailable";
|
|
70
|
+
const textOnly = references.every((reference) => reference.kind === "text");
|
|
71
|
+
const suggestion = availability === "unavailable" && textOnly ? suggestedRef(ref, catalog) : void 0;
|
|
62
72
|
return {
|
|
63
73
|
ref,
|
|
64
74
|
availability,
|
|
65
|
-
locations,
|
|
75
|
+
locations: references.map((reference) => reference.location),
|
|
66
76
|
...suggestion ? { suggestedRef: suggestion } : {}
|
|
67
77
|
};
|
|
68
78
|
}).sort((a, b) => a.ref.localeCompare(b.ref));
|
|
@@ -8,5 +8,7 @@ export type SessionPatchBody = {
|
|
|
8
8
|
/** When true, `tags` replaces the tag list; otherwise tags are union-merged. */
|
|
9
9
|
replaceTags?: boolean;
|
|
10
10
|
customData?: Record<string, unknown>;
|
|
11
|
+
hiddenFromSessionList?: boolean;
|
|
12
|
+
projectId?: string;
|
|
11
13
|
};
|
|
12
14
|
export declare function applySessionPatchToMetadata(existing: SessionMetadata, patch: SessionPatchBody): Partial<SessionMetadata>;
|
|
@@ -15,6 +15,8 @@ function applySessionPatchToMetadata(existing, patch) {
|
|
|
15
15
|
...existing.customData ?? {},
|
|
16
16
|
...patch.customData
|
|
17
17
|
};
|
|
18
|
+
if (typeof patch.hiddenFromSessionList === "boolean") out.hiddenFromSessionList = patch.hiddenFromSessionList;
|
|
19
|
+
if (typeof patch.projectId === "string") out.projectId = patch.projectId.trim() || void 0;
|
|
18
20
|
return out;
|
|
19
21
|
}
|
|
20
22
|
//#endregion
|
|
@@ -36,6 +36,7 @@ export declare class EmbeddedBackend implements TuiBackend {
|
|
|
36
36
|
start(): void;
|
|
37
37
|
private ensureAgent;
|
|
38
38
|
private createAgent;
|
|
39
|
+
private refreshXopcCloudModels;
|
|
39
40
|
stop(): void;
|
|
40
41
|
getActiveSignal(): AbortSignal | undefined;
|
|
41
42
|
private getWorkflowRunService;
|
|
@@ -100,6 +101,7 @@ export declare class EmbeddedBackend implements TuiBackend {
|
|
|
100
101
|
}>;
|
|
101
102
|
getSessionInfo(sessionKey: string): Promise<SessionInfo>;
|
|
102
103
|
listModels(): Promise<TuiModelChoice[]>;
|
|
104
|
+
refreshModels(): Promise<void>;
|
|
103
105
|
resetSession(sessionKey: string): Promise<void>;
|
|
104
106
|
patchSession(sessionKey: string, patch: Record<string, unknown>): Promise<void>;
|
|
105
107
|
compactSession(sessionKey: string, options?: {
|
|
@@ -122,6 +122,7 @@ var EmbeddedBackend = class {
|
|
|
122
122
|
}
|
|
123
123
|
}
|
|
124
124
|
async createAgent(config, sessionIndex) {
|
|
125
|
+
await this.refreshXopcCloudModels();
|
|
125
126
|
const { AgentService } = await import("../../agent/service.js");
|
|
126
127
|
const workspace = this.workspace || getWorkspacePath(config);
|
|
127
128
|
const modelId = getAgentDefaultModelRef(config);
|
|
@@ -143,6 +144,20 @@ var EmbeddedBackend = class {
|
|
|
143
144
|
await agent.start();
|
|
144
145
|
return agent;
|
|
145
146
|
}
|
|
147
|
+
async refreshXopcCloudModels() {
|
|
148
|
+
try {
|
|
149
|
+
const { XopcCloudModelSource } = await import("../../providers/xopc-cloud-model-source.js");
|
|
150
|
+
const result = await new XopcCloudModelSource().refresh();
|
|
151
|
+
if (result.status === "updated") log.info({ modelCount: result.modelCount }, `XOPC Cloud model catalog refreshed: ${result.modelCount} models`);
|
|
152
|
+
} catch (err) {
|
|
153
|
+
const errorMessage = err instanceof Error ? err.message : String(err);
|
|
154
|
+
log.warn({
|
|
155
|
+
err,
|
|
156
|
+
errorMessage,
|
|
157
|
+
phase: "model_catalog_refresh"
|
|
158
|
+
}, `XOPC Cloud model catalog refresh failed: ${errorMessage}`);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
146
161
|
stop() {
|
|
147
162
|
this.running = false;
|
|
148
163
|
this.chatAbort?.abort();
|
|
@@ -419,9 +434,10 @@ var EmbeddedBackend = class {
|
|
|
419
434
|
}
|
|
420
435
|
}
|
|
421
436
|
async getSessionStats(sessionKey) {
|
|
422
|
-
|
|
437
|
+
const store = this.agent?.sessionStore ?? this.sessionIndex?.getStore();
|
|
438
|
+
if (!store) return computeTuiSessionStats([]);
|
|
423
439
|
try {
|
|
424
|
-
return computeTuiSessionStats(await
|
|
440
|
+
return computeTuiSessionStats(await store.loadTranscriptRows(sessionKey));
|
|
425
441
|
} catch (error) {
|
|
426
442
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
427
443
|
log.warn({
|
|
@@ -485,9 +501,10 @@ var EmbeddedBackend = class {
|
|
|
485
501
|
}
|
|
486
502
|
}
|
|
487
503
|
async deleteSession(sessionKey) {
|
|
488
|
-
|
|
504
|
+
const store = this.agent?.sessionStore ?? this.sessionIndex?.getStore();
|
|
505
|
+
if (!store) return { ok: false };
|
|
489
506
|
try {
|
|
490
|
-
return { ok: await
|
|
507
|
+
return { ok: await store.deleteSession(sessionKey) };
|
|
491
508
|
} catch (error) {
|
|
492
509
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
493
510
|
log.warn({
|
|
@@ -535,6 +552,9 @@ var EmbeddedBackend = class {
|
|
|
535
552
|
contextWindow: model.contextWindow
|
|
536
553
|
}));
|
|
537
554
|
}
|
|
555
|
+
async refreshModels() {
|
|
556
|
+
await this.refreshXopcCloudModels();
|
|
557
|
+
}
|
|
538
558
|
async resetSession(sessionKey) {
|
|
539
559
|
if (!this.agent) return;
|
|
540
560
|
await this.agent.resetSession(sessionKey);
|
|
@@ -542,11 +562,6 @@ var EmbeddedBackend = class {
|
|
|
542
562
|
async patchSession(sessionKey, patch) {
|
|
543
563
|
const agent = await this.ensureAgent();
|
|
544
564
|
const projectId = typeof patch.projectId === "string" ? patch.projectId.trim() : "";
|
|
545
|
-
if (projectId) {
|
|
546
|
-
await this.sessionIndexReady;
|
|
547
|
-
await this.sessionIndex?.getStore().resolveTranscriptPath(sessionKey);
|
|
548
|
-
new ProjectService().attachSession(sessionKey, projectId);
|
|
549
|
-
}
|
|
550
565
|
const result = await agent.sessionConfig.patch(sessionKey, {
|
|
551
566
|
model: typeof patch.model === "string" ? patch.model : void 0,
|
|
552
567
|
thinkingLevel: typeof patch.thinkingLevel === "string" ? patch.thinkingLevel : void 0,
|
|
@@ -555,6 +570,28 @@ var EmbeddedBackend = class {
|
|
|
555
570
|
workingDirectory: typeof patch.workingDirectory === "string" ? patch.workingDirectory : void 0
|
|
556
571
|
});
|
|
557
572
|
if (!result.ok) throw new Error(result.error);
|
|
573
|
+
if (projectId) {
|
|
574
|
+
await this.sessionIndexReady;
|
|
575
|
+
await this.sessionIndex?.getStore().resolveTranscriptPath(sessionKey);
|
|
576
|
+
new ProjectService().attachSession(sessionKey, projectId);
|
|
577
|
+
}
|
|
578
|
+
const hiddenFromSessionList = typeof patch.hiddenFromSessionList === "boolean" ? patch.hiddenFromSessionList : void 0;
|
|
579
|
+
const customData = patch.customData && typeof patch.customData === "object" && !Array.isArray(patch.customData) ? patch.customData : void 0;
|
|
580
|
+
if (hiddenFromSessionList !== void 0 || customData !== void 0) {
|
|
581
|
+
await this.sessionIndexReady;
|
|
582
|
+
const store = this.sessionIndex?.getStore();
|
|
583
|
+
if (store) {
|
|
584
|
+
await store.resolveTranscriptPath(sessionKey);
|
|
585
|
+
const existing = getSessionMetadata(sessionKey);
|
|
586
|
+
if (existing && existing.messageCount === 0) await store.updateMetadata(sessionKey, {
|
|
587
|
+
...hiddenFromSessionList !== void 0 ? { hiddenFromSessionList } : {},
|
|
588
|
+
...customData ? { customData: {
|
|
589
|
+
...existing.customData ?? {},
|
|
590
|
+
...customData
|
|
591
|
+
} } : {}
|
|
592
|
+
});
|
|
593
|
+
}
|
|
594
|
+
}
|
|
558
595
|
}
|
|
559
596
|
async compactSession(sessionKey, options) {
|
|
560
597
|
if (!this.agent) return {
|
|
@@ -793,13 +793,20 @@ var GatewaySseBackend = class {
|
|
|
793
793
|
const json = await res.json().catch(() => ({}));
|
|
794
794
|
if (!res.ok || json.ok === false) throw new Error(json.error ?? `Session config patch failed (${res.status})`);
|
|
795
795
|
const projectId = typeof patch.projectId === "string" ? patch.projectId.trim() : "";
|
|
796
|
-
|
|
796
|
+
const hiddenFromSessionList = typeof patch.hiddenFromSessionList === "boolean" ? patch.hiddenFromSessionList : void 0;
|
|
797
|
+
const customData = patch.customData && typeof patch.customData === "object" && !Array.isArray(patch.customData) ? patch.customData : void 0;
|
|
798
|
+
if (projectId || hiddenFromSessionList !== void 0 || customData !== void 0) {
|
|
799
|
+
const metadataPatch = {
|
|
800
|
+
...projectId ? { projectId } : {},
|
|
801
|
+
...hiddenFromSessionList !== void 0 ? { hiddenFromSessionList } : {},
|
|
802
|
+
...customData ? { customData } : {}
|
|
803
|
+
};
|
|
797
804
|
const metaRes = await gatewayFetch(this.baseUrl, `/api/sessions/${encodeURIComponent(sessionKey)}`, this.credential, {
|
|
798
805
|
method: "PATCH",
|
|
799
|
-
body: JSON.stringify(
|
|
806
|
+
body: JSON.stringify(metadataPatch)
|
|
800
807
|
});
|
|
801
808
|
const metaJson = await metaRes.json().catch(() => ({}));
|
|
802
|
-
if (!metaRes.ok || metaJson.ok === false) throw new Error(metaJson.error ?? `Session
|
|
809
|
+
if (!metaRes.ok || metaJson.ok === false) throw new Error(metaJson.error ?? `Session metadata patch failed (${metaRes.status})`);
|
|
803
810
|
}
|
|
804
811
|
}
|
|
805
812
|
async renameSession(sessionKey, name) {
|
|
@@ -255,6 +255,8 @@ export interface TuiBackend {
|
|
|
255
255
|
getSessionInfo(sessionKey: string): Promise<SessionInfo>;
|
|
256
256
|
/** List available models. */
|
|
257
257
|
listModels(): Promise<TuiModelChoice[]>;
|
|
258
|
+
/** Refresh dynamic model catalogs after credentials change. */
|
|
259
|
+
refreshModels?(): Promise<void>;
|
|
258
260
|
/** Reset / create new session. */
|
|
259
261
|
resetSession(sessionKey: string): Promise<void>;
|
|
260
262
|
/** Rename session display name. */
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { TuiBackend } from './tui-backend.js';
|
|
2
|
+
export declare const GENERATED_TUI_SESSION_SHELL_PATCH: {
|
|
3
|
+
readonly hiddenFromSessionList: true;
|
|
4
|
+
readonly customData: {
|
|
5
|
+
readonly genericNewChatShell: true;
|
|
6
|
+
};
|
|
7
|
+
};
|
|
8
|
+
export declare function isGeneratedTuiSessionKey(sessionKey: string): boolean;
|
|
9
|
+
export declare function deleteGeneratedTuiSessionIfEmpty(client: Pick<TuiBackend, 'getSessionStats' | 'deleteSession'>, sessionKey: string): Promise<boolean>;
|
|
10
|
+
export declare function cleanupAbandonedTuiSessions(client: Pick<TuiBackend, 'listSessions' | 'getSessionStats' | 'deleteSession'>, currentSessionKey: string, nowMs?: number): Promise<string[]>;
|
|
11
|
+
export declare function hideLegacyEmptyTuiSessions(client: Pick<TuiBackend, 'listSessions' | 'patchSession'>): Promise<string[]>;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { parseAgentSessionKey } from "../routing/session-key-utils.js";
|
|
2
|
+
import { init_agent_session_key } from "../routing/agent-session-key.js";
|
|
3
|
+
//#region src/tui/tui-empty-session-cleanup.ts
|
|
4
|
+
init_agent_session_key();
|
|
5
|
+
const GENERATED_TUI_SUFFIX_RE = /^tui-[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
6
|
+
const ABANDONED_SESSION_AGE_MS = 60 * 6e4;
|
|
7
|
+
const GENERATED_TUI_SESSION_SHELL_PATCH = {
|
|
8
|
+
hiddenFromSessionList: true,
|
|
9
|
+
customData: { genericNewChatShell: true }
|
|
10
|
+
};
|
|
11
|
+
function isGeneratedTuiSessionKey(sessionKey) {
|
|
12
|
+
const parsed = parseAgentSessionKey(sessionKey);
|
|
13
|
+
return parsed ? GENERATED_TUI_SUFFIX_RE.test(parsed.rest) : false;
|
|
14
|
+
}
|
|
15
|
+
async function deleteGeneratedTuiSessionIfEmpty(client, sessionKey) {
|
|
16
|
+
if (!isGeneratedTuiSessionKey(sessionKey)) return false;
|
|
17
|
+
if ((await client.getSessionStats(sessionKey)).totalMessages > 0) return false;
|
|
18
|
+
return (await client.deleteSession(sessionKey)).ok;
|
|
19
|
+
}
|
|
20
|
+
async function cleanupAbandonedTuiSessions(client, currentSessionKey, nowMs = Date.now()) {
|
|
21
|
+
const candidates = (await client.listSessions()).filter((session) => session.key !== currentSessionKey && session.messageCount === 0 && typeof session.updatedAt === "number" && session.updatedAt <= nowMs - ABANDONED_SESSION_AGE_MS && isGeneratedTuiSessionKey(session.key));
|
|
22
|
+
const deleted = [];
|
|
23
|
+
for (const session of candidates) if (await deleteGeneratedTuiSessionIfEmpty(client, session.key)) deleted.push(session.key);
|
|
24
|
+
return deleted;
|
|
25
|
+
}
|
|
26
|
+
async function hideLegacyEmptyTuiSessions(client) {
|
|
27
|
+
const sessions = await client.listSessions();
|
|
28
|
+
const hidden = [];
|
|
29
|
+
for (const session of sessions) {
|
|
30
|
+
if (session.messageCount !== 0 || !isGeneratedTuiSessionKey(session.key)) continue;
|
|
31
|
+
await client.patchSession(session.key, GENERATED_TUI_SESSION_SHELL_PATCH);
|
|
32
|
+
hidden.push(session.key);
|
|
33
|
+
}
|
|
34
|
+
return hidden;
|
|
35
|
+
}
|
|
36
|
+
//#endregion
|
|
37
|
+
export { GENERATED_TUI_SESSION_SHELL_PATCH, cleanupAbandonedTuiSessions, deleteGeneratedTuiSessionIfEmpty, hideLegacyEmptyTuiSessions, isGeneratedTuiSessionKey };
|
package/dist/src/tui/tui.js
CHANGED
|
@@ -27,6 +27,7 @@ import { transcriptTreeEntryIdToRowNumber } from "./tui-transcript-tree.js";
|
|
|
27
27
|
import { formatTuiCompactionResult, formatTuiShareResult } from "./tui-command-formatters.js";
|
|
28
28
|
import { formatTuiStartupText } from "./tui-startup-text.js";
|
|
29
29
|
import { createTuiCommandHandler, getSlashCommands } from "./tui-commands.js";
|
|
30
|
+
import { GENERATED_TUI_SESSION_SHELL_PATCH, cleanupAbandonedTuiSessions, deleteGeneratedTuiSessionIfEmpty, hideLegacyEmptyTuiSessions, isGeneratedTuiSessionKey } from "./tui-empty-session-cleanup.js";
|
|
30
31
|
import { extensionCustomMessageContentToText, extensionCustomMessageToTurnText, extensionUserMessageContentToText } from "./tui-extension-user-message.js";
|
|
31
32
|
import { resolveFdPath } from "./tui-fd-path.js";
|
|
32
33
|
import { drainFollowUpQueue, restoreQueuedMessages } from "./tui-follow-up-queue.js";
|
|
@@ -197,6 +198,9 @@ async function runTui(opts) {
|
|
|
197
198
|
let tuiSettings = loadTuiSettings();
|
|
198
199
|
initTuiTheme({ themeId: opts.theme ?? tuiSettings.theme });
|
|
199
200
|
const state = createInitialState(startup.sessionKey);
|
|
201
|
+
const generatedStartupSessionKey = !opts.session?.trim() && isGeneratedTuiSessionKey(startup.sessionKey) ? startup.sessionKey : null;
|
|
202
|
+
const generatedStartupSessionKeys = new Set(generatedStartupSessionKey ? [generatedStartupSessionKey] : []);
|
|
203
|
+
let startupSessionHadUserTurn = false;
|
|
200
204
|
const startupWorkingDirectory = resolveStartupWorkingDirectory(opts, isLocalMode);
|
|
201
205
|
const implicitTrustedWorkspace = startupWorkingDirectory ?? (isLocalMode ? process.cwd() : void 0);
|
|
202
206
|
const projectTrustStore = new ProjectTrustStore();
|
|
@@ -947,14 +951,21 @@ async function runTui(opts) {
|
|
|
947
951
|
clearInterval(streamWatchdogId);
|
|
948
952
|
streamWatchdogId = null;
|
|
949
953
|
}
|
|
950
|
-
client.stop();
|
|
951
954
|
tui.terminal.setProgress(false);
|
|
952
|
-
|
|
955
|
+
(async () => {
|
|
956
|
+
const removedEmptyStartupSessions = /* @__PURE__ */ new Set();
|
|
957
|
+
if (!state.activeRunId) for (const sessionKey of generatedStartupSessionKeys) {
|
|
958
|
+
if (sessionKey === state.currentSessionKey && startupSessionHadUserTurn) continue;
|
|
959
|
+
if (await deleteGeneratedTuiSessionIfEmpty(client, sessionKey).catch(() => false)) removedEmptyStartupSessions.add(sessionKey);
|
|
960
|
+
}
|
|
961
|
+
client.stop();
|
|
962
|
+
await drainAndStopTuiSafely(tui);
|
|
953
963
|
restoreStdio();
|
|
954
|
-
|
|
964
|
+
const currentSessionWasRemoved = removedEmptyStartupSessions.has(state.currentSessionKey);
|
|
965
|
+
if (options?.showResumeHint !== false && !currentSessionWasRemoved) process.stdout.write(`\nTo resume this session: ${formatTuiResumeCommand(opts, state.currentSessionKey)}\n`);
|
|
955
966
|
finishTui?.();
|
|
956
967
|
process.exit(0);
|
|
957
|
-
});
|
|
968
|
+
})();
|
|
958
969
|
};
|
|
959
970
|
const { refreshSessionInfo, loadHistory: loadSessionHistory, loadHistoryWindow, setSession, abortActive, resetCurrentSession, clearChatForSessionSwitch } = createSessionActions({
|
|
960
971
|
client,
|
|
@@ -1001,7 +1012,10 @@ async function runTui(opts) {
|
|
|
1001
1012
|
const applyStartupWorkingDirectory = async () => {
|
|
1002
1013
|
if (startupWorkingDirectoryApplied || !startupWorkingDirectory) return;
|
|
1003
1014
|
startupWorkingDirectoryApplied = true;
|
|
1004
|
-
await client.patchSession(state.currentSessionKey, {
|
|
1015
|
+
await client.patchSession(state.currentSessionKey, {
|
|
1016
|
+
workingDirectory: startupWorkingDirectory,
|
|
1017
|
+
...isGeneratedTuiSessionKey(state.currentSessionKey) ? GENERATED_TUI_SESSION_SHELL_PATCH : {}
|
|
1018
|
+
});
|
|
1005
1019
|
state.sessionInfo.effectiveWorkspacePath = startupWorkingDirectory;
|
|
1006
1020
|
state.sessionInfo.workingDirectoryLocked = true;
|
|
1007
1021
|
};
|
|
@@ -1018,15 +1032,22 @@ async function runTui(opts) {
|
|
|
1018
1032
|
const projectAgentId = result.project.defaultAgentId?.trim() ? normalizeAgentId(result.project.defaultAgentId) : void 0;
|
|
1019
1033
|
const currentParsed = parseAgentSessionKey(state.currentSessionKey);
|
|
1020
1034
|
if (!opts.agentId?.trim() && currentParsed?.rest && projectAgentId && projectAgentId !== currentAgentId) {
|
|
1021
|
-
|
|
1035
|
+
const targetSessionKey = `agent:${projectAgentId}:${currentParsed.rest}`;
|
|
1036
|
+
await setSession(targetSessionKey);
|
|
1037
|
+
if (isGeneratedTuiSessionKey(targetSessionKey)) generatedStartupSessionKeys.add(targetSessionKey);
|
|
1022
1038
|
currentAgentId = projectAgentId;
|
|
1039
|
+
if (isGeneratedTuiSessionKey(state.currentSessionKey)) await client.patchSession(state.currentSessionKey, GENERATED_TUI_SESSION_SHELL_PATCH);
|
|
1023
1040
|
await client.patchSession(state.currentSessionKey, {
|
|
1024
1041
|
projectId: result.project.id,
|
|
1025
|
-
workingDirectory: startupWorkingDirectory
|
|
1042
|
+
workingDirectory: startupWorkingDirectory,
|
|
1043
|
+
...isGeneratedTuiSessionKey(state.currentSessionKey) ? GENERATED_TUI_SESSION_SHELL_PATCH : {}
|
|
1026
1044
|
});
|
|
1027
1045
|
state.sessionInfo.effectiveWorkspacePath = startupWorkingDirectory;
|
|
1028
1046
|
state.sessionInfo.workingDirectoryLocked = true;
|
|
1029
|
-
} else await client.patchSession(state.currentSessionKey, {
|
|
1047
|
+
} else await client.patchSession(state.currentSessionKey, {
|
|
1048
|
+
projectId: result.project.id,
|
|
1049
|
+
...isGeneratedTuiSessionKey(state.currentSessionKey) ? GENERATED_TUI_SESSION_SHELL_PATCH : {}
|
|
1050
|
+
});
|
|
1030
1051
|
const verb = result.created ? "Created project" : "Using project";
|
|
1031
1052
|
chatLog.addStatus(theme.dim(`${verb}: ${result.project.name}`));
|
|
1032
1053
|
};
|
|
@@ -1458,6 +1479,7 @@ async function runTui(opts) {
|
|
|
1458
1479
|
return;
|
|
1459
1480
|
}
|
|
1460
1481
|
chatLog.addUser(userDisplayContentForAttachments(text, attachments));
|
|
1482
|
+
startupSessionHadUserTurn = true;
|
|
1461
1483
|
sessionSnapshot.appendMessage("user", messageText);
|
|
1462
1484
|
lastRetryMessageText = messageText;
|
|
1463
1485
|
markRunSending(state);
|
|
@@ -1682,14 +1704,18 @@ async function runTui(opts) {
|
|
|
1682
1704
|
getEntry: () => projectTrustStore.getEntry(process.cwd()),
|
|
1683
1705
|
getSessionDecision: () => projectTrustSessionDecision
|
|
1684
1706
|
},
|
|
1685
|
-
runLogin: (provider) =>
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1707
|
+
runLogin: async (provider) => {
|
|
1708
|
+
await runTuiOAuthLogin(provider, {
|
|
1709
|
+
chatLog,
|
|
1710
|
+
tui,
|
|
1711
|
+
editor,
|
|
1712
|
+
openOverlay: openCommandOverlay,
|
|
1713
|
+
closeOverlay: closeCommandOverlay,
|
|
1714
|
+
keybindings
|
|
1715
|
+
});
|
|
1716
|
+
await client.refreshModels?.();
|
|
1717
|
+
await refreshModelChoices();
|
|
1718
|
+
}
|
|
1693
1719
|
});
|
|
1694
1720
|
const { runLocalShellLine } = createLocalShellRunner({
|
|
1695
1721
|
chatLog,
|
|
@@ -2064,6 +2090,7 @@ async function runTui(opts) {
|
|
|
2064
2090
|
await refreshSessionInfoWithBorder();
|
|
2065
2091
|
await refreshModelChoices();
|
|
2066
2092
|
await loadSessionHistory({ merge: true });
|
|
2093
|
+
cleanupAbandonedTuiSessions(client, state.currentSessionKey).then(() => hideLegacyEmptyTuiSessions(client)).catch(() => {});
|
|
2067
2094
|
showStartupCardOnce();
|
|
2068
2095
|
refreshStartupResources().then(() => {
|
|
2069
2096
|
updateFooter();
|
|
@@ -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 { resolveModelRef } from "../../config/agent-typed-models.js";
|
|
8
7
|
import { preflightWorkflowConnectors } from "../../connectors/workflow-preflight.js";
|
|
8
|
+
import { resolveModelRef } from "../../config/agent-typed-models.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";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xopcai/xopc",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.168",
|
|
4
4
|
"description": "Local-first AI system that remembers context, coordinates AI, and sustains long-term progress.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/src/index.js",
|
|
@@ -100,7 +100,7 @@
|
|
|
100
100
|
"semver": "^7.8.1",
|
|
101
101
|
"silk-wasm": "^3.7.1",
|
|
102
102
|
"thread-stream": "^4.2.0",
|
|
103
|
-
"undici": "^8.
|
|
103
|
+
"undici": "^8.9.0",
|
|
104
104
|
"uuid": "^14.0.0",
|
|
105
105
|
"ws": "^8.21.0",
|
|
106
106
|
"zod": "^4.4.3"
|