Add onCompleted callback system for guaranteed console log delivery

- Add onCompleted() callback registration in RuntimeMessageBridge
- Modify wrapperFunction to call completion callbacks before returning
- Update ConsoleRuntimeProvider to immediate send + completion batch pattern
- Extract DOWNLOADABLE_FILE_RUNTIME_DESCRIPTION from ATTACHMENTS_RUNTIME_DESCRIPTION
- Logs sent immediately (fire-and-forget), unsent logs batched at completion
- Ensures all console logs arrive before tool execution completes
This commit is contained in:
Mario Zechner 2025-10-09 20:03:51 +02:00
parent b288cd9448
commit af0297cd16
4 changed files with 70 additions and 20 deletions

View file

@ -25,7 +25,7 @@ export class ConsoleRuntimeProvider implements SandboxRuntimeProvider {
getRuntime(): (sandboxId: string) => void {
return (_sandboxId: string) => {
// Console capture
// Console capture with immediate send + completion batch pattern
const originalConsole = {
log: console.log,
error: console.error,
@ -33,6 +33,9 @@ export class ConsoleRuntimeProvider implements SandboxRuntimeProvider {
info: console.info,
};
// Track pending logs (not yet confirmed sent)
const pendingLogs: Array<{ method: string; text: string; args: any[] }> = [];
["log", "error", "warn", "info"].forEach((method) => {
(console as any)[method] = (...args: any[]) => {
const text = args
@ -45,7 +48,12 @@ export class ConsoleRuntimeProvider implements SandboxRuntimeProvider {
})
.join(" ");
// Send to extension if available (online mode)
const logEntry = { method, text, args };
// Add to pending logs
pendingLogs.push(logEntry);
// Try to send immediately (fire-and-forget)
if ((window as any).sendRuntimeMessage) {
(window as any)
.sendRuntimeMessage({
@ -54,8 +62,15 @@ export class ConsoleRuntimeProvider implements SandboxRuntimeProvider {
text,
args, // Send raw args for provider collection
})
.then(() => {
// Remove from pending on successful send
const index = pendingLogs.indexOf(logEntry);
if (index !== -1) {
pendingLogs.splice(index, 1);
}
})
.catch(() => {
// Ignore errors in fire-and-forget console messages
// Keep in pending array if send fails
});
}
@ -64,6 +79,25 @@ export class ConsoleRuntimeProvider implements SandboxRuntimeProvider {
};
});
// Register completion callback to send any remaining logs
if ((window as any).onCompleted) {
(window as any).onCompleted(async (_success: boolean) => {
// Send any logs that haven't been sent yet
if (pendingLogs.length > 0 && (window as any).sendRuntimeMessage) {
await Promise.all(
pendingLogs.map((logEntry) =>
(window as any).sendRuntimeMessage({
type: "console",
method: logEntry.method,
text: logEntry.text,
args: logEntry.args,
}),
),
);
}
});
}
// Track errors for HTML artifacts
let lastError: { message: string; stack: string } | null = null;