linkshell-cli 0.3.27 → 0.3.29
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/cli/src/commands/setup.js +20 -2
- package/dist/cli/src/commands/setup.js.map +1 -1
- package/dist/cli/src/commands/upgrade.js +9 -24
- package/dist/cli/src/commands/upgrade.js.map +1 -1
- package/dist/cli/src/index.js +28 -26
- package/dist/cli/src/index.js.map +1 -1
- package/dist/cli/src/providers.d.ts +3 -7
- package/dist/cli/src/providers.js +76 -19
- package/dist/cli/src/providers.js.map +1 -1
- package/dist/cli/src/runtime/acp/acp-client.d.ts +0 -10
- package/dist/cli/src/runtime/acp/acp-client.js +19 -146
- package/dist/cli/src/runtime/acp/acp-client.js.map +1 -1
- package/dist/cli/src/runtime/acp/agent-session.d.ts +62 -0
- package/dist/cli/src/runtime/acp/agent-session.js +1075 -0
- package/dist/cli/src/runtime/acp/agent-session.js.map +1 -0
- package/dist/cli/src/runtime/acp/agent-workspace.d.ts +1 -24
- package/dist/cli/src/runtime/acp/agent-workspace.js +162 -981
- package/dist/cli/src/runtime/acp/agent-workspace.js.map +1 -1
- package/dist/cli/src/runtime/acp/claude-sdk-client.d.ts +1 -3
- package/dist/cli/src/runtime/acp/claude-sdk-client.js +35 -81
- package/dist/cli/src/runtime/acp/claude-sdk-client.js.map +1 -1
- package/dist/cli/src/runtime/acp/claude-stream-json-client.d.ts +1 -2
- package/dist/cli/src/runtime/acp/claude-stream-json-client.js +35 -54
- package/dist/cli/src/runtime/acp/claude-stream-json-client.js.map +1 -1
- package/dist/cli/src/runtime/acp/codex-rpc-bridge.js +12 -1
- package/dist/cli/src/runtime/acp/codex-rpc-bridge.js.map +1 -1
- package/dist/cli/src/runtime/acp/json-rpc.d.ts +1 -34
- package/dist/cli/src/runtime/acp/json-rpc.js +8 -32
- package/dist/cli/src/runtime/acp/json-rpc.js.map +1 -1
- package/dist/cli/src/runtime/acp/provider-resolver.d.ts +0 -3
- package/dist/cli/src/runtime/acp/provider-resolver.js +6 -26
- package/dist/cli/src/runtime/acp/provider-resolver.js.map +1 -1
- package/dist/cli/src/runtime/bridge-session.d.ts +31 -1
- package/dist/cli/src/runtime/bridge-session.js +991 -81
- package/dist/cli/src/runtime/bridge-session.js.map +1 -1
- package/dist/cli/src/runtime/screen-fallback.d.ts +1 -1
- package/dist/cli/src/runtime/screen-fallback.js +4 -4
- package/dist/cli/src/runtime/screen-fallback.js.map +1 -1
- package/dist/cli/src/runtime/screen-share.d.ts +1 -1
- package/dist/cli/src/runtime/screen-share.js +7 -7
- package/dist/cli/src/runtime/screen-share.js.map +1 -1
- package/dist/cli/tsconfig.tsbuildinfo +1 -1
- package/dist/shared-protocol/src/index.d.ts +11940 -3423
- package/dist/shared-protocol/src/index.js +98 -164
- package/dist/shared-protocol/src/index.js.map +1 -1
- package/package.json +5 -5
- package/src/commands/setup.ts +31 -5
- package/src/commands/upgrade.ts +8 -28
- package/src/index.ts +34 -29
- package/src/providers.ts +108 -26
- package/src/runtime/acp/acp-client.ts +21 -159
- package/src/runtime/acp/agent-session.ts +1180 -0
- package/src/runtime/acp/agent-workspace.ts +170 -1068
- package/src/runtime/acp/claude-sdk-client.ts +37 -85
- package/src/runtime/acp/claude-stream-json-client.ts +41 -59
- package/src/runtime/acp/json-rpc.ts +14 -46
- package/src/runtime/acp/provider-resolver.ts +6 -29
- package/src/runtime/bridge-session.ts +1092 -84
- package/src/runtime/screen-fallback.ts +5 -5
- package/src/runtime/screen-share.ts +8 -8
- package/src/runtime/acp/claude-sessions.ts +0 -563
- package/src/runtime/acp/codex-rpc-bridge.ts +0 -221
- package/src/runtime/acp/codex-sessions.ts +0 -802
- package/src/types/linkshell-gateway.d.ts +0 -18
package/src/providers.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { accessSync, constants, existsSync } from "node:fs";
|
|
2
|
-
import {
|
|
2
|
+
import { delimiter, join } from "node:path";
|
|
3
|
+
import type { TerminalProvider } from "@linkshell/protocol";
|
|
3
4
|
|
|
4
|
-
export type ProviderName =
|
|
5
|
+
export type ProviderName = TerminalProvider;
|
|
5
6
|
|
|
6
7
|
export interface ProviderConfig {
|
|
7
8
|
provider: ProviderName;
|
|
@@ -10,8 +11,6 @@ export interface ProviderConfig {
|
|
|
10
11
|
env: NodeJS.ProcessEnv;
|
|
11
12
|
}
|
|
12
13
|
|
|
13
|
-
export type ShellConfig = ProviderConfig;
|
|
14
|
-
|
|
15
14
|
function stripOuterQuotes(value: string): string {
|
|
16
15
|
const trimmed = value.trim();
|
|
17
16
|
if (
|
|
@@ -66,42 +65,125 @@ function which(bin: string): string | undefined {
|
|
|
66
65
|
return undefined;
|
|
67
66
|
}
|
|
68
67
|
|
|
69
|
-
function
|
|
70
|
-
|
|
71
|
-
|
|
68
|
+
function resolveClaudeProvider(input: {
|
|
69
|
+
command?: string;
|
|
70
|
+
args: string[];
|
|
71
|
+
}): ProviderConfig {
|
|
72
|
+
const command = input.command ?? "claude";
|
|
73
|
+
const resolved = which(command);
|
|
74
|
+
if (!resolved) {
|
|
75
|
+
throw new Error(
|
|
76
|
+
`Claude CLI not found ("${command}"). Install it with: npm install -g @anthropic-ai/claude-code`,
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Claude starts an interactive REPL by default — that's exactly what we want in the PTY.
|
|
81
|
+
// Pass through any extra args the user provided.
|
|
82
|
+
return {
|
|
83
|
+
provider: "claude",
|
|
84
|
+
command: resolved,
|
|
85
|
+
args: input.args,
|
|
86
|
+
env: { ...process.env },
|
|
87
|
+
};
|
|
72
88
|
}
|
|
73
89
|
|
|
74
|
-
|
|
90
|
+
function resolveCodexProvider(input: {
|
|
75
91
|
command?: string;
|
|
76
|
-
args
|
|
77
|
-
}
|
|
78
|
-
const
|
|
79
|
-
const
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
92
|
+
args: string[];
|
|
93
|
+
}): ProviderConfig {
|
|
94
|
+
const command = input.command ?? "codex";
|
|
95
|
+
const resolved = which(command);
|
|
96
|
+
if (!resolved) {
|
|
97
|
+
throw new Error(
|
|
98
|
+
`Codex CLI not found ("${command}"). Install it with: npm install -g @openai/codex`,
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
if (!process.env.OPENAI_API_KEY) {
|
|
103
|
+
process.stderr.write(
|
|
104
|
+
"[warn] OPENAI_API_KEY not set — Codex may fail to authenticate\n",
|
|
105
|
+
);
|
|
106
|
+
}
|
|
87
107
|
|
|
88
108
|
return {
|
|
89
|
-
provider: "
|
|
109
|
+
provider: "codex",
|
|
90
110
|
command: resolved,
|
|
91
|
-
args,
|
|
111
|
+
args: input.args,
|
|
92
112
|
env: { ...process.env },
|
|
93
113
|
};
|
|
94
114
|
}
|
|
95
115
|
|
|
96
|
-
|
|
97
|
-
provider?: string;
|
|
116
|
+
function resolveGeminiProvider(input: {
|
|
98
117
|
command?: string;
|
|
99
118
|
args: string[];
|
|
100
119
|
}): ProviderConfig {
|
|
101
|
-
|
|
120
|
+
const command = input.command ?? "gemini";
|
|
121
|
+
const resolved = which(command);
|
|
122
|
+
if (!resolved) {
|
|
123
|
+
throw new Error(
|
|
124
|
+
`Gemini CLI not found ("${command}"). Install it with: npm install -g @anthropic-ai/gemini-cli or check https://github.com/anthropics/gemini-cli`,
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
if (!process.env.GOOGLE_API_KEY && !process.env.GEMINI_API_KEY) {
|
|
102
129
|
process.stderr.write(
|
|
103
|
-
|
|
130
|
+
"[warn] GOOGLE_API_KEY / GEMINI_API_KEY not set — Gemini may fail to authenticate\n",
|
|
104
131
|
);
|
|
105
132
|
}
|
|
106
|
-
|
|
133
|
+
|
|
134
|
+
return {
|
|
135
|
+
provider: "gemini",
|
|
136
|
+
command: resolved,
|
|
137
|
+
args: input.args,
|
|
138
|
+
env: { ...process.env },
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
function resolveCopilotProvider(input: {
|
|
143
|
+
command?: string;
|
|
144
|
+
args: string[];
|
|
145
|
+
}): ProviderConfig {
|
|
146
|
+
const command = input.command ?? "github-copilot";
|
|
147
|
+
const resolved = which(command);
|
|
148
|
+
if (!resolved) {
|
|
149
|
+
throw new Error(
|
|
150
|
+
`GitHub Copilot CLI not found ("${command}").`,
|
|
151
|
+
);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
return {
|
|
155
|
+
provider: "copilot",
|
|
156
|
+
command: resolved,
|
|
157
|
+
args: input.args,
|
|
158
|
+
env: { ...process.env },
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
export function resolveProviderConfig(input: {
|
|
163
|
+
provider: ProviderName;
|
|
164
|
+
command?: string;
|
|
165
|
+
args: string[];
|
|
166
|
+
}): ProviderConfig {
|
|
167
|
+
switch (input.provider) {
|
|
168
|
+
case "claude":
|
|
169
|
+
return resolveClaudeProvider(input);
|
|
170
|
+
case "codex":
|
|
171
|
+
return resolveCodexProvider(input);
|
|
172
|
+
case "gemini":
|
|
173
|
+
return resolveGeminiProvider(input);
|
|
174
|
+
case "copilot":
|
|
175
|
+
return resolveCopilotProvider(input);
|
|
176
|
+
case "custom": {
|
|
177
|
+
if (!input.command) {
|
|
178
|
+
throw new Error("custom provider requires --command");
|
|
179
|
+
}
|
|
180
|
+
const resolved = which(input.command);
|
|
181
|
+
return {
|
|
182
|
+
provider: "custom",
|
|
183
|
+
command: resolved ?? input.command,
|
|
184
|
+
args: input.args,
|
|
185
|
+
env: { ...process.env },
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
}
|
|
107
189
|
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { JsonRpcStdioTransport } from "./json-rpc.js";
|
|
2
|
-
import { listCodexStoredSessions, type CodexStoredSession } from "./codex-sessions.js";
|
|
3
2
|
import type { AgentFraming, AgentProtocol } from "./provider-resolver.js";
|
|
4
3
|
|
|
5
4
|
type AgentPermissionMode = "read_only" | "workspace_write" | "full_access";
|
|
@@ -16,83 +15,6 @@ function normalizeMcpServers(value: unknown): unknown[] {
|
|
|
16
15
|
});
|
|
17
16
|
}
|
|
18
17
|
|
|
19
|
-
function asRecord(value: unknown): Record<string, unknown> | undefined {
|
|
20
|
-
return value && typeof value === "object" && !Array.isArray(value)
|
|
21
|
-
? value as Record<string, unknown>
|
|
22
|
-
: undefined;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
function parseTimestamp(value: unknown): number | undefined {
|
|
26
|
-
if (typeof value === "number" && Number.isFinite(value)) {
|
|
27
|
-
return value > 10_000_000_000 ? value : value * 1000;
|
|
28
|
-
}
|
|
29
|
-
if (typeof value === "string" && value.trim()) {
|
|
30
|
-
const parsed = Date.parse(value);
|
|
31
|
-
return Number.isNaN(parsed) ? undefined : parsed;
|
|
32
|
-
}
|
|
33
|
-
return undefined;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
function firstString(record: Record<string, unknown>, keys: string[]): string | undefined {
|
|
37
|
-
for (const key of keys) {
|
|
38
|
-
const value = record[key];
|
|
39
|
-
if (typeof value === "string" && value.trim()) return value;
|
|
40
|
-
}
|
|
41
|
-
return undefined;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
function remoteSessionEntries(value: unknown): unknown[] {
|
|
45
|
-
const raw = asRecord(value);
|
|
46
|
-
return Array.isArray(value) ? value :
|
|
47
|
-
Array.isArray(raw?.data) ? raw.data :
|
|
48
|
-
Array.isArray(raw?.threads) ? raw.threads :
|
|
49
|
-
Array.isArray(raw?.sessions) ? raw.sessions :
|
|
50
|
-
Array.isArray(raw?.items) ? raw.items :
|
|
51
|
-
[];
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
function normalizeRemoteSession(entry: unknown, fallback?: CodexStoredSession): CodexStoredSession | undefined {
|
|
55
|
-
if (typeof entry === "string" && entry.trim()) {
|
|
56
|
-
return fallback ?? { id: entry, cwd: "", lastModified: Date.now() };
|
|
57
|
-
}
|
|
58
|
-
const session = asRecord(entry);
|
|
59
|
-
if (!session) return fallback;
|
|
60
|
-
const nestedThread = asRecord(session.thread);
|
|
61
|
-
const source = nestedThread ?? session;
|
|
62
|
-
const id = firstString(source, ["id", "threadId", "sessionId", "agentSessionId"]) ?? fallback?.id;
|
|
63
|
-
if (!id) return undefined;
|
|
64
|
-
return {
|
|
65
|
-
id,
|
|
66
|
-
cwd: firstString(source, ["cwd", "workingDirectory", "workspacePath"]) ?? fallback?.cwd ?? "",
|
|
67
|
-
title: firstString(source, ["title", "name", "summary", "thread_name"]) ?? fallback?.title,
|
|
68
|
-
createdAt: parseTimestamp(source.createdAt ?? source.created_at) ?? fallback?.createdAt,
|
|
69
|
-
lastModified: parseTimestamp(source.lastActivityAt ?? source.updatedAt ?? source.modifiedAt ?? source.lastModified ?? source.updated_at) ??
|
|
70
|
-
fallback?.lastModified ??
|
|
71
|
-
Date.now(),
|
|
72
|
-
archived: typeof source.archived === "boolean" ? source.archived : fallback?.archived,
|
|
73
|
-
status: firstString(source, ["status", "state", "phase"]) ?? fallback?.status,
|
|
74
|
-
runningTurnId: firstString(source, ["runningTurnId", "running_turn_id", "turnId", "activeTurnId"]) ?? fallback?.runningTurnId,
|
|
75
|
-
};
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
function mergeCodexSessionLists(remote: unknown, local: { sessions: CodexStoredSession[] }): { sessions: CodexStoredSession[] } {
|
|
79
|
-
const byId = new Map(local.sessions.map((session) => [session.id, session]));
|
|
80
|
-
for (const entry of remoteSessionEntries(remote)) {
|
|
81
|
-
const id = typeof entry === "string"
|
|
82
|
-
? entry
|
|
83
|
-
: (() => {
|
|
84
|
-
const session = asRecord(entry);
|
|
85
|
-
const source = asRecord(session?.thread) ?? session;
|
|
86
|
-
return source ? firstString(source, ["id", "threadId", "sessionId", "agentSessionId"]) : undefined;
|
|
87
|
-
})();
|
|
88
|
-
const merged = normalizeRemoteSession(entry, id ? byId.get(id) : undefined);
|
|
89
|
-
if (merged?.id) byId.set(merged.id, merged);
|
|
90
|
-
}
|
|
91
|
-
return {
|
|
92
|
-
sessions: [...byId.values()].sort((a, b) => b.lastModified - a.lastModified),
|
|
93
|
-
};
|
|
94
|
-
}
|
|
95
|
-
|
|
96
18
|
function permissionsForMode(
|
|
97
19
|
mode: AgentPermissionMode | undefined,
|
|
98
20
|
cwd: string,
|
|
@@ -115,47 +37,9 @@ function permissionsForMode(
|
|
|
115
37
|
};
|
|
116
38
|
}
|
|
117
39
|
|
|
118
|
-
function sandboxPolicyForMode(
|
|
119
|
-
mode: AgentPermissionMode | undefined,
|
|
120
|
-
cwd: string,
|
|
121
|
-
): unknown | undefined {
|
|
122
|
-
if (mode === "full_access") return { type: "dangerFullAccess" };
|
|
123
|
-
if (mode === "read_only") return { type: "readOnly", networkAccess: false };
|
|
124
|
-
if (mode === "workspace_write") {
|
|
125
|
-
return {
|
|
126
|
-
type: "workspaceWrite",
|
|
127
|
-
writableRoots: [cwd],
|
|
128
|
-
networkAccess: false,
|
|
129
|
-
excludeTmpdirEnvVar: false,
|
|
130
|
-
excludeSlashTmp: false,
|
|
131
|
-
};
|
|
132
|
-
}
|
|
133
|
-
return undefined;
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
function approvalPolicyForMode(mode: AgentPermissionMode | undefined): unknown | undefined {
|
|
137
|
-
if (mode === "full_access") return "never";
|
|
138
|
-
if (mode === "read_only" || mode === "workspace_write") return "on-request";
|
|
139
|
-
return undefined;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
function codexThreadConfig(input: {
|
|
143
|
-
cwd: string;
|
|
144
|
-
model?: string;
|
|
145
|
-
permissionMode?: AgentPermissionMode;
|
|
146
|
-
}): Record<string, unknown> {
|
|
147
|
-
return {
|
|
148
|
-
cwd: input.cwd,
|
|
149
|
-
...(input.model ? { model: input.model } : {}),
|
|
150
|
-
...(approvalPolicyForMode(input.permissionMode) ? { approvalPolicy: approvalPolicyForMode(input.permissionMode) } : {}),
|
|
151
|
-
...(sandboxPolicyForMode(input.permissionMode, input.cwd) ? { sandboxPolicy: sandboxPolicyForMode(input.permissionMode, input.cwd) } : {}),
|
|
152
|
-
};
|
|
153
|
-
}
|
|
154
|
-
|
|
155
40
|
export class AcpClient {
|
|
156
41
|
private readonly transport: JsonRpcStdioTransport;
|
|
157
42
|
private readonly protocol: AgentProtocol;
|
|
158
|
-
private readonly cwd: string;
|
|
159
43
|
|
|
160
44
|
constructor(input: {
|
|
161
45
|
command: string;
|
|
@@ -167,15 +51,12 @@ export class AcpClient {
|
|
|
167
51
|
onExit: (message: string) => void;
|
|
168
52
|
}) {
|
|
169
53
|
this.protocol = input.protocol;
|
|
170
|
-
this.cwd = input.cwd;
|
|
171
54
|
this.transport = new JsonRpcStdioTransport(
|
|
172
55
|
input.command,
|
|
173
56
|
input.framing,
|
|
174
57
|
input.onNotification,
|
|
175
58
|
input.onRequest,
|
|
176
59
|
input.onExit,
|
|
177
|
-
undefined,
|
|
178
|
-
{ includeJsonrpc: input.protocol !== "codex-app-server" },
|
|
179
60
|
);
|
|
180
61
|
this.transport.start(input.cwd);
|
|
181
62
|
}
|
|
@@ -184,7 +65,7 @@ export class AcpClient {
|
|
|
184
65
|
if (this.protocol === "codex-app-server") {
|
|
185
66
|
const result = await this.transport.request("initialize", {
|
|
186
67
|
clientInfo: { name: "LinkShell", version: "0.1" },
|
|
187
|
-
capabilities: { experimentalApi: true
|
|
68
|
+
capabilities: { experimentalApi: true },
|
|
188
69
|
});
|
|
189
70
|
this.transport.notify("initialized", {});
|
|
190
71
|
return result;
|
|
@@ -199,9 +80,12 @@ export class AcpClient {
|
|
|
199
80
|
});
|
|
200
81
|
}
|
|
201
82
|
|
|
202
|
-
newSession(input: { cwd: string; mcpServers?: unknown
|
|
83
|
+
newSession(input: { cwd: string; mcpServers?: unknown }): Promise<unknown> {
|
|
203
84
|
if (this.protocol === "codex-app-server") {
|
|
204
|
-
return this.transport.request("thread/start",
|
|
85
|
+
return this.transport.request("thread/start", {
|
|
86
|
+
cwd: input.cwd,
|
|
87
|
+
sessionStartSource: "startup",
|
|
88
|
+
});
|
|
205
89
|
}
|
|
206
90
|
return this.transport.request("session/new", {
|
|
207
91
|
cwd: input.cwd,
|
|
@@ -209,11 +93,12 @@ export class AcpClient {
|
|
|
209
93
|
});
|
|
210
94
|
}
|
|
211
95
|
|
|
212
|
-
loadSession(input: { sessionId: string; cwd: string; mcpServers?: unknown
|
|
96
|
+
loadSession(input: { sessionId: string; cwd: string; mcpServers?: unknown }): Promise<unknown> {
|
|
213
97
|
if (this.protocol === "codex-app-server") {
|
|
214
98
|
return this.transport.request("thread/resume", {
|
|
215
99
|
threadId: input.sessionId,
|
|
216
|
-
|
|
100
|
+
cwd: input.cwd,
|
|
101
|
+
excludeTurns: false,
|
|
217
102
|
});
|
|
218
103
|
}
|
|
219
104
|
return this.transport.request("session/load", {
|
|
@@ -223,15 +108,9 @@ export class AcpClient {
|
|
|
223
108
|
});
|
|
224
109
|
}
|
|
225
110
|
|
|
226
|
-
|
|
111
|
+
listSessions(): Promise<unknown> {
|
|
227
112
|
if (this.protocol === "codex-app-server") {
|
|
228
|
-
|
|
229
|
-
try {
|
|
230
|
-
const remoteSessions = await this.transport.request("thread/list", { limit: 200 });
|
|
231
|
-
return mergeCodexSessionLists(remoteSessions, localSessions);
|
|
232
|
-
} catch {
|
|
233
|
-
return localSessions;
|
|
234
|
-
}
|
|
113
|
+
return this.transport.request("thread/list", { limit: 20 });
|
|
235
114
|
}
|
|
236
115
|
return this.transport.request("session/list", {});
|
|
237
116
|
}
|
|
@@ -243,56 +122,39 @@ export class AcpClient {
|
|
|
243
122
|
return Promise.resolve(undefined);
|
|
244
123
|
}
|
|
245
124
|
|
|
246
|
-
listTurns(input: { sessionId: string; limit?: number }): Promise<unknown> {
|
|
247
|
-
if (this.protocol === "codex-app-server") {
|
|
248
|
-
return this.transport.request("thread/turns/list", {
|
|
249
|
-
threadId: input.sessionId,
|
|
250
|
-
limit: input.limit ?? 200,
|
|
251
|
-
});
|
|
252
|
-
}
|
|
253
|
-
return Promise.resolve(undefined);
|
|
254
|
-
}
|
|
255
|
-
|
|
256
125
|
prompt(input: {
|
|
257
126
|
sessionId: string;
|
|
258
127
|
content: unknown[];
|
|
259
128
|
clientMessageId: string;
|
|
260
129
|
model?: string;
|
|
261
130
|
reasoningEffort?: string;
|
|
262
|
-
serviceTier?: string;
|
|
263
131
|
permissionMode?: AgentPermissionMode;
|
|
264
132
|
collaborationMode?: AgentCollaborationMode;
|
|
265
133
|
cwd: string;
|
|
266
134
|
}): Promise<unknown> {
|
|
267
135
|
if (this.protocol === "codex-app-server") {
|
|
268
|
-
const
|
|
136
|
+
const collaborationSettings = {
|
|
137
|
+
...(input.model ? { model: input.model } : {}),
|
|
138
|
+
...(input.reasoningEffort ? { reasoning_effort: input.reasoningEffort } : {}),
|
|
139
|
+
};
|
|
140
|
+
const collaborationMode = input.collaborationMode && input.collaborationMode !== "default"
|
|
269
141
|
? {
|
|
270
142
|
mode: input.collaborationMode,
|
|
271
|
-
settings:
|
|
272
|
-
model: input.model,
|
|
273
|
-
reasoning_effort: input.reasoningEffort ?? null,
|
|
274
|
-
developer_instructions: null,
|
|
275
|
-
},
|
|
143
|
+
settings: collaborationSettings,
|
|
276
144
|
}
|
|
277
145
|
: undefined;
|
|
278
146
|
return this.transport.request("turn/start", {
|
|
279
147
|
threadId: input.sessionId,
|
|
280
|
-
cwd: input.cwd,
|
|
281
148
|
model: input.model,
|
|
282
149
|
effort: input.reasoningEffort,
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
...(sandboxPolicyForMode(input.permissionMode, input.cwd) ? { sandboxPolicy: sandboxPolicyForMode(input.permissionMode, input.cwd) } : {}),
|
|
286
|
-
...(collaborationMode ? { collaborationMode } : {}),
|
|
150
|
+
permissions: permissionsForMode(input.permissionMode, input.cwd),
|
|
151
|
+
collaborationMode,
|
|
287
152
|
input: input.content.map((block) => {
|
|
288
|
-
const raw = block as { type?: string; text?: string; data?: string
|
|
153
|
+
const raw = block as { type?: string; text?: string; data?: string };
|
|
289
154
|
if (raw.type === "image" && raw.data) {
|
|
290
155
|
return { type: "image", url: raw.data };
|
|
291
156
|
}
|
|
292
|
-
|
|
293
|
-
return { type: "mention", path: raw.path, name: raw.name };
|
|
294
|
-
}
|
|
295
|
-
return { type: "text", text: raw.text ?? "", text_elements: [] };
|
|
157
|
+
return { type: "text", text: raw.text ?? "" };
|
|
296
158
|
}),
|
|
297
159
|
}, null);
|
|
298
160
|
}
|