osborn 0.9.28 → 0.9.30

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.
@@ -1095,6 +1095,35 @@ class ClaudeLLMStream extends llm.LLMStream {
1095
1095
  catch (blErr) {
1096
1096
  console.error('⚠️ PostCompact: BEHAVIORAL_LEARNINGS write failed:', blErr instanceof Error ? blErr.message : blErr);
1097
1097
  }
1098
+ // ── Section 5: USER_CONTEXT — merge into user-context/CONTEXT.md ──
1099
+ // Passive UX: agent learns the user's language automatically after every
1100
+ // compaction. No explicit "grill me" command needed. The compact summary
1101
+ // captures vocabulary/style observations confirmed during the session.
1102
+ try {
1103
+ const userCtx = extractSection('=== USER_CONTEXT ===');
1104
+ const hasContent = userCtx.length >= 30 && !userCtx.includes('(none this session)');
1105
+ if (hasContent) {
1106
+ progress('Updating user context', `${userCtx.length} chars`);
1107
+ const ctxFolder = join(skillDir, '.claude', 'skills', 'user-context');
1108
+ const ctxPath = join(ctxFolder, 'CONTEXT.md');
1109
+ mkdirSync(ctxFolder, { recursive: true });
1110
+ // Append new observations to existing CONTEXT.md under a dated section.
1111
+ // The grill-me skill can consolidate/clean up on explicit request.
1112
+ const existing = existsSyncFs(ctxPath) ? readSyncFs(ctxPath, 'utf-8') : '# User Context\n\n';
1113
+ const entry = `\n## Observations — ${today} (session ${sessionId.substring(0, 8)})\n\n${userCtx}\n`;
1114
+ writeSyncFs(ctxPath, existing + entry, 'utf-8');
1115
+ console.log(`🧠 PostCompact: updated user context at ${ctxPath}`);
1116
+ skillsWritten++;
1117
+ skillNames.push('user-context');
1118
+ progress('Wrote skill', 'user-context');
1119
+ }
1120
+ else {
1121
+ console.log('🧠 PostCompact: no USER_CONTEXT observations this session — skipping');
1122
+ }
1123
+ }
1124
+ catch (ucErr) {
1125
+ console.error('⚠️ PostCompact: USER_CONTEXT write failed:', ucErr instanceof Error ? ucErr.message : ucErr);
1126
+ }
1098
1127
  this.#opts.onCompactionEvent?.({ type: 'compaction_complete', skillsWritten, skillNames });
1099
1128
  console.log(`🧠 PostCompact: complete — ${skillsWritten} skill file(s) written: [${skillNames.join(', ')}]`);
1100
1129
  }
@@ -56,4 +56,26 @@ If the EXISTING LEARNED SKILLS section is shown below, merge — update outdated
56
56
 
57
57
  ---
58
58
 
59
- IMPORTANT: All four sections MUST appear at the end of the compact summary even if some are empty. Empty sections should have a single line: (none this session)
59
+ ---
60
+
61
+ ## Section 5: USER_CONTEXT
62
+ Format: === USER_CONTEXT ===
63
+ Capture what you learned about THIS USER's language and communication style this session.
64
+ Only include observations that were CONFIRMED — things the user actually said, corrected, or repeated.
65
+ Skip if nothing new was observed.
66
+
67
+ VOCABULARY:
68
+ - List any terms the user used consistently with a specific meaning
69
+ - List any terms they used interchangeably that should be standardised
70
+ - Format: **term**: what they mean by it. _Avoid_: alternatives they used
71
+
72
+ STYLE:
73
+ - One or two sentences describing how they communicate (tone, pace, depth preference)
74
+ - Only include if a clear pattern emerged this session
75
+
76
+ RECURRING:
77
+ - Topics, projects, or concepts that came up repeatedly
78
+
79
+ ---
80
+
81
+ IMPORTANT: All five sections MUST appear at the end of the compact summary even if some are empty. Empty sections should have a single line: (none this session)
@@ -19,9 +19,9 @@ export class RecallClient extends EventEmitter {
19
19
  meeting_url: meetingUrl,
20
20
  bot_name: botName,
21
21
  recording_config: {
22
- // `transcript: true` was rejected as "Expected a dictionary, but got bool" —
23
- // omit; `transcription_options` below already configures the transcript provider.
24
- real_time_endpoints: [{
22
+ // Field names must match Recall API exactly (no underscore in realtime_endpoints).
23
+ // real_time_endpoints was silently ignored API uses realtime_endpoints.
24
+ realtime_endpoints: [{
25
25
  type: 'webhook',
26
26
  config: {
27
27
  url: `${webhookBaseUrl}/webhook/recall`,
@@ -30,7 +30,7 @@ export class RecallClient extends EventEmitter {
30
30
  }],
31
31
  transcription_options: {
32
32
  provider: 'assembly_ai',
33
- mode: 'prioritize_low_latency', // default delays transcripts 3-10 minutes
33
+ mode: 'prioritize_low_latency',
34
34
  },
35
35
  },
36
36
  output_media: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "osborn",
3
- "version": "0.9.28",
3
+ "version": "0.9.30",
4
4
  "description": "Voice AI coding assistant - local agent that connects to Osborn frontend",
5
5
  "type": "module",
6
6
  "bin": {