Implement tracking of outstanding LLM and Tool calls

This commit implements a listener pattern between ant.convo and the Agent for tracking outstanding calls.

* Added fields to the Agent struct to track outstanding LLM calls and Tool calls
* Implemented the listener methods to properly track and update these fields
* Added methods to retrieve the counts and names
* Updated the State struct in loophttp.go to expose this information
* Added a unit test to verify the tracking functionality
* Created UI components with lightbulb and wrench icons to display call status
* Added numerical indicators that always show when there are active calls

Co-Authored-By: sketch <hello@sketch.dev>
diff --git a/loop/agent_test.go b/loop/agent_test.go
index b9f9994..5bde1b1 100644
--- a/loop/agent_test.go
+++ b/loop/agent_test.go
@@ -152,3 +152,55 @@
 
 	t.Logf("Agent used %d tools in its response", toolUseCount)
 }
+
+func TestAgentTracksOutstandingCalls(t *testing.T) {
+	agent := &Agent{
+		outstandingLLMCalls:  make(map[string]struct{}),
+		outstandingToolCalls: make(map[string]string),
+	}
+
+	// Check initial state
+	if count := agent.OutstandingLLMCallCount(); count != 0 {
+		t.Errorf("Expected 0 outstanding LLM calls, got %d", count)
+	}
+
+	if tools := agent.OutstandingToolCalls(); len(tools) != 0 {
+		t.Errorf("Expected 0 outstanding tool calls, got %d", len(tools))
+	}
+
+	// Add some calls
+	agent.mu.Lock()
+	agent.outstandingLLMCalls["llm1"] = struct{}{}
+	agent.outstandingToolCalls["tool1"] = "bash"
+	agent.outstandingToolCalls["tool2"] = "think"
+	agent.mu.Unlock()
+
+	// Check tracking works
+	if count := agent.OutstandingLLMCallCount(); count != 1 {
+		t.Errorf("Expected 1 outstanding LLM call, got %d", count)
+	}
+
+	tools := agent.OutstandingToolCalls()
+	if len(tools) != 2 {
+		t.Errorf("Expected 2 outstanding tool calls, got %d", len(tools))
+	}
+
+	// Check removal
+	agent.mu.Lock()
+	delete(agent.outstandingLLMCalls, "llm1")
+	delete(agent.outstandingToolCalls, "tool1")
+	agent.mu.Unlock()
+
+	if count := agent.OutstandingLLMCallCount(); count != 0 {
+		t.Errorf("Expected 0 outstanding LLM calls after removal, got %d", count)
+	}
+
+	tools = agent.OutstandingToolCalls()
+	if len(tools) != 1 {
+		t.Errorf("Expected 1 outstanding tool call after removal, got %d", len(tools))
+	}
+
+	if tools[0] != "think" {
+		t.Errorf("Expected 'think' tool remaining, got %s", tools[0])
+	}
+}