Skip to content

Commit 4a19abe

Browse files
session management and http server code
1 parent 31a1ea6 commit 4a19abe

File tree

4 files changed

+39
-4
lines changed

4 files changed

+39
-4
lines changed

packages/agent/src/agent/GeminiAgent.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,6 @@ export class GeminiAgent {
9494
});
9595

9696
await geminiConfig.initialize();
97-
98-
console.log('resolvedConfig', resolvedConfig);
9997
const contentGenerator = new VercelAIContentGenerator(resolvedConfig);
10098

10199
(geminiConfig as unknown as { contentGenerator: VercelAIContentGenerator }).contentGenerator = contentGenerator;

packages/agent/src/agent/gemini-vercel-sdk-adapter/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ export class VercelAIContentGenerator implements ContentGenerator {
122122
tools,
123123
temperature: request.config?.temperature,
124124
topP: request.config?.topP,
125+
abortSignal: request.config?.abortSignal,
125126
});
126127

127128
return this.responseStrategy.streamToGemini(

packages/agent/src/agent/gemini-vercel-sdk-adapter/strategies/response.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,25 @@ export class ResponseConversionStrategy {
186186
usage = this.estimateUsage(textAccumulator);
187187
}
188188

189+
// Emit finish stream part to Hono SSE for useChat compatibility
190+
if (honoStream) {
191+
try {
192+
// Emit finish_message part with finishReason and usage
193+
// Format: e:{"finishReason":"stop","usage":{"promptTokens":10,"completionTokens":5}}
194+
// Map to LanguageModelV1FinishReason: 'stop' | 'length' | 'content-filter' | 'tool-calls' | 'error' | 'other' | 'unknown'
195+
const mappedFinishReason = this.mapToDataStreamFinishReason(finishReason);
196+
await honoStream.write(formatDataStreamPart('finish_message', {
197+
finishReason: mappedFinishReason,
198+
usage: usage ? {
199+
promptTokens: usage.promptTokens ?? 0,
200+
completionTokens: usage.completionTokens ?? 0,
201+
} : undefined,
202+
}));
203+
} catch {
204+
// Failed to write finish part
205+
}
206+
}
207+
189208
// Yield final response with tool calls and metadata
190209
if (toolCallsMap.size > 0 || finishReason || usage) {
191210
const parts: Part[] = [];
@@ -281,6 +300,19 @@ export class ResponseConversionStrategy {
281300
}
282301
}
283302

303+
/**
304+
* Map Vercel finish reasons to data stream protocol finish reasons
305+
* LanguageModelV1FinishReason: 'stop' | 'length' | 'content-filter' | 'tool-calls' | 'error' | 'other' | 'unknown'
306+
* Mostly passthrough except 'max-tokens' → 'length'
307+
*/
308+
private mapToDataStreamFinishReason(
309+
reason: VercelFinishReason | undefined,
310+
): 'stop' | 'length' | 'content-filter' | 'tool-calls' | 'error' | 'other' | 'unknown' {
311+
if (!reason) return 'stop';
312+
if (reason === 'max-tokens') return 'length';
313+
return reason;
314+
}
315+
284316
/**
285317
* Create empty response for error cases
286318
*/

packages/agent/src/http/HttpServer.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,10 @@ export function createHttpServer(config: HttpServerConfig) {
4848
app.use(
4949
'/*',
5050
cors({
51-
origin: validatedConfig.corsOrigins,
51+
origin: (origin) => origin || '*',
5252
allowMethods: ['GET', 'POST', 'DELETE', 'OPTIONS'],
5353
allowHeaders: ['Content-Type', 'Authorization'],
54+
credentials: true,
5455
}),
5556
);
5657

@@ -101,6 +102,9 @@ export function createHttpServer(config: HttpServerConfig) {
101102
c.header('Cache-Control', 'no-cache');
102103
c.header('Connection', 'keep-alive');
103104

105+
// Get abort signal from the raw request - fires when client disconnects
106+
const abortSignal = c.req.raw.signal;
107+
104108
return stream(c, async (honoStream) => {
105109
try {
106110
const agent = await sessionManager.getOrCreate({
@@ -121,7 +125,7 @@ export function createHttpServer(config: HttpServerConfig) {
121125
mcpServerUrl,
122126
});
123127

124-
await agent.execute(request.message, honoStream);
128+
await agent.execute(request.message, honoStream, abortSignal);
125129
} catch (error) {
126130
const errorMessage = error instanceof Error ? error.message : 'Agent execution failed';
127131
logger.error('Agent execution error', {

0 commit comments

Comments
 (0)