Skip to content

Commit 0787d7b

Browse files
authored
browseros fixes: loggicodex sdk" (#48)
* fix: LLM config for agent * logger: make JSON pretty print * fix: updating logging to be clean and concise
1 parent a23f8d6 commit 0787d7b

File tree

7 files changed

+69
-77
lines changed

7 files changed

+69
-77
lines changed

packages/agent/src/agent/BaseAgent.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,11 @@ export abstract class BaseAgent {
6868
// Merge config with agent-specific defaults, then with base defaults
6969
this.config = {
7070
resourcesDir: config.resourcesDir,
71+
executionDir: config.executionDir,
7172
mcpServerPort: config.mcpServerPort ?? agentDefaults?.mcpServerPort,
7273
apiKey: config.apiKey ?? agentDefaults?.apiKey,
73-
baseUrl: config.baseUrl ?? agentDefaults?.baseUrl,
74-
modelName: config.modelName ?? agentDefaults?.modelName,
74+
baseUrl: config.baseUrl,
75+
modelName: config.modelName,
7576
maxTurns:
7677
config.maxTurns ?? agentDefaults?.maxTurns ?? DEFAULT_CONFIG.maxTurns,
7778
maxThinkingTokens:

packages/agent/src/agent/CodexSDKAgent.config.ts

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ export interface McpServerConfig {
1717

1818
export interface BrowserOSCodexConfig {
1919
model_name: string;
20-
base_url: string;
20+
base_url?: string;
2121
api_key_env: string;
2222
wire_api: 'chat' | 'responses';
2323
base_instructions_file: string;
@@ -26,10 +26,6 @@ export interface BrowserOSCodexConfig {
2626
};
2727
}
2828

29-
export function getResourcesDir(resourcesDir?: string): string {
30-
return resourcesDir || process.cwd();
31-
}
32-
3329
export function generateBrowserOSCodexToml(
3430
config: BrowserOSCodexConfig,
3531
): string {

packages/agent/src/agent/CodexSDKAgent.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ import {BaseAgent} from './BaseAgent.js';
1616
import {CodexEventFormatter} from './CodexSDKAgent.formatter.js';
1717
import {
1818
type BrowserOSCodexConfig,
19-
getResourcesDir,
2019
writeBrowserOSCodexConfig,
2120
writePromptFile,
2221
} from './CodexSDKAgent.config.js';
@@ -109,14 +108,14 @@ export class CodexSDKAgent extends BaseAgent {
109108
}
110109

111110
private generateCodexConfig(): void {
112-
const outputDir = getResourcesDir(this.config.executionDir);
111+
const outputDir = this.config.executionDir;
113112
const port = this.config.mcpServerPort || CODEX_SDK_DEFAULTS.mcpServerPort;
114-
const modelName = this.config.modelName || 'o4-mini';
113+
const modelName = this.config.modelName;
115114
const baseUrl = this.config.baseUrl;
116115

117116
const codexConfig: BrowserOSCodexConfig = {
118117
model_name: modelName,
119-
base_url: baseUrl,
118+
...(baseUrl && {base_url: baseUrl}),
120119
api_key_env: 'BROWSEROS_API_KEY',
121120
wire_api: 'chat',
122121
base_instructions_file: 'browseros_prompt.md',

packages/agent/src/agent/types.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,15 +76,13 @@ export const AgentConfigSchema = z.object({
7676

7777
/**
7878
* Base URL for custom LLM endpoints
79-
* Optional - used for self-hosted or alternative LLM providers
8079
*/
81-
baseUrl: z.string().url().optional(),
80+
baseUrl: z.string().url(),
8281

8382
/**
8483
* Model name/identifier to use
85-
* Optional - defaults to agent-specific models (e.g., 'o4-mini', 'claude-3-5-sonnet')
8684
*/
87-
modelName: z.string().optional(),
85+
modelName: z.string(),
8886

8987
/**
9088
* Maximum conversation turns before stopping

packages/agent/src/session/SessionManager.ts

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ export class SessionManager {
9292
this.config = config;
9393
this.controllerBridge = controllerBridge;
9494

95-
logger.info('📦 SessionManager initialized', {
95+
logger.info('SessionManager initialized', {
9696
maxSessions: config.maxSessions,
9797
idleTimeoutMs: config.idleTimeoutMs,
9898
sharedControllerBridge: true,
@@ -145,7 +145,7 @@ export class SessionManager {
145145
);
146146
this.agents.set(sessionId, agent);
147147

148-
logger.info('Session created with agent', {
148+
logger.info('Session created with agent', {
149149
sessionId,
150150
agentType,
151151
totalSessions: this.sessions.size,
@@ -154,15 +154,15 @@ export class SessionManager {
154154
// Cleanup session if agent creation fails
155155
this.sessions.delete(sessionId);
156156

157-
logger.error('Failed to create agent for session', {
157+
logger.error('Failed to create agent for session', {
158158
sessionId,
159159
error: error instanceof Error ? error.message : String(error),
160160
});
161161

162162
throw error;
163163
}
164164
} else {
165-
logger.info('Session created without agent', {
165+
logger.info('Session created without agent', {
166166
sessionId,
167167
totalSessions: this.sessions.size,
168168
});
@@ -201,15 +201,15 @@ export class SessionManager {
201201
updateActivity(sessionId: string): void {
202202
const session = this.sessions.get(sessionId);
203203
if (!session) {
204-
logger.warn('⚠️ Attempted to update activity for non-existent session', {
204+
logger.warn('Attempted to update activity for non-existent session', {
205205
sessionId,
206206
});
207207
return;
208208
}
209209

210210
session.lastActivity = Date.now();
211211

212-
logger.debug('🔄 Session activity updated', {
212+
logger.debug('Session activity updated', {
213213
sessionId,
214214
messageCount: session.messageCount,
215215
});
@@ -227,7 +227,7 @@ export class SessionManager {
227227

228228
// Reject if already processing (prevent concurrent message handling)
229229
if (session.state === SessionState.PROCESSING) {
230-
logger.warn('⚠️ Session already processing message', {sessionId});
230+
logger.warn('Session already processing message', {sessionId});
231231
return false;
232232
}
233233

@@ -236,7 +236,7 @@ export class SessionManager {
236236
// ❌ Removed: session.lastActivity = Date.now()
237237
// Idle timer starts from markIdle(), not here
238238

239-
logger.debug('⚙️ Session marked as processing', {
239+
logger.debug('Session marked as processing', {
240240
sessionId,
241241
messageCount: session.messageCount,
242242
});
@@ -257,7 +257,7 @@ export class SessionManager {
257257
session.state = SessionState.IDLE;
258258
session.lastActivity = Date.now(); // ✅ Idle timer starts here
259259

260-
logger.debug('💤 Session marked as idle', {sessionId});
260+
logger.debug('Session marked as idle', {sessionId});
261261
}
262262

263263
/**
@@ -280,9 +280,9 @@ export class SessionManager {
280280
try {
281281
await agent.destroy();
282282
this.agents.delete(sessionId);
283-
logger.debug('🗑️ Agent destroyed', {sessionId});
283+
logger.debug('Agent destroyed', {sessionId});
284284
} catch (error) {
285-
logger.error('Failed to destroy agent', {
285+
logger.error('Failed to destroy agent', {
286286
sessionId,
287287
error: error instanceof Error ? error.message : String(error),
288288
});
@@ -293,7 +293,7 @@ export class SessionManager {
293293
// Delete session
294294
this.sessions.delete(sessionId);
295295

296-
logger.info('🗑️ Session deleted', {
296+
logger.info('Session deleted', {
297297
sessionId,
298298
remainingSessions: this.sessions.size,
299299
messageCount: session.messageCount,
@@ -341,7 +341,7 @@ export class SessionManager {
341341
) {
342342
idleSessionIds.push(sessionId);
343343

344-
logger.info('⏱️ Idle session detected', {
344+
logger.info('Idle session detected', {
345345
sessionId,
346346
idleTimeMs: idleTime,
347347
threshold: this.config.idleTimeoutMs,
@@ -358,17 +358,17 @@ export class SessionManager {
358358
*/
359359
startCleanup(intervalMs = 60000): () => void {
360360
if (this.cleanupTimerId) {
361-
logger.warn('⚠️ Cleanup timer already running');
361+
logger.warn('Cleanup timer already running');
362362
return () => {};
363363
}
364364

365-
logger.info('🧹 Starting periodic session cleanup', {intervalMs});
365+
logger.info('Starting periodic session cleanup', {intervalMs});
366366

367367
this.cleanupTimerId = setInterval(() => {
368368
const idleSessionIds = this.findIdleSessions();
369369

370370
if (idleSessionIds.length > 0) {
371-
logger.info('🧹 Cleanup found idle sessions', {
371+
logger.info('Cleanup found idle sessions', {
372372
count: idleSessionIds.length,
373373
sessionIds: idleSessionIds,
374374
});
@@ -383,7 +383,7 @@ export class SessionManager {
383383
if (this.cleanupTimerId) {
384384
clearInterval(this.cleanupTimerId);
385385
this.cleanupTimerId = undefined;
386-
logger.info('🛑 Session cleanup stopped');
386+
logger.info('Session cleanup stopped');
387387
}
388388
};
389389
}
@@ -429,7 +429,7 @@ export class SessionManager {
429429
* Now async to support agent cleanup
430430
*/
431431
async shutdown(): Promise<void> {
432-
logger.info('🛑 SessionManager shutting down', {
432+
logger.info('SessionManager shutting down', {
433433
activeSessions: this.sessions.size,
434434
activeAgents: this.agents.size,
435435
});
@@ -445,7 +445,7 @@ export class SessionManager {
445445
for (const [sessionId, agent] of this.agents) {
446446
destroyPromises.push(
447447
agent.destroy().catch(error => {
448-
logger.error('Failed to destroy agent during shutdown', {
448+
logger.error('Failed to destroy agent during shutdown', {
449449
sessionId,
450450
error: error instanceof Error ? error.message : String(error),
451451
});
@@ -459,6 +459,6 @@ export class SessionManager {
459459
// Clear all sessions
460460
this.sessions.clear();
461461

462-
logger.info('SessionManager shutdown complete');
462+
logger.info('SessionManager shutdown complete');
463463
}
464464
}

packages/common/src/logger.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,13 @@ class Logger {
3131
private format(level: LogLevel, message: string, meta?: object): string {
3232
const timestamp = new Date().toISOString();
3333
const color = COLORS[level];
34-
const metaStr = meta ? ` ${JSON.stringify(meta)}` : '';
34+
const metaStr = meta ? `\n${JSON.stringify(meta, null, 2)}` : '';
3535
return `${color}[${timestamp}] [${level.toUpperCase()}]${RESET} ${message}${metaStr}`;
3636
}
3737

3838
private formatPlain(level: LogLevel, message: string, meta?: object): string {
3939
const timestamp = new Date().toISOString();
40-
const metaStr = meta ? ` ${JSON.stringify(meta)}` : '';
40+
const metaStr = meta ? `\n${JSON.stringify(meta, null, 2)}` : '';
4141
return `[${timestamp}] [${level.toUpperCase()}] ${message}${metaStr}`;
4242
}
4343

packages/server/src/main.ts

Lines changed: 38 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -180,66 +180,64 @@ function startMcpServer(config: {
180180
return mcpServer;
181181
}
182182

183-
/**
184-
* Get LLM configuration - either all env vars OR all config values (no mixing)
185-
* Environment variables take precedence: if any env var is set, use all env vars
186-
* Otherwise, fetch and use 'default' provider from BROWSEROS_CONFIG_URL
187-
*/
183+
// get LLM configuration for agent server
188184
async function getLLMConfig(): Promise<{
189185
apiKey?: string;
190-
baseUrl?: string;
191-
modelName?: string;
186+
baseUrl: string;
187+
modelName: string;
192188
}> {
193-
// Check if any environment variable is set
194189
const envApiKey = process.env.BROWSEROS_API_KEY;
195190
const envBaseUrl = process.env.BROWSEROS_LLM_BASE_URL;
196191
const envModelName = process.env.BROWSEROS_LLM_MODEL_NAME;
197-
const hasAnyEnvVar =
198-
envApiKey !== undefined ||
199-
envBaseUrl !== undefined ||
200-
envModelName !== undefined;
201-
202-
// If any env var is set, use all env vars (no mixing with config)
203-
if (hasAnyEnvVar) {
204-
logger.info('✅ Using LLM config from environment variables');
205-
return {
206-
apiKey: envApiKey,
207-
baseUrl: envBaseUrl,
208-
modelName: envModelName,
209-
};
210-
}
211192

212-
// No env vars set, try to fetch from config URL
193+
let configApiKey: string | undefined;
194+
let configBaseUrl: string | undefined;
195+
let configModelName: string | undefined;
196+
197+
// Try to fetch from config URL
213198
const configUrl = process.env.BROWSEROS_CONFIG_URL;
214199
if (configUrl) {
215200
try {
216-
logger.info('🌐 Fetching LLM config from BrowserOS Config URL', {
201+
logger.info('Fetching LLM config from BrowserOS Config URL', {
217202
configUrl,
218203
});
219204
const config = await fetchBrowserOSConfig(configUrl);
220205
const llmConfig = getLLMConfigFromProvider(config, 'default');
221206

222-
logger.info('✅ Using LLM config from BrowserOS Config (default provider)');
223-
return {
224-
apiKey: llmConfig.apiKey,
225-
baseUrl: llmConfig.baseUrl,
226-
modelName: llmConfig.modelName,
227-
};
207+
configApiKey = llmConfig.apiKey;
208+
configBaseUrl = llmConfig.baseUrl;
209+
configModelName = llmConfig.modelName;
210+
211+
logger.info('Loaded config from BrowserOS Config (default provider)');
228212
} catch (error) {
229-
logger.warn(
230-
'⚠️ Failed to fetch config from URL, no LLM config available',
231-
{
232-
error: error instanceof Error ? error.message : String(error),
233-
},
234-
);
213+
logger.warn('Failed to fetch config from URL', {
214+
error: error instanceof Error ? error.message : String(error),
215+
});
235216
}
236217
}
237218

238-
// No env vars and no config available
219+
// Apply env var overrides (env takes precedence)
220+
const apiKey = envApiKey ?? configApiKey;
221+
const baseUrl = envBaseUrl ?? configBaseUrl;
222+
const modelName = envModelName ?? configModelName;
223+
224+
// Validate required fields
225+
if (!baseUrl || !modelName) {
226+
throw new Error(
227+
'LLM configuration required: baseUrl and modelName must be set via BROWSEROS_LLM_BASE_URL and BROWSEROS_LLM_MODEL_NAME environment variables, or via BROWSEROS_CONFIG_URL',
228+
);
229+
}
230+
231+
logger.info('Using LLM config', {
232+
baseUrl,
233+
modelName,
234+
apiKeySource: envApiKey ? 'env' : configApiKey ? 'config' : 'none',
235+
});
236+
239237
return {
240-
apiKey: undefined,
241-
baseUrl: undefined,
242-
modelName: undefined,
238+
apiKey,
239+
baseUrl,
240+
modelName,
243241
};
244242
}
245243

0 commit comments

Comments
 (0)