linkshell-cli 0.3.28 → 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 +20 -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 -27
- package/dist/cli/src/runtime/acp/agent-workspace.js +168 -1008
- 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/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 +13 -13
- 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 +22 -159
- package/src/runtime/acp/agent-session.ts +1180 -0
- package/src/runtime/acp/agent-workspace.ts +176 -1094
- 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 -233
- 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,8 +65,9 @@ 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
|
});
|
|
70
|
+
this.transport.notify("initialized", {});
|
|
189
71
|
return result;
|
|
190
72
|
}
|
|
191
73
|
return this.transport.request("initialize", {
|
|
@@ -198,9 +80,12 @@ export class AcpClient {
|
|
|
198
80
|
});
|
|
199
81
|
}
|
|
200
82
|
|
|
201
|
-
newSession(input: { cwd: string; mcpServers?: unknown
|
|
83
|
+
newSession(input: { cwd: string; mcpServers?: unknown }): Promise<unknown> {
|
|
202
84
|
if (this.protocol === "codex-app-server") {
|
|
203
|
-
return this.transport.request("thread/start",
|
|
85
|
+
return this.transport.request("thread/start", {
|
|
86
|
+
cwd: input.cwd,
|
|
87
|
+
sessionStartSource: "startup",
|
|
88
|
+
});
|
|
204
89
|
}
|
|
205
90
|
return this.transport.request("session/new", {
|
|
206
91
|
cwd: input.cwd,
|
|
@@ -208,11 +93,12 @@ export class AcpClient {
|
|
|
208
93
|
});
|
|
209
94
|
}
|
|
210
95
|
|
|
211
|
-
loadSession(input: { sessionId: string; cwd: string; mcpServers?: unknown
|
|
96
|
+
loadSession(input: { sessionId: string; cwd: string; mcpServers?: unknown }): Promise<unknown> {
|
|
212
97
|
if (this.protocol === "codex-app-server") {
|
|
213
98
|
return this.transport.request("thread/resume", {
|
|
214
99
|
threadId: input.sessionId,
|
|
215
|
-
|
|
100
|
+
cwd: input.cwd,
|
|
101
|
+
excludeTurns: false,
|
|
216
102
|
});
|
|
217
103
|
}
|
|
218
104
|
return this.transport.request("session/load", {
|
|
@@ -222,15 +108,9 @@ export class AcpClient {
|
|
|
222
108
|
});
|
|
223
109
|
}
|
|
224
110
|
|
|
225
|
-
|
|
111
|
+
listSessions(): Promise<unknown> {
|
|
226
112
|
if (this.protocol === "codex-app-server") {
|
|
227
|
-
|
|
228
|
-
try {
|
|
229
|
-
const remoteSessions = await this.transport.request("thread/list", { limit: 200 });
|
|
230
|
-
return mergeCodexSessionLists(remoteSessions, localSessions);
|
|
231
|
-
} catch {
|
|
232
|
-
return localSessions;
|
|
233
|
-
}
|
|
113
|
+
return this.transport.request("thread/list", { limit: 20 });
|
|
234
114
|
}
|
|
235
115
|
return this.transport.request("session/list", {});
|
|
236
116
|
}
|
|
@@ -242,56 +122,39 @@ export class AcpClient {
|
|
|
242
122
|
return Promise.resolve(undefined);
|
|
243
123
|
}
|
|
244
124
|
|
|
245
|
-
listTurns(input: { sessionId: string; limit?: number }): Promise<unknown> {
|
|
246
|
-
if (this.protocol === "codex-app-server") {
|
|
247
|
-
return this.transport.request("thread/turns/list", {
|
|
248
|
-
threadId: input.sessionId,
|
|
249
|
-
limit: input.limit ?? 200,
|
|
250
|
-
});
|
|
251
|
-
}
|
|
252
|
-
return Promise.resolve(undefined);
|
|
253
|
-
}
|
|
254
|
-
|
|
255
125
|
prompt(input: {
|
|
256
126
|
sessionId: string;
|
|
257
127
|
content: unknown[];
|
|
258
128
|
clientMessageId: string;
|
|
259
129
|
model?: string;
|
|
260
130
|
reasoningEffort?: string;
|
|
261
|
-
serviceTier?: string;
|
|
262
131
|
permissionMode?: AgentPermissionMode;
|
|
263
132
|
collaborationMode?: AgentCollaborationMode;
|
|
264
133
|
cwd: string;
|
|
265
134
|
}): Promise<unknown> {
|
|
266
135
|
if (this.protocol === "codex-app-server") {
|
|
267
|
-
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"
|
|
268
141
|
? {
|
|
269
142
|
mode: input.collaborationMode,
|
|
270
|
-
settings:
|
|
271
|
-
model: input.model,
|
|
272
|
-
reasoning_effort: input.reasoningEffort ?? null,
|
|
273
|
-
developer_instructions: null,
|
|
274
|
-
},
|
|
143
|
+
settings: collaborationSettings,
|
|
275
144
|
}
|
|
276
145
|
: undefined;
|
|
277
146
|
return this.transport.request("turn/start", {
|
|
278
147
|
threadId: input.sessionId,
|
|
279
|
-
cwd: input.cwd,
|
|
280
148
|
model: input.model,
|
|
281
149
|
effort: input.reasoningEffort,
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
...(sandboxPolicyForMode(input.permissionMode, input.cwd) ? { sandboxPolicy: sandboxPolicyForMode(input.permissionMode, input.cwd) } : {}),
|
|
285
|
-
...(collaborationMode ? { collaborationMode } : {}),
|
|
150
|
+
permissions: permissionsForMode(input.permissionMode, input.cwd),
|
|
151
|
+
collaborationMode,
|
|
286
152
|
input: input.content.map((block) => {
|
|
287
|
-
const raw = block as { type?: string; text?: string; data?: string
|
|
153
|
+
const raw = block as { type?: string; text?: string; data?: string };
|
|
288
154
|
if (raw.type === "image" && raw.data) {
|
|
289
155
|
return { type: "image", url: raw.data };
|
|
290
156
|
}
|
|
291
|
-
|
|
292
|
-
return { type: "mention", path: raw.path, name: raw.name };
|
|
293
|
-
}
|
|
294
|
-
return { type: "text", text: raw.text ?? "", text_elements: [] };
|
|
157
|
+
return { type: "text", text: raw.text ?? "" };
|
|
295
158
|
}),
|
|
296
159
|
}, null);
|
|
297
160
|
}
|