Skip to content

Commit 79fb6d5

Browse files
committed
fix: use proper ACP setSessionMode, restore multi-provider gateway env
1 parent c4f60d1 commit 79fb6d5

4 files changed

Lines changed: 24 additions & 52 deletions

File tree

apps/twig/src/main/services/agent/service.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -614,10 +614,7 @@ export class AgentService extends TypedEventEmitter<AgentServiceEvents> {
614614
}
615615

616616
try {
617-
await session.clientSideConnection.extMethod("session/setMode", {
618-
sessionId,
619-
modeId,
620-
});
617+
await session.clientSideConnection.setSessionMode({ sessionId, modeId });
621618
log.info("Session mode updated", { sessionId, modeId });
622619
} catch (err) {
623620
log.error("Failed to set session mode", { sessionId, modeId, err });

packages/agent/src/adapters/base-acp-agent.ts

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ export interface BaseSession {
2626

2727
export abstract class BaseAcpAgent implements Agent {
2828
abstract readonly adapterName: string;
29-
protected session: BaseSession | null = null;
30-
protected sessionId: string | null = null;
29+
protected session!: BaseSession;
30+
protected sessionId!: string;
3131
client: AgentSideConnection;
3232
protected logger: Logger;
3333
protected fileContentCache: { [key: string]: string } = {};
@@ -43,7 +43,7 @@ export abstract class BaseAcpAgent implements Agent {
4343
protected abstract interruptSession(): Promise<void>;
4444

4545
async cancel(params: CancelNotification): Promise<void> {
46-
if (this.sessionId !== params.sessionId || !this.session) {
46+
if (this.sessionId !== params.sessionId) {
4747
throw new Error("Session not found");
4848
}
4949
this.session.cancelled = true;
@@ -55,9 +55,6 @@ export abstract class BaseAcpAgent implements Agent {
5555
}
5656

5757
async closeSession(): Promise<void> {
58-
if (!this.session || !this.sessionId) {
59-
return;
60-
}
6158
try {
6259
await this.cancel({ sessionId: this.sessionId });
6360
this.session.abortController.abort();
@@ -68,19 +65,17 @@ export abstract class BaseAcpAgent implements Agent {
6865
error: err,
6966
});
7067
}
71-
this.session = null;
72-
this.sessionId = null;
7368
}
7469

7570
hasSession(sessionId: string): boolean {
76-
return this.sessionId === sessionId && this.session !== null;
71+
return this.sessionId === sessionId;
7772
}
7873

7974
appendNotification(
8075
sessionId: string,
8176
notification: SessionNotification,
8277
): void {
83-
if (this.sessionId === sessionId && this.session) {
78+
if (this.sessionId === sessionId) {
8479
this.session.notificationHistory.push(notification);
8580
}
8681
}

packages/agent/src/adapters/claude/claude-agent.ts

Lines changed: 14 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ async function getAvailableSlashCommands(
146146

147147
export class ClaudeAcpAgent extends BaseAcpAgent {
148148
readonly adapterName = "claude";
149-
declare session: Session | null;
149+
declare session: Session;
150150
toolUseCache: ToolUseCache;
151151
backgroundTerminals: { [key: string]: BackgroundTerminal } = {};
152152
clientCapabilities?: ClientCapabilities;
@@ -239,13 +239,6 @@ export class ClaudeAcpAgent extends BaseAcpAgent {
239239
}, 0);
240240
}
241241

242-
private getSession(): Session {
243-
if (!this.session) {
244-
throw new Error("Session not found");
245-
}
246-
return this.session;
247-
}
248-
249242
private registerPersistence(
250243
sessionId: string,
251244
meta: Record<string, unknown> | undefined,
@@ -412,11 +405,10 @@ export class ClaudeAcpAgent extends BaseAcpAgent {
412405
}
413406

414407
async prompt(params: PromptRequest): Promise<PromptResponse> {
415-
const session = this.getSession();
416-
session.cancelled = false;
417-
session.interruptReason = undefined;
408+
this.session.cancelled = false;
409+
this.session.interruptReason = undefined;
418410

419-
const { query: q, input } = session;
411+
const { query: q, input } = this.session;
420412

421413
for (const chunk of params.prompt) {
422414
const userNotification = {
@@ -433,7 +425,7 @@ export class ClaudeAcpAgent extends BaseAcpAgent {
433425
input.push(promptToClaude({ ...params, prompt: params.prompt }));
434426

435427
const context = {
436-
session,
428+
session: this.session,
437429
sessionId: params.sessionId,
438430
client: this.client,
439431
toolUseCache: this.toolUseCache,
@@ -444,11 +436,11 @@ export class ClaudeAcpAgent extends BaseAcpAgent {
444436
while (true) {
445437
const { value: message, done } = await q.next();
446438
if (done || !message) {
447-
if (session.cancelled) {
439+
if (this.session.cancelled) {
448440
return {
449441
stopReason: "cancelled",
450-
_meta: session.interruptReason
451-
? { interruptReason: session.interruptReason }
442+
_meta: this.session.interruptReason
443+
? { interruptReason: this.session.interruptReason }
452444
: undefined,
453445
};
454446
}
@@ -498,30 +490,24 @@ export class ClaudeAcpAgent extends BaseAcpAgent {
498490
}
499491

500492
protected async interruptSession(): Promise<void> {
501-
if (!this.session) {
502-
return;
503-
}
504493
await this.session.query.interrupt();
505494
}
506495

507496
async setSessionModel(params: SetSessionModelRequest) {
508-
const session = this.getSession();
509-
await session.query.setModel(params.modelId);
497+
await this.session.query.setModel(params.modelId);
510498
}
511499

512500
async setSessionMode(
513501
params: SetSessionModeRequest,
514502
): Promise<SetSessionModeResponse> {
515-
const session = this.getSession();
516-
517503
switch (params.modeId) {
518504
case "default":
519505
case "acceptEdits":
520506
case "bypassPermissions":
521507
case "plan":
522-
session.permissionMode = params.modeId;
508+
this.session.permissionMode = params.modeId;
523509
try {
524-
await session.query.setPermissionMode(params.modeId);
510+
await this.session.query.setPermissionMode(params.modeId);
525511
} catch (error) {
526512
const errorMessage =
527513
error instanceof Error && error.message
@@ -541,17 +527,16 @@ export class ClaudeAcpAgent extends BaseAcpAgent {
541527

542528
canUseTool(sessionId: string): CanUseTool {
543529
return async (toolName, toolInput, { suggestions, toolUseID }) => {
544-
if (this.sessionId !== sessionId || !this.session) {
530+
if (this.sessionId !== sessionId) {
545531
return {
546532
behavior: "deny",
547533
message: "Session not found",
548534
interrupt: true,
549535
};
550536
}
551-
const session = this.session;
552537

553538
const context = {
554-
session,
539+
session: this.session,
555540
toolName,
556541
toolInput: toolInput as Record<string, unknown>,
557542
toolUseID,
@@ -584,15 +569,6 @@ export class ClaudeAcpAgent extends BaseAcpAgent {
584569
return {};
585570
}
586571

587-
if (method === "session/setMode") {
588-
const { sessionId, modeId } = params as {
589-
sessionId: string;
590-
modeId: string;
591-
};
592-
await this.setSessionMode({ sessionId, modeId });
593-
return {};
594-
}
595-
596572
throw RequestError.methodNotFound(method);
597573
}
598574

@@ -602,7 +578,7 @@ export class ClaudeAcpAgent extends BaseAcpAgent {
602578
this.logger.info("[RESUME] Resuming session", { params });
603579
const { sessionId } = params;
604580

605-
if (this.sessionId === sessionId && this.session) {
581+
if (this.sessionId === sessionId) {
606582
return {};
607583
}
608584

packages/agent/src/agent.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ export class Agent {
4242
const apiKey = this.posthogAPI.getApiKey();
4343
process.env.ANTHROPIC_BASE_URL = gatewayUrl;
4444
process.env.ANTHROPIC_AUTH_TOKEN = apiKey;
45+
process.env.OPENAI_BASE_URL = gatewayUrl;
46+
process.env.OPENAI_API_KEY = apiKey;
47+
process.env.GEMINI_BASE_URL = gatewayUrl;
48+
process.env.GEMINI_API_KEY = apiKey;
4549
} catch (error) {
4650
this.logger.error("Failed to configure LLM gateway", error);
4751
throw error;

0 commit comments

Comments
 (0)