@personai/agent-ui-terminal 1.0.0-preview.1 → 1.0.0-preview.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -1
- package/dist/index.js +48 -36
- package/dist/src/index.d.ts +6 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
## 安装
|
|
6
6
|
|
|
7
7
|
```sh
|
|
8
|
-
npm install @personai/agent-ui-terminal
|
|
8
|
+
npm install --save-exact @personai/agent-ui-terminal@1.0.0-preview.3
|
|
9
9
|
```
|
|
10
10
|
|
|
11
11
|
应用入口需导入 `@personai/agent-ui-terminal/styles.css`。包内 `npm run dev` 提供本地模拟宿主演示。
|
|
@@ -38,6 +38,26 @@ terminal.dispose();
|
|
|
38
38
|
|
|
39
39
|
`createTerminalTransport` 使用 Socket.IO 连接远端 PTY。服务端负责安全地创建并管理 shell 进程;浏览器组件只发送终端输入、尺寸变化和信号。连接地址、认证、租户信息和进程启动策略均由宿主决定。
|
|
40
40
|
|
|
41
|
+
## 实例控制
|
|
42
|
+
|
|
43
|
+
`initTerminal()` 返回可直接调用的实例,无需获取内部 Terminal 类或 xterm 对象。以下三个方法从 `1.0.0-preview.3` 开始提供,`1.0.0-preview.2` 不包含它们。
|
|
44
|
+
|
|
45
|
+
| 方法 | 返回值 | 行为 |
|
|
46
|
+
| --- | --- | --- |
|
|
47
|
+
| `clear()` | `void` | 调用 xterm 清屏,清除缓冲区并保留当前提示行;不向 shell 发送 clear 命令、不停止 PTY,也不删除宿主历史 |
|
|
48
|
+
| `getSelection()` | `string` | 读取终端选中的文本;未选择时返回空字符串 |
|
|
49
|
+
| `focus()` | `void` | 聚焦终端输入;不重建实例或连接 |
|
|
50
|
+
|
|
51
|
+
```ts
|
|
52
|
+
terminal.clear();
|
|
53
|
+
const selectedText = terminal.getSelection();
|
|
54
|
+
terminal.focus();
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
这些方法在实例存活期间使用;关闭后调用 `dispose()`,不要继续操作已销毁的实例。三个方法均保留当前主题和语言设置。
|
|
58
|
+
|
|
59
|
+
主题初始化放在 `terminalOptions.themeTokens`;运行中通过 `setThemeTokens(tokens)` 更新,通过 `resetTheme()` 清除覆盖,通过 `refreshTheme()` 将当前 CSS 颜色同步到 xterm。`setLocale()` / `setMessages()` 更新文案。
|
|
60
|
+
|
|
41
61
|
## 自定义传输
|
|
42
62
|
|
|
43
63
|
如果宿主的传输协议不同,实现并注入 `TerminalTransport` 即可。它负责连接、发送键盘输入/尺寸/信号,并通知组件输出、会话信息、退出和错误。需要 AI 能力时再实现 `AITransport` 的 `request` 与 `stream`;流式结果通过 `onChunk` 提供文本,通过 `onEvent` 提供结构化 Agent 活动。详见包导出的 TypeScript 接口。
|
package/dist/index.js
CHANGED
|
@@ -2552,8 +2552,8 @@ class Yi {
|
|
|
2552
2552
|
}
|
|
2553
2553
|
}
|
|
2554
2554
|
getOrCreateSession(e) {
|
|
2555
|
-
var
|
|
2556
|
-
if (!((
|
|
2555
|
+
var C;
|
|
2556
|
+
if (!((C = this.terminal) != null && C.element))
|
|
2557
2557
|
return;
|
|
2558
2558
|
const t = Zi(e.requestId, e.conversationId), i = this.sessions.get(t);
|
|
2559
2559
|
if (i)
|
|
@@ -3964,8 +3964,8 @@ class Ds {
|
|
|
3964
3964
|
let g;
|
|
3965
3965
|
try {
|
|
3966
3966
|
g = JSON.parse(u);
|
|
3967
|
-
} catch (
|
|
3968
|
-
h(
|
|
3967
|
+
} catch (C) {
|
|
3968
|
+
h(C);
|
|
3969
3969
|
return;
|
|
3970
3970
|
}
|
|
3971
3971
|
const w = $s(g);
|
|
@@ -4072,13 +4072,13 @@ function Qs(s) {
|
|
|
4072
4072
|
let o, r = !1;
|
|
4073
4073
|
const a = {}, l = /* @__PURE__ */ new Map(), c = /* @__PURE__ */ new Map(), h = /* @__PURE__ */ new Map(), p = /* @__PURE__ */ new Set(), u = (d, m, E) => {
|
|
4074
4074
|
var T;
|
|
4075
|
-
const
|
|
4076
|
-
|
|
4075
|
+
const I = (T = a.current) == null ? void 0 : T.shellIntegrationAddon, $ = (I == null ? void 0 : I.sanitizeInput(d)) ?? d;
|
|
4076
|
+
I == null || I.noteInput($), t.input($, m, E);
|
|
4077
4077
|
}, g = i ? async (d) => {
|
|
4078
4078
|
var T, ie, Ue, He, ze, We;
|
|
4079
4079
|
const m = ((ie = (T = globalThis.crypto) == null ? void 0 : T.randomUUID) == null ? void 0 : ie.call(T)) ?? `${Date.now()}-${Math.random()}`, E = new AbortController();
|
|
4080
4080
|
h.set(m, E);
|
|
4081
|
-
let
|
|
4081
|
+
let I;
|
|
4082
4082
|
const $ = async (Y) => {
|
|
4083
4083
|
var D, fe;
|
|
4084
4084
|
await i.stream(
|
|
@@ -4099,7 +4099,7 @@ function Qs(s) {
|
|
|
4099
4099
|
if (r) return;
|
|
4100
4100
|
const _ = Fs(R);
|
|
4101
4101
|
if (_) {
|
|
4102
|
-
|
|
4102
|
+
I = _, (se = (k = a.current) == null ? void 0 : k.modelSessionAddon) == null || se.appendUserInputRequest({
|
|
4103
4103
|
conversationId: "default",
|
|
4104
4104
|
requestId: m,
|
|
4105
4105
|
request: _,
|
|
@@ -4122,9 +4122,9 @@ function Qs(s) {
|
|
|
4122
4122
|
requestId: m
|
|
4123
4123
|
}), await $();
|
|
4124
4124
|
} finally {
|
|
4125
|
-
h.delete(m), !r && !
|
|
4125
|
+
h.delete(m), !r && !I && !p.has(m) && await (((We = (ze = a.current) == null ? void 0 : ze.modelSessionAddon) == null ? void 0 : We.complete(m)) ?? Promise.resolve());
|
|
4126
4126
|
}
|
|
4127
|
-
if (
|
|
4127
|
+
if (I && !r) {
|
|
4128
4128
|
let Y, D;
|
|
4129
4129
|
const fe = new Promise((R, _) => {
|
|
4130
4130
|
Y = R, D = _;
|
|
@@ -4135,7 +4135,7 @@ function Qs(s) {
|
|
|
4135
4135
|
}), l.set(m, async (R, _) => {
|
|
4136
4136
|
var se;
|
|
4137
4137
|
const k = (se = a.current) == null ? void 0 : se.modelSessionAddon;
|
|
4138
|
-
k == null || k.clearUserInputRequest(m, R, _),
|
|
4138
|
+
k == null || k.clearUserInputRequest(m, R, _), I = void 0;
|
|
4139
4139
|
try {
|
|
4140
4140
|
await $([
|
|
4141
4141
|
{
|
|
@@ -4143,11 +4143,11 @@ function Qs(s) {
|
|
|
4143
4143
|
status: "resolved",
|
|
4144
4144
|
payload: { answers: _ }
|
|
4145
4145
|
}
|
|
4146
|
-
]),
|
|
4146
|
+
]), I || (await (k == null ? void 0 : k.complete(m)), Y());
|
|
4147
4147
|
} catch (ne) {
|
|
4148
4148
|
throw D(ne), ne;
|
|
4149
4149
|
} finally {
|
|
4150
|
-
k == null || k.setUserInputSubmitting(m, !1),
|
|
4150
|
+
k == null || k.setUserInputSubmitting(m, !1), I || (l.delete(m), c.delete(m));
|
|
4151
4151
|
}
|
|
4152
4152
|
}), await fe;
|
|
4153
4153
|
}
|
|
@@ -4156,7 +4156,7 @@ function Qs(s) {
|
|
|
4156
4156
|
signal: E
|
|
4157
4157
|
}) => {
|
|
4158
4158
|
var $, T;
|
|
4159
|
-
let
|
|
4159
|
+
let I = "";
|
|
4160
4160
|
return await i.stream(
|
|
4161
4161
|
((T = ($ = s.prompts) == null ? void 0 : $.explain) == null ? void 0 : T.call($, d)) ?? `Command:
|
|
4162
4162
|
${d.command}
|
|
@@ -4165,18 +4165,18 @@ Output:
|
|
|
4165
4165
|
${d.output}`,
|
|
4166
4166
|
{
|
|
4167
4167
|
onChunk: ({ delta: ie }) => {
|
|
4168
|
-
|
|
4168
|
+
I += ie, m == null || m(ie);
|
|
4169
4169
|
},
|
|
4170
4170
|
signal: E
|
|
4171
4171
|
}
|
|
4172
|
-
),
|
|
4172
|
+
), I;
|
|
4173
4173
|
} : void 0, f = i ? (d) => {
|
|
4174
4174
|
var m, E;
|
|
4175
4175
|
return i.request(((E = (m = s.prompts) == null ? void 0 : m.generate) == null ? void 0 : E.call(m, d)) ?? d);
|
|
4176
4176
|
} : void 0, F = (d) => {
|
|
4177
4177
|
const m = a.current;
|
|
4178
4178
|
return m ? m.executeCommand(d) : Promise.reject(new Error("终端尚未完成初始化"));
|
|
4179
|
-
},
|
|
4179
|
+
}, C = new ks(s.el, {
|
|
4180
4180
|
cursorBlink: !0,
|
|
4181
4181
|
cursorStyle: "bar",
|
|
4182
4182
|
cursorWidth: 2,
|
|
@@ -4234,14 +4234,14 @@ ${d.output}`,
|
|
|
4234
4234
|
requestId: m,
|
|
4235
4235
|
answers: E
|
|
4236
4236
|
}) => {
|
|
4237
|
-
const
|
|
4238
|
-
|
|
4237
|
+
const I = l.get(d);
|
|
4238
|
+
I && await I(m, E);
|
|
4239
4239
|
},
|
|
4240
4240
|
onCancelSession: async ({ requestId: d }) => {
|
|
4241
|
-
var E,
|
|
4241
|
+
var E, I, $, T;
|
|
4242
4242
|
p.add(d), l.delete(d), (E = c.get(d)) == null || E.resolve(), c.delete(d);
|
|
4243
4243
|
const m = h.get(d);
|
|
4244
|
-
m == null || m.abort(new DOMException("会话已终止", "AbortError")), await ((
|
|
4244
|
+
m == null || m.abort(new DOMException("会话已终止", "AbortError")), await ((I = i == null ? void 0 : i.cancel) == null ? void 0 : I.call(
|
|
4245
4245
|
i,
|
|
4246
4246
|
(m == null ? void 0 : m.signal) ?? new AbortController().signal
|
|
4247
4247
|
)), await ((T = ($ = a.current) == null ? void 0 : $.modelSessionAddon) == null ? void 0 : T.complete(
|
|
@@ -4250,22 +4250,22 @@ ${d.output}`,
|
|
|
4250
4250
|
}
|
|
4251
4251
|
} : void 0
|
|
4252
4252
|
});
|
|
4253
|
-
a.current =
|
|
4253
|
+
a.current = C;
|
|
4254
4254
|
const v = t.onOutput((d) => {
|
|
4255
|
-
|
|
4255
|
+
C.terminal.write(d, () => {
|
|
4256
4256
|
var m;
|
|
4257
|
-
(m =
|
|
4257
|
+
(m = C.shellIntegrationAddon) == null || m.noteOutput(d);
|
|
4258
4258
|
});
|
|
4259
4259
|
}), S = t.onSessionChange((d) => {
|
|
4260
4260
|
var m, E;
|
|
4261
|
-
o = d, (m =
|
|
4261
|
+
o = d, (m = C.shellIntegrationAddon) == null || m.setCwd(d.currentDirectory), d.supportsBlocks || (E = s.onDegraded) == null || E.call(s, d);
|
|
4262
4262
|
}), q = t.onExit((d) => {
|
|
4263
4263
|
var m;
|
|
4264
4264
|
(m = s.onExit) == null || m.call(s, d);
|
|
4265
4265
|
}), K = t.onError((d) => {
|
|
4266
4266
|
te(d);
|
|
4267
|
-
}), _e =
|
|
4268
|
-
|
|
4267
|
+
}), _e = C.terminal.onResize((d) => {
|
|
4268
|
+
C.shouldNotifyTransportResize() && t.resize(d);
|
|
4269
4269
|
});
|
|
4270
4270
|
t.connect().catch((d) => {
|
|
4271
4271
|
te(qs(d));
|
|
@@ -4276,15 +4276,27 @@ ${d.output}`,
|
|
|
4276
4276
|
return {
|
|
4277
4277
|
dispose() {
|
|
4278
4278
|
var d;
|
|
4279
|
-
r = !0, v.dispose(), S.dispose(), q.dispose(), K.dispose(), _e.dispose(), t.dispose(), (d = i == null ? void 0 : i.dispose) == null || d.call(i),
|
|
4279
|
+
r = !0, v.dispose(), S.dispose(), q.dispose(), K.dispose(), _e.dispose(), t.dispose(), (d = i == null ? void 0 : i.dispose) == null || d.call(i), C.dispose();
|
|
4280
|
+
},
|
|
4281
|
+
/** Clears xterm's buffer while keeping the current prompt line and PTY session. */
|
|
4282
|
+
clear() {
|
|
4283
|
+
C.terminal.clear();
|
|
4284
|
+
},
|
|
4285
|
+
/** Returns selected terminal text, or an empty string when nothing is selected. */
|
|
4286
|
+
getSelection() {
|
|
4287
|
+
return C.terminal.getSelection();
|
|
4288
|
+
},
|
|
4289
|
+
/** Focuses the terminal input without reconnecting its transport. */
|
|
4290
|
+
focus() {
|
|
4291
|
+
C.terminal.focus();
|
|
4280
4292
|
},
|
|
4281
4293
|
/** Runs a command through the real prompt, producing a normal block. */
|
|
4282
4294
|
executeCommand(d) {
|
|
4283
|
-
return
|
|
4295
|
+
return C.executeCommand(d);
|
|
4284
4296
|
},
|
|
4285
4297
|
appendChatChunk(d, m) {
|
|
4286
4298
|
var E;
|
|
4287
|
-
(E =
|
|
4299
|
+
(E = C.modelSessionAddon) == null || E.appendMessageChunk({
|
|
4288
4300
|
requestId: (m == null ? void 0 : m.requestId) ?? "default",
|
|
4289
4301
|
conversationId: (m == null ? void 0 : m.conversationId) ?? "default",
|
|
4290
4302
|
response: d
|
|
@@ -4292,22 +4304,22 @@ ${d.output}`,
|
|
|
4292
4304
|
},
|
|
4293
4305
|
completeChat(d = "default") {
|
|
4294
4306
|
var m;
|
|
4295
|
-
return ((m =
|
|
4307
|
+
return ((m = C.modelSessionAddon) == null ? void 0 : m.complete(d)) ?? Promise.resolve();
|
|
4296
4308
|
},
|
|
4297
4309
|
setThemeTokens(d) {
|
|
4298
|
-
|
|
4310
|
+
C.setThemeTokens(d);
|
|
4299
4311
|
},
|
|
4300
4312
|
resetTheme() {
|
|
4301
|
-
|
|
4313
|
+
C.resetTheme();
|
|
4302
4314
|
},
|
|
4303
4315
|
refreshTheme() {
|
|
4304
|
-
|
|
4316
|
+
C.refreshTheme();
|
|
4305
4317
|
},
|
|
4306
4318
|
setLocale(d, m) {
|
|
4307
|
-
n.setLocale(d), m && n.setMessages(m),
|
|
4319
|
+
n.setLocale(d), m && n.setMessages(m), C.refreshLocale();
|
|
4308
4320
|
},
|
|
4309
4321
|
setMessages(d) {
|
|
4310
|
-
n.setMessages(d),
|
|
4322
|
+
n.setMessages(d), C.refreshLocale();
|
|
4311
4323
|
}
|
|
4312
4324
|
};
|
|
4313
4325
|
}
|
package/dist/src/index.d.ts
CHANGED
|
@@ -49,6 +49,12 @@ export interface ChatTerminalOptions {
|
|
|
49
49
|
export type IOptions = ChatTerminalOptions;
|
|
50
50
|
export declare function initTerminal(options: ChatTerminalOptions): {
|
|
51
51
|
dispose(): void;
|
|
52
|
+
/** Clears xterm's buffer while keeping the current prompt line and PTY session. */
|
|
53
|
+
clear(): void;
|
|
54
|
+
/** Returns selected terminal text, or an empty string when nothing is selected. */
|
|
55
|
+
getSelection(): string;
|
|
56
|
+
/** Focuses the terminal input without reconnecting its transport. */
|
|
57
|
+
focus(): void;
|
|
52
58
|
/** Runs a command through the real prompt, producing a normal block. */
|
|
53
59
|
executeCommand(command: string): Promise<TerminalCommandBlock>;
|
|
54
60
|
appendChatChunk(response: string, ids?: {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@personai/agent-ui-terminal",
|
|
3
|
-
"version": "1.0.0-preview.
|
|
3
|
+
"version": "1.0.0-preview.3",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
31
|
"@microsoft/fetch-event-source": "^2.0.1",
|
|
32
|
-
"@personai/agent-ui-chat-core": "1.0.0-preview.
|
|
32
|
+
"@personai/agent-ui-chat-core": "1.0.0-preview.3",
|
|
33
33
|
"@preact/signals-core": "^1.14.4",
|
|
34
34
|
"@xterm/addon-fit": "^0.10.0",
|
|
35
35
|
"@xterm/addon-web-links": "^0.11.0",
|