shennian 0.2.51 → 0.2.52
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/src/agents/adapter.d.ts +1 -1
- package/dist/src/agents/claude.d.ts +2 -1
- package/dist/src/agents/claude.js +14 -1
- package/dist/src/agents/codex.d.ts +3 -1
- package/dist/src/agents/codex.js +34 -13
- package/dist/src/agents/model-registry/parsers.js +21 -7
- package/dist/src/native-fusion/parsers.js +46 -5
- package/dist/src/session/handlers/chat.js +15 -4
- package/dist/src/session/queue.js +2 -0
- package/package.json +1 -1
|
@@ -25,7 +25,7 @@ export interface AgentAdapterEvents {
|
|
|
25
25
|
export declare abstract class AgentAdapter extends EventEmitter<AgentAdapterEvents> {
|
|
26
26
|
abstract readonly type: AgentType;
|
|
27
27
|
abstract start(sessionId: string, workDir: string, agentSessionId?: string | null): Promise<void>;
|
|
28
|
-
abstract send(text: string, modelId?: string): Promise<void>;
|
|
28
|
+
abstract send(text: string, modelId?: string, reasoningEffort?: string): Promise<void>;
|
|
29
29
|
abstract resume(agentSessionId: string): Promise<void>;
|
|
30
30
|
abstract stop(): Promise<void>;
|
|
31
31
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { AgentAdapter } from './adapter.js';
|
|
2
2
|
export declare function normalizeClaudeModelId(modelId?: string | null): string;
|
|
3
|
+
export declare function normalizeClaudeReasoningEffort(reasoningEffort?: string | null): string | undefined;
|
|
3
4
|
export declare class ClaudeAdapter extends AgentAdapter {
|
|
4
5
|
private readonly options;
|
|
5
6
|
readonly type: "claude";
|
|
@@ -16,7 +17,7 @@ export declare class ClaudeAdapter extends AgentAdapter {
|
|
|
16
17
|
hidden?: boolean;
|
|
17
18
|
});
|
|
18
19
|
start(sessionId: string, workDir: string, agentSessionId?: string | null): Promise<void>;
|
|
19
|
-
send(text: string, modelId?: string): Promise<void>;
|
|
20
|
+
send(text: string, modelId?: string, reasoningEffort?: string): Promise<void>;
|
|
20
21
|
resume(agentSessionId: string): Promise<void>;
|
|
21
22
|
stop(): Promise<void>;
|
|
22
23
|
private spawnAndParse;
|
|
@@ -8,6 +8,15 @@ export function normalizeClaudeModelId(modelId) {
|
|
|
8
8
|
const trimmed = modelId?.trim();
|
|
9
9
|
return trimmed || 'default';
|
|
10
10
|
}
|
|
11
|
+
const CLAUDE_REASONING_EFFORTS = new Set(['low', 'medium', 'high', 'xhigh', 'max']);
|
|
12
|
+
export function normalizeClaudeReasoningEffort(reasoningEffort) {
|
|
13
|
+
const trimmed = reasoningEffort?.trim();
|
|
14
|
+
if (!trimmed)
|
|
15
|
+
return undefined;
|
|
16
|
+
if (CLAUDE_REASONING_EFFORTS.has(trimmed))
|
|
17
|
+
return trimmed;
|
|
18
|
+
throw new Error(`Unsupported Claude reasoning effort "${trimmed}". Supported values: low, medium, high, xhigh, max.`);
|
|
19
|
+
}
|
|
11
20
|
export class ClaudeAdapter extends AgentAdapter {
|
|
12
21
|
options;
|
|
13
22
|
type = 'claude';
|
|
@@ -30,7 +39,7 @@ export class ClaudeAdapter extends AgentAdapter {
|
|
|
30
39
|
if (agentSessionId)
|
|
31
40
|
this.agentSessionId = agentSessionId;
|
|
32
41
|
}
|
|
33
|
-
async send(text, modelId) {
|
|
42
|
+
async send(text, modelId, reasoningEffort) {
|
|
34
43
|
await this.killProcess();
|
|
35
44
|
this.runId = randomUUID();
|
|
36
45
|
this.resetRunState();
|
|
@@ -46,6 +55,10 @@ export class ClaudeAdapter extends AgentAdapter {
|
|
|
46
55
|
args.push('--dangerously-skip-permissions');
|
|
47
56
|
}
|
|
48
57
|
args.push('--model', normalizeClaudeModelId(modelId));
|
|
58
|
+
const effort = normalizeClaudeReasoningEffort(reasoningEffort);
|
|
59
|
+
if (effort) {
|
|
60
|
+
args.push('--effort', effort);
|
|
61
|
+
}
|
|
49
62
|
if (this.agentSessionId) {
|
|
50
63
|
args.push('--resume', this.agentSessionId);
|
|
51
64
|
}
|
|
@@ -26,7 +26,7 @@ export declare class CodexAdapter extends AgentAdapter {
|
|
|
26
26
|
hidden?: boolean;
|
|
27
27
|
});
|
|
28
28
|
start(_sessionId: string, workDir: string, agentSessionId?: string | null): Promise<void>;
|
|
29
|
-
send(text: string, modelId?: string): Promise<void>;
|
|
29
|
+
send(text: string, modelId?: string, reasoningEffort?: string): Promise<void>;
|
|
30
30
|
resume(agentSessionId: string): Promise<void>;
|
|
31
31
|
stop(): Promise<void>;
|
|
32
32
|
private spawnCodex;
|
|
@@ -58,4 +58,6 @@ export declare class CodexAdapter extends AgentAdapter {
|
|
|
58
58
|
private clearForceCloseTimer;
|
|
59
59
|
}
|
|
60
60
|
export declare function normalizeCodexModelId(modelId?: string | null): string | undefined;
|
|
61
|
+
export declare function normalizeCodexReasoningEffort(reasoningEffort?: string | null): string | undefined;
|
|
61
62
|
export declare function isMissingCodexRolloutError(error: unknown): boolean;
|
|
63
|
+
export declare function isCodexUnsupportedEffortError(error: unknown): boolean;
|
package/dist/src/agents/codex.js
CHANGED
|
@@ -38,12 +38,13 @@ export class CodexAdapter extends AgentAdapter {
|
|
|
38
38
|
if (agentSessionId)
|
|
39
39
|
this.agentSessionId = agentSessionId;
|
|
40
40
|
}
|
|
41
|
-
async send(text, modelId) {
|
|
41
|
+
async send(text, modelId, reasoningEffort) {
|
|
42
42
|
if (this.activeTurnId) {
|
|
43
43
|
await this.interruptActiveTurn().catch(() => { });
|
|
44
44
|
await this.killProcess();
|
|
45
45
|
}
|
|
46
46
|
const codexModelId = normalizeCodexModelId(modelId);
|
|
47
|
+
const codexReasoningEffort = normalizeCodexReasoningEffort(reasoningEffort);
|
|
47
48
|
this.runId = randomUUID();
|
|
48
49
|
this.seq = 0;
|
|
49
50
|
this.resetRunState();
|
|
@@ -59,7 +60,7 @@ export class CodexAdapter extends AgentAdapter {
|
|
|
59
60
|
}).catch(() => { });
|
|
60
61
|
this.namedThread = true;
|
|
61
62
|
}
|
|
62
|
-
const response = await this.startTurnWithRecovery(threadId, text, codexModelId);
|
|
63
|
+
const response = await this.startTurnWithRecovery(threadId, text, codexModelId, codexReasoningEffort);
|
|
63
64
|
this.activeTurnId = response.turn?.id ?? null;
|
|
64
65
|
}
|
|
65
66
|
async resume(agentSessionId) {
|
|
@@ -227,26 +228,35 @@ export class CodexAdapter extends AgentAdapter {
|
|
|
227
228
|
this.agentSessionId = threadId;
|
|
228
229
|
this.namedThread = !!response.thread?.name;
|
|
229
230
|
}
|
|
230
|
-
async startTurnWithRecovery(threadId, text, codexModelId) {
|
|
231
|
+
async startTurnWithRecovery(threadId, text, codexModelId, reasoningEffort) {
|
|
231
232
|
try {
|
|
232
|
-
return await this.startTurn(threadId, text, codexModelId);
|
|
233
|
+
return await this.startTurn(threadId, text, codexModelId, reasoningEffort);
|
|
233
234
|
}
|
|
234
235
|
catch (error) {
|
|
235
236
|
if (!isMissingCodexRolloutError(error))
|
|
236
237
|
throw error;
|
|
237
238
|
await this.killProcess();
|
|
238
239
|
await this.ensureAppServer(codexModelId);
|
|
239
|
-
return await this.startTurn(threadId, text, codexModelId);
|
|
240
|
+
return await this.startTurn(threadId, text, codexModelId, reasoningEffort);
|
|
240
241
|
}
|
|
241
242
|
}
|
|
242
|
-
async startTurn(threadId, text, codexModelId) {
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
243
|
+
async startTurn(threadId, text, codexModelId, reasoningEffort) {
|
|
244
|
+
try {
|
|
245
|
+
return await this.sendRpc('turn/start', {
|
|
246
|
+
threadId,
|
|
247
|
+
input: [{ type: 'text', text, text_elements: [] }],
|
|
248
|
+
approvalPolicy: 'never',
|
|
249
|
+
sandboxPolicy: { type: 'dangerFullAccess' },
|
|
250
|
+
...(codexModelId ? { model: codexModelId } : {}),
|
|
251
|
+
...(reasoningEffort ? { effort: reasoningEffort } : {}),
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
catch (error) {
|
|
255
|
+
if (reasoningEffort && isCodexUnsupportedEffortError(error)) {
|
|
256
|
+
throw new Error(`Codex app-server does not accept reasoning effort "${reasoningEffort}" for this turn. Refresh models or upgrade Codex CLI, then retry.`);
|
|
257
|
+
}
|
|
258
|
+
throw error;
|
|
259
|
+
}
|
|
250
260
|
}
|
|
251
261
|
async interruptActiveTurn() {
|
|
252
262
|
const threadId = this.agentSessionId;
|
|
@@ -793,10 +803,21 @@ export function normalizeCodexModelId(modelId) {
|
|
|
793
803
|
return undefined;
|
|
794
804
|
return trimmed.toLowerCase() === 'openai' ? undefined : trimmed;
|
|
795
805
|
}
|
|
806
|
+
export function normalizeCodexReasoningEffort(reasoningEffort) {
|
|
807
|
+
const trimmed = reasoningEffort?.trim();
|
|
808
|
+
return trimmed || undefined;
|
|
809
|
+
}
|
|
796
810
|
export function isMissingCodexRolloutError(error) {
|
|
797
811
|
const message = error instanceof Error ? error.message : String(error ?? '');
|
|
798
812
|
return /\bno rollout found for thread id\b/i.test(message);
|
|
799
813
|
}
|
|
814
|
+
export function isCodexUnsupportedEffortError(error) {
|
|
815
|
+
const message = error instanceof Error ? error.message : String(error ?? '');
|
|
816
|
+
return (/\bunknown field\b.*\beffort\b/i.test(message) ||
|
|
817
|
+
/\binvalid.*\beffort\b/i.test(message) ||
|
|
818
|
+
/\bunsupported.*\beffort\b/i.test(message) ||
|
|
819
|
+
/\breasoning effort\b/i.test(message));
|
|
820
|
+
}
|
|
800
821
|
function extractAppServerErrorMessage(params) {
|
|
801
822
|
if (typeof params.message === 'string' && params.message.trim())
|
|
802
823
|
return params.message.trim();
|
|
@@ -123,13 +123,13 @@ export function parseClaudeModels(raw) {
|
|
|
123
123
|
for (const [pattern, id, name] of patterns) {
|
|
124
124
|
const match = rawClean.match(pattern);
|
|
125
125
|
if (match) {
|
|
126
|
-
models.push({
|
|
126
|
+
models.push(withClaudeReasoningEfforts({
|
|
127
127
|
id,
|
|
128
128
|
name,
|
|
129
129
|
description: `v${match[1]}`,
|
|
130
130
|
provider: 'anthropic',
|
|
131
131
|
isDefault: id === 'default',
|
|
132
|
-
});
|
|
132
|
+
}));
|
|
133
133
|
}
|
|
134
134
|
}
|
|
135
135
|
if (models.length > 0)
|
|
@@ -144,12 +144,12 @@ export function parseClaudeModels(raw) {
|
|
|
144
144
|
continue;
|
|
145
145
|
const version = match[2] ?? '';
|
|
146
146
|
const isDefault = defaultMatch && defaultMatch[1]?.toLowerCase() === family && defaultMatch[2] === version;
|
|
147
|
-
fallback.push({
|
|
147
|
+
fallback.push(withClaudeReasoningEfforts({
|
|
148
148
|
id: alias,
|
|
149
149
|
name: `${titleCaseSegment(family)} ${version}`,
|
|
150
150
|
provider: 'anthropic',
|
|
151
151
|
isDefault: Boolean(isDefault),
|
|
152
|
-
});
|
|
152
|
+
}));
|
|
153
153
|
}
|
|
154
154
|
return uniqueModels(fallback);
|
|
155
155
|
}
|
|
@@ -193,6 +193,20 @@ const CLAUDE_ALIAS_MODEL_ENV = {
|
|
|
193
193
|
opus: 'ANTHROPIC_DEFAULT_OPUS_MODEL',
|
|
194
194
|
haiku: 'ANTHROPIC_DEFAULT_HAIKU_MODEL',
|
|
195
195
|
};
|
|
196
|
+
const CLAUDE_REASONING_EFFORTS = [
|
|
197
|
+
{ id: 'low', name: 'Low' },
|
|
198
|
+
{ id: 'medium', name: 'Medium' },
|
|
199
|
+
{ id: 'high', name: 'High' },
|
|
200
|
+
{ id: 'xhigh', name: 'Extra High' },
|
|
201
|
+
{ id: 'max', name: 'Max' },
|
|
202
|
+
];
|
|
203
|
+
function withClaudeReasoningEfforts(model) {
|
|
204
|
+
return {
|
|
205
|
+
...model,
|
|
206
|
+
supportedReasoningEfforts: CLAUDE_REASONING_EFFORTS,
|
|
207
|
+
defaultReasoningEffort: 'medium',
|
|
208
|
+
};
|
|
209
|
+
}
|
|
196
210
|
function readEnvValue(env, key) {
|
|
197
211
|
const value = env[key]?.trim();
|
|
198
212
|
return value || null;
|
|
@@ -244,13 +258,13 @@ export function parseClaudeBinaryModels(raw) {
|
|
|
244
258
|
if (!new RegExp(`\\b${alias}\\b`, 'i').test(clean))
|
|
245
259
|
continue;
|
|
246
260
|
const version = (alias === 'default' ? familyVersions.get('sonnet') : familyVersions.get(alias)) ?? null;
|
|
247
|
-
models.push({
|
|
261
|
+
models.push(withClaudeReasoningEfforts({
|
|
248
262
|
id: alias,
|
|
249
263
|
name: CLAUDE_ALIAS_LABELS[alias],
|
|
250
264
|
description: formatClaudeVersion(version),
|
|
251
265
|
provider: 'anthropic',
|
|
252
266
|
isDefault: alias === 'default',
|
|
253
|
-
});
|
|
267
|
+
}));
|
|
254
268
|
}
|
|
255
269
|
return uniqueModels(models);
|
|
256
270
|
}
|
|
@@ -260,7 +274,7 @@ export function fallbackClaudeAliasModels() {
|
|
|
260
274
|
{ id: 'sonnet', name: 'Sonnet', provider: 'anthropic' },
|
|
261
275
|
{ id: 'opus', name: 'Opus', provider: 'anthropic' },
|
|
262
276
|
{ id: 'haiku', name: 'Haiku', provider: 'anthropic' },
|
|
263
|
-
]);
|
|
277
|
+
]).map(withClaudeReasoningEfforts);
|
|
264
278
|
}
|
|
265
279
|
export function parseCodexModels(raw) {
|
|
266
280
|
const clean = stripAnsi(raw);
|
|
@@ -7,6 +7,10 @@ import path from 'node:path';
|
|
|
7
7
|
import { buildUserMessagePayload, isToolPayload } from '@shennian/wire';
|
|
8
8
|
import { resolveBuiltinCommand, spawnResolvedCommandSync } from '../agents/command-spec.js';
|
|
9
9
|
const MAX_JSONL_LINE_BYTES = 64 * 1024 * 1024;
|
|
10
|
+
const DEFAULT_NATIVE_SCAN_IGNORED_PATHS = [
|
|
11
|
+
'/root/.claude-mem/observer-session',
|
|
12
|
+
];
|
|
13
|
+
const DEFAULT_NATIVE_SCAN_IGNORED_CLAUDE_PROJECT_DIRS = DEFAULT_NATIVE_SCAN_IGNORED_PATHS.map(encodeClaudeProjectDir);
|
|
10
14
|
function normalizeText(text) {
|
|
11
15
|
return stripGitDirectiveArtifacts(text.replace(/\r\n/g, '\n').trim());
|
|
12
16
|
}
|
|
@@ -103,6 +107,33 @@ function readClaudeEventCwd(parsed) {
|
|
|
103
107
|
function isClaudeSubagentTranscript(filePath) {
|
|
104
108
|
return path.basename(path.dirname(filePath)) === 'subagents';
|
|
105
109
|
}
|
|
110
|
+
function normalizePathForCompare(filePath) {
|
|
111
|
+
const normalized = path.resolve(filePath);
|
|
112
|
+
return process.platform === 'win32' ? normalized.toLowerCase() : normalized;
|
|
113
|
+
}
|
|
114
|
+
function isSameOrChildPath(filePath, parentPath) {
|
|
115
|
+
const normalizedFilePath = normalizePathForCompare(filePath);
|
|
116
|
+
const normalizedParentPath = normalizePathForCompare(parentPath);
|
|
117
|
+
return normalizedFilePath === normalizedParentPath
|
|
118
|
+
|| normalizedFilePath.startsWith(normalizedParentPath + path.sep);
|
|
119
|
+
}
|
|
120
|
+
function encodeClaudeProjectDir(filePath) {
|
|
121
|
+
return path.resolve(filePath).replace(/\//g, '-');
|
|
122
|
+
}
|
|
123
|
+
function shouldIgnoreNativeScanPath(filePath) {
|
|
124
|
+
return DEFAULT_NATIVE_SCAN_IGNORED_PATHS.some((ignoredPath) => isSameOrChildPath(filePath, ignoredPath));
|
|
125
|
+
}
|
|
126
|
+
function shouldIgnoreClaudeProjectDir(projectDirName) {
|
|
127
|
+
return DEFAULT_NATIVE_SCAN_IGNORED_CLAUDE_PROJECT_DIRS.includes(projectDirName);
|
|
128
|
+
}
|
|
129
|
+
function shouldIgnoreClaudeTranscriptPath(filePath) {
|
|
130
|
+
const root = path.join(os.homedir(), '.claude', 'projects');
|
|
131
|
+
const relative = path.relative(root, filePath);
|
|
132
|
+
if (!relative || relative.startsWith('..') || path.isAbsolute(relative))
|
|
133
|
+
return false;
|
|
134
|
+
const [projectDirName] = relative.split(path.sep);
|
|
135
|
+
return projectDirName ? shouldIgnoreClaudeProjectDir(projectDirName) : false;
|
|
136
|
+
}
|
|
106
137
|
function makeCursor(filePath, offset) {
|
|
107
138
|
return `${filePath}:${offset}`;
|
|
108
139
|
}
|
|
@@ -715,8 +746,11 @@ export function listClaudeTranscriptFiles() {
|
|
|
715
746
|
const walk = (dir) => {
|
|
716
747
|
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
717
748
|
const full = path.join(dir, entry.name);
|
|
718
|
-
if (entry.isDirectory())
|
|
749
|
+
if (entry.isDirectory()) {
|
|
750
|
+
if (dir === root && shouldIgnoreClaudeProjectDir(entry.name))
|
|
751
|
+
continue;
|
|
719
752
|
walk(full);
|
|
753
|
+
}
|
|
720
754
|
else if (entry.isFile() && entry.name.endsWith('.jsonl'))
|
|
721
755
|
files.push(full);
|
|
722
756
|
}
|
|
@@ -805,12 +839,16 @@ export function parseCodexRolloutChunk(filePath, startOffset) {
|
|
|
805
839
|
return { nextOffset, events };
|
|
806
840
|
}
|
|
807
841
|
export function parseClaudeTranscriptChunk(filePath, startOffset) {
|
|
808
|
-
|
|
809
|
-
|
|
842
|
+
const fileSize = fs.statSync(filePath).size;
|
|
843
|
+
if (isClaudeSubagentTranscript(filePath) || shouldIgnoreClaudeTranscriptPath(filePath)) {
|
|
844
|
+
return { nextOffset: fileSize, events: [] };
|
|
810
845
|
}
|
|
811
846
|
const events = [];
|
|
812
847
|
const sourceSessionKey = path.basename(filePath, '.jsonl');
|
|
813
848
|
const fallbackWorkDir = relativeProjectDir(path.dirname(filePath).replace(path.join(os.homedir(), '.claude', 'projects') + path.sep, ''));
|
|
849
|
+
if (shouldIgnoreNativeScanPath(fallbackWorkDir)) {
|
|
850
|
+
return { nextOffset: fileSize, events: [] };
|
|
851
|
+
}
|
|
814
852
|
let title = '';
|
|
815
853
|
const nextOffset = readJsonlLines(filePath, startOffset, (line, lineOffset) => {
|
|
816
854
|
const parsed = safeParse(line);
|
|
@@ -820,6 +858,9 @@ export function parseClaudeTranscriptChunk(filePath, startOffset) {
|
|
|
820
858
|
const type = typeof parsed.type === 'string' ? parsed.type : '';
|
|
821
859
|
if (!ts || !type)
|
|
822
860
|
return;
|
|
861
|
+
const eventCwd = readClaudeEventCwd(parsed);
|
|
862
|
+
if (eventCwd && shouldIgnoreNativeScanPath(eventCwd))
|
|
863
|
+
return;
|
|
823
864
|
if (type === 'user') {
|
|
824
865
|
const message = typeof parsed.message === 'object' && parsed.message !== null
|
|
825
866
|
? parsed.message
|
|
@@ -839,7 +880,7 @@ export function parseClaudeTranscriptChunk(filePath, startOffset) {
|
|
|
839
880
|
ts,
|
|
840
881
|
payload: text,
|
|
841
882
|
title,
|
|
842
|
-
workDir:
|
|
883
|
+
workDir: eventCwd ?? fallbackWorkDir,
|
|
843
884
|
});
|
|
844
885
|
}
|
|
845
886
|
else if (type === 'assistant') {
|
|
@@ -867,7 +908,7 @@ export function parseClaudeTranscriptChunk(filePath, startOffset) {
|
|
|
867
908
|
payload: text,
|
|
868
909
|
title,
|
|
869
910
|
modelId,
|
|
870
|
-
workDir:
|
|
911
|
+
workDir: eventCwd ?? fallbackWorkDir,
|
|
871
912
|
});
|
|
872
913
|
}
|
|
873
914
|
});
|
|
@@ -283,7 +283,7 @@ export async function handleChatSend(runtime, req) {
|
|
|
283
283
|
return;
|
|
284
284
|
}
|
|
285
285
|
rememberProcessedReqId(runtime, req.id);
|
|
286
|
-
const { sessionId, text, agentType, workDir, agentSessionId: incomingAgentSid, modelId, clientMessageId, sessionListProjection, waitForDispatch } = req.params;
|
|
286
|
+
const { sessionId, text, agentType, workDir, agentSessionId: incomingAgentSid, modelId, reasoningEffort, clientMessageId, sessionListProjection, waitForDispatch } = req.params;
|
|
287
287
|
mergeProjectedSessions(sessionListProjection);
|
|
288
288
|
if (!sessionId || !text) {
|
|
289
289
|
runtime.processedReqIds.delete(req.id);
|
|
@@ -291,6 +291,11 @@ export async function handleChatSend(runtime, req) {
|
|
|
291
291
|
return;
|
|
292
292
|
}
|
|
293
293
|
const requestedAgentType = agentType;
|
|
294
|
+
const resolvedReasoningEffort = (requestedAgentType === 'claude' || requestedAgentType === 'codex') &&
|
|
295
|
+
typeof reasoningEffort === 'string' &&
|
|
296
|
+
reasoningEffort.trim()
|
|
297
|
+
? reasoningEffort.trim()
|
|
298
|
+
: undefined;
|
|
294
299
|
const resolvedWorkDir = runtime.resolvePath(maybeResolveClaudeImportedWorkDir(requestedAgentType, workDir || os.homedir(), incomingAgentSid) || os.homedir());
|
|
295
300
|
let session = runtime.sessions.get(sessionId);
|
|
296
301
|
if (session) {
|
|
@@ -365,7 +370,7 @@ export async function handleChatSend(runtime, req) {
|
|
|
365
370
|
level: 'info',
|
|
366
371
|
sessionId,
|
|
367
372
|
wsEvent: 'chat.send.start',
|
|
368
|
-
metadata: { reqId: req.id, agentType: requestedAgentType, modelId },
|
|
373
|
+
metadata: { reqId: req.id, agentType: requestedAgentType, modelId, reasoningEffort: resolvedReasoningEffort },
|
|
369
374
|
});
|
|
370
375
|
const markAccepted = () => {
|
|
371
376
|
sendSessionUpdateEvent(runtime, {
|
|
@@ -424,7 +429,10 @@ export async function handleChatSend(runtime, req) {
|
|
|
424
429
|
};
|
|
425
430
|
if (waitForDispatch) {
|
|
426
431
|
try {
|
|
427
|
-
|
|
432
|
+
if (resolvedReasoningEffort)
|
|
433
|
+
await session.adapter.send(text, modelId, resolvedReasoningEffort);
|
|
434
|
+
else
|
|
435
|
+
await session.adapter.send(text, modelId);
|
|
428
436
|
reportLog({
|
|
429
437
|
level: 'info',
|
|
430
438
|
sessionId,
|
|
@@ -454,7 +462,10 @@ export async function handleChatSend(runtime, req) {
|
|
|
454
462
|
wsEvent: 'chat.send.res',
|
|
455
463
|
metadata: { reqId: req.id, ok: true },
|
|
456
464
|
});
|
|
457
|
-
|
|
465
|
+
const sendPromise = resolvedReasoningEffort
|
|
466
|
+
? session.adapter.send(text, modelId, resolvedReasoningEffort)
|
|
467
|
+
: session.adapter.send(text, modelId);
|
|
468
|
+
void sendPromise
|
|
458
469
|
.then(() => {
|
|
459
470
|
reportLog({
|
|
460
471
|
level: 'info',
|
|
@@ -53,6 +53,7 @@ function queueMessageFromParams(params) {
|
|
|
53
53
|
workDir: params.workDir,
|
|
54
54
|
agentSessionId: params.agentSessionId ?? null,
|
|
55
55
|
modelId: params.modelId ?? null,
|
|
56
|
+
reasoningEffort: params.reasoningEffort ?? null,
|
|
56
57
|
clientMessageId: params.clientMessageId ?? null,
|
|
57
58
|
attachments: normalizeAttachments(params.attachments),
|
|
58
59
|
createdAt: timestamp,
|
|
@@ -233,6 +234,7 @@ export class ChatQueueManager {
|
|
|
233
234
|
workDir: message.workDir,
|
|
234
235
|
agentSessionId: message.agentSessionId ?? null,
|
|
235
236
|
modelId: message.modelId ?? undefined,
|
|
237
|
+
reasoningEffort: message.reasoningEffort ?? undefined,
|
|
236
238
|
clientMessageId: message.clientMessageId ?? message.id,
|
|
237
239
|
attachments: message.attachments,
|
|
238
240
|
},
|