Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .loopal/memory-events/2026-08-07_86a4020a.jsonl
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
{"v":1,"ts":1786096118670,"sid":"86a4020a-9f73-4911-a98d-9327f03f49f4","type":"query_event","qid":"q-1786096118670618000","anchor":["archived-project-decisions"],"result_count":1,"latency_ms":0,"caller":"recall"}
{"v":1,"ts":1786096118671,"sid":"86a4020a-9f73-4911-a98d-9327f03f49f4","type":"recall_hit","qid":"q-1786096118670618000","node":"archived-project-decisions","rank":0,"score":0.9925666,"source":"direct_hit"}
19 changes: 5 additions & 14 deletions .loopal/memory/MEMORY.md
Original file line number Diff line number Diff line change
@@ -1,26 +1,17 @@
---
generated_from: graph
generated_at: 2026-08-04T14:16:51Z
generated_at: 2026-08-07T09:47:57Z
node_count: 1
edge_count: 0
---

# Memory Index

## User
## Recently added
- 2026-08-04 [[archived-project-decisions]]

_No entries._
## Reference (high-relevance)
- [[archived-project-decisions]] — Retain the Windows rules_rust PATH workaround until its upstream fix is verified; releases target four platforms and require Node.js-compatible actions; the hub defaults to 16 agents with MetaHub remote spawning

## Feedback

_No entries._

## Project

_No active entries._

## Reference

- 2026-08-04 [[archived-project-decisions]] — Preserve the verified release-platform, Windows rules_rust workaround, and agent-hub scaling decisions after their project memories expired.

[Use memory_recall(query=...) to look up content. Do NOT Read individual .md files unless you are about to edit one.]
9 changes: 9 additions & 0 deletions crates/loopal-runtime/src/agent_loop/cold_start_emit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,15 @@ impl AgentLoopRunner {
model: self.params.config.model(),
})
.await?;
self.emit(AgentEventPayload::TokenUsage {
input_tokens: 0,
output_tokens: 0,
context_window: self.turns.view().budget().context_window,
cache_creation_input_tokens: 0,
cache_read_input_tokens: 0,
thinking_tokens: 0,
})
.await?;
self.emit(AgentEventPayload::ModeChanged {
mode: self.params.config.mode.as_str().to_string(),
})
Expand Down
15 changes: 15 additions & 0 deletions crates/loopal-tui/tests/suite/e2e_control_lifecycle_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,17 @@ async fn test_cold_start_emits_initial_observable_seed() {
let has_thinking = evts
.iter()
.any(|e| matches!(e, AgentEventPayload::ThinkingChanged { .. }));
let seeded_context_window = evts.iter().find_map(|e| match e {
AgentEventPayload::TokenUsage { context_window, .. } => Some(*context_window),
_ => None,
});
assert!(has_model_changed, "cold-start must emit ModelChanged");
assert!(has_mode_changed, "cold-start must emit ModeChanged");
assert!(has_thinking, "cold-start must emit ThinkingChanged");
assert!(
seeded_context_window.is_some_and(|window| window > 0),
"cold-start must seed the selected model's context window"
);

let obs = harness.app.observable_for("main");
assert!(
Expand All @@ -66,6 +74,13 @@ async fn test_cold_start_emits_initial_observable_seed() {
!obs.thinking_config.is_empty(),
"observable.thinking_config must be seeded by cold-start"
);
assert_eq!(
harness
.app
.with_active_conversation(|conv| conv.context_window),
seeded_context_window.unwrap(),
"cold-start context window event must reach the active conversation"
);
}

#[tokio::test]
Expand Down
13 changes: 10 additions & 3 deletions crates/loopal-tui/tests/suite/e2e_system_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,16 @@ async fn test_event_ordering() {
let stream = evts
.iter()
.position(|e| matches!(e, AgentEventPayload::Stream { .. }));
let usage = evts
.iter()
.position(|e| matches!(e, AgentEventPayload::TokenUsage { .. }));
let usage = evts.iter().position(|e| {
matches!(
e,
AgentEventPayload::TokenUsage {
input_tokens,
output_tokens,
..
} if *input_tokens > 0 || *output_tokens > 0
)
});
let terminal = evts.iter().position(|e| {
matches!(
e,
Expand Down
Loading