@xenosystem/agent-interface-ui 0.1.22 → 0.1.23
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/adapters/agentHostPlatformBridge.d.ts.map +1 -1
- package/dist/adapters/agentHostPlatformBridge.js +131 -0
- package/dist/adapters/agentHostPlatformBridge.js.map +1 -1
- package/dist/adapters/hubAgentPlatformBridge.d.ts.map +1 -1
- package/dist/adapters/hubAgentPlatformBridge.js +9 -0
- package/dist/adapters/hubAgentPlatformBridge.js.map +1 -1
- package/dist/components/agent/AgentInterface.d.ts.map +1 -1
- package/dist/components/agent/AgentInterface.js +247 -32
- package/dist/components/agent/AgentInterface.js.map +1 -1
- package/dist/components/agent/AgentPtyTerminalPanel.d.ts.map +1 -1
- package/dist/components/agent/AgentPtyTerminalPanel.js +66 -21
- package/dist/components/agent/AgentPtyTerminalPanel.js.map +1 -1
- package/dist/components/agent/AgentView.d.ts +5 -0
- package/dist/components/agent/AgentView.d.ts.map +1 -1
- package/dist/components/agent/AgentView.js +188 -35
- package/dist/components/agent/AgentView.js.map +1 -1
- package/dist/components/agent/nativeTuiComposerInput.d.ts +42 -0
- package/dist/components/agent/nativeTuiComposerInput.d.ts.map +1 -0
- package/dist/components/agent/nativeTuiComposerInput.js +51 -0
- package/dist/components/agent/nativeTuiComposerInput.js.map +1 -0
- package/dist/components/agent/ptyOutputReconciliation.d.ts +41 -0
- package/dist/components/agent/ptyOutputReconciliation.d.ts.map +1 -0
- package/dist/components/agent/ptyOutputReconciliation.js +68 -0
- package/dist/components/agent/ptyOutputReconciliation.js.map +1 -0
- package/dist/components/agent/settings/sections/DefaultAgentConfigSection.d.ts.map +1 -1
- package/dist/components/agent/settings/sections/DefaultAgentConfigSection.js +3 -2
- package/dist/components/agent/settings/sections/DefaultAgentConfigSection.js.map +1 -1
- package/dist/components/agent/settings/sections/WorkspaceDirectoryAccessSection.js +1 -1
- package/dist/components/agent/settings/sections/WorkspaceDirectoryAccessSection.js.map +1 -1
- package/dist/components/agent/terminalSurfaceAvailability.d.ts +22 -0
- package/dist/components/agent/terminalSurfaceAvailability.d.ts.map +1 -0
- package/dist/components/agent/terminalSurfaceAvailability.js +43 -0
- package/dist/components/agent/terminalSurfaceAvailability.js.map +1 -0
- package/dist/platformApiTypes.d.ts +32 -0
- package/dist/platformApiTypes.d.ts.map +1 -1
- package/dist/stores/agentChatStore.d.ts.map +1 -1
- package/dist/stores/agentChatStore.js +31 -3
- package/dist/stores/agentChatStore.js.map +1 -1
- package/dist/stores/xenoChatStore.d.ts.map +1 -1
- package/dist/stores/xenoChatStore.js +2 -1
- package/dist/stores/xenoChatStore.js.map +1 -1
- package/dist/utils/acpExecutionAuthority.d.ts +8 -0
- package/dist/utils/acpExecutionAuthority.d.ts.map +1 -1
- package/dist/utils/acpExecutionAuthority.js +24 -0
- package/dist/utils/acpExecutionAuthority.js.map +1 -1
- package/dist/utils/modelAvailability.d.ts +11 -0
- package/dist/utils/modelAvailability.d.ts.map +1 -0
- package/dist/utils/modelAvailability.js +10 -0
- package/dist/utils/modelAvailability.js.map +1 -0
- package/dist/utils/providerAvailability.d.ts +8 -0
- package/dist/utils/providerAvailability.d.ts.map +1 -0
- package/dist/utils/providerAvailability.js +13 -0
- package/dist/utils/providerAvailability.js.map +1 -0
- package/package.json +5 -5
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AgentPtyTerminalPanel.d.ts","sourceRoot":"","sources":["../../../src/components/agent/AgentPtyTerminalPanel.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"AgentPtyTerminalPanel.d.ts","sourceRoot":"","sources":["../../../src/components/agent/AgentPtyTerminalPanel.tsx"],"names":[],"mappings":"AAIA,OAAO,4BAA4B,CAAA;AAEnC,UAAU,0BAA0B;IAClC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,MAAM,EAAE,MAAM,CAAA;IACd,yBAAyB,EAAE,OAAO,CAAA;IAClC,aAAa,EAAE,OAAO,CAAA;IACtB,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IAC/B,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;CAC/C;AAED,MAAM,CAAC,OAAO,UAAU,qBAAqB,CAAC,EAC5C,WAAW,EACX,UAAU,EACV,MAAM,EACN,yBAAyB,EACzB,aAAa,EACb,OAAO,EACP,QAAQ,GACT,EAAE,0BAA0B,+BA8K5B"}
|
|
@@ -2,15 +2,17 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
2
2
|
import { useEffect, useRef } from 'react';
|
|
3
3
|
import { Terminal as XTerm } from '@xterm/xterm';
|
|
4
4
|
import { FitAddon } from '@xterm/addon-fit';
|
|
5
|
+
import { createPtyReplayInputGate, planPtyOutputRender } from './ptyOutputReconciliation.js';
|
|
5
6
|
import '@xterm/xterm/css/xterm.css';
|
|
6
7
|
export default function AgentPtyTerminalPanel({ terminalKey, terminalId, output, terminalCapabilityEnabled, terminalReady, onInput, onResize, }) {
|
|
7
8
|
const containerRef = useRef(null);
|
|
8
9
|
const terminalRef = useRef(null);
|
|
9
10
|
const fitAddonRef = useRef(null);
|
|
10
|
-
const
|
|
11
|
+
const writtenOutputRef = useRef('');
|
|
11
12
|
const outputRef = useRef(output);
|
|
12
13
|
const onInputRef = useRef(onInput);
|
|
13
14
|
const onResizeRef = useRef(onResize);
|
|
15
|
+
const replayInputGateRef = useRef(createPtyReplayInputGate());
|
|
14
16
|
useEffect(() => {
|
|
15
17
|
outputRef.current = output;
|
|
16
18
|
}, [output]);
|
|
@@ -57,21 +59,34 @@ export default function AgentPtyTerminalPanel({ terminalKey, terminalId, output,
|
|
|
57
59
|
const fitAddon = new FitAddon();
|
|
58
60
|
terminal.loadAddon(fitAddon);
|
|
59
61
|
terminal.open(containerRef.current);
|
|
60
|
-
fitAddon.fit();
|
|
61
|
-
terminal.focus();
|
|
62
62
|
terminalRef.current = terminal;
|
|
63
63
|
fitAddonRef.current = fitAddon;
|
|
64
|
-
|
|
64
|
+
writtenOutputRef.current = '';
|
|
65
65
|
if (outputRef.current) {
|
|
66
|
-
|
|
67
|
-
|
|
66
|
+
const finishReplay = replayInputGateRef.current.beginReplay();
|
|
67
|
+
try {
|
|
68
|
+
terminal.write(outputRef.current, finishReplay);
|
|
69
|
+
}
|
|
70
|
+
catch (error) {
|
|
71
|
+
finishReplay();
|
|
72
|
+
throw error;
|
|
73
|
+
}
|
|
74
|
+
writtenOutputRef.current = outputRef.current;
|
|
68
75
|
}
|
|
69
76
|
const dataDisposable = terminal.onData((data) => {
|
|
70
|
-
|
|
77
|
+
if (replayInputGateRef.current.shouldForwardInput())
|
|
78
|
+
onInputRef.current(data);
|
|
71
79
|
});
|
|
72
80
|
const resizeDisposable = terminal.onResize(({ cols, rows }) => {
|
|
73
81
|
onResizeRef.current(cols, rows);
|
|
74
82
|
});
|
|
83
|
+
// Subscribe before the first fit. The previous ordering fitted the xterm
|
|
84
|
+
// viewport while the provider PTY was still fixed at its bootstrap 80x24
|
|
85
|
+
// geometry, then discarded that first resize event. Full-screen Codex and
|
|
86
|
+
// Claude frames were consequently decoded at one width and painted at
|
|
87
|
+
// another, producing duplicated/fragmented rows.
|
|
88
|
+
fitAddon.fit();
|
|
89
|
+
terminal.focus();
|
|
75
90
|
const resizeObserver = new ResizeObserver(() => {
|
|
76
91
|
try {
|
|
77
92
|
fitAddon.fit();
|
|
@@ -86,37 +101,67 @@ export default function AgentPtyTerminalPanel({ terminalKey, terminalId, output,
|
|
|
86
101
|
terminal.dispose();
|
|
87
102
|
terminalRef.current = null;
|
|
88
103
|
fitAddonRef.current = null;
|
|
89
|
-
|
|
104
|
+
writtenOutputRef.current = '';
|
|
90
105
|
};
|
|
91
106
|
}, [terminalCapabilityEnabled, terminalReady]);
|
|
92
107
|
useEffect(() => {
|
|
93
108
|
const terminal = terminalRef.current;
|
|
94
109
|
if (!terminal)
|
|
95
110
|
return;
|
|
96
|
-
terminal.
|
|
97
|
-
|
|
111
|
+
terminal.reset();
|
|
112
|
+
writtenOutputRef.current = '';
|
|
98
113
|
if (output) {
|
|
99
|
-
|
|
100
|
-
|
|
114
|
+
const finishReplay = replayInputGateRef.current.beginReplay();
|
|
115
|
+
try {
|
|
116
|
+
terminal.write(output, finishReplay);
|
|
117
|
+
}
|
|
118
|
+
catch (error) {
|
|
119
|
+
finishReplay();
|
|
120
|
+
throw error;
|
|
121
|
+
}
|
|
122
|
+
writtenOutputRef.current = output;
|
|
101
123
|
}
|
|
102
124
|
}, [terminalKey]);
|
|
103
125
|
useEffect(() => {
|
|
104
126
|
const terminal = terminalRef.current;
|
|
105
127
|
if (!terminal)
|
|
106
128
|
return;
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
129
|
+
const plan = planPtyOutputRender(writtenOutputRef.current, output);
|
|
130
|
+
if (plan.mode === 'none')
|
|
131
|
+
return;
|
|
132
|
+
if (plan.mode === 'replace') {
|
|
133
|
+
terminal.reset();
|
|
134
|
+
if (plan.chunk) {
|
|
135
|
+
const finishReplay = replayInputGateRef.current.beginReplay();
|
|
136
|
+
try {
|
|
137
|
+
terminal.write(plan.chunk, finishReplay);
|
|
138
|
+
}
|
|
139
|
+
catch (error) {
|
|
140
|
+
finishReplay();
|
|
141
|
+
throw error;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
110
144
|
}
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
terminal.write(nextChunk);
|
|
114
|
-
writtenOutputLengthRef.current = output.length;
|
|
145
|
+
else if (plan.chunk) {
|
|
146
|
+
terminal.write(plan.chunk);
|
|
115
147
|
}
|
|
148
|
+
writtenOutputRef.current = output;
|
|
116
149
|
}, [output]);
|
|
117
150
|
useEffect(() => {
|
|
118
|
-
|
|
119
|
-
|
|
151
|
+
const terminal = terminalRef.current;
|
|
152
|
+
if (!terminalId || !terminal)
|
|
153
|
+
return;
|
|
154
|
+
terminal.focus();
|
|
155
|
+
// The PTY id arrives after the tab and xterm are mounted. The parent keeps
|
|
156
|
+
// the id in a ref for stable event callbacks, and parent passive effects
|
|
157
|
+
// run after this child's passive effect. Defer one animation frame so that
|
|
158
|
+
// ref is current before sending the authoritative initial ConPTY resize.
|
|
159
|
+
// Without this, the resize is silently dropped and a 24-row provider TUI
|
|
160
|
+
// paints into a ~90-row xterm, leaving every old full-screen frame visible.
|
|
161
|
+
const frame = requestAnimationFrame(() => {
|
|
162
|
+
onResizeRef.current(terminal.cols, terminal.rows);
|
|
163
|
+
});
|
|
164
|
+
return () => cancelAnimationFrame(frame);
|
|
120
165
|
}, [terminalId]);
|
|
121
166
|
if (!terminalCapabilityEnabled) {
|
|
122
167
|
return _jsx("div", { className: "h-full bg-[#050506] px-3 py-2 font-mono text-[12px] text-amber-200/60", children: "Terminal access is disabled for this agent." });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AgentPtyTerminalPanel.js","sourceRoot":"","sources":["../../../src/components/agent/AgentPtyTerminalPanel.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,OAAO,CAAA;AACzC,OAAO,EAAE,QAAQ,IAAI,KAAK,EAAE,MAAM,cAAc,CAAA;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAC3C,OAAO,4BAA4B,CAAA;AAYnC,MAAM,CAAC,OAAO,UAAU,qBAAqB,CAAC,EAC5C,WAAW,EACX,UAAU,EACV,MAAM,EACN,yBAAyB,EACzB,aAAa,EACb,OAAO,EACP,QAAQ,GACmB;IAC3B,MAAM,YAAY,GAAG,MAAM,CAAiB,IAAI,CAAC,CAAA;IACjD,MAAM,WAAW,GAAG,MAAM,CAAe,IAAI,CAAC,CAAA;IAC9C,MAAM,WAAW,GAAG,MAAM,CAAkB,IAAI,CAAC,CAAA;IACjD,MAAM,
|
|
1
|
+
{"version":3,"file":"AgentPtyTerminalPanel.js","sourceRoot":"","sources":["../../../src/components/agent/AgentPtyTerminalPanel.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,OAAO,CAAA;AACzC,OAAO,EAAE,QAAQ,IAAI,KAAK,EAAE,MAAM,cAAc,CAAA;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAC3C,OAAO,EAAE,wBAAwB,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAA;AAC5F,OAAO,4BAA4B,CAAA;AAYnC,MAAM,CAAC,OAAO,UAAU,qBAAqB,CAAC,EAC5C,WAAW,EACX,UAAU,EACV,MAAM,EACN,yBAAyB,EACzB,aAAa,EACb,OAAO,EACP,QAAQ,GACmB;IAC3B,MAAM,YAAY,GAAG,MAAM,CAAiB,IAAI,CAAC,CAAA;IACjD,MAAM,WAAW,GAAG,MAAM,CAAe,IAAI,CAAC,CAAA;IAC9C,MAAM,WAAW,GAAG,MAAM,CAAkB,IAAI,CAAC,CAAA;IACjD,MAAM,gBAAgB,GAAG,MAAM,CAAC,EAAE,CAAC,CAAA;IACnC,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,CAAA;IAChC,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,CAAC,CAAA;IAClC,MAAM,WAAW,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAA;IACpC,MAAM,kBAAkB,GAAG,MAAM,CAAC,wBAAwB,EAAE,CAAC,CAAA;IAE7D,SAAS,CAAC,GAAG,EAAE;QACb,SAAS,CAAC,OAAO,GAAG,MAAM,CAAA;IAC5B,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAA;IAEZ,SAAS,CAAC,GAAG,EAAE;QACb,UAAU,CAAC,OAAO,GAAG,OAAO,CAAA;QAC5B,WAAW,CAAC,OAAO,GAAG,QAAQ,CAAA;IAChC,CAAC,EAAE,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAA;IAEvB,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,yBAAyB,IAAI,CAAC,aAAa,IAAI,CAAC,YAAY,CAAC,OAAO;YAAE,OAAM;QAEjF,MAAM,QAAQ,GAAG,IAAI,KAAK,CAAC;YACzB,WAAW,EAAE,IAAI;YACjB,WAAW,EAAE,OAAO;YACpB,UAAU,EAAE,uDAAuD;YACnE,QAAQ,EAAE,EAAE;YACZ,UAAU,EAAE,IAAI;YAChB,aAAa,EAAE,CAAC;YAChB,UAAU,EAAE,IAAI;YAChB,UAAU,EAAE,KAAK;YACjB,KAAK,EAAE;gBACL,UAAU,EAAE,SAAS;gBACrB,UAAU,EAAE,SAAS;gBACrB,MAAM,EAAE,SAAS;gBACjB,YAAY,EAAE,SAAS;gBACvB,mBAAmB,EAAE,SAAS;gBAC9B,KAAK,EAAE,SAAS;gBAChB,GAAG,EAAE,SAAS;gBACd,KAAK,EAAE,SAAS;gBAChB,MAAM,EAAE,SAAS;gBACjB,IAAI,EAAE,SAAS;gBACf,OAAO,EAAE,SAAS;gBAClB,IAAI,EAAE,SAAS;gBACf,KAAK,EAAE,SAAS;gBAChB,WAAW,EAAE,SAAS;gBACtB,SAAS,EAAE,SAAS;gBACpB,WAAW,EAAE,SAAS;gBACtB,YAAY,EAAE,SAAS;gBACvB,UAAU,EAAE,SAAS;gBACrB,aAAa,EAAE,SAAS;gBACxB,UAAU,EAAE,SAAS;gBACrB,WAAW,EAAE,SAAS;aACvB;SACF,CAAC,CAAA;QACF,MAAM,QAAQ,GAAG,IAAI,QAAQ,EAAE,CAAA;QAC/B,QAAQ,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAA;QAC5B,QAAQ,CAAC,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,CAAA;QACnC,WAAW,CAAC,OAAO,GAAG,QAAQ,CAAA;QAC9B,WAAW,CAAC,OAAO,GAAG,QAAQ,CAAA;QAC9B,gBAAgB,CAAC,OAAO,GAAG,EAAE,CAAA;QAC7B,IAAI,SAAS,CAAC,OAAO,EAAE,CAAC;YACtB,MAAM,YAAY,GAAG,kBAAkB,CAAC,OAAO,CAAC,WAAW,EAAE,CAAA;YAC7D,IAAI,CAAC;gBACH,QAAQ,CAAC,KAAK,CAAC,SAAS,CAAC,OAAO,EAAE,YAAY,CAAC,CAAA;YACjD,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,YAAY,EAAE,CAAA;gBACd,MAAM,KAAK,CAAA;YACb,CAAC;YACD,gBAAgB,CAAC,OAAO,GAAG,SAAS,CAAC,OAAO,CAAA;QAC9C,CAAC;QAED,MAAM,cAAc,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE;YAC9C,IAAI,kBAAkB,CAAC,OAAO,CAAC,kBAAkB,EAAE;gBAAE,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;QAC/E,CAAC,CAAC,CAAA;QAEF,MAAM,gBAAgB,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE;YAC5D,WAAW,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;QACjC,CAAC,CAAC,CAAA;QAEF,yEAAyE;QACzE,yEAAyE;QACzE,0EAA0E;QAC1E,sEAAsE;QACtE,iDAAiD;QACjD,QAAQ,CAAC,GAAG,EAAE,CAAA;QACd,QAAQ,CAAC,KAAK,EAAE,CAAA;QAEhB,MAAM,cAAc,GAAG,IAAI,cAAc,CAAC,GAAG,EAAE;YAC7C,IAAI,CAAC;gBAAC,QAAQ,CAAC,GAAG,EAAE,CAAA;YAAC,CAAC;YAAC,MAAM,CAAC,CAAC,uBAAuB,CAAC,CAAC;QAC1D,CAAC,CAAC,CAAA;QACF,cAAc,CAAC,OAAO,CAAC,YAAY,CAAC,OAAO,CAAC,CAAA;QAE5C,OAAO,GAAG,EAAE;YACV,cAAc,CAAC,UAAU,EAAE,CAAA;YAC3B,gBAAgB,CAAC,OAAO,EAAE,CAAA;YAC1B,cAAc,CAAC,OAAO,EAAE,CAAA;YACxB,QAAQ,CAAC,OAAO,EAAE,CAAA;YAClB,WAAW,CAAC,OAAO,GAAG,IAAI,CAAA;YAC1B,WAAW,CAAC,OAAO,GAAG,IAAI,CAAA;YAC1B,gBAAgB,CAAC,OAAO,GAAG,EAAE,CAAA;QAC/B,CAAC,CAAA;IACH,CAAC,EAAE,CAAC,yBAAyB,EAAE,aAAa,CAAC,CAAC,CAAA;IAE9C,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,QAAQ,GAAG,WAAW,CAAC,OAAO,CAAA;QACpC,IAAI,CAAC,QAAQ;YAAE,OAAM;QACrB,QAAQ,CAAC,KAAK,EAAE,CAAA;QAChB,gBAAgB,CAAC,OAAO,GAAG,EAAE,CAAA;QAC7B,IAAI,MAAM,EAAE,CAAC;YACX,MAAM,YAAY,GAAG,kBAAkB,CAAC,OAAO,CAAC,WAAW,EAAE,CAAA;YAC7D,IAAI,CAAC;gBACH,QAAQ,CAAC,KAAK,CAAC,MAAM,EAAE,YAAY,CAAC,CAAA;YACtC,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,YAAY,EAAE,CAAA;gBACd,MAAM,KAAK,CAAA;YACb,CAAC;YACD,gBAAgB,CAAC,OAAO,GAAG,MAAM,CAAA;QACnC,CAAC;IACH,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAA;IAEjB,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,QAAQ,GAAG,WAAW,CAAC,OAAO,CAAA;QACpC,IAAI,CAAC,QAAQ;YAAE,OAAM;QACrB,MAAM,IAAI,GAAG,mBAAmB,CAAC,gBAAgB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAA;QAClE,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM;YAAE,OAAM;QAChC,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YAC5B,QAAQ,CAAC,KAAK,EAAE,CAAA;YAChB,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;gBACf,MAAM,YAAY,GAAG,kBAAkB,CAAC,OAAO,CAAC,WAAW,EAAE,CAAA;gBAC7D,IAAI,CAAC;oBACH,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,YAAY,CAAC,CAAA;gBAC1C,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,YAAY,EAAE,CAAA;oBACd,MAAM,KAAK,CAAA;gBACb,CAAC;YACH,CAAC;QACH,CAAC;aAAM,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACtB,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QAC5B,CAAC;QACD,gBAAgB,CAAC,OAAO,GAAG,MAAM,CAAA;IACnC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAA;IAEZ,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,QAAQ,GAAG,WAAW,CAAC,OAAO,CAAA;QACpC,IAAI,CAAC,UAAU,IAAI,CAAC,QAAQ;YAAE,OAAM;QACpC,QAAQ,CAAC,KAAK,EAAE,CAAA;QAChB,2EAA2E;QAC3E,yEAAyE;QACzE,2EAA2E;QAC3E,yEAAyE;QACzE,yEAAyE;QACzE,4EAA4E;QAC5E,MAAM,KAAK,GAAG,qBAAqB,CAAC,GAAG,EAAE;YACvC,WAAW,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAA;QACnD,CAAC,CAAC,CAAA;QACF,OAAO,GAAG,EAAE,CAAC,oBAAoB,CAAC,KAAK,CAAC,CAAA;IAC1C,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAA;IAEhB,IAAI,CAAC,yBAAyB,EAAE,CAAC;QAC/B,OAAO,cAAK,SAAS,EAAC,uEAAuE,4DAAkD,CAAA;IACjJ,CAAC;IAED,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,OAAO,cAAK,SAAS,EAAC,mEAAmE,0DAAgD,CAAA;IAC3I,CAAC;IAED,OAAO,CACL,cACE,GAAG,EAAE,YAAY,EACjB,SAAS,EAAC,0HAA0H,EACpI,WAAW,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC,OAAO,EAAE,KAAK,EAAE,GAC/C,CACH,CAAA;AACH,CAAC"}
|
|
@@ -142,6 +142,11 @@ interface AgentViewProps {
|
|
|
142
142
|
onConversationCreated?: (conversationId: string) => void;
|
|
143
143
|
renderWorkbenchPanel?: boolean;
|
|
144
144
|
externalInputLockReason?: string;
|
|
145
|
+
/** Route GUI composer text through the attached provider PTY's sole writer. */
|
|
146
|
+
onSendToNativeTui?: (text: string) => Promise<{
|
|
147
|
+
success: boolean;
|
|
148
|
+
error?: string | null;
|
|
149
|
+
}>;
|
|
145
150
|
}
|
|
146
151
|
interface WorkspacePlacementCardState {
|
|
147
152
|
workspacePlacementId: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AgentView.d.ts","sourceRoot":"","sources":["../../../src/components/agent/AgentView.tsx"],"names":[],"mappings":"AAQA,OAAO,KAA4D,MAAM,OAAO,CAAA;AAMhF,OAAO,EAA2N,KAAK,YAAY,EAA2N,MAAM,gCAAgC,CAAA;AAYpf,OAAO,KAAK,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,0BAA0B,EAAE,MAAM,qBAAqB,CAAA;AAC3G,OAAO,KAAK,EACV,wBAAwB,EAEzB,MAAM,qCAAqC,CAAA;AAC5C,OAAO,KAAK,EAAE,sBAAsB,EAA2B,MAAM,4BAA4B,CAAA;
|
|
1
|
+
{"version":3,"file":"AgentView.d.ts","sourceRoot":"","sources":["../../../src/components/agent/AgentView.tsx"],"names":[],"mappings":"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"}
|
|
@@ -25,6 +25,8 @@ import { AssistantTurnErrorNotice, AssistantTurnStatusNotice } from './Assistant
|
|
|
25
25
|
import { commandPreviewText, compactCommandPreview, deriveToolInteractionState, hideDuplicateToolTitle, isCommandToolCall } from './toolCardDisplay.js';
|
|
26
26
|
import { deriveWebJobProgressView, webJobStopAvailability, WEB_JOB_STOP_LABEL, WEB_JOB_STOP_TITLE } from './webJobProgressView.js';
|
|
27
27
|
import { cloudModelName, cloudModelSortScore } from '../../utils/cloudModels.js';
|
|
28
|
+
import { isSelectableLiveModel } from '../../utils/modelAvailability.js';
|
|
29
|
+
import { availableAcpConfigIds } from '../../utils/providerAvailability.js';
|
|
28
30
|
import { extractWindowsFilePathsFromToolResult, prepareAgentMarkdown, resolveMarkdownLocalFilePath, } from '../../utils/markdownWindowsPaths.js';
|
|
29
31
|
import { agentReasoningEffortLabel, buildExplicitAgentReasoningEffortFamilies, indexAgentReasoningEffortFamilies, preferredAgentReasoningModelId, resolveAgentReasoningEffortFamily, } from '../../utils/agentReasoningEffort.js';
|
|
30
32
|
import { acpAgentDisplayName, resolveHubAgentRuntimeProvider } from '../../utils/agentRuntimeProvider.js';
|
|
@@ -32,6 +34,7 @@ import { createConversationRuntimeBinding, reconcileCloudConversationModel, runt
|
|
|
32
34
|
import { extractUserFileCreateRequest, extractUserFileEditRequest, isAbsoluteOrRootedPath } from '../../utils/fileCreateIntent.js';
|
|
33
35
|
import { buildRuntimeAttachedContextPrompt } from '../../utils/agentAttachedContextPrompt.js';
|
|
34
36
|
import { buildWorkspaceSelectionContinuationPrompt } from '../../utils/workspaceSelectionContinuation.js';
|
|
37
|
+
import { isAgentComposerInputLocked } from './nativeTuiComposerInput.js';
|
|
35
38
|
import { AgentProviderSelectorController } from '../../providerSelector.js';
|
|
36
39
|
import { loadHubAgentProviderCatalog, refreshHubAgentProviderCatalog, subscribeHubAgentProviderCatalog, } from '../../adapters/xenoAgentHostCatalog.js';
|
|
37
40
|
const AGENT_GPT55_DEFAULT_MODEL = 'gpt-5.5-high';
|
|
@@ -3364,7 +3367,10 @@ export function AgentView(props) {
|
|
|
3364
3367
|
acpAgents: acpAgentsForRuntime,
|
|
3365
3368
|
}), [acpAgentsForRuntime, effectiveRuntimeSelection, props.permissionProfile]);
|
|
3366
3369
|
const runtimeMode = acpModePending || runtimeProvider.kind === 'acp-provider' ? 'acp' : inferenceMode;
|
|
3367
|
-
const selectableAcpAgents = useMemo(() =>
|
|
3370
|
+
const selectableAcpAgents = useMemo(() => {
|
|
3371
|
+
const availableConfigIds = availableAcpConfigIds(sharedRuntimeProviders);
|
|
3372
|
+
return acpAgentsForRuntime.filter((agent) => agent.enabled && availableConfigIds.has(agent.id));
|
|
3373
|
+
}, [acpAgentsForRuntime, sharedRuntimeProviders]);
|
|
3368
3374
|
const rawAcpProviderModel = effectiveRuntimeSelection?.providerKind === 'acp-provider'
|
|
3369
3375
|
? effectiveRuntimeSelection.providerModel
|
|
3370
3376
|
: undefined;
|
|
@@ -3374,6 +3380,7 @@ export function AgentView(props) {
|
|
|
3374
3380
|
: EMPTY_ACP_MODEL_CHOICES;
|
|
3375
3381
|
const acpModelOptions = useMemo(() => acpProviderModelOptions
|
|
3376
3382
|
.filter((option) => !option.familyBaseModelId)
|
|
3383
|
+
.filter((option) => option.available !== false)
|
|
3377
3384
|
.map((option) => option.id), [acpProviderModelOptions]);
|
|
3378
3385
|
const acpProviderModelOptionById = useMemo(() => new Map(acpProviderModelOptions.map((option) => [option.id, option])), [acpProviderModelOptions]);
|
|
3379
3386
|
const acpModelMessage = selectedAcpAgentConfigId ? acpModelMessagesByAgentId[selectedAcpAgentConfigId] : undefined;
|
|
@@ -3452,6 +3459,38 @@ export function AgentView(props) {
|
|
|
3452
3459
|
cancelled = true;
|
|
3453
3460
|
};
|
|
3454
3461
|
}, [acpModelListOpen, selectedAcpAgentConfigId]);
|
|
3462
|
+
useEffect(() => {
|
|
3463
|
+
if (!modelListOpen || runtimeMode !== 'cloud')
|
|
3464
|
+
return;
|
|
3465
|
+
let cancelled = false;
|
|
3466
|
+
setSharedProviderCatalogRefreshing(true);
|
|
3467
|
+
refreshHubAgentProviderCatalog({ force: true })
|
|
3468
|
+
.then((catalog) => {
|
|
3469
|
+
if (cancelled)
|
|
3470
|
+
return;
|
|
3471
|
+
setSharedRuntimeProviders(catalog.providers);
|
|
3472
|
+
setSharedProviderCatalogLoaded(true);
|
|
3473
|
+
})
|
|
3474
|
+
.catch(() => {
|
|
3475
|
+
if (cancelled)
|
|
3476
|
+
return;
|
|
3477
|
+
setSharedRuntimeProviders((current) => current.map((provider) => (provider.id === 'xeno-cloud'
|
|
3478
|
+
? {
|
|
3479
|
+
...provider,
|
|
3480
|
+
availability: 'unavailable',
|
|
3481
|
+
safeUnavailableReason: 'The live XENO model catalog could not be refreshed.',
|
|
3482
|
+
models: [],
|
|
3483
|
+
}
|
|
3484
|
+
: provider)));
|
|
3485
|
+
})
|
|
3486
|
+
.finally(() => {
|
|
3487
|
+
if (!cancelled)
|
|
3488
|
+
setSharedProviderCatalogRefreshing(false);
|
|
3489
|
+
});
|
|
3490
|
+
return () => {
|
|
3491
|
+
cancelled = true;
|
|
3492
|
+
};
|
|
3493
|
+
}, [modelListOpen, runtimeMode]);
|
|
3455
3494
|
useEffect(() => {
|
|
3456
3495
|
if (effectiveRuntimeSelection?.providerKind !== 'acp-provider' && !modelListOpen && !acpCliListOpen && !acpModelListOpen)
|
|
3457
3496
|
return;
|
|
@@ -3513,9 +3552,10 @@ export function AgentView(props) {
|
|
|
3513
3552
|
const acpCliBtnRef = useRef(null);
|
|
3514
3553
|
const acpModelBtnRef = useRef(null);
|
|
3515
3554
|
const authDisplayName = useAuthStore(s => s.user?.display_name ?? null);
|
|
3555
|
+
const cloudRuntimeProvider = useMemo(() => sharedRuntimeProviders.find((entry) => entry.id === 'xeno-cloud'), [sharedRuntimeProviders]);
|
|
3516
3556
|
const cloudModels = useMemo(() => {
|
|
3517
|
-
|
|
3518
|
-
|
|
3557
|
+
return (cloudRuntimeProvider?.models || [])
|
|
3558
|
+
.filter(isSelectableLiveModel)
|
|
3519
3559
|
.map((modelEntry) => ({
|
|
3520
3560
|
id: modelEntry.id,
|
|
3521
3561
|
name: modelEntry.displayName || cloudModelName(modelEntry.id),
|
|
@@ -3532,7 +3572,9 @@ export function AgentView(props) {
|
|
|
3532
3572
|
const score = cloudModelSortScore(a.id) - cloudModelSortScore(b.id);
|
|
3533
3573
|
return score || a.name.localeCompare(b.name);
|
|
3534
3574
|
});
|
|
3535
|
-
}, [
|
|
3575
|
+
}, [cloudRuntimeProvider]);
|
|
3576
|
+
const cloudCatalogUnavailableReason = cloudRuntimeProvider?.safeUnavailableReason
|
|
3577
|
+
|| 'The live XENO model catalog is unavailable.';
|
|
3536
3578
|
const availableModels = useXenoChatStore(s => s.availableModels);
|
|
3537
3579
|
const fetchModels = useXenoChatStore(s => s.fetchModels);
|
|
3538
3580
|
const localModels = useMemo(() => availableModels.filter(m => m.provider === 'local'), [availableModels]);
|
|
@@ -3694,10 +3736,9 @@ export function AgentView(props) {
|
|
|
3694
3736
|
}).filter((entry) => !normalizedModelSearch || `${entry.name} ${entry.searchText}`.toLowerCase().includes(normalizedModelSearch));
|
|
3695
3737
|
}, [acpEffortFamilies, acpEffortFamilyByModelId, acpModelOptions, acpProviderModel, acpProviderModelOptionById, normalizedModelSearch, selectedAcpEffortFamily?.baseId]);
|
|
3696
3738
|
const preferredGpt55Model = useMemo(() => {
|
|
3697
|
-
|
|
3698
|
-
|
|
3699
|
-
||
|
|
3700
|
-
|| selectableCloudModels[0]?.id
|
|
3739
|
+
return cloudModels.find(m => m.id === AGENT_GPT55_DEFAULT_MODEL)?.id
|
|
3740
|
+
|| cloudModels.find(m => m.id === 'gpt-5.5')?.id
|
|
3741
|
+
|| cloudModels[0]?.id
|
|
3701
3742
|
|| AGENT_GPT55_DEFAULT_MODEL;
|
|
3702
3743
|
}, [cloudModels]);
|
|
3703
3744
|
useEffect(() => {
|
|
@@ -3716,9 +3757,12 @@ export function AgentView(props) {
|
|
|
3716
3757
|
return cloudModelName(selectedCloudEffortFamily.baseId);
|
|
3717
3758
|
return isThinkingVariant ? `${cloud.name} (Thinking)` : cloud.name;
|
|
3718
3759
|
}
|
|
3760
|
+
if (inferenceMode === 'cloud' && sharedProviderCatalogLoaded) {
|
|
3761
|
+
return cloudCatalogUnavailableReason.startsWith('Sign in') ? 'Sign in for Cloud' : 'Cloud unavailable';
|
|
3762
|
+
}
|
|
3719
3763
|
const local = availableModels.find(m => m.id === actualModelId);
|
|
3720
3764
|
return local?.name || actualModelId;
|
|
3721
|
-
}, [cloudModels, availableModels, selectedModel, actualModelId, selectedCloudEffortFamily, isThinkingVariant, runtimeProvider.kind, runtimeProvider.displayName, acpProviderModelDisplayName]);
|
|
3765
|
+
}, [cloudModels, availableModels, selectedModel, actualModelId, selectedCloudEffortFamily, isThinkingVariant, runtimeProvider.kind, runtimeProvider.displayName, acpProviderModelDisplayName, inferenceMode, sharedProviderCatalogLoaded, cloudCatalogUnavailableReason]);
|
|
3722
3766
|
const currentCloudModel = useMemo(() => cloudModels.find(m => m.id === actualModelId), [cloudModels, actualModelId]);
|
|
3723
3767
|
const cloudModelSelectionMissing = runtimeProvider.kind !== 'acp-provider'
|
|
3724
3768
|
&& inferenceMode === 'cloud'
|
|
@@ -3731,11 +3775,13 @@ export function AgentView(props) {
|
|
|
3731
3775
|
}, [actualModelId, currentCloudModel, preferredGpt55Model]);
|
|
3732
3776
|
const cloudModelUnavailable = runtimeProvider.kind !== 'acp-provider'
|
|
3733
3777
|
&& inferenceMode === 'cloud'
|
|
3734
|
-
&& (
|
|
3778
|
+
&& ((sharedProviderCatalogLoaded && cloudModels.length === 0) || cloudModelSelectionMissing);
|
|
3735
3779
|
const cloudModelDegraded = runtimeProvider.kind !== 'acp-provider' && inferenceMode === 'cloud' && currentCloudModel?.availability === 'degraded';
|
|
3736
3780
|
const cloudModelStatusReason = cloudModelSelectionMissing
|
|
3737
3781
|
? 'The selected model is not present in the live model catalog. Choose an available model.'
|
|
3738
|
-
: (
|
|
3782
|
+
: (cloudModels.length === 0 && sharedProviderCatalogLoaded
|
|
3783
|
+
? cloudCatalogUnavailableReason
|
|
3784
|
+
: (currentCloudModel?.availabilityReason || null));
|
|
3739
3785
|
const renderModelSearch = () => (_jsx("div", { className: "shrink-0 border-b border-white/[0.06] bg-[#111111]", children: _jsxs("div", { className: "relative", children: [_jsx(Search, { className: "pointer-events-none absolute left-3 top-1/2 h-3 w-3 -translate-y-1/2 text-white/25" }), _jsx("input", { autoFocus: true, type: "text", value: modelSearchQuery, onChange: (event) => setModelSearchQuery(event.target.value), onKeyDown: (event) => {
|
|
3740
3786
|
if (event.key === 'Escape') {
|
|
3741
3787
|
setModelListOpen(false);
|
|
@@ -3751,6 +3797,64 @@ export function AgentView(props) {
|
|
|
3751
3797
|
if (availableModels.length === 0)
|
|
3752
3798
|
void fetchModels();
|
|
3753
3799
|
}, [availableModels.length, fetchModels]);
|
|
3800
|
+
const providerLaneSelectionRevisionRef = useRef(0);
|
|
3801
|
+
const bindRuntimeProviderLane = useCallback((selection, modelId) => {
|
|
3802
|
+
const providerLaneSelect = getAgentPlatformBridge().workspace.providerLaneSelect;
|
|
3803
|
+
if (!conversationId || !conversation || !providerLaneSelect)
|
|
3804
|
+
return;
|
|
3805
|
+
const binding = resolveConversationWorkspaceBinding({
|
|
3806
|
+
workspaceMode: conversation.workspaceMode,
|
|
3807
|
+
rootDirectory: conversation.rootDirectory,
|
|
3808
|
+
grantedDirectories: conversation.grantedDirectories || EMPTY_STRINGS,
|
|
3809
|
+
inheritedDirectories: allowedDirectories,
|
|
3810
|
+
hasMessages: conversation.messages.length > 0,
|
|
3811
|
+
});
|
|
3812
|
+
if (binding.mode === 'unselected') {
|
|
3813
|
+
setToolStatus('Choose Chat or Agent mode before selecting a provider.');
|
|
3814
|
+
return;
|
|
3815
|
+
}
|
|
3816
|
+
const bindRevision = ++providerLaneSelectionRevisionRef.current;
|
|
3817
|
+
const selectedAt = selection.selectedAt;
|
|
3818
|
+
const providerId = selection.providerId;
|
|
3819
|
+
const acpAgentConfigId = selection.acpAgentConfigId;
|
|
3820
|
+
void providerLaneSelect({
|
|
3821
|
+
conversationId,
|
|
3822
|
+
workspaceMode: binding.mode,
|
|
3823
|
+
...(binding.mode === 'workspace' && binding.rootDirectory
|
|
3824
|
+
? { workingDirectory: binding.rootDirectory }
|
|
3825
|
+
: {}),
|
|
3826
|
+
...(props.workspaceId ? { workspaceId: props.workspaceId } : {}),
|
|
3827
|
+
providerKind: selection.providerKind === 'acp-provider'
|
|
3828
|
+
? 'acp-provider'
|
|
3829
|
+
: 'sdk-native',
|
|
3830
|
+
...(providerId ? { providerId } : {}),
|
|
3831
|
+
...(acpAgentConfigId ? { acpAgentConfigId } : {}),
|
|
3832
|
+
model: modelId.replace(/:thinking$/, ''),
|
|
3833
|
+
}).then((result) => {
|
|
3834
|
+
if (bindRevision !== providerLaneSelectionRevisionRef.current)
|
|
3835
|
+
return;
|
|
3836
|
+
const latest = useAgentChatStore.getState().getConversation(conversationId);
|
|
3837
|
+
if (!latest || latest.runtime?.selection.selectedAt !== selectedAt)
|
|
3838
|
+
return;
|
|
3839
|
+
if (!result?.success || !result.activeLane || !result.hostBinding) {
|
|
3840
|
+
setToolStatus(result?.error || 'The selected provider could not be bound to this conversation.');
|
|
3841
|
+
return;
|
|
3842
|
+
}
|
|
3843
|
+
setToolStatus(null);
|
|
3844
|
+
updateConversation(conversationId, {
|
|
3845
|
+
sessionUi: {
|
|
3846
|
+
...(latest.sessionUi || {}),
|
|
3847
|
+
hostBinding: result.hostBinding,
|
|
3848
|
+
activeLane: result.activeLane,
|
|
3849
|
+
lanes: result.lanes || [result.activeLane],
|
|
3850
|
+
},
|
|
3851
|
+
});
|
|
3852
|
+
}).catch((error) => {
|
|
3853
|
+
if (bindRevision !== providerLaneSelectionRevisionRef.current)
|
|
3854
|
+
return;
|
|
3855
|
+
setToolStatus(error instanceof Error ? error.message : 'The selected provider could not be bound to this conversation.');
|
|
3856
|
+
});
|
|
3857
|
+
}, [allowedDirectories, conversation, conversationId, props.workspaceId, setToolStatus, updateConversation]);
|
|
3754
3858
|
const persistRuntimeBinding = useCallback((selection, uiModel, mode) => {
|
|
3755
3859
|
const previousSelection = conversation?.runtime?.selection;
|
|
3756
3860
|
const runtime = createConversationRuntimeBinding({
|
|
@@ -3765,7 +3869,12 @@ export function AgentView(props) {
|
|
|
3765
3869
|
schemaVersion: 2,
|
|
3766
3870
|
model: uiModel,
|
|
3767
3871
|
runtime,
|
|
3872
|
+
sessionUi: {
|
|
3873
|
+
...(conversation?.sessionUi || {}),
|
|
3874
|
+
activeLane: undefined,
|
|
3875
|
+
},
|
|
3768
3876
|
});
|
|
3877
|
+
bindRuntimeProviderLane(selection, uiModel);
|
|
3769
3878
|
}
|
|
3770
3879
|
if (conversationId
|
|
3771
3880
|
&& previousSelection?.providerKind === 'acp-provider'
|
|
@@ -3785,6 +3894,8 @@ export function AgentView(props) {
|
|
|
3785
3894
|
return runtime;
|
|
3786
3895
|
}, [
|
|
3787
3896
|
agentId,
|
|
3897
|
+
bindRuntimeProviderLane,
|
|
3898
|
+
conversation?.sessionUi,
|
|
3788
3899
|
conversation?.runtime?.selection,
|
|
3789
3900
|
conversationId,
|
|
3790
3901
|
props.teamId,
|
|
@@ -3828,11 +3939,14 @@ export function AgentView(props) {
|
|
|
3828
3939
|
setEffortListOpen(false);
|
|
3829
3940
|
setAcpCliListOpen(false);
|
|
3830
3941
|
setAcpModelListOpen(false);
|
|
3831
|
-
|
|
3832
|
-
|
|
3833
|
-
|
|
3834
|
-
|
|
3835
|
-
|
|
3942
|
+
if (cloudModels.length === 0) {
|
|
3943
|
+
setToolStatus('No cloud models are currently available from the live XENO catalog.');
|
|
3944
|
+
setModeExpanded(false);
|
|
3945
|
+
setModelListOpen(false);
|
|
3946
|
+
return;
|
|
3947
|
+
}
|
|
3948
|
+
const rememberedCloudModel = cloudModels.find((modelEntry) => (modelEntry.id === lastCloudModel.replace(/:thinking$/, '')));
|
|
3949
|
+
const fallbackCloudModel = rememberedCloudModel ? lastCloudModel : preferredGpt55Model;
|
|
3836
3950
|
setToolStatus(null);
|
|
3837
3951
|
setInferenceMode('cloud');
|
|
3838
3952
|
setModeExpanded(false);
|
|
@@ -3863,27 +3977,40 @@ export function AgentView(props) {
|
|
|
3863
3977
|
setShowLocalRuntimePrompt(false);
|
|
3864
3978
|
setToolStatus(null);
|
|
3865
3979
|
setAcpModePending(true);
|
|
3866
|
-
|
|
3867
|
-
|
|
3868
|
-
|
|
3869
|
-
|
|
3870
|
-
|
|
3871
|
-
}
|
|
3980
|
+
// Close the previous mode's menus as part of the synchronous transition.
|
|
3981
|
+
// Doing this after the awaited Host/registry loads lets a user open the
|
|
3982
|
+
// ACP provider picker and then has the stale transition completion close
|
|
3983
|
+
// it underneath them — exactly the "empty picker" race seen in the live
|
|
3984
|
+
// Electron scenario.
|
|
3872
3985
|
setModelListOpen(false);
|
|
3873
3986
|
setEffortListOpen(false);
|
|
3874
3987
|
setAcpCliListOpen(false);
|
|
3875
3988
|
setAcpModelListOpen(false);
|
|
3876
|
-
|
|
3989
|
+
let providers = sharedRuntimeProviders;
|
|
3990
|
+
if (!sharedProviderCatalogLoaded) {
|
|
3991
|
+
const catalog = await loadHubAgentProviderCatalog();
|
|
3992
|
+
providers = catalog.providers;
|
|
3993
|
+
setSharedRuntimeProviders(catalog.providers);
|
|
3994
|
+
setSharedProviderCatalogLoaded(true);
|
|
3995
|
+
}
|
|
3996
|
+
await loadAcpAgentsForRuntime();
|
|
3997
|
+
const availableConfigIds = availableAcpConfigIds(providers);
|
|
3998
|
+
const hasAvailableProvider = useAcpAgentStore.getState().agents.some((agent) => (agent.enabled && availableConfigIds.has(agent.id)));
|
|
3999
|
+
if (!hasAvailableProvider) {
|
|
4000
|
+
setToolStatus('No available ACP providers. Enable or repair one in Settings.');
|
|
4001
|
+
}
|
|
4002
|
+
}, [loadAcpAgentsForRuntime, setToolStatus, sharedProviderCatalogLoaded, sharedRuntimeProviders]);
|
|
3877
4003
|
const selectAcpRuntime = useCallback((acpAgentConfigId, providerModel) => {
|
|
3878
4004
|
const nextAcpAgentConfigId = acpAgentConfigId || selectedAcpAgentConfigId;
|
|
3879
4005
|
if (!nextAcpAgentConfigId)
|
|
3880
4006
|
return;
|
|
4007
|
+
setToolStatus(null);
|
|
3881
4008
|
setAcpRuntimeSelection(nextAcpAgentConfigId, providerModel);
|
|
3882
4009
|
setModelListOpen(false);
|
|
3883
4010
|
setEffortListOpen(false);
|
|
3884
4011
|
setAcpCliListOpen(false);
|
|
3885
4012
|
setAcpModelListOpen(false);
|
|
3886
|
-
}, [selectedAcpAgentConfigId, setAcpRuntimeSelection]);
|
|
4013
|
+
}, [selectedAcpAgentConfigId, setAcpRuntimeSelection, setToolStatus]);
|
|
3887
4014
|
// Delay model selector visibility - hide instantly on expand, show after collapse animation (200ms)
|
|
3888
4015
|
useEffect(() => {
|
|
3889
4016
|
if (modeExpanded) {
|
|
@@ -4022,12 +4149,15 @@ export function AgentView(props) {
|
|
|
4022
4149
|
&& !!selectedAcpAgentConfigId
|
|
4023
4150
|
&& !acpRuntimeAgentDetails[selectedAcpAgentConfigId]
|
|
4024
4151
|
&& !acpRuntimeAgentDetailErrors[selectedAcpAgentConfigId];
|
|
4025
|
-
const inputLocked =
|
|
4026
|
-
|
|
4027
|
-
|
|
4028
|
-
|
|
4029
|
-
|
|
4030
|
-
|
|
4152
|
+
const inputLocked = isAgentComposerInputLocked({
|
|
4153
|
+
workspaceUnselected: workspaceBinding.mode === 'unselected',
|
|
4154
|
+
externalInputLocked: !!props.externalInputLockReason,
|
|
4155
|
+
nativeTuiWriterAttached: !!props.onSendToNativeTui,
|
|
4156
|
+
commandRunning: isRunningCommand,
|
|
4157
|
+
acpRuntimeReadinessPending,
|
|
4158
|
+
nonAcpModelNotReady: runtimeProvider.kind !== 'acp-provider' && !isModelReady,
|
|
4159
|
+
cloudModelUnavailable,
|
|
4160
|
+
});
|
|
4031
4161
|
const queuedTurnCount = conversation?.pendingTurns?.length ?? 0;
|
|
4032
4162
|
const checkpoints = conversation?.checkpoints || [];
|
|
4033
4163
|
const pendingTurns = conversation?.pendingTurns || [];
|
|
@@ -6021,6 +6151,30 @@ export function AgentView(props) {
|
|
|
6021
6151
|
const hasAttachments = attachmentsToSend.length > 0;
|
|
6022
6152
|
if ((!trimmed && !hasAttachments) || inputLocked)
|
|
6023
6153
|
return;
|
|
6154
|
+
if (props.onSendToNativeTui) {
|
|
6155
|
+
const targetConversationId = ensureConversationId(conversationId);
|
|
6156
|
+
if (hasAttachments) {
|
|
6157
|
+
appendMessage(targetConversationId, {
|
|
6158
|
+
role: 'assistant',
|
|
6159
|
+
content: 'Attach files from the native provider TUI or return to structured chat before sending attachments.',
|
|
6160
|
+
error: 'Native provider TUI input accepts text only.',
|
|
6161
|
+
});
|
|
6162
|
+
return;
|
|
6163
|
+
}
|
|
6164
|
+
setInput('');
|
|
6165
|
+
if (textareaRef.current)
|
|
6166
|
+
textareaRef.current.style.height = 'auto';
|
|
6167
|
+
const delivered = await props.onSendToNativeTui(trimmed);
|
|
6168
|
+
if (!delivered.success) {
|
|
6169
|
+
setInput(trimmed);
|
|
6170
|
+
appendMessage(targetConversationId, {
|
|
6171
|
+
role: 'assistant',
|
|
6172
|
+
content: delivered.error || 'The native provider TUI could not receive the message.',
|
|
6173
|
+
error: delivered.error || 'Native provider TUI input failed.',
|
|
6174
|
+
});
|
|
6175
|
+
}
|
|
6176
|
+
return;
|
|
6177
|
+
}
|
|
6024
6178
|
const useLegacyDeterministicFileActions = isLegacyDeterministicFileActionCompatibilityEnabled();
|
|
6025
6179
|
const replaceExistingFileCreate = useLegacyDeterministicFileActions && !hasAttachments && isReplaceExistingFileIntent(trimmed)
|
|
6026
6180
|
? findLastExistingFileWriteRequest(messages)
|
|
@@ -7324,18 +7478,17 @@ export function AgentView(props) {
|
|
|
7324
7478
|
const fixture = agent.certification?.status === 'fixture_only';
|
|
7325
7479
|
const ready = fixture || (agent.certification?.status === 'certified' && agent.providerReview?.runnable === true);
|
|
7326
7480
|
return (_jsxs("button", { onClick: () => { selectAcpRuntime(agent.id, selected ? acpProviderModel : undefined); }, role: "option", "aria-selected": selected, className: `w-full flex items-center justify-between gap-2 px-3 py-1.5 text-left transition-colors cursor-pointer ${selected ? 'bg-white/[0.06]' : 'hover:bg-white/[0.04]'}`, children: [_jsx("span", { className: `min-w-0 flex-1 text-[11px] truncate ${selected ? 'text-white/70' : 'text-white/40'}`, children: acpAgentDisplayName(agent) }), _jsx("span", { className: `text-[8px] uppercase tracking-wide ${ready ? 'text-[#96e59d]/70' : 'text-[#ffd38a]/70'}`, children: ready ? 'ready' : 'check' })] }, agent.id));
|
|
7327
|
-
})) : (_jsx("div", { className: "px-3 py-2.5 text-[10px] text-white/25 text-center", children: "No
|
|
7481
|
+
})) : (_jsx("div", { className: "px-3 py-2.5 text-[10px] text-white/25 text-center", children: "No available ACP CLI providers. Enable or repair one in Settings." }))] })), runtimeMode === 'acp' && acpModelListOpen && (_jsxs("div", { ref: acpModelListRef, className: "xeno-elevated-shell xeno-border-subtle absolute left-[170px] bottom-[44px] z-50 flex max-h-[280px] w-[220px] flex-col overflow-hidden rounded-md border", children: [renderModelSearch(), _jsxs("div", { role: "listbox", className: "min-h-0 overflow-y-auto", children: [_jsxs("div", { className: "flex items-center justify-between gap-2 px-3 pt-2 pb-1 text-[9px] uppercase tracking-[0.14em] text-white/25", children: [_jsx("span", { children: "ACP model" }), sharedProviderCatalogRefreshing && !acpModelsLoading && _jsx("span", { children: "Refreshing..." })] }), _jsx("button", { onClick: () => { if (selectedAcpAgentConfigId)
|
|
7328
7482
|
selectAcpRuntime(selectedAcpAgentConfigId, undefined); }, disabled: !selectedAcpAgentConfigId, role: "option", "aria-selected": !acpProviderModel, className: `w-full flex items-center justify-between px-3 py-1.5 text-left transition-colors cursor-pointer disabled:opacity-30 disabled:cursor-not-allowed ${!acpProviderModel ? 'bg-white/[0.06]' : 'hover:bg-white/[0.04]'}`, children: _jsx("span", { className: `text-[11px] truncate ${!acpProviderModel ? 'text-white/70' : 'text-white/40'}`, children: "CLI default" }) }), acpModelsLoading ? (_jsx("div", { className: "px-3 py-2.5 text-[10px] text-white/25 text-center", children: "Loading models..." })) : acpModelOptions.length > 0 ? (filteredAcpModelOptions.length > 0 ? filteredAcpModelOptions.map((entry) => {
|
|
7329
7483
|
const selected = entry.selectionKey === (selectedAcpEffortFamily?.baseId || acpProviderModel);
|
|
7330
7484
|
return (_jsxs("button", { onClick: () => { if (selectedAcpAgentConfigId)
|
|
7331
7485
|
selectAcpRuntime(selectedAcpAgentConfigId, entry.id); }, disabled: !selectedAcpAgentConfigId || !entry.available, role: "option", "aria-selected": selected, className: `w-full flex items-center justify-between px-3 py-1.5 text-left transition-colors cursor-pointer disabled:opacity-30 disabled:cursor-not-allowed ${selected ? 'bg-white/[0.06]' : 'hover:bg-white/[0.04]'}`, title: entry.reason || undefined, children: [_jsx("span", { className: `min-w-0 flex-1 text-[11px] truncate ${selected ? 'text-white/70' : 'text-white/40'}`, children: entry.name }), !entry.available && _jsx("span", { className: "ml-2 flex-shrink-0 text-[8px] uppercase tracking-wide text-[#ff8f8f]", children: "Unavailable" })] }, entry.selectionKey));
|
|
7332
|
-
}) : (_jsx("div", { className: "px-3 py-2.5 text-[10px] text-white/25 text-center", children: "No matching models" }))) : (_jsx("div", { className: "px-3 py-2.5 text-[10px] text-white/25 text-center", children: selectedAcpAgentConfigId ? (acpModelMessage || 'No preset models for this ACP CLI') : 'Select a CLI first' }))] })] })), modelListOpen && runtimeMode !== 'acp' && (_jsxs("div", { ref: modelListRef, className: "xeno-elevated-shell xeno-border-subtle absolute left-3 bottom-[44px] z-50 flex max-h-[340px] w-[280px] flex-col overflow-hidden rounded-md border", children: [renderModelSearch(), _jsx("div", { role: "listbox", className: "min-h-0 overflow-y-auto", children: runtimeMode === 'cloud' ? (cloudModels.length > 0 ? (filteredCloudModelOptions.length > 0 ? filteredCloudModelOptions.map(entry => ((() => {
|
|
7486
|
+
}) : (_jsx("div", { className: "px-3 py-2.5 text-[10px] text-white/25 text-center", children: "No matching models" }))) : (_jsx("div", { className: "px-3 py-2.5 text-[10px] text-white/25 text-center", children: selectedAcpAgentConfigId ? (acpModelMessage || 'No preset models for this ACP CLI') : 'Select a CLI first' }))] })] })), modelListOpen && runtimeMode !== 'acp' && (_jsxs("div", { ref: modelListRef, className: "xeno-elevated-shell xeno-border-subtle absolute left-3 bottom-[44px] z-50 flex max-h-[340px] w-[280px] flex-col overflow-hidden rounded-md border", children: [renderModelSearch(), _jsx("div", { role: "listbox", className: "min-h-0 overflow-y-auto", children: runtimeMode === 'cloud' ? (sharedProviderCatalogRefreshing ? (_jsx("div", { className: "px-3 py-3 text-[10px] text-white/25 text-center", children: "Refreshing available models..." })) : cloudModels.length > 0 ? (filteredCloudModelOptions.length > 0 ? filteredCloudModelOptions.map(entry => ((() => {
|
|
7333
7487
|
const modelMeta = cloudModels.find(cm => cm.id === entry.id.replace(/:thinking$/, ''));
|
|
7334
|
-
const unavailable = modelMeta?.availability === 'unavailable';
|
|
7335
7488
|
const degraded = modelMeta?.availability === 'degraded';
|
|
7336
7489
|
const selected = entry.selectionKey === (selectedCloudEffortFamily?.baseId || selectedModel);
|
|
7337
|
-
return (_jsxs("button", { onClick: () => { setInferenceMode('cloud'); setSelectedModel(entry.id); setModelListOpen(false); setEffortListOpen(false); }, role: "option", "aria-selected": selected, className: `w-full flex items-center justify-between px-3 py-1.5 text-left transition-colors cursor-pointer ${selected ? 'bg-white/[0.06]' : 'hover:bg-white/[0.04]'}
|
|
7338
|
-
})())) : (_jsx("div", { className: "px-3 py-3 text-[10px] text-white/25 text-center", children: "No matching models" }))) : (_jsx("div", { className: "px-3 py-3 text-[10px] text-white/
|
|
7490
|
+
return (_jsxs("button", { onClick: () => { setInferenceMode('cloud'); setSelectedModel(entry.id); setModelListOpen(false); setEffortListOpen(false); }, role: "option", "aria-selected": selected, className: `w-full flex items-center justify-between px-3 py-1.5 text-left transition-colors cursor-pointer ${selected ? 'bg-white/[0.06]' : 'hover:bg-white/[0.04]'}`, title: modelMeta?.availabilityReason || undefined, children: [_jsxs("div", { className: "min-w-0 flex-1 flex items-center gap-2", children: [_jsx("span", { className: `text-[11px] truncate ${selected ? 'text-white/70' : 'text-white/40'}`, children: entry.name }), degraded && _jsx("span", { className: "text-[8px] uppercase tracking-wide text-[#ffd38a]", children: "Fallback" })] }), _jsx("span", { className: "text-[9px] text-white/20 flex-shrink-0 ml-2 tabular-nums", children: (() => { const m = cloudModels.find(cm => cm.id === entry.id.replace(/:thinking$/, '')); return m?.creditsPerKToken != null ? `${m.creditsPerKToken}/1k` : ''; })() })] }, entry.id));
|
|
7491
|
+
})())) : (_jsx("div", { className: "px-3 py-3 text-[10px] text-white/25 text-center", children: "No matching models" }))) : (_jsx("div", { className: "px-3 py-3 text-[10px] leading-relaxed text-white/35 text-center", children: cloudCatalogUnavailableReason }))) : (_jsxs(_Fragment, { children: [localModels.length > 0 ? (filteredLocalModels.length > 0 ? filteredLocalModels.map(m => {
|
|
7339
7492
|
const selected = m.id === (selectedLocalEffortFamily?.baseId || selectedModel);
|
|
7340
7493
|
return (_jsxs("button", { onClick: () => { setInferenceMode('local'); setSelectedModel(m.id); setModelListOpen(false); setEffortListOpen(false); }, role: "option", "aria-selected": selected, className: `w-full flex items-center gap-2 px-3 py-1.5 text-left transition-colors cursor-pointer ${selected ? 'bg-white/[0.06]' : 'hover:bg-white/[0.04]'}`, children: [_jsx("span", { className: `text-[11px] truncate ${selected ? 'text-white/70' : 'text-white/40'}`, children: m.name }), m.parameterSize && _jsx("span", { className: "text-[8px] text-white/20 flex-shrink-0 ml-auto", children: m.parameterSize })] }, m.id));
|
|
7341
7494
|
}) : (_jsx("div", { className: "px-3 py-2.5 text-[10px] text-white/25 text-center", children: "No matching models" }))) : (_jsx("div", { className: "px-3 py-2.5 text-[10px] text-white/25 text-center", children: "No local models installed" })), _jsx("button", { onClick: () => { setModelListOpen(false); goToModelsMarketplace(); }, className: "w-full flex items-center justify-center gap-1.5 px-3 py-2 border-t border-white/[0.06] text-[10px] text-white/35 hover:text-white/60 hover:bg-white/[0.04] transition-colors cursor-pointer", children: "Browse models" })] })) })] })), _jsxs("div", { className: "space-y-0", children: [pendingTurns.length > 0 && (_jsxs("div", { className: "xeno-border-subtle rounded-t-md border border-b-0 bg-[#111111] overflow-hidden", children: [_jsxs("div", { className: "flex items-center justify-between gap-3 px-3 py-2 border-b xeno-border-subtle", children: [_jsxs("div", { className: "flex items-center gap-2 min-w-0", children: [_jsx("span", { className: "text-[10px] uppercase tracking-[0.14em] xeno-text-faint whitespace-nowrap", children: "Queued Messages" }), _jsx("span", { className: "text-[10px] xeno-text-muted tabular-nums whitespace-nowrap", children: pendingTurns.length })] }), _jsx("button", { onClick: () => patchSessionUi({ panelOpen: true }), className: "text-[10px] xeno-text-faint hover:text-[color:var(--xeno-ink-secondary)] transition-colors whitespace-nowrap cursor-pointer focus-visible:outline focus-visible:outline-1 focus-visible:outline-white/35", children: "Manage queue" })] }), _jsxs("div", { className: "divide-y xeno-border-subtle", children: [pendingTurns.slice(0, 3).map((turn) => (_jsxs("div", { className: "flex items-center gap-3 px-3 py-2", children: [_jsx("span", { className: "inline-flex h-5 min-w-5 items-center justify-center rounded-[4px] bg-white/[0.04] px-1.5 text-[10px] xeno-text-faint tabular-nums", children: new Date(turn.queuedAt).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }) }), _jsx("span", { className: "min-w-0 flex-1 text-[12px] leading-4 xeno-text-secondary truncate", children: turn.content }), _jsx("button", { onClick: () => handleRemoveQueuedConversationTurn(turn.id), className: "text-[10px] xeno-text-faint hover:text-[color:var(--xeno-ink-secondary)] transition-colors whitespace-nowrap cursor-pointer focus-visible:outline focus-visible:outline-1 focus-visible:outline-white/35", title: "Remove queued message", children: "Remove" })] }, turn.id))), pendingTurns.length > 3 && (_jsxs("div", { className: "px-3 py-2 text-[11px] xeno-text-faint", children: [pendingTurns.length - 3, " more queued"] }))] })] })), _jsxs("div", { className: "mb-2 flex items-center justify-between gap-2", "data-agent-workspace-binding": workspaceBinding.mode, children: [_jsxs("div", { className: "inline-flex items-center rounded-md border border-white/[0.08] bg-white/[0.025] p-0.5 text-[11px]", children: [_jsx("button", { type: "button", onClick: () => { void handleSelectWorkspaceMode('chat-only'); }, disabled: isBusy || !!props.externalInputLockReason || isSelectingConversationWorkspace, className: `rounded px-2.5 py-1 font-medium transition-colors disabled:cursor-not-allowed disabled:opacity-40 ${workspaceBinding.mode !== 'workspace'
|