@nomad-e/bluma-cli 0.1.47 → 0.1.49
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/README.md +153 -27
- package/dist/main.js +181 -121
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -4,7 +4,9 @@
|
|
|
4
4
|
[](LICENSE)
|
|
5
5
|
[](https://nodejs.org/)
|
|
6
6
|
|
|
7
|
-
**BluMa** is a CLI-based model agent for advanced software engineering workflows. Built with React/Ink 5, it provides an interactive terminal interface for LLM-powered automation, code generation, refactoring, and task execution. Features persistent sessions, contextual reasoning, smart feedback, and extensible tools/skills architecture.
|
|
7
|
+
**BluMa** is a CLI-based model agent for advanced software engineering workflows. Built with React/Ink 5, it provides an interactive terminal interface for LLM-powered automation, code generation, refactoring, and task execution. Features persistent sessions, contextual reasoning, smart feedback, coordinator mode for worker orchestration, and extensible tools/skills architecture.
|
|
8
|
+
|
|
9
|
+
**Current Version:** 0.1.47
|
|
8
10
|
|
|
9
11
|
---
|
|
10
12
|
|
|
@@ -34,8 +36,8 @@ BluMa operates as a **conversational agent** in the terminal, combining:
|
|
|
34
36
|
|
|
35
37
|
- **Rich UI Layer**: React/Ink 5 components for interactive prompts, live overlays, and real-time feedback
|
|
36
38
|
- **Agent Layer**: LLM orchestration via FactorRouter with tool invocation and context management
|
|
37
|
-
- **Runtime Layer**: Task tracking, plugin system, hooks, diagnostics, and
|
|
38
|
-
- **Tool Layer**:
|
|
39
|
+
- **Runtime Layer**: Task tracking, plugin system, hooks, diagnostics, session management, and coordinator mode
|
|
40
|
+
- **Tool Layer**: 40+ native tools + MCP SDK integration for external tools
|
|
39
41
|
|
|
40
42
|
The agent maintains persistent conversation history, workspace snapshots, and coding memory across sessions.
|
|
41
43
|
|
|
@@ -60,7 +62,8 @@ The agent maintains persistent conversation history, workspace snapshots, and co
|
|
|
60
62
|
- **Tool Execution Policy**: Intelligent decisions based on sandbox mode and safety
|
|
61
63
|
|
|
62
64
|
### Tools & Skills
|
|
63
|
-
- **
|
|
65
|
+
- **40+ Native Tools**: File operations, search, shell commands, web fetch, agent coordination, task management, MCP resources, cron scheduling, LSP queries, notebook editing
|
|
66
|
+
- **Coordinator Mode**: Orchestrator playbook for delegating work to background workers
|
|
64
67
|
- **MCP Integration**: Model Context Protocol SDK for external tool servers
|
|
65
68
|
- **Skills System**: Pluggable knowledge modules (git, PDF, Excel, etc.)
|
|
66
69
|
- **Agent Coordination**: Spawn/wait/list subagents for parallel work
|
|
@@ -220,15 +223,26 @@ npm start
|
|
|
220
223
|
│ │Sandbox │ │ToolExec │ │Diagnostics│ │SessionView │ │
|
|
221
224
|
│ │Policy │ │Policy │ │ │ │ │ │
|
|
222
225
|
│ └──────────┘ └──────────┘ └──────────┘ └──────────────┘ │
|
|
226
|
+
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────────┐ │
|
|
227
|
+
│ │Feature │ │Plan Mode │ │Tool Auto │ │Tool Permission│ │
|
|
228
|
+
│ │Flags │ │Session │ │Approve │ │Classifier │ │
|
|
229
|
+
│ └──────────┘ └──────────┘ └──────────┘ └──────────────┘ │
|
|
223
230
|
└─────────────────────────────────────────────────────────────┘
|
|
224
231
|
│
|
|
225
232
|
┌────────────────────────┼────────────────────────────────────┐
|
|
226
233
|
│ Tools Layer │
|
|
227
234
|
│ ┌──────────────────────────────────────────────────────┐ │
|
|
228
|
-
│ │ Native Tools (
|
|
235
|
+
│ │ Native Tools (40+) │ │
|
|
229
236
|
│ │ edit_tool, file_write, shell_command, grep_search, │ │
|
|
230
|
-
│ │ spawn_agent,
|
|
231
|
-
│ │
|
|
237
|
+
│ │ spawn_agent, wait_agent, list_agents, │ │
|
|
238
|
+
│ │ todo, task_boundary, task_create, task_list, │ │
|
|
239
|
+
│ │ task_get, task_update, task_stop, │ │
|
|
240
|
+
│ │ coding_memory, search_web, web_fetch, load_skill, │ │
|
|
241
|
+
│ │ message, ask_user_question, │ │
|
|
242
|
+
│ │ list_mcp_resources, read_mcp_resource, │ │
|
|
243
|
+
│ │ cron_create, cron_list, cron_delete, │ │
|
|
244
|
+
│ │ lsp_query, notebook_edit, │ │
|
|
245
|
+
│ │ enter_plan_mode, exit_plan_mode, ... │ │
|
|
232
246
|
│ └──────────────────────────────────────────────────────┘ │
|
|
233
247
|
│ ┌──────────────────────────────────────────────────────┐ │
|
|
234
248
|
│ │ MCP SDK Integration │ │
|
|
@@ -241,26 +255,27 @@ npm start
|
|
|
241
255
|
|
|
242
256
|
## Native Tools
|
|
243
257
|
|
|
244
|
-
BluMa includes
|
|
258
|
+
BluMa includes **40+ built-in tools** organized by category:
|
|
245
259
|
|
|
246
260
|
### File Operations
|
|
247
261
|
| Tool | Description |
|
|
248
262
|
|------|-------------|
|
|
249
|
-
| `edit_tool` | Replace text in files (precise, multi-line) |
|
|
263
|
+
| `edit_tool` | Replace text in files (precise, multi-line, batch edits) |
|
|
250
264
|
| `file_write` | Create/overwrite entire files |
|
|
251
|
-
| `read_file_lines` | Read specific line ranges |
|
|
265
|
+
| `read_file_lines` | Read specific line ranges (up to 2000 lines) |
|
|
252
266
|
| `count_file_lines` | Get file line count |
|
|
253
|
-
| `ls_tool` | List directories with filtering |
|
|
267
|
+
| `ls_tool` | List directories with filtering and pagination |
|
|
254
268
|
| `find_by_name` | Glob-based file search |
|
|
255
269
|
| `grep_search` | Text/regex search across files |
|
|
256
|
-
| `view_file_outline` | Show code structure (classes, functions) |
|
|
270
|
+
| `view_file_outline` | Show code structure (classes, functions, interfaces) |
|
|
271
|
+
| `notebook_edit` | Edit Jupyter `.ipynb` files (cells operations) |
|
|
257
272
|
|
|
258
273
|
### Shell & Commands
|
|
259
274
|
| Tool | Description |
|
|
260
275
|
|------|-------------|
|
|
261
276
|
| `shell_command` | Execute background commands |
|
|
262
277
|
| `command_status` | Check command progress/output |
|
|
263
|
-
| `send_command_input` | Send input to running commands |
|
|
278
|
+
| `send_command_input` | Send input to running commands' stdin |
|
|
264
279
|
| `kill_command` | Terminate running commands |
|
|
265
280
|
|
|
266
281
|
### Agent Coordination
|
|
@@ -275,6 +290,11 @@ BluMa includes 25+ built-in tools organized by category:
|
|
|
275
290
|
|------|-------------|
|
|
276
291
|
| `todo` | Manage task lists |
|
|
277
292
|
| `task_boundary` | Track task phases (PLANNING/EXECUTION/VERIFICATION) |
|
|
293
|
+
| `task_create` | Create session-scoped tasks |
|
|
294
|
+
| `task_list` | List all session tasks |
|
|
295
|
+
| `task_get` | Get one task by id |
|
|
296
|
+
| `task_update` | Update task fields |
|
|
297
|
+
| `task_stop` | Cancel a task |
|
|
278
298
|
| `create_artifact` | Save documents to `~/.bluma/artifacts/` |
|
|
279
299
|
| `read_artifact` | Retrieve saved artifacts |
|
|
280
300
|
|
|
@@ -284,12 +304,37 @@ BluMa includes 25+ built-in tools organized by category:
|
|
|
284
304
|
| `search_web` | Search programming solutions (Reddit, GitHub, StackOverflow) |
|
|
285
305
|
| `web_fetch` | Fetch and analyze remote URLs |
|
|
286
306
|
| `load_skill` | Activate domain-specific skills |
|
|
287
|
-
| `coding_memory` |
|
|
307
|
+
| `coding_memory` | CRUD for persistent coding notes |
|
|
288
308
|
|
|
289
|
-
### Communication
|
|
309
|
+
### Communication & Interaction
|
|
290
310
|
| Tool | Description |
|
|
291
311
|
|------|-------------|
|
|
292
312
|
| `message` | Post user-visible chat (info/result types) |
|
|
313
|
+
| `ask_user_question` | Ask multiple-choice questions in terminal |
|
|
314
|
+
|
|
315
|
+
### MCP & Resources
|
|
316
|
+
| Tool | Description |
|
|
317
|
+
|------|-------------|
|
|
318
|
+
| `list_mcp_resources` | List resources from MCP servers |
|
|
319
|
+
| `read_mcp_resource` | Read a resource URI from MCP server |
|
|
320
|
+
|
|
321
|
+
### Scheduling
|
|
322
|
+
| Tool | Description |
|
|
323
|
+
|------|-------------|
|
|
324
|
+
| `cron_create` | Schedule one-shot or repeating reminders |
|
|
325
|
+
| `cron_list` | List scheduled cron jobs |
|
|
326
|
+
| `cron_delete` | Cancel scheduled job |
|
|
327
|
+
|
|
328
|
+
### Development Tools
|
|
329
|
+
| Tool | Description |
|
|
330
|
+
|------|-------------|
|
|
331
|
+
| `lsp_query` | LSP go-to-definition or references (TS/JS) |
|
|
332
|
+
|
|
333
|
+
### Plan Mode
|
|
334
|
+
| Tool | Description |
|
|
335
|
+
|------|-------------|
|
|
336
|
+
| `enter_plan_mode` | Enter plan-only mode (edits require confirmation) |
|
|
337
|
+
| `exit_plan_mode` | Leave plan mode |
|
|
293
338
|
|
|
294
339
|
---
|
|
295
340
|
|
|
@@ -461,6 +506,8 @@ Built-in terminal commands (type `/` to see all):
|
|
|
461
506
|
| `/img ./shot.png [question]` | Send local image(s) to the model |
|
|
462
507
|
| `/image` | Alias of /img |
|
|
463
508
|
| `/init` | Run init subagent — BluMa.md codebase documentation |
|
|
509
|
+
| `/agent [default\|coordinator]` | Set prompt profile (coordinator playbook for worker orchestration) |
|
|
510
|
+
| `/agents` | List worker/agent sessions (spawn_agent children) |
|
|
464
511
|
|
|
465
512
|
### Inspect
|
|
466
513
|
| Command | Description |
|
|
@@ -468,7 +515,7 @@ Built-in terminal commands (type `/` to see all):
|
|
|
468
515
|
| `/plugins` | List installed plugins and plugin paths |
|
|
469
516
|
| `/plugin <name>` | Inspect one plugin |
|
|
470
517
|
| `/diagnostics` | Show a consolidated health snapshot |
|
|
471
|
-
| `/permissions` | Inspect sandbox and tool
|
|
518
|
+
| `/permissions` | Inspect sandbox and tool rules; set mode |
|
|
472
519
|
| `/hooks` | Inspect, enable, disable, or clear lifecycle hooks |
|
|
473
520
|
| `/model [list\|name\|auto]` | Show, list, or set the active model |
|
|
474
521
|
| `/effort [low\|medium\|high]` | Show or set reasoning effort |
|
|
@@ -479,6 +526,7 @@ Built-in terminal commands (type `/` to see all):
|
|
|
479
526
|
| `/skills` | List load_skill modules, dirs, and conflicts |
|
|
480
527
|
| `/tools [grep]` | List native tools (optional filter) |
|
|
481
528
|
| `/mcp [fs]` | List MCP tools (optional filter) |
|
|
529
|
+
| `/features` | Feature flags: `/features` or `/features <key> on\|off` |
|
|
482
530
|
|
|
483
531
|
### Help
|
|
484
532
|
| Command | Description |
|
|
@@ -488,8 +536,8 @@ Built-in terminal commands (type `/` to see all):
|
|
|
488
536
|
### Input (Keyboard Shortcuts)
|
|
489
537
|
| Shortcut | Description |
|
|
490
538
|
|----------|-------------|
|
|
491
|
-
| `Ctrl+V / Cmd+V` | Paste from clipboard: image →
|
|
492
|
-
| `Ctrl+Shift+I` | Same as Ctrl+V
|
|
539
|
+
| `Ctrl+V / Cmd+V` | Paste from clipboard: image → cache `~/.cache/bluma/clipboard`; text; or file path as image |
|
|
540
|
+
| `Ctrl+Shift+I` | Same as Ctrl+V (paste image, text, or file path) |
|
|
493
541
|
|
|
494
542
|
---
|
|
495
543
|
|
|
@@ -517,6 +565,12 @@ src/
|
|
|
517
565
|
│ ├── agent/
|
|
518
566
|
│ │ ├── agent.ts # Main orchestrator
|
|
519
567
|
│ │ ├── bluma/ # Core agent logic
|
|
568
|
+
│ │ │ ├── core/
|
|
569
|
+
│ │ │ │ └── bluma.ts # BluMaAgent class
|
|
570
|
+
│ │ │ └── turn_start_payload.ts # Backend turn payload
|
|
571
|
+
│ │ ├── config/
|
|
572
|
+
│ │ │ ├── native_tools.json # Tool definitions (40+)
|
|
573
|
+
│ │ │ └── skills/ # Bundled skills (git-commit, git-pr, pdf, xlsx, skill-creator)
|
|
520
574
|
│ │ ├── core/ # LLM, context, prompts
|
|
521
575
|
│ │ │ ├── context-api/ # Context management
|
|
522
576
|
│ │ │ │ ├── context_manager.ts # Token-aware context
|
|
@@ -528,41 +582,80 @@ src/
|
|
|
528
582
|
│ │ │ └── prompt/ # Prompt engineering
|
|
529
583
|
│ │ │ ├── prompt_builder.ts # Dynamic prompts
|
|
530
584
|
│ │ │ └── workspace_snapshot.ts
|
|
585
|
+
│ │ ├── feedback/
|
|
586
|
+
│ │ │ └── feedback_system.ts # Smart feedback system
|
|
531
587
|
│ │ ├── runtime/ # Orchestration layer (v0.1.41+)
|
|
532
588
|
│ │ │ ├── diagnostics.ts # System snapshots
|
|
589
|
+
│ │ │ ├── feature_flags.ts # Feature gates
|
|
533
590
|
│ │ │ ├── hook_registry.ts # Event-driven hooks
|
|
534
591
|
│ │ │ ├── native_tool_catalog.ts # Tool registry
|
|
592
|
+
│ │ │ ├── plan_mode_session.ts # Plan mode state
|
|
535
593
|
│ │ │ ├── plugin_registry.ts # Plugin system
|
|
594
|
+
│ │ │ ├── plugin_runtime.ts # Plugin execution
|
|
536
595
|
│ │ │ ├── runtime_config.ts # Runtime settings
|
|
537
596
|
│ │ │ ├── sandbox_policy.ts # Safety policies
|
|
538
597
|
│ │ │ ├── session_registry.ts # Multi-session mgmt
|
|
539
598
|
│ │ │ ├── session_view.ts # Session monitoring
|
|
540
599
|
│ │ │ ├── task_store.ts # Task lifecycle
|
|
541
|
-
│ │ │
|
|
542
|
-
│ │ ├──
|
|
543
|
-
│ │ │
|
|
600
|
+
│ │ │ ├── tool_auto_approve.ts # Auto-approve rules
|
|
601
|
+
│ │ │ ├── tool_execution_policy.ts
|
|
602
|
+
│ │ │ ├── tool_orchestration.ts # Parallel read eligibility
|
|
603
|
+
│ │ │ └── tool_permission_classifier.ts
|
|
604
|
+
│ │ ├── session_manager/
|
|
605
|
+
│ │ │ └── session_manager.ts # Session persistence
|
|
606
|
+
│ │ ├── skills/
|
|
607
|
+
│ │ │ └── skill_loader.ts # Skill loading
|
|
608
|
+
│ │ ├── subagents/ # Subagent system
|
|
609
|
+
│ │ │ ├── base_llm_subagent.ts
|
|
610
|
+
│ │ │ ├── init/ # Init subagent (BluMa.md)
|
|
611
|
+
│ │ │ ├── registry.ts
|
|
612
|
+
│ │ │ ├── subagents_bluma.ts
|
|
613
|
+
│ │ │ └── types.ts
|
|
614
|
+
│ │ ├── tools/
|
|
615
|
+
│ │ │ ├── mcp/
|
|
616
|
+
│ │ │ │ └── mcp_client.ts # MCP SDK client
|
|
617
|
+
│ │ │ └── natives/ # 27 native tool implementations
|
|
544
618
|
│ │ │ ├── agent_coordination.ts
|
|
619
|
+
│ │ │ ├── ask_user_question.ts
|
|
545
620
|
│ │ │ ├── async_command.ts
|
|
546
621
|
│ │ │ ├── coding_memory.ts
|
|
622
|
+
│ │ │ ├── coding_memory_consolidate.ts
|
|
623
|
+
│ │ │ ├── coordinator_tools.ts
|
|
624
|
+
│ │ │ ├── count_lines.ts
|
|
547
625
|
│ │ │ ├── edit.ts
|
|
548
626
|
│ │ │ ├── file_write.ts
|
|
549
627
|
│ │ │ ├── find_by_name.ts
|
|
550
628
|
│ │ │ ├── grep_search.ts
|
|
551
629
|
│ │ │ ├── load_skill.ts
|
|
552
630
|
│ │ │ ├── ls.ts
|
|
631
|
+
│ │ │ ├── lsp_query.ts
|
|
632
|
+
│ │ │ ├── mcp_resources.ts
|
|
553
633
|
│ │ │ ├── message.ts
|
|
634
|
+
│ │ │ ├── notebook_edit.ts
|
|
635
|
+
│ │ │ ├── plan_mode_tools.ts
|
|
554
636
|
│ │ │ ├── readLines.ts
|
|
555
637
|
│ │ │ ├── search_web.ts
|
|
638
|
+
│ │ │ ├── session_cron.ts
|
|
556
639
|
│ │ │ ├── shell_command.ts
|
|
557
640
|
│ │ │ ├── task_boundary.ts
|
|
641
|
+
│ │ │ ├── task_tools.ts
|
|
558
642
|
│ │ │ ├── todo.ts
|
|
559
643
|
│ │ │ ├── view_file_outline.ts
|
|
560
644
|
│ │ │ └── web_fetch.ts
|
|
561
|
-
│ │
|
|
645
|
+
│ │ ├── types/
|
|
646
|
+
│ │ │ └── index.ts
|
|
647
|
+
│ │ └── utils/
|
|
648
|
+
│ │ ├── coordinator_prompt.ts # Coordinator mode playbook
|
|
649
|
+
│ │ ├── update_check.ts
|
|
650
|
+
│ │ └── user_message_images.ts
|
|
562
651
|
│ └── ui/
|
|
563
652
|
│ ├── App.tsx # Main UI component
|
|
564
|
-
│ ├──
|
|
653
|
+
│ ├── Asci/
|
|
654
|
+
│ │ └── AsciiArt.ts
|
|
655
|
+
│ ├── components/ # 24+ UI components
|
|
565
656
|
│ │ ├── AnimatedBorder.tsx
|
|
657
|
+
│ │ ├── AskUserQuestionPrompt.tsx
|
|
658
|
+
│ │ ├── AssistantMessageDisplay.tsx
|
|
566
659
|
│ │ ├── CollapsibleResult.tsx
|
|
567
660
|
│ │ ├── EditToolDiffPanel.tsx # Diff preview for edits
|
|
568
661
|
│ │ ├── ErrorMessage.tsx
|
|
@@ -573,20 +666,44 @@ src/
|
|
|
573
666
|
│ │ ├── ReasoningDisplay.tsx # LLM reasoning
|
|
574
667
|
│ │ ├── SessionStats.tsx
|
|
575
668
|
│ │ ├── SimpleDiff.tsx
|
|
576
|
-
│ │ ├── SlashCommands.tsx #
|
|
669
|
+
│ │ ├── SlashCommands.tsx # 30+ commands
|
|
577
670
|
│ │ ├── StatusNotification.tsx
|
|
578
671
|
│ │ ├── StreamingText.tsx # Live text output
|
|
579
672
|
│ │ ├── TodoPlanDisplay.tsx # Task visualization
|
|
580
673
|
│ │ ├── ToolCallDisplay.tsx
|
|
674
|
+
│ │ ├── ToolInvocationBlock.tsx
|
|
581
675
|
│ │ ├── ToolResultCard.tsx # Structured results
|
|
582
676
|
│ │ ├── ToolResultDisplay.tsx
|
|
583
677
|
│ │ ├── TypewriterText.tsx
|
|
584
678
|
│ │ ├── UpdateNotice.tsx
|
|
679
|
+
│ │ ├── streamingTextFlush.ts
|
|
585
680
|
│ │ └── toolCallRenderers.tsx
|
|
586
|
-
│ ├──
|
|
587
|
-
│
|
|
681
|
+
│ ├── constants/
|
|
682
|
+
│ │ ├── historyLayout.ts
|
|
683
|
+
│ │ ├── inputPaste.ts
|
|
684
|
+
│ │ └── toolUiPreview.ts
|
|
685
|
+
│ ├── hooks/
|
|
686
|
+
│ │ └── useAtCompletion.ts
|
|
687
|
+
│ ├── theme/
|
|
688
|
+
│ │ ├── blumaTerminal.ts
|
|
689
|
+
│ │ └── m3Layout.tsx
|
|
690
|
+
│ └── utils/
|
|
691
|
+
│ ├── clipboardImage.ts
|
|
692
|
+
│ ├── editToolDiffUtils.ts
|
|
693
|
+
│ ├── expandPreviewHotkey.ts
|
|
694
|
+
│ ├── expandablePreviewStore.ts
|
|
695
|
+
│ ├── formatTurnDurationMs.ts
|
|
696
|
+
│ ├── inlineImageInputLabels.ts
|
|
697
|
+
│ ├── pathDisplay.ts
|
|
698
|
+
│ ├── shellToolNames.ts
|
|
699
|
+
│ ├── slashRegistry.ts
|
|
700
|
+
│ ├── terminalTitle.ts
|
|
701
|
+
│ ├── toolDisplayLabels.ts
|
|
702
|
+
│ ├── toolInvocationPairing.ts
|
|
703
|
+
│ └── useSimpleInputBuffer.ts
|
|
588
704
|
├── main.ts # Entry point
|
|
589
|
-
└── types/
|
|
705
|
+
└── types/
|
|
706
|
+
└── semver-functions.d.ts
|
|
590
707
|
```
|
|
591
708
|
|
|
592
709
|
---
|
|
@@ -679,6 +796,12 @@ BluMa's runtime layer provides enterprise-grade orchestration:
|
|
|
679
796
|
| `session_view.ts` | Session monitoring | Log streaming, status display |
|
|
680
797
|
| `native_tool_catalog.ts` | Tool registry | Discovery and metadata |
|
|
681
798
|
| `runtime_config.ts` | Settings | Runtime configuration management |
|
|
799
|
+
| `feature_flags.ts` | Feature gates | Opt-in features via env or settings |
|
|
800
|
+
| `plan_mode_session.ts` | Plan mode | Forces confirmation for edits/writes |
|
|
801
|
+
| `tool_auto_approve.ts` | Auto-approve | Effective approve rules |
|
|
802
|
+
| `tool_orchestration.ts` | Parallel reads | Eligibility for parallel execution |
|
|
803
|
+
| `tool_permission_classifier` | Tool classification | Classify tool invocations |
|
|
804
|
+
| `plugin_runtime.ts` | Plugin execution | Plugin runtime context |
|
|
682
805
|
|
|
683
806
|
### UI Components
|
|
684
807
|
|
|
@@ -696,6 +819,9 @@ Key UI components that power the rich terminal experience:
|
|
|
696
819
|
| `AnimatedBorder.tsx` | Visual feedback for active elements |
|
|
697
820
|
| `CollapsibleResult.tsx` | Expandable result sections |
|
|
698
821
|
| `ProgressBar.tsx` | Progress indicators |
|
|
822
|
+
| `AskUserQuestionPrompt.tsx` | Multiple-choice question UI |
|
|
823
|
+
| `ToolInvocationBlock.tsx` | Tool call visualization |
|
|
824
|
+
| `AssistantMessageDisplay.tsx` | Assistant message formatting |
|
|
699
825
|
|
|
700
826
|
---
|
|
701
827
|
|
package/dist/main.js
CHANGED
|
@@ -10234,9 +10234,9 @@ var BluMaAgent = class {
|
|
|
10234
10234
|
this.mcpClient = mcpClient;
|
|
10235
10235
|
this.feedbackSystem = feedbackSystem;
|
|
10236
10236
|
this.skillLoader = new SkillLoader(process.cwd());
|
|
10237
|
-
this.eventBus.on("user_interrupt", () => {
|
|
10237
|
+
this.eventBus.on("user_interrupt", async () => {
|
|
10238
10238
|
this.isInterrupted = true;
|
|
10239
|
-
|
|
10239
|
+
await this.notifyFactorTurnEndIfNeeded("user_interrupt");
|
|
10240
10240
|
this.eventBus.emit("backend_message", { type: "done", status: "interrupted" });
|
|
10241
10241
|
});
|
|
10242
10242
|
this.eventBus.on("user_overlay", async (data) => {
|
|
@@ -10475,9 +10475,8 @@ var BluMaAgent = class {
|
|
|
10475
10475
|
}
|
|
10476
10476
|
}
|
|
10477
10477
|
}
|
|
10478
|
-
const skipEditDiffRepeat = toolName === "edit_tool" && decisionData.editPreviewAlreadyShown === true;
|
|
10479
10478
|
let previewContent;
|
|
10480
|
-
if (toolName === "edit_tool"
|
|
10479
|
+
if (toolName === "edit_tool") {
|
|
10481
10480
|
try {
|
|
10482
10481
|
previewContent = await this._generateEditPreview(toolArgs);
|
|
10483
10482
|
} catch (previewError) {
|
|
@@ -10490,7 +10489,7 @@ var BluMaAgent = class {
|
|
|
10490
10489
|
tool_name: toolName,
|
|
10491
10490
|
arguments: toolArgs,
|
|
10492
10491
|
preview: previewContent,
|
|
10493
|
-
suppress_edit_diff_preview:
|
|
10492
|
+
suppress_edit_diff_preview: false,
|
|
10494
10493
|
tool_policy: this.buildToolPolicyForUi(toolName, toolArgs)
|
|
10495
10494
|
});
|
|
10496
10495
|
try {
|
|
@@ -10553,7 +10552,7 @@ var BluMaAgent = class {
|
|
|
10553
10552
|
tool_name: toolName,
|
|
10554
10553
|
arguments: toolArgs,
|
|
10555
10554
|
result: toolResultContent,
|
|
10556
|
-
suppress_edit_diff:
|
|
10555
|
+
suppress_edit_diff: false
|
|
10557
10556
|
});
|
|
10558
10557
|
if (toolName === "message") {
|
|
10559
10558
|
try {
|
|
@@ -10782,6 +10781,10 @@ ${editData.error.display}`;
|
|
|
10782
10781
|
reason
|
|
10783
10782
|
});
|
|
10784
10783
|
}
|
|
10784
|
+
/** Fecho explícito de turno (útil para workers antes de process.exit). */
|
|
10785
|
+
async closeActiveTurn(reason = "worker_exit") {
|
|
10786
|
+
await this.notifyFactorTurnEndIfNeeded(reason);
|
|
10787
|
+
}
|
|
10785
10788
|
async _continueConversation() {
|
|
10786
10789
|
try {
|
|
10787
10790
|
if (this.isInterrupted) {
|
|
@@ -10807,7 +10810,7 @@ ${editData.error.display}`;
|
|
|
10807
10810
|
} catch (error) {
|
|
10808
10811
|
const errorMessage = error instanceof Error ? error.message : "An unknown API error occurred.";
|
|
10809
10812
|
this.eventBus.emit("backend_message", { type: "error", message: errorMessage });
|
|
10810
|
-
|
|
10813
|
+
await this.notifyFactorTurnEndIfNeeded("llm_error");
|
|
10811
10814
|
this.eventBus.emit("backend_message", { type: "done", status: "failed" });
|
|
10812
10815
|
} finally {
|
|
10813
10816
|
this.persistSession();
|
|
@@ -11721,6 +11724,10 @@ var Agent = class {
|
|
|
11721
11724
|
}
|
|
11722
11725
|
await this.routeManager.handleRoute({ content: inputText, userContext: resolvedUserContext });
|
|
11723
11726
|
}
|
|
11727
|
+
/** Fecha o turno ativo no FactorRouter (idempotente). */
|
|
11728
|
+
async closeActiveTurn(reason = "worker_exit") {
|
|
11729
|
+
await this.core.closeActiveTurn(reason);
|
|
11730
|
+
}
|
|
11724
11731
|
/**
|
|
11725
11732
|
* Handler para o comando /coordinator
|
|
11726
11733
|
* /coordinator enable - Ativa o Coordinator Mode
|
|
@@ -14607,6 +14614,14 @@ var AskUserQuestionPrompt = memo14(AskUserQuestionPromptComponent);
|
|
|
14607
14614
|
import { jsx as jsx24, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
14608
14615
|
var MAX_STATIC_HISTORY_ITEMS = 220;
|
|
14609
14616
|
var blumaUpdateRegistryCheckStarted = false;
|
|
14617
|
+
function nextHistoryId(items) {
|
|
14618
|
+
if (items.length === 0) return HEADER_PANEL_HISTORY_ID + 1;
|
|
14619
|
+
let maxId = HEADER_PANEL_HISTORY_ID;
|
|
14620
|
+
for (const it of items) {
|
|
14621
|
+
if (typeof it.id === "number" && it.id > maxId) maxId = it.id;
|
|
14622
|
+
}
|
|
14623
|
+
return maxId + 1;
|
|
14624
|
+
}
|
|
14610
14625
|
function trimRecentActivity(s, max = 72) {
|
|
14611
14626
|
const t = String(s ?? "").replace(/\s+/g, " ").trim();
|
|
14612
14627
|
if (!t) return "";
|
|
@@ -14740,13 +14755,16 @@ var AppComponent = ({ eventBus, sessionId, cliVersion }) => {
|
|
|
14740
14755
|
turnStartedAtRef.current = null;
|
|
14741
14756
|
setProcessingStartMs(null);
|
|
14742
14757
|
setIsProcessing(false);
|
|
14743
|
-
setHistory((prev) =>
|
|
14744
|
-
|
|
14745
|
-
|
|
14746
|
-
|
|
14747
|
-
|
|
14748
|
-
|
|
14749
|
-
|
|
14758
|
+
setHistory((prev) => {
|
|
14759
|
+
const id = nextHistoryId(prev);
|
|
14760
|
+
return [
|
|
14761
|
+
...prev,
|
|
14762
|
+
{
|
|
14763
|
+
id,
|
|
14764
|
+
component: /* @__PURE__ */ jsx24(ChatMeta, { children: "cancelled (Esc)" })
|
|
14765
|
+
}
|
|
14766
|
+
];
|
|
14767
|
+
});
|
|
14750
14768
|
}, [isProcessing, eventBus]);
|
|
14751
14769
|
const handleSubmit = useCallback3(
|
|
14752
14770
|
(text) => {
|
|
@@ -14754,13 +14772,16 @@ var AppComponent = ({ eventBus, sessionId, cliVersion }) => {
|
|
|
14754
14772
|
const trimmedForSlash = text.trim();
|
|
14755
14773
|
if (isProcessing && !isSlashRoutingLine(trimmedForSlash)) {
|
|
14756
14774
|
if (trimmedForSlash.startsWith("/")) {
|
|
14757
|
-
setHistory((prev) =>
|
|
14758
|
-
|
|
14759
|
-
|
|
14760
|
-
|
|
14761
|
-
|
|
14762
|
-
|
|
14763
|
-
|
|
14775
|
+
setHistory((prev) => {
|
|
14776
|
+
const id = nextHistoryId(prev);
|
|
14777
|
+
return [
|
|
14778
|
+
...prev,
|
|
14779
|
+
{
|
|
14780
|
+
id,
|
|
14781
|
+
component: /* @__PURE__ */ jsx24(ChatMeta, { children: "Slash command not recognized or incomplete. Type /help for the list." })
|
|
14782
|
+
}
|
|
14783
|
+
];
|
|
14784
|
+
});
|
|
14764
14785
|
}
|
|
14765
14786
|
return;
|
|
14766
14787
|
}
|
|
@@ -14769,13 +14790,16 @@ var AppComponent = ({ eventBus, sessionId, cliVersion }) => {
|
|
|
14769
14790
|
if (/^\/img\s+/i.test(text) || /^\/image\s+/i.test(text)) {
|
|
14770
14791
|
const payload = text.replace(/^\/img\s+/i, "").replace(/^\/image\s+/i, "").trim();
|
|
14771
14792
|
if (!payload) {
|
|
14772
|
-
setHistory((prev) =>
|
|
14773
|
-
|
|
14774
|
-
|
|
14775
|
-
|
|
14776
|
-
|
|
14777
|
-
|
|
14778
|
-
|
|
14793
|
+
setHistory((prev) => {
|
|
14794
|
+
const id = nextHistoryId(prev);
|
|
14795
|
+
return [
|
|
14796
|
+
...prev,
|
|
14797
|
+
{
|
|
14798
|
+
id,
|
|
14799
|
+
component: /* @__PURE__ */ jsx24(ChatMeta, { children: "Usage: /img ./screenshot.png \u2014 optional text after the path is sent too" })
|
|
14800
|
+
}
|
|
14801
|
+
];
|
|
14802
|
+
});
|
|
14779
14803
|
return;
|
|
14780
14804
|
}
|
|
14781
14805
|
setIsProcessing(true);
|
|
@@ -14785,13 +14809,16 @@ var AppComponent = ({ eventBus, sessionId, cliVersion }) => {
|
|
|
14785
14809
|
sessionId,
|
|
14786
14810
|
summary: trimRecentActivity(payload, 120)
|
|
14787
14811
|
});
|
|
14788
|
-
setHistory((prev) =>
|
|
14789
|
-
|
|
14790
|
-
|
|
14791
|
-
|
|
14792
|
-
|
|
14793
|
-
|
|
14794
|
-
|
|
14812
|
+
setHistory((prev) => {
|
|
14813
|
+
const id = nextHistoryId(prev);
|
|
14814
|
+
return [
|
|
14815
|
+
...prev,
|
|
14816
|
+
{
|
|
14817
|
+
id,
|
|
14818
|
+
component: /* @__PURE__ */ jsx24(UserMessageWithOptionalImages, { raw: payload, variant: "slash-img" })
|
|
14819
|
+
}
|
|
14820
|
+
];
|
|
14821
|
+
});
|
|
14795
14822
|
agentInstance.current.processTurn({ content: payload });
|
|
14796
14823
|
return;
|
|
14797
14824
|
}
|
|
@@ -14814,24 +14841,28 @@ var AppComponent = ({ eventBus, sessionId, cliVersion }) => {
|
|
|
14814
14841
|
setIsProcessing(false);
|
|
14815
14842
|
setIsInitAgentActive(false);
|
|
14816
14843
|
}
|
|
14817
|
-
setHistory((prev) =>
|
|
14818
|
-
|
|
14819
|
-
|
|
14820
|
-
|
|
14821
|
-
|
|
14822
|
-
|
|
14823
|
-
|
|
14824
|
-
|
|
14825
|
-
|
|
14826
|
-
|
|
14827
|
-
|
|
14828
|
-
|
|
14829
|
-
|
|
14830
|
-
|
|
14831
|
-
|
|
14832
|
-
|
|
14833
|
-
|
|
14834
|
-
|
|
14844
|
+
setHistory((prev) => {
|
|
14845
|
+
const firstId = nextHistoryId(prev);
|
|
14846
|
+
const secondId = firstId + 1;
|
|
14847
|
+
return [
|
|
14848
|
+
...prev,
|
|
14849
|
+
{
|
|
14850
|
+
id: firstId,
|
|
14851
|
+
component: /* @__PURE__ */ jsx24(ChatUserMessage, { children: /* @__PURE__ */ jsx24(Text22, { color: BLUMA_TERMINAL.m3OnSurface, bold: true, wrap: "wrap", children: text }) })
|
|
14852
|
+
},
|
|
14853
|
+
{
|
|
14854
|
+
id: secondId,
|
|
14855
|
+
component: /* @__PURE__ */ jsx24(
|
|
14856
|
+
SlashCommands_default,
|
|
14857
|
+
{
|
|
14858
|
+
input: text,
|
|
14859
|
+
setHistory,
|
|
14860
|
+
agentRef: agentInstance
|
|
14861
|
+
}
|
|
14862
|
+
)
|
|
14863
|
+
}
|
|
14864
|
+
];
|
|
14865
|
+
});
|
|
14835
14866
|
return;
|
|
14836
14867
|
}
|
|
14837
14868
|
if (text.startsWith("!")) {
|
|
@@ -14847,16 +14878,19 @@ var AppComponent = ({ eventBus, sessionId, cliVersion }) => {
|
|
|
14847
14878
|
sessionId,
|
|
14848
14879
|
summary: trimRecentActivity(command, 120)
|
|
14849
14880
|
});
|
|
14850
|
-
setHistory((prev) =>
|
|
14851
|
-
|
|
14852
|
-
|
|
14853
|
-
|
|
14854
|
-
|
|
14855
|
-
|
|
14856
|
-
|
|
14857
|
-
|
|
14858
|
-
|
|
14859
|
-
|
|
14881
|
+
setHistory((prev) => {
|
|
14882
|
+
const id = nextHistoryId(prev);
|
|
14883
|
+
return [
|
|
14884
|
+
...prev,
|
|
14885
|
+
{
|
|
14886
|
+
id,
|
|
14887
|
+
component: /* @__PURE__ */ jsx24(ChatUserMessage, { children: /* @__PURE__ */ jsxs22(Text22, { bold: true, color: "white", children: [
|
|
14888
|
+
"$ !",
|
|
14889
|
+
command
|
|
14890
|
+
] }) })
|
|
14891
|
+
}
|
|
14892
|
+
];
|
|
14893
|
+
});
|
|
14860
14894
|
Promise.resolve().then(() => (init_async_command(), async_command_exports)).then(async ({ runCommandAsync: runCommandAsync2 }) => {
|
|
14861
14895
|
try {
|
|
14862
14896
|
const result = await runCommandAsync2({ command, cwd: workdir });
|
|
@@ -14870,31 +14904,37 @@ Please use command_status to check the result and report back to the user.`;
|
|
|
14870
14904
|
} else {
|
|
14871
14905
|
turnStartedAtRef.current = null;
|
|
14872
14906
|
setProcessingStartMs(null);
|
|
14873
|
-
setHistory((prev) =>
|
|
14874
|
-
|
|
14875
|
-
|
|
14876
|
-
|
|
14877
|
-
|
|
14878
|
-
|
|
14879
|
-
|
|
14880
|
-
|
|
14881
|
-
|
|
14882
|
-
|
|
14907
|
+
setHistory((prev) => {
|
|
14908
|
+
const id = nextHistoryId(prev);
|
|
14909
|
+
return [
|
|
14910
|
+
...prev,
|
|
14911
|
+
{
|
|
14912
|
+
id,
|
|
14913
|
+
component: /* @__PURE__ */ jsxs22(Text22, { color: "red", children: [
|
|
14914
|
+
"Failed to execute: ",
|
|
14915
|
+
result.error || result.message
|
|
14916
|
+
] })
|
|
14917
|
+
}
|
|
14918
|
+
];
|
|
14919
|
+
});
|
|
14883
14920
|
setIsProcessing(false);
|
|
14884
14921
|
}
|
|
14885
14922
|
} catch (err) {
|
|
14886
14923
|
turnStartedAtRef.current = null;
|
|
14887
14924
|
setProcessingStartMs(null);
|
|
14888
|
-
setHistory((prev) =>
|
|
14889
|
-
|
|
14890
|
-
|
|
14891
|
-
|
|
14892
|
-
|
|
14893
|
-
|
|
14894
|
-
|
|
14895
|
-
|
|
14896
|
-
|
|
14897
|
-
|
|
14925
|
+
setHistory((prev) => {
|
|
14926
|
+
const id = nextHistoryId(prev);
|
|
14927
|
+
return [
|
|
14928
|
+
...prev,
|
|
14929
|
+
{
|
|
14930
|
+
id,
|
|
14931
|
+
component: /* @__PURE__ */ jsxs22(Text22, { color: "red", children: [
|
|
14932
|
+
"Error: ",
|
|
14933
|
+
err.message
|
|
14934
|
+
] })
|
|
14935
|
+
}
|
|
14936
|
+
];
|
|
14937
|
+
});
|
|
14898
14938
|
setIsProcessing(false);
|
|
14899
14939
|
}
|
|
14900
14940
|
});
|
|
@@ -14902,13 +14942,16 @@ Please use command_status to check the result and report back to the user.`;
|
|
|
14902
14942
|
}
|
|
14903
14943
|
setIsProcessing(true);
|
|
14904
14944
|
markTurnStarted();
|
|
14905
|
-
setHistory((prev) =>
|
|
14906
|
-
|
|
14907
|
-
|
|
14908
|
-
|
|
14909
|
-
|
|
14910
|
-
|
|
14911
|
-
|
|
14945
|
+
setHistory((prev) => {
|
|
14946
|
+
const id = nextHistoryId(prev);
|
|
14947
|
+
return [
|
|
14948
|
+
...prev,
|
|
14949
|
+
{
|
|
14950
|
+
id,
|
|
14951
|
+
component: /* @__PURE__ */ jsx24(UserMessageWithOptionalImages, { raw: text, variant: "plain" })
|
|
14952
|
+
}
|
|
14953
|
+
];
|
|
14954
|
+
});
|
|
14912
14955
|
agentInstance.current.processTurn({ content: text });
|
|
14913
14956
|
},
|
|
14914
14957
|
[isProcessing, markTurnStarted]
|
|
@@ -14940,26 +14983,32 @@ Please use command_status to check the result and report back to the user.`;
|
|
|
14940
14983
|
const key = reasoningDedupeKey(r);
|
|
14941
14984
|
if (!r || key === lastReasoningTextRef.current) return;
|
|
14942
14985
|
lastReasoningTextRef.current = key;
|
|
14943
|
-
setHistory((prev) =>
|
|
14944
|
-
|
|
14945
|
-
|
|
14946
|
-
|
|
14947
|
-
|
|
14948
|
-
|
|
14949
|
-
|
|
14986
|
+
setHistory((prev) => {
|
|
14987
|
+
const id = nextHistoryId(prev);
|
|
14988
|
+
return [
|
|
14989
|
+
...prev,
|
|
14990
|
+
{
|
|
14991
|
+
id,
|
|
14992
|
+
component: /* @__PURE__ */ jsx24(ReasoningDisplay, { reasoning })
|
|
14993
|
+
}
|
|
14994
|
+
];
|
|
14995
|
+
});
|
|
14950
14996
|
}, []);
|
|
14951
14997
|
const appendStreamedAssistant = useCallback3((content) => {
|
|
14952
14998
|
const t = String(content ?? "").trim();
|
|
14953
14999
|
if (!t) return;
|
|
14954
15000
|
const key = reasoningDedupeKey(t);
|
|
14955
15001
|
lastStreamAssistantKeyRef.current = key;
|
|
14956
|
-
setHistory((prev) =>
|
|
14957
|
-
|
|
14958
|
-
|
|
14959
|
-
|
|
14960
|
-
|
|
14961
|
-
|
|
14962
|
-
|
|
15002
|
+
setHistory((prev) => {
|
|
15003
|
+
const id = nextHistoryId(prev);
|
|
15004
|
+
return [
|
|
15005
|
+
...prev,
|
|
15006
|
+
{
|
|
15007
|
+
id,
|
|
15008
|
+
component: /* @__PURE__ */ jsx24(AssistantMessageDisplay, { content })
|
|
15009
|
+
}
|
|
15010
|
+
];
|
|
15011
|
+
});
|
|
14963
15012
|
}, []);
|
|
14964
15013
|
const cappedHistory = useMemo2(() => {
|
|
14965
15014
|
if (history.length <= MAX_STATIC_HISTORY_ITEMS) return history;
|
|
@@ -14999,13 +15048,16 @@ Please use command_status to check the result and report back to the user.`;
|
|
|
14999
15048
|
turnStartedAtRef.current = null;
|
|
15000
15049
|
setProcessingStartMs(null);
|
|
15001
15050
|
const ms = Date.now() - t;
|
|
15002
|
-
setHistory((prev) =>
|
|
15003
|
-
|
|
15004
|
-
|
|
15005
|
-
|
|
15006
|
-
|
|
15007
|
-
|
|
15008
|
-
|
|
15051
|
+
setHistory((prev) => {
|
|
15052
|
+
const id = nextHistoryId(prev);
|
|
15053
|
+
return [
|
|
15054
|
+
...prev,
|
|
15055
|
+
{
|
|
15056
|
+
id,
|
|
15057
|
+
component: /* @__PURE__ */ jsx24(ChatTurnDuration, { durationMs: ms })
|
|
15058
|
+
}
|
|
15059
|
+
];
|
|
15060
|
+
});
|
|
15009
15061
|
};
|
|
15010
15062
|
if (parsed.type === "done" || parsed.type === "error") {
|
|
15011
15063
|
setIsInitAgentActive(false);
|
|
@@ -15179,9 +15231,10 @@ Please use command_status to check the result and report back to the user.`;
|
|
|
15179
15231
|
}
|
|
15180
15232
|
if (newComponent) {
|
|
15181
15233
|
setHistory((prev) => {
|
|
15234
|
+
const id = nextHistoryId(prev);
|
|
15182
15235
|
const next = [
|
|
15183
15236
|
...prev,
|
|
15184
|
-
{ id
|
|
15237
|
+
{ id, component: newComponent }
|
|
15185
15238
|
];
|
|
15186
15239
|
if (parsed.type === "error") {
|
|
15187
15240
|
const t = turnStartedAtRef.current;
|
|
@@ -15190,7 +15243,7 @@ Please use command_status to check the result and report back to the user.`;
|
|
|
15190
15243
|
setProcessingStartMs(null);
|
|
15191
15244
|
const ms = Date.now() - t;
|
|
15192
15245
|
next.push({
|
|
15193
|
-
id: next
|
|
15246
|
+
id: nextHistoryId(next),
|
|
15194
15247
|
component: /* @__PURE__ */ jsx24(ChatTurnDuration, { durationMs: ms })
|
|
15195
15248
|
});
|
|
15196
15249
|
}
|
|
@@ -15207,10 +15260,10 @@ Please use command_status to check the result and report back to the user.`;
|
|
|
15207
15260
|
const handleInputNotice = (data) => {
|
|
15208
15261
|
const msg = String(data.message || "").trim();
|
|
15209
15262
|
if (!msg) return;
|
|
15210
|
-
setHistory((prev) =>
|
|
15211
|
-
|
|
15212
|
-
{ id
|
|
15213
|
-
|
|
15263
|
+
setHistory((prev) => {
|
|
15264
|
+
const id = nextHistoryId(prev);
|
|
15265
|
+
return [...prev, { id, component: /* @__PURE__ */ jsx24(ChatMeta, { children: msg }) }];
|
|
15266
|
+
});
|
|
15214
15267
|
};
|
|
15215
15268
|
uiEventBus.on("user_overlay", handleUiOverlay);
|
|
15216
15269
|
uiEventBus.on("input_notice", handleInputNotice);
|
|
@@ -15255,11 +15308,9 @@ Please use command_status to check the result and report back to the user.`;
|
|
|
15255
15308
|
toolCalls: pendingConfirmation,
|
|
15256
15309
|
preview: confirmationPreview,
|
|
15257
15310
|
onDecision: (decision) => {
|
|
15258
|
-
const hadPreview = confirmationPreview != null && String(confirmationPreview).trim().length > 0;
|
|
15259
|
-
const tname = pendingConfirmation?.[0]?.function?.name ?? "";
|
|
15260
15311
|
setConfirmationPreview(null);
|
|
15261
15312
|
handleConfirmation(decision, pendingConfirmation, {
|
|
15262
|
-
editPreviewAlreadyShown:
|
|
15313
|
+
editPreviewAlreadyShown: false
|
|
15263
15314
|
});
|
|
15264
15315
|
}
|
|
15265
15316
|
}
|
|
@@ -15494,7 +15545,8 @@ async function runAgentMode() {
|
|
|
15494
15545
|
let reasoningBuffer = null;
|
|
15495
15546
|
let lastAttachments = null;
|
|
15496
15547
|
let resultEmitted = false;
|
|
15497
|
-
|
|
15548
|
+
let agentRef = null;
|
|
15549
|
+
eventBus.on("backend_message", async (payload) => {
|
|
15498
15550
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
15499
15551
|
writeAgentEvent(sessionId, {
|
|
15500
15552
|
event_type: "backend_message",
|
|
@@ -15527,6 +15579,9 @@ async function runAgentMode() {
|
|
|
15527
15579
|
}
|
|
15528
15580
|
if (!resultEmitted && payload?.type === "done") {
|
|
15529
15581
|
resultEmitted = true;
|
|
15582
|
+
if (agentRef) {
|
|
15583
|
+
await agentRef.closeActiveTurn("worker_done_exit");
|
|
15584
|
+
}
|
|
15530
15585
|
finalizeSession(sessionId, "completed", { finishedBy: "done-event" });
|
|
15531
15586
|
writeAgentEvent(sessionId, {
|
|
15532
15587
|
event_type: "result",
|
|
@@ -15567,6 +15622,7 @@ async function runAgentMode() {
|
|
|
15567
15622
|
});
|
|
15568
15623
|
try {
|
|
15569
15624
|
const agent = new Agent(sessionId, eventBus);
|
|
15625
|
+
agentRef = agent;
|
|
15570
15626
|
await agent.initialize();
|
|
15571
15627
|
const userContent = JSON.stringify({
|
|
15572
15628
|
message_id: envelope.message_id || sessionId,
|
|
@@ -15578,6 +15634,7 @@ async function runAgentMode() {
|
|
|
15578
15634
|
await agent.processTurn({ content: userContent }, userContextInput);
|
|
15579
15635
|
if (!resultEmitted) {
|
|
15580
15636
|
resultEmitted = true;
|
|
15637
|
+
await agent.closeActiveTurn("worker_post_turn_fallback");
|
|
15581
15638
|
finalizeSession(sessionId, "completed", { finishedBy: "post-turn-fallback" });
|
|
15582
15639
|
writeAgentEvent(sessionId, {
|
|
15583
15640
|
event_type: "result",
|
|
@@ -15595,6 +15652,9 @@ async function runAgentMode() {
|
|
|
15595
15652
|
}
|
|
15596
15653
|
} catch (err) {
|
|
15597
15654
|
if (!resultEmitted) {
|
|
15655
|
+
if (agentRef) {
|
|
15656
|
+
await agentRef.closeActiveTurn("worker_exception");
|
|
15657
|
+
}
|
|
15598
15658
|
finalizeSession(sessionId, "error", { finishedBy: "exception" });
|
|
15599
15659
|
writeAgentEvent(sessionId, {
|
|
15600
15660
|
event_type: "result",
|