wtagent 0.1.0-alpha.5 → 0.1.0
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 +42 -92
- package/docs/technical-design.md +1 -0
- package/package.json +2 -1
- package/src/browser/cdp-browser.js +32 -4
- package/src/browser/chatgpt-web-adapter.js +351 -100
- package/src/browser/fake-web-model-adapter.js +5 -1
- package/src/cli/main.js +183 -16
- package/src/cli/prompt-input.js +154 -4
- package/src/cli/render-events.js +22 -0
- package/src/policy/approval-store.js +67 -0
- package/src/policy/policy-engine.js +16 -0
- package/src/protocol/prompt-builder.js +5 -2
- package/src/runtime/agent-runtime.js +192 -21
- package/src/shared/limits.js +8 -1
- package/src/shared/usage-limit.js +21 -0
- package/src/tools/default-tools.js +23 -3
- package/src/tools/search-fallback.js +27 -3
package/README.md
CHANGED
|
@@ -1,144 +1,94 @@
|
|
|
1
1
|
# WTAgent
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Use GPT Web as a local CLI agent.
|
|
4
4
|
|
|
5
|
-
把 GPT
|
|
5
|
+
把 GPT 网页聊天变成可读写本地文件、运行本地命令的 CLI Agent。
|
|
6
6
|
|
|
7
7
|
[中文](#中文) · [English](#english)
|
|
8
8
|
|
|
9
9
|
## 中文
|
|
10
10
|
|
|
11
|
-
WTAgent 把 GPT
|
|
11
|
+
WTAgent 把 GPT Web 连接到你的本地项目,提供类似 Codex 的命令行体验:GPT 在网页中思考,WTAgent 在本机读写文件、编译代码并运行测试。
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
当前支持 ChatGPT Web。无需 OpenAI API Key,也不要求 ChatGPT Pro;使用的是你自己的网页账号、可用模型和额度。
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
- 调用结构化本地命令,运行构建、测试和开发服务
|
|
15
|
+
### 开始使用
|
|
17
16
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
支持矩阵:
|
|
21
|
-
|
|
22
|
-
- macOS
|
|
23
|
-
- Linux
|
|
24
|
-
- Windows 10 1809+ / Windows 11 x64
|
|
25
|
-
- Windows ARM64 目前为预览支持
|
|
26
|
-
|
|
27
|
-
边界:
|
|
28
|
-
|
|
29
|
-
- 需要 Chrome 或 Chromium;首版不支持 Edge
|
|
30
|
-
- Git 和 `rg` 是可选项,不是运行前提
|
|
31
|
-
- WSL 不在首版支持范围内;请直接在原生 PowerShell / CMD / Windows Terminal 中运行
|
|
32
|
-
|
|
33
|
-
### 快速开始
|
|
34
|
-
|
|
35
|
-
需要 Node.js 20.17+ 和 Chrome/Chromium。
|
|
17
|
+
需要 Node.js 20.17+ 和 Chrome/Chromium;支持 macOS、Linux 和原生 Windows,暂不支持 WSL。
|
|
36
18
|
|
|
37
19
|
```bash
|
|
38
|
-
npm install -g wtagent
|
|
39
|
-
wtagent login
|
|
20
|
+
npm install -g wtagent
|
|
40
21
|
```
|
|
41
22
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
```powershell
|
|
45
|
-
npm install -g wtagent --registry=https://registry.npmjs.org/
|
|
46
|
-
wtagent doctor
|
|
47
|
-
wtagent login
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
登录完成后,进入项目目录:
|
|
23
|
+
进入要工作的目录并启动:
|
|
51
24
|
|
|
52
25
|
```bash
|
|
53
|
-
|
|
26
|
+
mkdir wtagent-demo
|
|
27
|
+
cd wtagent-demo
|
|
54
28
|
wtagent
|
|
55
29
|
```
|
|
56
30
|
|
|
57
|
-
|
|
31
|
+
启动后选择 `Pro` 或 `Current`,然后直接输入任务。如果尚未登录 ChatGPT,WTAgent 会打开专用 Chrome 并提示你登录;登录成功后任务会自动继续。
|
|
58
32
|
|
|
59
|
-
|
|
33
|
+
例如,启动后直接在终端输入:
|
|
60
34
|
|
|
61
|
-
```
|
|
62
|
-
wtagent
|
|
63
|
-
|
|
35
|
+
```text
|
|
36
|
+
$ wtagent
|
|
37
|
+
you › 创建 qsort.c,实现整数快速排序。使用系统可用的 C 编译器开启警告编译,并运行测试,覆盖普通输入、重复值和空输入。
|
|
38
|
+
you › 再增加一组包含负数的测试
|
|
64
39
|
```
|
|
65
40
|
|
|
66
|
-
|
|
41
|
+
WTAgent 会在当前目录创建代码、调用本地编译器并运行测试。任务完成后可以继续在同一个终端中对话。
|
|
67
42
|
|
|
68
|
-
|
|
43
|
+
也可以在启动时直接附带任务:
|
|
69
44
|
|
|
70
|
-
|
|
45
|
+
```bash
|
|
46
|
+
wtagent "创建 qsort.c,编译并测试"
|
|
47
|
+
```
|
|
71
48
|
|
|
72
|
-
|
|
73
|
-
- 首次登录只会写入 WTAgent 的专用 Chrome Profile,不会接管你的日常浏览器 Profile
|
|
74
|
-
- 如果系统没有 Git 或 `rg`,WTAgent 仍应保留核心文件读写与搜索能力
|
|
49
|
+
支持多行粘贴和 `↑` / `↓` 输入历史。使用 `Ctrl+C` 或 `Ctrl+D` 退出。
|
|
75
50
|
|
|
76
51
|
## English
|
|
77
52
|
|
|
78
|
-
WTAgent connects GPT Web
|
|
53
|
+
WTAgent connects GPT Web to your local project and provides a Codex-like CLI experience: GPT reasons in the browser while WTAgent reads and writes files, compiles code, and runs tests on your machine.
|
|
79
54
|
|
|
80
|
-
|
|
55
|
+
The current adapter supports ChatGPT Web. No OpenAI API key or ChatGPT Pro subscription is required; WTAgent uses your own web account, available models, and quota.
|
|
81
56
|
|
|
82
|
-
|
|
83
|
-
- Run structured local commands, builds, tests, and development servers
|
|
57
|
+
### Get started
|
|
84
58
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
Support matrix:
|
|
88
|
-
|
|
89
|
-
- macOS
|
|
90
|
-
- Linux
|
|
91
|
-
- Windows 10 1809+ / Windows 11 x64
|
|
92
|
-
- Windows ARM64 is currently preview only
|
|
93
|
-
|
|
94
|
-
Boundaries:
|
|
95
|
-
|
|
96
|
-
- Requires Chrome or Chromium; Edge is out of scope for the first Windows release
|
|
97
|
-
- Git and `rg` are optional accelerators, not runtime requirements
|
|
98
|
-
- WSL is not supported in v1; run WTAgent from native PowerShell, CMD, or Windows Terminal
|
|
99
|
-
|
|
100
|
-
### Quick start
|
|
101
|
-
|
|
102
|
-
Requires Node.js 20.17+ and Chrome/Chromium.
|
|
59
|
+
Requires Node.js 20.17+ and Chrome/Chromium. macOS, Linux, and native Windows are supported; WSL is not currently supported.
|
|
103
60
|
|
|
104
61
|
```bash
|
|
105
|
-
npm install -g wtagent
|
|
106
|
-
wtagent login
|
|
62
|
+
npm install -g wtagent
|
|
107
63
|
```
|
|
108
64
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
```powershell
|
|
112
|
-
npm install -g wtagent --registry=https://registry.npmjs.org/
|
|
113
|
-
wtagent doctor
|
|
114
|
-
wtagent login
|
|
115
|
-
```
|
|
116
|
-
|
|
117
|
-
After signing in, start WTAgent inside a project:
|
|
65
|
+
Open a working directory and start WTAgent:
|
|
118
66
|
|
|
119
67
|
```bash
|
|
120
|
-
|
|
68
|
+
mkdir wtagent-demo
|
|
69
|
+
cd wtagent-demo
|
|
121
70
|
wtagent
|
|
122
71
|
```
|
|
123
72
|
|
|
124
|
-
|
|
73
|
+
Choose `Pro` or `Current`, then type a task. If ChatGPT is not signed in, WTAgent opens its dedicated Chrome profile and asks you to sign in. The task continues automatically after login.
|
|
125
74
|
|
|
126
|
-
|
|
75
|
+
For example, start it and type directly in the terminal:
|
|
127
76
|
|
|
128
|
-
```
|
|
129
|
-
wtagent
|
|
130
|
-
|
|
77
|
+
```text
|
|
78
|
+
$ wtagent
|
|
79
|
+
you › Create qsort.c with an integer quicksort. Compile it with warnings using an available C compiler, then test normal input, duplicate values, and empty input.
|
|
80
|
+
you › Add another test containing negative numbers.
|
|
131
81
|
```
|
|
132
82
|
|
|
133
|
-
|
|
83
|
+
WTAgent creates the code in the current directory, invokes the local compiler, and runs the tests. Keep chatting in the same terminal after the task finishes.
|
|
134
84
|
|
|
135
|
-
|
|
85
|
+
You can also provide the first task directly:
|
|
136
86
|
|
|
137
|
-
|
|
87
|
+
```bash
|
|
88
|
+
wtagent "create qsort.c, compile it, and test it"
|
|
89
|
+
```
|
|
138
90
|
|
|
139
|
-
|
|
140
|
-
- WTAgent always uses its own Chrome profile and does not reuse your daily browsing profile
|
|
141
|
-
- Core file and search capabilities must continue to work even when Git or `rg` is missing
|
|
91
|
+
Multiline paste and `↑` / `↓` input history are supported. Press `Ctrl+C` or `Ctrl+D` to exit.
|
|
142
92
|
|
|
143
93
|
## License
|
|
144
94
|
|
package/docs/technical-design.md
CHANGED
|
@@ -652,6 +652,7 @@ sessionId + assistantMessageIdentity + normalizedToolCall
|
|
|
652
652
|
- Chrome 崩溃:用相同 Profile 重启并打开会话 URL。
|
|
653
653
|
- 同一 CLI 进程中的 follow-up 保持在当前会话 Page,不重复导航;跨进程恢复需要等待本地记录的最近 assistant message ID 出现在 DOM 后才能发送。
|
|
654
654
|
- 每次发送记录已有消息 ID 和新 user turn,只接受位于该 user turn 之后的新 assistant turn;无法建立可靠消息身份时超时并保存诊断,禁止退化为基于数量或文本变化猜测。
|
|
655
|
+
- 新 assistant 节点在停止生成后持续 10 秒仍为空时,Runtime 只发送“继续上一轮”的短提示,不重发原任务、附件或工具结果;自动恢复最多 3 次。仍为空时保留 Chrome、Session 和待确认工具结果并回到 CLI,允许用户输入 `/retry` 或新的指令。
|
|
655
656
|
- 同一 Profile 同时只允许一个 WTAgent CLI Session;启动和接管过程使用 Profile 级互斥锁。
|
|
656
657
|
- 登录失效或出现验证:进入 `AUTH_REQUIRED`/`PAUSED`,让用户接管。
|
|
657
658
|
- 会话页面丢失:从本地记录打开原会话;无法恢复时创建新的本地 Session 和新的网页对话,不向旧 rollout 继续追加。
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wtagent",
|
|
3
|
-
"version": "0.1.0
|
|
3
|
+
"version": "0.1.0",
|
|
4
4
|
"description": "Turn your own web AI session into a local tool-using agent.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -37,6 +37,7 @@
|
|
|
37
37
|
"doctor": "node src/cli/main.js doctor",
|
|
38
38
|
"login": "node src/cli/main.js login",
|
|
39
39
|
"prepack": "npm run check && npm test",
|
|
40
|
+
"release": "npm publish --tag latest",
|
|
40
41
|
"release:alpha": "npm publish --tag alpha"
|
|
41
42
|
},
|
|
42
43
|
"engines": {
|
|
@@ -132,11 +132,23 @@ async function setWindowState(context, page, windowState) {
|
|
|
132
132
|
}
|
|
133
133
|
}
|
|
134
134
|
|
|
135
|
+
function sameOriginPath(left, right) {
|
|
136
|
+
try {
|
|
137
|
+
const leftUrl = new URL(left);
|
|
138
|
+
const rightUrl = new URL(right);
|
|
139
|
+
return leftUrl.origin === rightUrl.origin
|
|
140
|
+
&& leftUrl.pathname === rightUrl.pathname;
|
|
141
|
+
} catch {
|
|
142
|
+
return false;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
135
146
|
export async function launchAndConnectCdpChrome({
|
|
136
147
|
executablePath,
|
|
137
148
|
profileDir,
|
|
138
149
|
url = "about:blank",
|
|
139
150
|
minimized = false,
|
|
151
|
+
preferredUrl = null,
|
|
140
152
|
}, {
|
|
141
153
|
acquireProfileLock = acquireCdpProfileLock,
|
|
142
154
|
connectOverCDP = (endpoint) => chromium.connectOverCDP(endpoint),
|
|
@@ -267,10 +279,20 @@ export async function launchAndConnectCdpChrome({
|
|
|
267
279
|
}
|
|
268
280
|
|
|
269
281
|
// A reused browser may still contain the previous conversation. Keep it
|
|
270
|
-
// intact and
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
282
|
+
// intact and, when a preferred URL is given, reuse an existing tab already
|
|
283
|
+
// showing that conversation (origin + path) so resumed runs do not pile up
|
|
284
|
+
// tabs; otherwise create a fresh target for this CLI session.
|
|
285
|
+
let page;
|
|
286
|
+
if (reused) {
|
|
287
|
+
const matchingTab = preferredUrl
|
|
288
|
+
? context.pages().find((candidate) =>
|
|
289
|
+
sameOriginPath(candidate.url?.() ?? "", preferredUrl)
|
|
290
|
+
) ?? null
|
|
291
|
+
: null;
|
|
292
|
+
page = matchingTab ?? await context.newPage();
|
|
293
|
+
} else {
|
|
294
|
+
page = context.pages()[0] ?? await context.newPage();
|
|
295
|
+
}
|
|
274
296
|
if (minimized) {
|
|
275
297
|
await setWindowState(context, page, "minimized");
|
|
276
298
|
}
|
|
@@ -293,6 +315,12 @@ export async function launchAndConnectCdpChrome({
|
|
|
293
315
|
async restore() {
|
|
294
316
|
return await setWindowState(context, page, "normal");
|
|
295
317
|
},
|
|
318
|
+
// Drops only the Playwright transport. Unlike close(), never asks Chrome
|
|
319
|
+
// to exit and never kills the process: used to recover from a dead CDP
|
|
320
|
+
// connection (e.g. after the Mac slept) while Chrome itself is alive.
|
|
321
|
+
async disconnect() {
|
|
322
|
+
await settleWithin(browser.close(), 1_500);
|
|
323
|
+
},
|
|
296
324
|
async close() {
|
|
297
325
|
if (closePromise) {
|
|
298
326
|
return await closePromise;
|