osborn 0.9.131 → 0.9.132
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.
- package/dist/claude-llm.js +4 -3
- package/dist/index.js +19 -15
- package/dist/pipeline-direct-llm.d.ts +0 -2
- package/dist/pipeline-direct-llm.js +1 -4
- package/package.json +1 -1
package/dist/claude-llm.js
CHANGED
|
@@ -1132,7 +1132,7 @@ class ClaudeLLMStream extends llm.LLMStream {
|
|
|
1132
1132
|
// Writer agent: no longer auto-approved — falls through to canUseTool for permission dialog
|
|
1133
1133
|
if (agentType === 'writer') {
|
|
1134
1134
|
console.log(`✍️ Writer agent: deferring to canUseTool for permission`);
|
|
1135
|
-
this.#eventEmitter.emit('tool_use', { name: toolName, input: toolInput });
|
|
1135
|
+
this.#eventEmitter.emit('tool_use', { name: toolName, input: toolInput, agentRole: agentType || 'main' });
|
|
1136
1136
|
return { hookSpecificOutput: { hookEventName: 'PreToolUse', permissionDecision: 'ask' } };
|
|
1137
1137
|
}
|
|
1138
1138
|
// All other agents (main, researcher, reasoner, etc.): workspace only
|
|
@@ -1144,7 +1144,7 @@ class ClaudeLLMStream extends llm.LLMStream {
|
|
|
1144
1144
|
}
|
|
1145
1145
|
}
|
|
1146
1146
|
console.log(`🔧 Claude: ${toolName}`);
|
|
1147
|
-
this.#eventEmitter.emit('tool_use', { name: toolName, input: toolInput });
|
|
1147
|
+
this.#eventEmitter.emit('tool_use', { name: toolName, input: toolInput, agentRole: agentType || 'main' });
|
|
1148
1148
|
return {};
|
|
1149
1149
|
}]
|
|
1150
1150
|
}],
|
|
@@ -1154,8 +1154,9 @@ class ClaudeLLMStream extends llm.LLMStream {
|
|
|
1154
1154
|
const toolName = input?.tool_name || 'unknown';
|
|
1155
1155
|
const toolInput = input?.tool_input || {};
|
|
1156
1156
|
const toolResponse = input?.tool_response; // Capture actual tool output for fast brain processing
|
|
1157
|
+
const agentTypePost = input?.agent_type || null;
|
|
1157
1158
|
console.log(`✅ Done: ${toolName}`);
|
|
1158
|
-
this.#eventEmitter.emit('tool_result', { name: toolName, input: toolInput, response: toolResponse });
|
|
1159
|
+
this.#eventEmitter.emit('tool_result', { name: toolName, input: toolInput, response: toolResponse, agentRole: agentTypePost || 'main' });
|
|
1159
1160
|
return {};
|
|
1160
1161
|
}]
|
|
1161
1162
|
}],
|
package/dist/index.js
CHANGED
|
@@ -18,7 +18,7 @@ import { randomUUID } from 'node:crypto';
|
|
|
18
18
|
import { createRequire } from 'node:module';
|
|
19
19
|
// 0.9.71: createRequire for resolving package.json versions inside ESM
|
|
20
20
|
const __sdkVersionRequire = createRequire(import.meta.url);
|
|
21
|
-
import { homedir, tmpdir } from 'node:os';
|
|
21
|
+
import { homedir, tmpdir, totalmem, freemem } from 'node:os';
|
|
22
22
|
import { PassThrough } from 'node:stream';
|
|
23
23
|
import { createGunzip } from 'node:zlib';
|
|
24
24
|
// Resolve __dirname for this ESM module so we can find sibling files (e.g.
|
|
@@ -518,6 +518,15 @@ function startApiServer(workingDir, port) {
|
|
|
518
518
|
}
|
|
519
519
|
}
|
|
520
520
|
catch { /* version optional */ }
|
|
521
|
+
// System memory snapshot — use os.totalmem/freemem for WHOLE-MACHINE
|
|
522
|
+
// stats (the OOM killer watches these, not per-process RSS). processRssMb
|
|
523
|
+
// is additive: useful for spotting leaks but never the headline number.
|
|
524
|
+
const totalMb = Math.round(totalmem() / 1024 / 1024);
|
|
525
|
+
const freeMb = Math.round(freemem() / 1024 / 1024);
|
|
526
|
+
const usedMb = totalMb - freeMb;
|
|
527
|
+
const availableMb = freeMb;
|
|
528
|
+
const usedPct = Math.round((usedMb / totalMb) * 100);
|
|
529
|
+
const processRssMb = Math.round(process.memoryUsage().rss / 1024 / 1024);
|
|
521
530
|
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
522
531
|
res.end(JSON.stringify({
|
|
523
532
|
status: 'ok',
|
|
@@ -538,6 +547,8 @@ function startApiServer(workingDir, port) {
|
|
|
538
547
|
attemptCount: livekitState.attemptCount,
|
|
539
548
|
lastAttemptAt: livekitState.lastAttemptAt,
|
|
540
549
|
},
|
|
550
|
+
// Whole-machine memory — what the OOM killer watches. All values in MB.
|
|
551
|
+
memory: { totalMb, usedMb, availableMb, usedPct, processRssMb },
|
|
541
552
|
}));
|
|
542
553
|
return;
|
|
543
554
|
}
|
|
@@ -2214,7 +2225,7 @@ async function main() {
|
|
|
2214
2225
|
const { readSessionHistory } = await import('./session-access.js');
|
|
2215
2226
|
const history = readSessionHistory(sessionId, workingDir, {
|
|
2216
2227
|
lastN: 10,
|
|
2217
|
-
types: ['assistant'
|
|
2228
|
+
types: ['assistant'],
|
|
2218
2229
|
});
|
|
2219
2230
|
recentMessages = history
|
|
2220
2231
|
.filter((m) => m.text)
|
|
@@ -2230,14 +2241,8 @@ async function main() {
|
|
|
2230
2241
|
// BEFORE the previous TTS completed, and we may have already suppressed in-flight
|
|
2231
2242
|
// tts_say events that arrived during that overlap).
|
|
2232
2243
|
const carriedSuppressed = lastInterruption?.suppressedText ?? '';
|
|
2233
|
-
lastInterruption = {
|
|
2234
|
-
|
|
2235
|
-
recentMessages,
|
|
2236
|
-
suppressedText: carriedSuppressed,
|
|
2237
|
-
fullBlockText: fullBlockText && fullBlockText !== fullText ? fullBlockText : undefined,
|
|
2238
|
-
timestamp: Date.now(),
|
|
2239
|
-
};
|
|
2240
|
-
console.log(`📋 Interruption context stored (text: ${fullText.length} chars, JSONL: ${recentMessages.length} chars, block: ${fullBlockText?.length ?? 0} chars, suppressed carried: ${carriedSuppressed.length} chars)`);
|
|
2244
|
+
lastInterruption = { spokenText: fullText, recentMessages, suppressedText: carriedSuppressed, timestamp: Date.now() };
|
|
2245
|
+
console.log(`📋 Interruption context stored (text: ${fullText.length} chars, JSONL: ${recentMessages.length} chars, suppressed carried: ${carriedSuppressed.length} chars)`);
|
|
2241
2246
|
}
|
|
2242
2247
|
/**
|
|
2243
2248
|
* Append text the agent tried to say while the user was speaking, but which we
|
|
@@ -2277,7 +2282,6 @@ async function main() {
|
|
|
2277
2282
|
spokenText: lastInterruption.spokenText,
|
|
2278
2283
|
recentMessages: lastInterruption.recentMessages,
|
|
2279
2284
|
suppressedText: lastInterruption.suppressedText,
|
|
2280
|
-
fullBlockText: lastInterruption.fullBlockText,
|
|
2281
2285
|
};
|
|
2282
2286
|
lastInterruption = null;
|
|
2283
2287
|
return ctx;
|
|
@@ -2689,11 +2693,11 @@ async function main() {
|
|
|
2689
2693
|
// Wire up events from the Claude SDK wrapper to frontend
|
|
2690
2694
|
directLLM.events.on('tool_use', (data) => {
|
|
2691
2695
|
console.log(`🔧 Claude: ${data.name}`);
|
|
2692
|
-
sendToFrontend(buildToolLogEvent(data.name, data.input, 'running', '
|
|
2696
|
+
sendToFrontend(buildToolLogEvent(data.name, data.input, 'running', data.agentRole || 'main'));
|
|
2693
2697
|
});
|
|
2694
2698
|
directLLM.events.on('tool_result', (data) => {
|
|
2695
2699
|
console.log(`✅ Done: ${data.name}`);
|
|
2696
|
-
sendToFrontend(buildToolLogEvent(data.name, data.input, 'completed', '
|
|
2700
|
+
sendToFrontend(buildToolLogEvent(data.name, data.input, 'completed', data.agentRole || 'main'));
|
|
2697
2701
|
// Detect research artifact writes (session workspace or legacy research dir)
|
|
2698
2702
|
if ((data.name === 'Write' || data.name === 'Edit') && data.input?.file_path) {
|
|
2699
2703
|
const fp = data.input.file_path;
|
|
@@ -3128,11 +3132,11 @@ async function main() {
|
|
|
3128
3132
|
// Wire up Claude events to frontend
|
|
3129
3133
|
realtimeClaudeHandler.events.on('tool_use', (data) => {
|
|
3130
3134
|
console.log(`🔧 Claude: ${data.name}`);
|
|
3131
|
-
sendToFrontend(buildToolLogEvent(data.name, data.input, 'running', '
|
|
3135
|
+
sendToFrontend(buildToolLogEvent(data.name, data.input, 'running', data.agentRole || 'main'));
|
|
3132
3136
|
});
|
|
3133
3137
|
realtimeClaudeHandler.events.on('tool_result', (data) => {
|
|
3134
3138
|
console.log(`✅ Done: ${data.name}`);
|
|
3135
|
-
sendToFrontend(buildToolLogEvent(data.name, data.input, 'completed', '
|
|
3139
|
+
sendToFrontend(buildToolLogEvent(data.name, data.input, 'completed', data.agentRole || 'main'));
|
|
3136
3140
|
// Detect research artifact writes (session workspace or legacy research dir)
|
|
3137
3141
|
if ((data.name === 'Write' || data.name === 'Edit') && data.input?.file_path) {
|
|
3138
3142
|
const fp = data.input.file_path;
|
|
@@ -21,8 +21,6 @@ export interface InterruptionContext {
|
|
|
21
21
|
* and can re-articulate the relevant bits in its next response.
|
|
22
22
|
*/
|
|
23
23
|
suppressedText: string;
|
|
24
|
-
/** Full text of the interrupted TTS block — fallback when JSONL read returns empty */
|
|
25
|
-
fullBlockText?: string;
|
|
26
24
|
}
|
|
27
25
|
export interface PipelineDirectOptions extends ClaudeLLMOptions {
|
|
28
26
|
onFastBrainResult?: (result: FastBrainPanelResult) => void;
|
|
@@ -122,10 +122,7 @@ export class PipelineDirectLLM extends llm.LLM {
|
|
|
122
122
|
`Anything in "Your recent messages" below that appears AFTER the quoted heard text is content the user did not hear. The user has no memory of it.`,
|
|
123
123
|
``,
|
|
124
124
|
`Your recent messages (full untruncated — you wrote these):`,
|
|
125
|
-
interruptCtx.recentMessages
|
|
126
|
-
|| (interruptCtx.fullBlockText
|
|
127
|
-
? `(JSONL unavailable — full TTS block text follows)\n"${interruptCtx.fullBlockText}"`
|
|
128
|
-
: '(no recent messages found)'),
|
|
125
|
+
interruptCtx.recentMessages || '(no recent messages found)',
|
|
129
126
|
suppressedBlock,
|
|
130
127
|
``,
|
|
131
128
|
`User's message: "${userText}"`,
|