opencodeがパラレル実行時にセッションIDを引き継げないことがある
This commit is contained in:
parent
f5d1c6fae2
commit
54e9f80a57
@ -14,26 +14,17 @@ export interface RunAgentOptions {
|
|||||||
sessionId?: string;
|
sessionId?: string;
|
||||||
model?: string;
|
model?: string;
|
||||||
provider?: 'claude' | 'codex' | 'opencode' | 'mock';
|
provider?: 'claude' | 'codex' | 'opencode' | 'mock';
|
||||||
/** Resolved path to persona prompt file */
|
|
||||||
personaPath?: string;
|
personaPath?: string;
|
||||||
/** Allowed tools for this agent run */
|
|
||||||
allowedTools?: string[];
|
allowedTools?: string[];
|
||||||
/** MCP servers for this agent run */
|
|
||||||
mcpServers?: Record<string, McpServerConfig>;
|
mcpServers?: Record<string, McpServerConfig>;
|
||||||
/** Maximum number of agentic turns */
|
|
||||||
maxTurns?: number;
|
maxTurns?: number;
|
||||||
/** Permission mode for tool execution (from piece step) */
|
|
||||||
permissionMode?: PermissionMode;
|
permissionMode?: PermissionMode;
|
||||||
/** Provider-specific movement options */
|
|
||||||
providerOptions?: MovementProviderOptions;
|
providerOptions?: MovementProviderOptions;
|
||||||
onStream?: StreamCallback;
|
onStream?: StreamCallback;
|
||||||
onPermissionRequest?: PermissionHandler;
|
onPermissionRequest?: PermissionHandler;
|
||||||
onAskUserQuestion?: AskUserQuestionHandler;
|
onAskUserQuestion?: AskUserQuestionHandler;
|
||||||
/** Bypass all permission checks (sacrifice-my-pc mode) */
|
|
||||||
bypassPermissions?: boolean;
|
bypassPermissions?: boolean;
|
||||||
/** Language for template resolution */
|
|
||||||
language?: Language;
|
language?: Language;
|
||||||
/** Piece meta information for system prompt template */
|
|
||||||
pieceMeta?: {
|
pieceMeta?: {
|
||||||
pieceName: string;
|
pieceName: string;
|
||||||
pieceDescription?: string;
|
pieceDescription?: string;
|
||||||
@ -41,6 +32,5 @@ export interface RunAgentOptions {
|
|||||||
movementsList: ReadonlyArray<{ name: string; description?: string }>;
|
movementsList: ReadonlyArray<{ name: string; description?: string }>;
|
||||||
currentPosition: string;
|
currentPosition: string;
|
||||||
};
|
};
|
||||||
/** JSON Schema for structured output */
|
|
||||||
outputSchema?: Record<string, unknown>;
|
outputSchema?: Record<string, unknown>;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -273,6 +273,8 @@ export class OpenCodeClient {
|
|||||||
let diagRef: StreamDiagnostics | undefined;
|
let diagRef: StreamDiagnostics | undefined;
|
||||||
let serverClose: (() => void) | undefined;
|
let serverClose: (() => void) | undefined;
|
||||||
let opencodeApiClient: Awaited<ReturnType<typeof createOpencode>>['client'] | undefined;
|
let opencodeApiClient: Awaited<ReturnType<typeof createOpencode>>['client'] | undefined;
|
||||||
|
let sessionId: string | undefined = options.sessionId;
|
||||||
|
const interactionTimeoutMs = options.interactionTimeoutMs ?? OPENCODE_INTERACTION_TIMEOUT_MS;
|
||||||
|
|
||||||
const resetIdleTimeout = (): void => {
|
const resetIdleTimeout = (): void => {
|
||||||
if (idleTimeoutId !== undefined) {
|
if (idleTimeoutId !== undefined) {
|
||||||
@ -330,14 +332,14 @@ export class OpenCodeClient {
|
|||||||
opencodeApiClient = client;
|
opencodeApiClient = client;
|
||||||
serverClose = server.close;
|
serverClose = server.close;
|
||||||
|
|
||||||
const sessionResult = options.sessionId
|
const sessionResult = sessionId
|
||||||
? { data: { id: options.sessionId } }
|
? { data: { id: sessionId } }
|
||||||
: await client.session.create({
|
: await client.session.create({
|
||||||
directory: options.cwd,
|
directory: options.cwd,
|
||||||
permission: buildOpenCodePermissionRuleset(options.permissionMode, options.networkAccess),
|
permission: buildOpenCodePermissionRuleset(options.permissionMode, options.networkAccess),
|
||||||
});
|
});
|
||||||
|
|
||||||
const sessionId = sessionResult.data?.id;
|
sessionId = sessionResult.data?.id;
|
||||||
if (!sessionId) {
|
if (!sessionId) {
|
||||||
throw new Error('Failed to create OpenCode session');
|
throw new Error('Failed to create OpenCode session');
|
||||||
}
|
}
|
||||||
@ -420,18 +422,24 @@ export class OpenCodeClient {
|
|||||||
sessionID: string;
|
sessionID: string;
|
||||||
};
|
};
|
||||||
if (permProps.sessionID === sessionId) {
|
if (permProps.sessionID === sessionId) {
|
||||||
const reply = options.permissionMode
|
try {
|
||||||
? mapToOpenCodePermissionReply(options.permissionMode)
|
const reply = options.permissionMode
|
||||||
: 'once';
|
? mapToOpenCodePermissionReply(options.permissionMode)
|
||||||
await withTimeout(
|
: 'once';
|
||||||
(signal) => client.permission.reply({
|
await withTimeout(
|
||||||
requestID: permProps.id,
|
(signal) => client.permission.reply({
|
||||||
directory: options.cwd,
|
requestID: permProps.id,
|
||||||
reply,
|
directory: options.cwd,
|
||||||
}, { signal }),
|
reply,
|
||||||
OPENCODE_INTERACTION_TIMEOUT_MS,
|
}, { signal }),
|
||||||
'OpenCode permission reply timed out',
|
interactionTimeoutMs,
|
||||||
);
|
'OpenCode permission reply timed out',
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
success = false;
|
||||||
|
failureMessage = getErrorMessage(e);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -440,14 +448,20 @@ export class OpenCodeClient {
|
|||||||
const questionProps = sseEvent.properties as OpenCodeQuestionAskedProperties;
|
const questionProps = sseEvent.properties as OpenCodeQuestionAskedProperties;
|
||||||
if (questionProps.sessionID === sessionId) {
|
if (questionProps.sessionID === sessionId) {
|
||||||
if (!options.onAskUserQuestion) {
|
if (!options.onAskUserQuestion) {
|
||||||
await withTimeout(
|
try {
|
||||||
(signal) => client.question.reject({
|
await withTimeout(
|
||||||
requestID: questionProps.id,
|
(signal) => client.question.reject({
|
||||||
directory: options.cwd,
|
requestID: questionProps.id,
|
||||||
}, { signal }),
|
directory: options.cwd,
|
||||||
OPENCODE_INTERACTION_TIMEOUT_MS,
|
}, { signal }),
|
||||||
'OpenCode question reject timed out',
|
interactionTimeoutMs,
|
||||||
);
|
'OpenCode question reject timed out',
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
success = false;
|
||||||
|
failureMessage = getErrorMessage(e);
|
||||||
|
break;
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -459,20 +473,12 @@ export class OpenCodeClient {
|
|||||||
directory: options.cwd,
|
directory: options.cwd,
|
||||||
answers: toQuestionAnswers(questionProps, answers),
|
answers: toQuestionAnswers(questionProps, answers),
|
||||||
}, { signal }),
|
}, { signal }),
|
||||||
OPENCODE_INTERACTION_TIMEOUT_MS,
|
interactionTimeoutMs,
|
||||||
'OpenCode question reply timed out',
|
'OpenCode question reply timed out',
|
||||||
);
|
);
|
||||||
} catch {
|
} catch (e) {
|
||||||
await withTimeout(
|
|
||||||
(signal) => client.question.reject({
|
|
||||||
requestID: questionProps.id,
|
|
||||||
directory: options.cwd,
|
|
||||||
}, { signal }),
|
|
||||||
OPENCODE_INTERACTION_TIMEOUT_MS,
|
|
||||||
'OpenCode question reject timed out',
|
|
||||||
);
|
|
||||||
success = false;
|
success = false;
|
||||||
failureMessage = 'OpenCode question handling failed';
|
failureMessage = getErrorMessage(e);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -631,8 +637,8 @@ export class OpenCodeClient {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.sessionId) {
|
if (sessionId) {
|
||||||
emitResult(options.onStream, false, errorMessage, options.sessionId);
|
emitResult(options.onStream, false, errorMessage, sessionId);
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -640,7 +646,7 @@ export class OpenCodeClient {
|
|||||||
status: 'error',
|
status: 'error',
|
||||||
content: errorMessage,
|
content: errorMessage,
|
||||||
timestamp: new Date(),
|
timestamp: new Date(),
|
||||||
sessionId: options.sessionId,
|
sessionId,
|
||||||
};
|
};
|
||||||
} finally {
|
} finally {
|
||||||
if (idleTimeoutId !== undefined) {
|
if (idleTimeoutId !== undefined) {
|
||||||
|
|||||||
@ -187,15 +187,11 @@ export interface OpenCodeCallOptions {
|
|||||||
model: string;
|
model: string;
|
||||||
systemPrompt?: string;
|
systemPrompt?: string;
|
||||||
allowedTools?: string[];
|
allowedTools?: string[];
|
||||||
/** Permission mode for automatic permission handling */
|
|
||||||
permissionMode?: PermissionMode;
|
permissionMode?: PermissionMode;
|
||||||
/** Override network access (webfetch/websearch) */
|
|
||||||
networkAccess?: boolean;
|
networkAccess?: boolean;
|
||||||
/** Enable streaming mode with callback (best-effort) */
|
|
||||||
onStream?: StreamCallback;
|
onStream?: StreamCallback;
|
||||||
onAskUserQuestion?: AskUserQuestionHandler;
|
onAskUserQuestion?: AskUserQuestionHandler;
|
||||||
/** OpenCode API key */
|
|
||||||
opencodeApiKey?: string;
|
opencodeApiKey?: string;
|
||||||
/** JSON Schema for structured output */
|
|
||||||
outputSchema?: Record<string, unknown>;
|
outputSchema?: Record<string, unknown>;
|
||||||
|
interactionTimeoutMs?: number;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -24,25 +24,17 @@ export interface ProviderCallOptions {
|
|||||||
sessionId?: string;
|
sessionId?: string;
|
||||||
model?: string;
|
model?: string;
|
||||||
allowedTools?: string[];
|
allowedTools?: string[];
|
||||||
/** MCP servers configuration */
|
|
||||||
mcpServers?: Record<string, McpServerConfig>;
|
mcpServers?: Record<string, McpServerConfig>;
|
||||||
/** Maximum number of agentic turns */
|
|
||||||
maxTurns?: number;
|
maxTurns?: number;
|
||||||
/** Permission mode for tool execution (from piece step) */
|
|
||||||
permissionMode?: PermissionMode;
|
permissionMode?: PermissionMode;
|
||||||
/** Provider-specific movement options */
|
|
||||||
providerOptions?: MovementProviderOptions;
|
providerOptions?: MovementProviderOptions;
|
||||||
onStream?: StreamCallback;
|
onStream?: StreamCallback;
|
||||||
onPermissionRequest?: PermissionHandler;
|
onPermissionRequest?: PermissionHandler;
|
||||||
onAskUserQuestion?: AskUserQuestionHandler;
|
onAskUserQuestion?: AskUserQuestionHandler;
|
||||||
bypassPermissions?: boolean;
|
bypassPermissions?: boolean;
|
||||||
/** Anthropic API key for Claude provider */
|
|
||||||
anthropicApiKey?: string;
|
anthropicApiKey?: string;
|
||||||
/** OpenAI API key for Codex provider */
|
|
||||||
openaiApiKey?: string;
|
openaiApiKey?: string;
|
||||||
/** OpenCode API key for OpenCode provider */
|
|
||||||
opencodeApiKey?: string;
|
opencodeApiKey?: string;
|
||||||
/** JSON Schema for structured output */
|
|
||||||
outputSchema?: Record<string, unknown>;
|
outputSchema?: Record<string, unknown>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user