@xopcai/xopc 0.0.167 → 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/telegram/xopc.extension.json +1 -1
- package/dist/gateway/static/root/assets/{agent-avatar-dicebear-DQULz7qY.js → agent-avatar-dicebear-DVuLzaJi.js} +1 -1
- package/dist/gateway/static/root/assets/{agents-CnzkBgKC.js → agents-tF_QTWxn.js} +1 -1
- package/dist/gateway/static/root/assets/{app-management-settings-panel-DOjWALVF.js → app-management-settings-panel-spzVBvAu.js} +1 -1
- package/dist/gateway/static/root/assets/{appearance-settings-C31COUIC.js → appearance-settings-CetimI47.js} +1 -1
- package/dist/gateway/static/root/assets/{apps-page-lSC486eu.js → apps-page-HDyN6Fjx.js} +1 -1
- package/dist/gateway/static/root/assets/{archive-plugin-DQPvLqfx.js → archive-plugin-TOmQ2XKc.js} +1 -1
- package/dist/gateway/static/root/assets/{attachment-load-DwT1x1rc.js → attachment-load-NFNEWVLJ.js} +1 -1
- package/dist/gateway/static/root/assets/{automation-suggestion-card-ByYBiiMR.js → automation-suggestion-card-B0FnLpSl.js} +1 -1
- package/dist/gateway/static/root/assets/{automations-page-iZTnc1YZ.js → automations-page-DVevVD6A.js} +1 -1
- package/dist/gateway/static/root/assets/{binary-plugins-CRXiHoZS.js → binary-plugins-Csc4xkR9.js} +1 -1
- package/dist/gateway/static/root/assets/{block-editor-CHO6ILiz.js → block-editor-C6Xgrbse.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-settings-page-C-OOPZcJ.js → browser-settings-page-CyDDEKxB.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-workflow-inputs-3UaarfXS.js → browser-workflow-inputs-DaxyAai1.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-workflows-page-BFaa-N_D.js → browser-workflows-page-CaX6iIJA.js} +1 -1
- package/dist/gateway/static/root/assets/{capabilities-settings-panel-BayH0Uom.js → capabilities-settings-panel-EXZv96j1.js} +1 -1
- package/dist/gateway/static/root/assets/{capability-presets-settings-panel-JlhjAhT7.js → capability-presets-settings-panel-o08SXqM4.js} +1 -1
- package/dist/gateway/static/root/assets/{channels-settings-C-Spmwr5.js → channels-settings-aCN05KdJ.js} +1 -1
- package/dist/gateway/static/root/assets/{connector-logo-CbcC0T6i.js → connector-logo-Mp40HWsb.js} +1 -1
- package/dist/gateway/static/root/assets/{connectors-page-DpDmJ3Nx.js → connectors-page-i0cu5rg5.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-CR7RGQff.js → desktop-pet-BtzUJ0d7.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-settings-BudmCcPE.js → desktop-pet-settings-Dg0Duj8B.js} +1 -1
- package/dist/gateway/static/root/assets/{directory-picker-path-field-BLG2Oe6z.js → directory-picker-path-field-9f0k1wZq.js} +1 -1
- package/dist/gateway/static/root/assets/{dreaming-settings-BwBGC0SG.js → dreaming-settings-rdW7dsGP.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-debug-page-Pr65_hLC.js → extension-debug-page-C9zUnn-z.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-BuJDcoKn.js → extension-page-Cy5rfU0h.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-B3802tn5.js → extension-settings-page-BjIquAw6.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-config-api-D-NVkfts.js → gateway-config-api-AQQmI6SW.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-settings-DIdsKVXv.js → gateway-settings-CYNmbqHj.js} +1 -1
- package/dist/gateway/static/root/assets/{goal-create-dialog-51j_DxgV.js → goal-create-dialog-CkXaDfN3.js} +1 -1
- package/dist/gateway/static/root/assets/{goal-detail-page-CeqMr5GF.js → goal-detail-page-FqDa5bfO.js} +1 -1
- package/dist/gateway/static/root/assets/{goals-config-api-BkVBh7ct.js → goals-config-api-CaVGtM6n.js} +1 -1
- package/dist/gateway/static/root/assets/{goals-page-lf3oM4Xa.js → goals-page-B-uBRGN6.js} +1 -1
- package/dist/gateway/static/root/assets/{goals-settings-Cg7MJLvx.js → goals-settings-C9J3MX0F.js} +1 -1
- package/dist/gateway/static/root/assets/{heartbeat-settings-BV3kJOcX.js → heartbeat-settings-C0qFLyew.js} +1 -1
- package/dist/gateway/static/root/assets/{index-B24B26og.js → index-DchbD-qM.js} +6 -6
- package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-B9K5rTZZ.js → keyboard-shortcuts-settings-BAZlRZMd.js} +1 -1
- package/dist/gateway/static/root/assets/{local-app-workbench-page-ehzr9CBG.js → local-app-workbench-page-DkJUQRyC.js} +1 -1
- package/dist/gateway/static/root/assets/{local-apps-page-BBx6mfAD.js → local-apps-page-PcQABi7F.js} +1 -1
- package/dist/gateway/static/root/assets/{logs-page-xuwEkusZ.js → logs-page-B-nXM29t.js} +1 -1
- package/dist/gateway/static/root/assets/{markdown-split-DRDddIt8.js → markdown-split-B6W1H0Fj.js} +1 -1
- package/dist/gateway/static/root/assets/{media-plugins-Dn3hxhOV.js → media-plugins-B-r9Tj74.js} +1 -1
- package/dist/gateway/static/root/assets/{notes-page-BtKHSb4z.js → notes-page-BNECY6Oy.js} +1 -1
- package/dist/gateway/static/root/assets/{notes-workbench-DXGXn5XF.js → notes-workbench-Be97S0Im.js} +2 -2
- package/dist/gateway/static/root/assets/{page-tabs-P2BEd1D8.js → page-tabs-BmUWVWO9.js} +1 -1
- package/dist/gateway/static/root/assets/{preview-open-alternatives-DrkjmW0F.js → preview-open-alternatives-a76A8p5R.js} +1 -1
- package/dist/gateway/static/root/assets/{product-open-page-CGzMEowb.js → product-open-page-BWhYrt-U.js} +1 -1
- package/dist/gateway/static/root/assets/{project-detail-page-IiE2ddWb.js → project-detail-page-md0ANZ-f.js} +1 -1
- package/dist/gateway/static/root/assets/{projects-page-DGOVhaYI.js → projects-page-D1MNrLcy.js} +1 -1
- package/dist/gateway/static/root/assets/{remote-access-hub-l_y_Shgl.js → remote-access-hub-GTuiqlJO.js} +1 -1
- package/dist/gateway/static/root/assets/{save-bar-controls-BkGrufxl.js → save-bar-controls-_ZMLDSUw.js} +1 -1
- package/dist/gateway/static/root/assets/{schedule-field-A8tDpL-9.js → schedule-field-D4ErObRc.js} +1 -1
- package/dist/gateway/static/root/assets/{schema-form-N6_hDWgx.js → schema-form-PqNSGlcH.js} +1 -1
- package/dist/gateway/static/root/assets/{sessions-page-CAX4ipPv.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-Bb6yYt5f.js → settings-form-section-BCKaoLhJ.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-loading-skeleton-Q_Vh6HEl.js → settings-loading-skeleton-Dn95fked.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-CjOtQpbR.js → settings-page-C8MPUl2Q.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-layout-CtESNNdx.js → settings-page-layout-Bigc8-GR.js} +1 -1
- package/dist/gateway/static/root/assets/{setup-status-panel-CGxHXgJB.js → setup-status-panel-DFTcAHsd.js} +1 -1
- package/dist/gateway/static/root/assets/{share-preview-page-C65IsFmd.js → share-preview-page-xAjqaV4y.js} +1 -1
- package/dist/gateway/static/root/assets/{shares-settings-Ct3fcbHr.js → shares-settings-D2uvC_aM.js} +1 -1
- package/dist/gateway/static/root/assets/{skill-reload-api-ElA5kabh.js → skill-reload-api-DYtfQXB-.js} +1 -1
- package/dist/gateway/static/root/assets/{skills-page-FeieOEn3.js → skills-page-6dr3RRVW.js} +1 -1
- package/dist/gateway/static/root/assets/{system-settings-panel-CdUl2I0D.js → system-settings-panel-BJJQulg9.js} +1 -1
- package/dist/gateway/static/root/assets/{time-picker-EkhqT3fS.js → time-picker-DsuPUbRE.js} +1 -1
- package/dist/gateway/static/root/assets/{typed-models-lib-5xRRUE9Y.js → typed-models-lib-Djk3F3EL.js} +1 -1
- package/dist/gateway/static/root/assets/{user-context-page-DHiRvd4i.js → user-context-page-BC585kHK.js} +1 -1
- package/dist/gateway/static/root/assets/{voice-api-key-field-Bql0SPCp.js → voice-api-key-field-CvocOFat.js} +1 -1
- package/dist/gateway/static/root/assets/{work-discovery-page-BcmZux7y.js → work-discovery-page-DiMn6nrT.js} +1 -1
- package/dist/gateway/static/root/assets/{work-item-detail-page-D94Q5zVD.js → work-item-detail-page-CFBlQbPy.js} +1 -1
- package/dist/gateway/static/root/assets/{work-page-DdFBMDcB.js → work-page-CLJLKqsf.js} +1 -1
- package/dist/gateway/static/root/assets/{workflow-run-setup-panel-Dow7ZztR.js → workflow-run-setup-panel-DbQwWPjv.js} +1 -1
- package/dist/gateway/static/root/assets/{workflows-page-wOVSoduy.js → workflows-page-BJOhlABF.js} +1 -1
- package/dist/gateway/static/root/index.html +1 -1
- package/dist/package.js +1 -1
- package/dist/src/agent/agent-manager.js +12 -5
- 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/gateway/heartbeat/service.js +1 -1
- package/dist/src/heartbeat/index.js +1 -1
- 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 +1 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-eVlH9brU.js +0 -1
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png?v=20260713-1" />
|
|
12
12
|
<link rel="manifest" href="/site.webmanifest?v=20260713-1" />
|
|
13
13
|
<title>XOPC — Turn goals into loops. Keep what matters moving.</title>
|
|
14
|
-
<script type="module" crossorigin src="/assets/index-
|
|
14
|
+
<script type="module" crossorigin src="/assets/index-DchbD-qM.js"></script>
|
|
15
15
|
<link rel="modulepreload" crossorigin href="/assets/rolldown-runtime-aKtaBQYM.js">
|
|
16
16
|
<link rel="modulepreload" crossorigin href="/assets/preload-helper-zJ_50EbN.js">
|
|
17
17
|
<link rel="modulepreload" crossorigin href="/assets/vendor-react-BOUWij0V.js">
|
package/dist/package.js
CHANGED
|
@@ -649,7 +649,17 @@ var AgentManager = class {
|
|
|
649
649
|
if (isMemorySubsystemEnabled(cfg) && shouldRegisterCuratedMemoryTool(cfg)) rt.builtinMemoryStore.loadFromDiskSync();
|
|
650
650
|
const activeProjectContext = buildActiveProjectContextForPrompt(sessionKey);
|
|
651
651
|
const activeSelfVerifyContext = this.getSelfVerifyPromptContext(sessionKey, profile.agentId);
|
|
652
|
-
const
|
|
652
|
+
const profileModelRef = profile.primaryModelRef?.trim() || this.defaultModel;
|
|
653
|
+
const modelManager = this.config.getModelManager?.();
|
|
654
|
+
const initialModelRef = modelManager?.resolveInitialModelForSession(sessionKey, profileModelRef, profile.fallbacks) ?? profileModelRef;
|
|
655
|
+
let created;
|
|
656
|
+
try {
|
|
657
|
+
created = this.createAgentForProfile(sessionKey, profile, initialModelRef, resolvedPath, rt, activeProjectContext, activeSelfVerifyContext);
|
|
658
|
+
} catch (err) {
|
|
659
|
+
modelManager?.clearSessionProfileDefault(sessionKey);
|
|
660
|
+
throw err;
|
|
661
|
+
}
|
|
662
|
+
const { agent, registeredToolNames } = created;
|
|
653
663
|
this.agents.set(sessionKey, {
|
|
654
664
|
agent,
|
|
655
665
|
sessionKey,
|
|
@@ -663,8 +673,6 @@ var AgentManager = class {
|
|
|
663
673
|
activeSelfVerifyContext,
|
|
664
674
|
skillEnvPassthroughKeys: /* @__PURE__ */ new Set()
|
|
665
675
|
});
|
|
666
|
-
const modelRef = profile.primaryModelRef?.trim() || this.defaultModel;
|
|
667
|
-
this.config.getModelManager?.().setSessionProfileDefault(sessionKey, modelRef, profile.fallbacks);
|
|
668
676
|
log.debug({
|
|
669
677
|
sessionKey,
|
|
670
678
|
totalAgents: this.agents.size,
|
|
@@ -822,8 +830,7 @@ var AgentManager = class {
|
|
|
822
830
|
const inst = sessionKey?.trim() ? this.agents.get(sessionKey.trim()) : void 0;
|
|
823
831
|
return this.resolveCapabilityCatalogForInstance(inst);
|
|
824
832
|
}
|
|
825
|
-
createAgentForProfile(sessionKey, profile, resolvedWorkspacePath, rt, activeProjectContext, activeSelfVerifyContext) {
|
|
826
|
-
const modelRef = profile.primaryModelRef?.trim() || this.defaultModel;
|
|
833
|
+
createAgentForProfile(sessionKey, profile, modelRef, resolvedWorkspacePath, rt, activeProjectContext, activeSelfVerifyContext) {
|
|
827
834
|
const model = this.resolveModelStringToModel(modelRef);
|
|
828
835
|
let agent;
|
|
829
836
|
const contextFiles = this.resolveContextFilesForSession(sessionKey, profile);
|
|
@@ -31,6 +31,11 @@ export declare class ModelManager {
|
|
|
31
31
|
* Cleared by {@link updateFromConfig} or {@link clearSessionProfileDefault}.
|
|
32
32
|
*/
|
|
33
33
|
setSessionProfileDefault(sessionKey: string, modelRef: string, fallbacks?: string[]): void;
|
|
34
|
+
/**
|
|
35
|
+
* Register the profile model and return the model that should initialize the
|
|
36
|
+
* session agent. An existing per-session override always wins.
|
|
37
|
+
*/
|
|
38
|
+
resolveInitialModelForSession(sessionKey: string, profileModelRef: string, fallbacks?: string[]): string;
|
|
34
39
|
clearSessionProfileDefault(sessionKey: string): void;
|
|
35
40
|
/**
|
|
36
41
|
* Get current model name
|
|
@@ -44,6 +44,14 @@ var ModelManager = class {
|
|
|
44
44
|
if (cleanFallbacks.length > 0) this.sessionProfileFallbacks.set(sessionKey, cleanFallbacks);
|
|
45
45
|
else this.sessionProfileFallbacks.delete(sessionKey);
|
|
46
46
|
}
|
|
47
|
+
/**
|
|
48
|
+
* Register the profile model and return the model that should initialize the
|
|
49
|
+
* session agent. An existing per-session override always wins.
|
|
50
|
+
*/
|
|
51
|
+
resolveInitialModelForSession(sessionKey, profileModelRef, fallbacks = []) {
|
|
52
|
+
this.setSessionProfileDefault(sessionKey, profileModelRef, fallbacks);
|
|
53
|
+
return this.getModelForSession(sessionKey);
|
|
54
|
+
}
|
|
47
55
|
clearSessionProfileDefault(sessionKey) {
|
|
48
56
|
this.sessionProfileDefaults.delete(sessionKey);
|
|
49
57
|
this.sessionProfileFallbacks.delete(sessionKey);
|
|
@@ -3,7 +3,7 @@ import { NO_REPLY } from "../../../heartbeat/tokens.js";
|
|
|
3
3
|
function buildMessagingSection(params) {
|
|
4
4
|
if (params.isMinimal || params.channels.length === 0) return "";
|
|
5
5
|
const channelList = params.channels.join(", ");
|
|
6
|
-
const messageToolLine = params.hasSendMessage ? `- Use \`send_message\` for proactive sends + channel actions` : "- Outbound messaging tools are not available in this session";
|
|
6
|
+
const messageToolLine = params.hasSendMessage ? `- Use \`send_message\` for proactive sends + channel actions; provide \`channel\` and \`chat_id\` together for a cross-channel destination` : "- Outbound messaging tools are not available in this session";
|
|
7
7
|
return [
|
|
8
8
|
"## Messaging",
|
|
9
9
|
`- Reply in current session → automatically routes to the source channel (${channelList})`,
|
|
@@ -57,7 +57,7 @@ const CORE_TOOL_SUMMARIES = {
|
|
|
57
57
|
web_fetch: "Fetch and extract readable content from a URL",
|
|
58
58
|
web_extract: "Extract structured content from a URL",
|
|
59
59
|
browser_use: "Control the configured browser",
|
|
60
|
-
send_message: "Send messages to the current channel",
|
|
60
|
+
send_message: "Send messages to the current conversation or an explicit configured channel",
|
|
61
61
|
send_media: "Send media attachments to the current channel",
|
|
62
62
|
memory_search: "Semantic search over indexed memory sources",
|
|
63
63
|
memory_get: "Read specific lines from memory sources returned by search",
|
|
@@ -6,6 +6,9 @@ init_logger();
|
|
|
6
6
|
const log = createLogger("MessageTool");
|
|
7
7
|
const MessageSendSchema = Type.Object({
|
|
8
8
|
content: Type.String({ description: "The message content to send" }),
|
|
9
|
+
channel: Type.Optional(Type.String({ description: "Configured destination channel (for example weixin or telegram). Defaults to the current channel." })),
|
|
10
|
+
chat_id: Type.Optional(Type.String({ description: "Destination chat/peer id. Required when channel is provided." })),
|
|
11
|
+
accountId: Type.Optional(Type.String({ description: "Optional account id for a multi-account destination channel." })),
|
|
9
12
|
mediaUrl: Type.Optional(Type.String({ description: "URL of the media to send" })),
|
|
10
13
|
mediaType: Type.Optional(Type.Enum({
|
|
11
14
|
photo: "photo",
|
|
@@ -36,7 +39,9 @@ const MessageSendSchema = Type.Object({
|
|
|
36
39
|
function createMessageTool(bus, getContext) {
|
|
37
40
|
return {
|
|
38
41
|
name: "send_message",
|
|
39
|
-
description: `Send a message to the
|
|
42
|
+
description: `Send a message to the current conversation or an explicit configured channel.
|
|
43
|
+
|
|
44
|
+
For a proactive cross-channel send, provide both \`channel\` and \`chat_id\` (for example \`channel: "weixin"\`). Use \`accountId\` when the destination has multiple configured accounts. Omit destination fields to reply to the current conversation.
|
|
40
45
|
|
|
41
46
|
TTS (Text-to-Speech) is handled automatically by the system based on configuration:
|
|
42
47
|
- trigger=off: Never use voice
|
|
@@ -50,18 +55,31 @@ When TTS is enabled, you may also use the \`text_to_speech\` tool to send a stan
|
|
|
50
55
|
async execute(_toolCallId, params, _signal) {
|
|
51
56
|
const p = params;
|
|
52
57
|
const ctx = getContext();
|
|
53
|
-
|
|
58
|
+
const requestedChannel = p.channel?.trim();
|
|
59
|
+
const requestedChatId = p.chat_id?.trim();
|
|
60
|
+
if (Boolean(requestedChannel) !== Boolean(requestedChatId)) return {
|
|
61
|
+
content: [{
|
|
62
|
+
type: "text",
|
|
63
|
+
text: "Error: channel and chat_id must be provided together"
|
|
64
|
+
}],
|
|
65
|
+
details: {}
|
|
66
|
+
};
|
|
67
|
+
if (!ctx && (!requestedChannel || !requestedChatId)) return {
|
|
54
68
|
content: [{
|
|
55
69
|
type: "text",
|
|
56
70
|
text: "Error: No active conversation context"
|
|
57
71
|
}],
|
|
58
72
|
details: {}
|
|
59
73
|
};
|
|
74
|
+
const channel = requestedChannel || ctx.channel;
|
|
75
|
+
const chatId = requestedChatId || ctx.chatId;
|
|
76
|
+
const accountId = p.accountId?.trim();
|
|
60
77
|
try {
|
|
61
78
|
const msg = {
|
|
62
|
-
channel
|
|
63
|
-
chat_id:
|
|
79
|
+
channel,
|
|
80
|
+
chat_id: chatId,
|
|
64
81
|
content: p.content,
|
|
82
|
+
...accountId ? { metadata: { accountId } } : {},
|
|
65
83
|
mediaUrl: p.mediaUrl,
|
|
66
84
|
mediaType: p.mediaType,
|
|
67
85
|
replyToMessageId: p.replyTo,
|
|
@@ -83,10 +101,10 @@ When TTS is enabled, you may also use the \`text_to_speech\` tool to send a stan
|
|
|
83
101
|
log.error({
|
|
84
102
|
err: error,
|
|
85
103
|
errorMessage: em,
|
|
86
|
-
channel
|
|
87
|
-
chatId
|
|
104
|
+
channel,
|
|
105
|
+
chatId,
|
|
88
106
|
contentPreview: String(p.content ?? "").slice(0, 100)
|
|
89
|
-
}, `send_message: outbound publish failed (${
|
|
107
|
+
}, `send_message: outbound publish failed (${channel}/${chatId}): ${em}`);
|
|
90
108
|
return {
|
|
91
109
|
content: [{
|
|
92
110
|
type: "text",
|
|
@@ -7,7 +7,12 @@ const log = createLogger("ChannelPluginRegistry");
|
|
|
7
7
|
var ChannelPluginRegistry = class {
|
|
8
8
|
plugins = /* @__PURE__ */ new Map();
|
|
9
9
|
register(plugin) {
|
|
10
|
-
|
|
10
|
+
const current = this.plugins.get(plugin.id);
|
|
11
|
+
if (current === plugin) {
|
|
12
|
+
log.debug({ channel: plugin.id }, "Channel plugin already registered");
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
if (current) log.warn({ channel: plugin.id }, "Channel plugin already registered, overwriting");
|
|
11
16
|
this.plugins.set(plugin.id, plugin);
|
|
12
17
|
syncChannelPluginsFromManager(this.all());
|
|
13
18
|
log.debug({ channel: plugin.id }, "Registered channel plugin");
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { createLogger } from "../../utils/logger/index.js";
|
|
2
2
|
import { init_logger } from "../../utils/logger.js";
|
|
3
3
|
import { shouldSilence, stripHeartbeatToken } from "../../heartbeat/tokens.js";
|
|
4
|
-
import { appendCronEventLines } from "../../heartbeat/event-prompt.js";
|
|
5
4
|
import { isWithinActiveHours } from "../../heartbeat/active-hours.js";
|
|
6
5
|
import { isHeartbeatContentEmpty } from "../../heartbeat/content-check.js";
|
|
6
|
+
import { appendCronEventLines } from "../../heartbeat/event-prompt.js";
|
|
7
7
|
import { createHeartbeatWake } from "../../heartbeat/wake.js";
|
|
8
8
|
import { resolveHeartbeatMdPath } from "../workspace-heartbeat-path.js";
|
|
9
9
|
import { readFile } from "fs/promises";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { DEFAULT_ACK_MAX_CHARS, HEARTBEAT_OK, NO_REPLY, shouldSilence, stripHeartbeatToken } from "./tokens.js";
|
|
2
|
-
import { appendCronEventLines } from "./event-prompt.js";
|
|
3
2
|
import { isWithinActiveHours } from "./active-hours.js";
|
|
4
3
|
import { isHeartbeatContentEmpty } from "./content-check.js";
|
|
4
|
+
import { appendCronEventLines } from "./event-prompt.js";
|
|
5
5
|
import { createHeartbeatWake } from "./wake.js";
|
|
6
6
|
export { DEFAULT_ACK_MAX_CHARS, HEARTBEAT_OK, NO_REPLY, appendCronEventLines, createHeartbeatWake, isHeartbeatContentEmpty, isWithinActiveHours, shouldSilence, stripHeartbeatToken };
|
|
@@ -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 +0,0 @@
|
|
|
1
|
-
import{ti as e}from"./index-B24B26og.js";function t(t){let{children:n,fallback:r}=t,i=r===void 0?null:r;return e()?n:i}export{t};
|