shennian 0.2.5 → 0.2.7
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.
|
@@ -15,6 +15,7 @@ export declare class CodexAdapter extends AgentAdapter {
|
|
|
15
15
|
private rpcSeq;
|
|
16
16
|
private pendingRequests;
|
|
17
17
|
private appServerReady;
|
|
18
|
+
private appServerStartupError;
|
|
18
19
|
private activeTurnId;
|
|
19
20
|
private namedThread;
|
|
20
21
|
private deltaItemIds;
|
|
@@ -29,6 +30,8 @@ export declare class CodexAdapter extends AgentAdapter {
|
|
|
29
30
|
private initializeAppServer;
|
|
30
31
|
private sendRpc;
|
|
31
32
|
private handleAppServerMessage;
|
|
33
|
+
private handleAppServerNonJsonStdout;
|
|
34
|
+
private failAppServerStartup;
|
|
32
35
|
private handleAppServerCompletedItem;
|
|
33
36
|
private handleAppServerUsage;
|
|
34
37
|
private handleCodexItemLine;
|
package/dist/src/agents/codex.js
CHANGED
|
@@ -20,6 +20,7 @@ export class CodexAdapter extends AgentAdapter {
|
|
|
20
20
|
rpcSeq = 1;
|
|
21
21
|
pendingRequests = new Map();
|
|
22
22
|
appServerReady = null;
|
|
23
|
+
appServerStartupError = null;
|
|
23
24
|
activeTurnId = null;
|
|
24
25
|
namedThread = false;
|
|
25
26
|
deltaItemIds = new Set();
|
|
@@ -128,6 +129,7 @@ export class CodexAdapter extends AgentAdapter {
|
|
|
128
129
|
});
|
|
129
130
|
this.process = proc;
|
|
130
131
|
this.stderrBuf = '';
|
|
132
|
+
this.appServerStartupError = null;
|
|
131
133
|
const rl = createInterface({ input: proc.stdout });
|
|
132
134
|
rl.on('line', (line) => {
|
|
133
135
|
if (!line.trim())
|
|
@@ -137,6 +139,7 @@ export class CodexAdapter extends AgentAdapter {
|
|
|
137
139
|
msg = JSON.parse(line);
|
|
138
140
|
}
|
|
139
141
|
catch {
|
|
142
|
+
this.handleAppServerNonJsonStdout(line);
|
|
140
143
|
return;
|
|
141
144
|
}
|
|
142
145
|
this.handleAppServerMessage(msg);
|
|
@@ -215,6 +218,8 @@ export class CodexAdapter extends AgentAdapter {
|
|
|
215
218
|
this.namedThread = !!response.thread?.name;
|
|
216
219
|
}
|
|
217
220
|
sendRpc(method, params, timeoutMs = 60_000) {
|
|
221
|
+
if (this.appServerStartupError)
|
|
222
|
+
return Promise.reject(this.appServerStartupError);
|
|
218
223
|
const proc = this.process;
|
|
219
224
|
if (!proc?.stdin)
|
|
220
225
|
return Promise.reject(new Error('codex app-server is not running'));
|
|
@@ -289,6 +294,19 @@ export class CodexAdapter extends AgentAdapter {
|
|
|
289
294
|
}
|
|
290
295
|
}
|
|
291
296
|
}
|
|
297
|
+
handleAppServerNonJsonStdout(line) {
|
|
298
|
+
const normalized = normalizeTerminalText(line);
|
|
299
|
+
if (!looksLikeCodexInteractiveAuthPrompt(normalized))
|
|
300
|
+
return;
|
|
301
|
+
this.failAppServerStartup(new Error('Codex 未登录。请先在这台电脑的终端运行 `codex`,按提示完成 ChatGPT 登录或配置 API key,然后再回到神念发送消息。'));
|
|
302
|
+
}
|
|
303
|
+
failAppServerStartup(error) {
|
|
304
|
+
if (this.appServerStartupError)
|
|
305
|
+
return;
|
|
306
|
+
this.appServerStartupError = error;
|
|
307
|
+
this.rejectAllPending(error);
|
|
308
|
+
this.process?.kill('SIGTERM');
|
|
309
|
+
}
|
|
292
310
|
handleAppServerCompletedItem(params) {
|
|
293
311
|
const item = typeof params.item === 'object' && params.item !== null
|
|
294
312
|
? params.item
|
|
@@ -766,6 +784,23 @@ function normalizeCodexStderr(stderr) {
|
|
|
766
784
|
.filter((line) => !isIgnorableCodexStderrLine(line))
|
|
767
785
|
.join('\n');
|
|
768
786
|
}
|
|
787
|
+
function normalizeTerminalText(text) {
|
|
788
|
+
return text
|
|
789
|
+
.replace(/\x1b\[[0-?]*[ -/]*[@-~]/g, ' ')
|
|
790
|
+
.replace(/\x1b\][^\x07]*(?:\x07|\x1b\\)/g, ' ')
|
|
791
|
+
.replace(/[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]/g, ' ')
|
|
792
|
+
.replace(/\s+/g, ' ')
|
|
793
|
+
.trim();
|
|
794
|
+
}
|
|
795
|
+
function looksLikeCodexInteractiveAuthPrompt(text) {
|
|
796
|
+
if (!text)
|
|
797
|
+
return false;
|
|
798
|
+
const normalized = text.toLowerCase();
|
|
799
|
+
return (normalized.includes('welcome to codex') ||
|
|
800
|
+
normalized.includes('sign in with chatgpt') ||
|
|
801
|
+
normalized.includes('provide your own api key') ||
|
|
802
|
+
normalized.includes('press enter to continue'));
|
|
803
|
+
}
|
|
769
804
|
function isIgnorableCodexStderrLine(line) {
|
|
770
805
|
return [
|
|
771
806
|
/WARNING: proceeding, even though we could not update PATH:/i,
|
|
@@ -114,27 +114,32 @@ async function discoverGeminiModels() {
|
|
|
114
114
|
return [];
|
|
115
115
|
return fallbackGeminiModels();
|
|
116
116
|
}
|
|
117
|
+
const fallbackPiModels = [
|
|
118
|
+
{ id: 'qwen3.6-plus', name: 'Qwen 3.6 Plus', provider: 'dashscope', isDefault: true },
|
|
119
|
+
{ id: 'qwen3.6-flash', name: 'Qwen 3.6 Flash', provider: 'dashscope' },
|
|
120
|
+
];
|
|
117
121
|
async function discoverPiModels(context) {
|
|
118
122
|
if (!context.serverUrl || !context.authToken)
|
|
119
|
-
return
|
|
123
|
+
return fallbackPiModels;
|
|
120
124
|
try {
|
|
121
|
-
const response = await fetch(`${context.serverUrl.replace(/\/$/, '')}/models`, {
|
|
125
|
+
const response = await fetch(`${context.serverUrl.replace(/\/$/, '')}/api/models`, {
|
|
122
126
|
headers: {
|
|
123
127
|
Authorization: `Bearer ${context.authToken}`,
|
|
124
128
|
},
|
|
125
129
|
});
|
|
126
130
|
if (!response.ok)
|
|
127
|
-
return
|
|
131
|
+
return fallbackPiModels;
|
|
128
132
|
const data = (await response.json());
|
|
129
|
-
|
|
133
|
+
const models = (data.models ?? []).map((model) => ({
|
|
130
134
|
id: model.id,
|
|
131
135
|
name: model.name?.trim() || model.id,
|
|
132
136
|
provider: model.provider,
|
|
133
137
|
isDefault: model.id === data.default,
|
|
134
138
|
}));
|
|
139
|
+
return models.length > 0 ? models : fallbackPiModels;
|
|
135
140
|
}
|
|
136
141
|
catch {
|
|
137
|
-
return
|
|
142
|
+
return fallbackPiModels;
|
|
138
143
|
}
|
|
139
144
|
}
|
|
140
145
|
async function discoverBuiltinModels(type, context) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "shennian",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.7",
|
|
4
4
|
"description": "Shennian — AI Agent Mobile Console CLI",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
},
|
|
51
51
|
"scripts": {
|
|
52
52
|
"build": "tsc",
|
|
53
|
-
"build:publish": "node -e \"require('node:fs').rmSync('dist', { recursive: true, force: true })\" && tsc -p tsconfig.publish.json",
|
|
53
|
+
"build:publish": "node -e \"const fs=require('node:fs'); fs.rmSync('dist', { recursive: true, force: true }); fs.rmSync('.tsbuildinfo.publish', { force: true })\" && tsc -p tsconfig.publish.json",
|
|
54
54
|
"dev": "tsc --watch"
|
|
55
55
|
}
|
|
56
56
|
}
|