osborn 0.9.180 → 0.9.181

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.
@@ -167,7 +167,7 @@ ensureCompactionSettings();
167
167
  // (1M) window; without it opus runs at its 200K default. NOTE: 1M activation
168
168
  // also depends on account entitlement (auto on Team seats; else usage credits).
169
169
  process.env.ENABLE_1M_CONTEXT = '1';
170
- process.env.CLAUDE_AUTOCOMPACT_PCT_OVERRIDE = '75'; // auto-compact at 75% of 1M context (750k tokens) — prevents compaction at extreme tail
170
+ process.env.CLAUDE_AUTOCOMPACT_PCT_OVERRIDE = '92';
171
171
  // Research mode tools — full research capabilities
172
172
  // Named sub-agents — the orchestrator delegates to these specialists. Each has
173
173
  // a specific role, model, and tool set. Module-level + exported so the HTTP
@@ -276,13 +276,13 @@ export const NAMED_AGENTS = {
276
276
  },
277
277
  writer: {
278
278
  description: [
279
- 'Execution agent with file write/edit permissions (Opus).',
279
+ 'Execution agent with file write/edit permissions (Sonnet).',
280
280
  'Handles ALL file operations: code, config, docs, scripts, data files.',
281
281
  'VERIFY-FIRST workflow: checks assumptions before making changes, runs tests after.',
282
282
  'If anything is unclear, asks the main agent for clarification before touching files.',
283
283
  ].join(' '),
284
284
  tools: ['Read', 'Write', 'Edit', 'MultiEdit', 'Bash', 'Glob', 'Grep', 'NotebookRead', 'NotebookEdit'],
285
- model: 'opus',
285
+ model: 'sonnet',
286
286
  prompt: [
287
287
  'You are Osborn\'s writer agent. You execute file changes with a verify-first approach.',
288
288
  '',
@@ -421,13 +421,13 @@ export const NAMED_AGENTS = {
421
421
  },
422
422
  planner: {
423
423
  description: [
424
- 'Planning agent (Sonnet). Use for: decomposing a large or ambiguous request into a concrete,',
424
+ 'Planning agent (Opus). Use for: decomposing a large or ambiguous request into a concrete,',
425
425
  'ordered sequence of atomic writer-safe steps. Returns a self-contained brief the writer',
426
426
  'can execute without further clarification. Slow but thorough — only use for genuinely',
427
427
  'complex multi-file changes or when the approach is uncertain.',
428
428
  ].join(' '),
429
429
  tools: ['Read', 'Glob', 'Grep', 'WebSearch'],
430
- model: 'sonnet',
430
+ model: 'opus',
431
431
  prompt: [
432
432
  'You are Osborn\'s planning agent. Your job is to decompose complex tasks into clear, atomic steps.',
433
433
  '',
@@ -474,13 +474,13 @@ export const NAMED_AGENTS = {
474
474
  },
475
475
  reviewer: {
476
476
  description: [
477
- 'Code-review agent (Sonnet). Use for: the VERIFY step in a generator-verifier loop — after the',
477
+ 'Code-review agent (Opus). Use for: the VERIFY step in a generator-verifier loop — after the',
478
478
  'writer completes a change, the reviewer reads the diff, checks correctness, spec/requirement',
479
479
  'adherence, obvious bugs, and security issues, then tags each finding BLOCKER/MAJOR/MINOR/NIT',
480
480
  'and returns an ACCEPT or REJECT verdict with specific, actionable feedback. May write documentation files (.md etc.) only.',
481
481
  ].join(' '),
482
482
  tools: ['Read', 'Glob', 'Grep', 'Bash', 'Write', 'Edit'],
483
- model: 'sonnet',
483
+ model: 'opus',
484
484
  prompt: [
485
485
  'You are Osborn\'s reviewer agent. You are the VERIFY step in a generator-verifier loop.',
486
486
  '',
package/dist/config.d.ts CHANGED
@@ -1,18 +1,9 @@
1
1
  import type { McpServerConfig } from './claude-handler.js';
2
- export type VoiceMode = 'direct' | 'realtime' | 'pipeline';
2
+ export type VoiceMode = 'pipeline';
3
3
  export type EditMode = 'read-only' | 'edit';
4
4
  export type AgentMode = 'plan' | 'execute' | 'research';
5
- export type RealtimeProvider = 'openai' | 'gemini';
6
5
  export type STTProvider = 'deepgram' | 'groq-whisper' | 'openai-whisper';
7
- export type TTSProvider = 'gemini' | 'openai' | 'elevenlabs' | 'deepgram';
8
- export type BridgeLLMProvider = 'gemini-pro' | 'gpt-4o';
9
- export interface RealtimeConfig {
10
- provider?: RealtimeProvider;
11
- openaiVoice?: 'alloy' | 'echo' | 'fable' | 'onyx' | 'nova' | 'shimmer';
12
- openaiModel?: string;
13
- geminiVoice?: 'Aoede' | 'Charon' | 'Kore' | 'Fenrir' | 'Puck';
14
- geminiModel?: string;
15
- }
6
+ export type TTSProvider = 'openai' | 'deepgram';
16
7
  export interface DirectConfig {
17
8
  stt?: {
18
9
  provider?: STTProvider;
@@ -25,35 +16,11 @@ export interface DirectConfig {
25
16
  voice?: string;
26
17
  };
27
18
  }
28
- export interface PipelineDirectConfig extends DirectConfig {
29
- enableCollisionGuard?: boolean;
30
- }
31
- export interface PipelinedConfig {
32
- stt?: {
33
- provider?: STTProvider;
34
- model?: string;
35
- language?: string;
36
- };
37
- llm?: {
38
- provider?: BridgeLLMProvider;
39
- model?: string;
40
- };
41
- tts?: {
42
- provider?: TTSProvider;
43
- model?: string;
44
- voice?: string;
45
- };
46
- }
47
19
  export interface OsbornConfig {
48
20
  workingDirectory?: string;
49
21
  mcpServers?: Record<string, McpServerConfigYaml>;
50
- defaultProvider?: 'gemini' | 'openai';
51
- defaultCodingAgent?: 'claude' | 'codex';
52
22
  voiceMode?: VoiceMode;
53
- realtime?: RealtimeConfig;
54
23
  direct?: DirectConfig;
55
- 'pipeline-direct'?: PipelineDirectConfig;
56
- pipelined?: PipelinedConfig;
57
24
  }
58
25
  interface McpServerConfigYaml {
59
26
  enabled?: boolean;
@@ -103,19 +70,11 @@ export declare function getMcpServers(config: OsbornConfig): Record<string, McpS
103
70
  */
104
71
  export declare function getEnabledMcpServerNames(config: OsbornConfig): string[];
105
72
  /**
106
- * Get pipelined config with defaults merged
107
- */
108
- export declare function getPipelinedConfig(config: OsbornConfig): Required<PipelinedConfig>;
109
- /**
110
- * Get voice mode from config
111
- */
112
- export declare function getVoiceMode(config: OsbornConfig): VoiceMode;
113
- /**
114
- * Get realtime config with defaults merged
73
+ * Get voice mode from config (always pipeline)
115
74
  */
116
- export declare function getRealtimeConfig(config: OsbornConfig): Required<RealtimeConfig>;
75
+ export declare function getVoiceMode(_config: OsbornConfig): VoiceMode;
117
76
  /**
118
- * Get direct mode config with defaults merged
77
+ * Get pipeline mode config with defaults merged
119
78
  */
120
79
  export declare function getDirectConfig(config: OsbornConfig): Required<DirectConfig>;
121
80
  /**
@@ -179,6 +138,7 @@ export interface ClaudeSessionEntry {
179
138
  filePath: string;
180
139
  fileSize: number;
181
140
  }
141
+ export declare function invalidateSessionListCache(): void;
182
142
  /**
183
143
  * Scan ALL Claude Code projects for sessions.
184
144
  * Returns lightweight metadata for every main session JSONL across all projects.
package/dist/config.js CHANGED
@@ -44,18 +44,7 @@ export const MCP_CATALOG = [
44
44
  // Leaving it undefined lets the runtime self-heal in index.ts resolve it on every boot
45
45
  // from OSBORN_CWD → process.cwd() at the actual time the agent starts.
46
46
  const DEFAULT_CONFIG = {
47
- defaultProvider: 'gemini',
48
- defaultCodingAgent: 'claude',
49
- // Voice mode: 'direct' (Claude Agent SDK) or 'realtime' (OpenAI/Gemini native)
50
- voiceMode: 'direct',
51
- // Realtime mode config (used when voiceMode='realtime')
52
- realtime: {
53
- provider: 'openai',
54
- openaiVoice: 'alloy',
55
- geminiVoice: 'Aoede',
56
- geminiModel: 'gemini-2.5-flash-native-audio-preview-12-2025',
57
- },
58
- // Direct mode config (used when voiceMode='direct')
47
+ voiceMode: 'pipeline',
59
48
  direct: {
60
49
  stt: {
61
50
  provider: 'deepgram',
@@ -193,50 +182,13 @@ export function getEnabledMcpServerNames(config) {
193
182
  .map(([name, _]) => name);
194
183
  }
195
184
  /**
196
- * Get pipelined config with defaults merged
185
+ * Get voice mode from config (always pipeline)
197
186
  */
198
- export function getPipelinedConfig(config) {
199
- const defaults = DEFAULT_CONFIG.pipelined;
200
- const userConfig = config.pipelined || {};
201
- return {
202
- stt: {
203
- provider: userConfig.stt?.provider || defaults.stt.provider,
204
- model: userConfig.stt?.model,
205
- language: userConfig.stt?.language || 'en',
206
- },
207
- llm: {
208
- provider: userConfig.llm?.provider || defaults.llm.provider,
209
- model: userConfig.llm?.model,
210
- },
211
- tts: {
212
- provider: userConfig.tts?.provider || defaults.tts.provider,
213
- model: userConfig.tts?.model,
214
- voice: userConfig.tts?.voice || defaults.tts.voice,
215
- },
216
- };
187
+ export function getVoiceMode(_config) {
188
+ return 'pipeline';
217
189
  }
218
190
  /**
219
- * Get voice mode from config
220
- */
221
- export function getVoiceMode(config) {
222
- return config.voiceMode || 'direct';
223
- }
224
- /**
225
- * Get realtime config with defaults merged
226
- */
227
- export function getRealtimeConfig(config) {
228
- const defaults = DEFAULT_CONFIG.realtime;
229
- const userConfig = config.realtime || {};
230
- return {
231
- provider: userConfig.provider || defaults.provider,
232
- openaiVoice: userConfig.openaiVoice || defaults.openaiVoice,
233
- openaiModel: userConfig.openaiModel || 'gpt-4o-realtime-preview',
234
- geminiVoice: userConfig.geminiVoice || defaults.geminiVoice,
235
- geminiModel: userConfig.geminiModel || defaults.geminiModel,
236
- };
237
- }
238
- /**
239
- * Get direct mode config with defaults merged
191
+ * Get pipeline mode config with defaults merged
240
192
  */
241
193
  export function getDirectConfig(config) {
242
194
  const defaults = DEFAULT_CONFIG.direct;
@@ -588,6 +540,13 @@ async function extractCwd(filePath) {
588
540
  rl.on('error', () => done(''));
589
541
  });
590
542
  }
543
+ // In-memory cache for the session list — invalidated on new session creation or import.
544
+ // Avoids re-crawling all JSONL files on every agent connect / dashboard load.
545
+ let _sessionListCache = null;
546
+ const SESSION_LIST_TTL_MS = 300_000;
547
+ export function invalidateSessionListCache() {
548
+ _sessionListCache = null;
549
+ }
591
550
  /**
592
551
  * Scan ALL Claude Code projects for sessions.
593
552
  * Returns lightweight metadata for every main session JSONL across all projects.
@@ -596,6 +555,9 @@ async function extractCwd(filePath) {
596
555
  * @param limit - Max sessions to return (default 100, sorted by recency)
597
556
  */
598
557
  export async function listAllClaudeSessions(limit = 1000) {
558
+ if (_sessionListCache && Date.now() < _sessionListCache.expiresAt) {
559
+ return _sessionListCache.data.slice(0, limit);
560
+ }
599
561
  const projectsDir = getClaudeProjectsDir();
600
562
  if (!existsSync(projectsDir))
601
563
  return [];
@@ -702,7 +664,8 @@ export async function listAllClaudeSessions(limit = 1000) {
702
664
  fileSize: c.size,
703
665
  });
704
666
  }
705
- return sessions;
667
+ _sessionListCache = { data: sessions, expiresAt: Date.now() + SESSION_LIST_TTL_MS };
668
+ return sessions.slice(0, limit);
706
669
  }
707
670
  /**
708
671
  * Get a summary of a session for context briefing