akseljoonas HF Staff commited on
Commit
8bff299
Β·
1 Parent(s): 08028f6

working events and session

Browse files
agent/__init__.py CHANGED
@@ -2,6 +2,6 @@
2
  HF Agent - Main agent module
3
  """
4
 
5
- from agent.core.agent_loop import Agent
6
 
7
- __all__ = ["Agent"]
 
2
  HF Agent - Main agent module
3
  """
4
 
5
+ from agent.core.agent_loop import submission_loop
6
 
7
+ __all__ = ["submission_loop"]
agent/context_manager/__init__.py CHANGED
@@ -1,7 +1,7 @@
1
  """
2
- Prompt templates and management
3
  """
4
 
5
- from agent.prompts.manager import PromptManager
6
 
7
- __all__ = ["PromptManager"]
 
1
  """
2
+ Context manager for handling conversation history
3
  """
4
 
5
+ from agent.context_manager.manager import ContextManager
6
 
7
+ __all__ = ["ContextManager"]
agent/context_manager/manager.py CHANGED
@@ -1,16 +1,16 @@
1
  """
2
- Prompt template management
3
  """
4
 
5
  from litellm import Message
6
 
7
 
8
  class ContextManager:
9
- """Manages context templates for the agent"""
10
 
11
  def __init__(self):
12
  self.system_prompt = self._load_system_prompt()
13
- self.messages: list[Message] = [
14
  Message(role="system", content=self.system_prompt)
15
  ]
16
 
@@ -21,7 +21,24 @@ class ContextManager:
21
  return "You are a helpful assistant."
22
 
23
  def add_message(self, message: Message) -> None:
24
- self.messages.append(message)
 
25
 
26
  def get_messages(self) -> list[Message]:
27
- return self.messages
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  """
2
+ Context management for conversation history
3
  """
4
 
5
  from litellm import Message
6
 
7
 
8
  class ContextManager:
9
+ """Manages conversation context and message history for the agent"""
10
 
11
  def __init__(self):
12
  self.system_prompt = self._load_system_prompt()
13
+ self.items: list[Message] = [
14
  Message(role="system", content=self.system_prompt)
15
  ]
16
 
 
21
  return "You are a helpful assistant."
22
 
23
  def add_message(self, message: Message) -> None:
24
+ """Add a message to the history"""
25
+ self.items.append(message)
26
 
27
  def get_messages(self) -> list[Message]:
28
+ """Get all messages for sending to LLM"""
29
+ return self.items
30
+
31
+ def compact(self, target_size: int) -> None:
32
+ """Remove old messages to keep history under target size"""
33
+ # Keep system prompt (first message) and remove oldest user/assistant messages
34
+ if len(self.items) <= target_size:
35
+ return
36
+
37
+ # Always keep system prompt
38
+ system_msg = self.items[0] if self.items and self.items[0].role == "system" else None
39
+ messages_to_keep = self.items[-(target_size - 1):]
40
+
41
+ if system_msg:
42
+ self.items = [system_msg] + messages_to_keep
43
+ else:
44
+ self.items = messages_to_keep
agent/core/agent_loop.py CHANGED
@@ -132,13 +132,13 @@ class Handlers:
132
 
133
 
134
  async def submission_loop(
135
- submission_queue: asyncio.Queue, event_queue: asyncio.Queue
136
  ) -> None:
137
  """
138
  Main agent loop - processes submissions and dispatches to handlers.
139
  This is the core of the agent (like submission_loop in codex.rs:1259-1340)
140
  """
141
- session = Session(event_queue)
142
 
143
  print("πŸ€– Agent loop started")
144
 
 
132
 
133
 
134
  async def submission_loop(
135
+ submission_queue: asyncio.Queue, event_queue: asyncio.Queue, config=None
136
  ) -> None:
137
  """
138
  Main agent loop - processes submissions and dispatches to handlers.
139
  This is the core of the agent (like submission_loop in codex.rs:1259-1340)
140
  """
141
+ session = Session(event_queue, config=config)
142
 
143
  print("πŸ€– Agent loop started")
144
 
agent/core/session.py CHANGED
@@ -6,6 +6,7 @@ from pydantic import BaseModel
6
 
7
  from agent.context_manager.manager import ContextManager
8
  from agent.core import ToolExecutor
 
9
 
10
 
11
  class OpType(Enum):
@@ -20,13 +21,15 @@ class OpType(Enum):
20
  class Event(BaseModel):
21
  event_type: Literal[
22
  "processing",
 
 
23
  "turn_complete",
24
  "compacted",
25
  "undo_complete",
26
  "shutdown",
27
  "error",
28
  "interrupted",
29
- ] # Dummy events for now
30
  data: dict[str, Any] | None = None
31
 
32
 
@@ -36,10 +39,13 @@ class Session:
36
  Similar to Session in codex-rs/core/src/codex.rs
37
  """
38
 
39
- def __init__(self, event_queue: asyncio.Queue):
40
  self.context_manager = ContextManager()
41
  self.tool_executor = ToolExecutor()
42
  self.event_queue = event_queue
 
 
 
43
  self.is_running = True
44
  self.current_task: asyncio.Task | None = None
45
 
 
6
 
7
  from agent.context_manager.manager import ContextManager
8
  from agent.core import ToolExecutor
9
+ from agent.config import Config
10
 
11
 
12
  class OpType(Enum):
 
21
  class Event(BaseModel):
22
  event_type: Literal[
23
  "processing",
24
+ "assistant_message",
25
+ "tool_output",
26
  "turn_complete",
27
  "compacted",
28
  "undo_complete",
29
  "shutdown",
30
  "error",
31
  "interrupted",
32
+ ]
33
  data: dict[str, Any] | None = None
34
 
35
 
 
39
  Similar to Session in codex-rs/core/src/codex.rs
40
  """
41
 
42
+ def __init__(self, event_queue: asyncio.Queue, config: Config | None = None):
43
  self.context_manager = ContextManager()
44
  self.tool_executor = ToolExecutor()
45
  self.event_queue = event_queue
46
+ self.config = config or Config(
47
+ model_name="gpt-3.5-turbo", tools=[], system_prompt_path=""
48
+ )
49
  self.is_running = True
50
  self.current_task: asyncio.Task | None = None
51
 
agent/main.py ADDED
@@ -0,0 +1,108 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Simple runner for the agent with a single dummy input
3
+ """
4
+
5
+ import asyncio
6
+ from dataclasses import dataclass
7
+ from typing import Any, Optional
8
+
9
+ from agent.core.agent_loop import submission_loop
10
+ from agent.core.session import OpType
11
+
12
+
13
+ @dataclass
14
+ class Operation:
15
+ """Operation to be executed by the agent"""
16
+
17
+ op_type: OpType
18
+ data: Optional[dict[str, Any]] = None
19
+
20
+
21
+ @dataclass
22
+ class Submission:
23
+ """Submission to the agent loop"""
24
+
25
+ id: str
26
+ operation: Operation
27
+
28
+
29
+ async def main():
30
+ """Run agent with a single dummy input"""
31
+
32
+ print("πŸš€ Starting agent...")
33
+
34
+ # Create queues for communication
35
+ submission_queue = asyncio.Queue()
36
+ event_queue = asyncio.Queue()
37
+
38
+ # Start agent loop in background
39
+ agent_task = asyncio.create_task(submission_loop(submission_queue, event_queue))
40
+
41
+ # Wait a moment for agent to initialize
42
+ await asyncio.sleep(0.1)
43
+
44
+ # Submit dummy input
45
+ print("\nπŸ“ Submitting dummy input...")
46
+ dummy_submission = Submission(
47
+ id="sub_1",
48
+ operation=Operation(
49
+ op_type=OpType.USER_INPUT,
50
+ data={"text": "Hello! What tools do you have available?"},
51
+ ),
52
+ )
53
+ await submission_queue.put(dummy_submission)
54
+
55
+ # Listen for events
56
+ print("\nπŸ‘‚ Listening for events...\n")
57
+ events_received = 0
58
+ max_events = 10 # Safety limit
59
+
60
+ while events_received < max_events:
61
+ try:
62
+ event = await asyncio.wait_for(event_queue.get(), timeout=2.0)
63
+ events_received += 1
64
+
65
+ # Display event
66
+ if event.event_type == "assistant_message":
67
+ msg = event.data.get("message", {})
68
+ content = msg.get("content", "")
69
+ print(f"πŸ€– Assistant: {content}")
70
+ elif event.event_type == "tool_output":
71
+ msg = event.data.get("message", {})
72
+ content = msg.get("content", "")
73
+ print(f"πŸ”§ Tool output: {content}")
74
+ elif event.event_type == "turn_complete":
75
+ print(f"βœ… Turn complete: {event.data}")
76
+ break
77
+ elif event.event_type == "error":
78
+ print(f"❌ Error: {event.data}")
79
+ break
80
+ else:
81
+ print(f"πŸ“¨ Event: {event.event_type} - {event.data}")
82
+
83
+ except asyncio.TimeoutError:
84
+ print("⏱️ No more events, timing out...")
85
+ break
86
+
87
+ # Shutdown
88
+ print("\nπŸ›‘ Shutting down agent...")
89
+ shutdown_submission = Submission(
90
+ id="sub_shutdown", operation=Operation(op_type=OpType.SHUTDOWN)
91
+ )
92
+ await submission_queue.put(shutdown_submission)
93
+
94
+ # Wait for shutdown event
95
+ try:
96
+ event = await asyncio.wait_for(event_queue.get(), timeout=1.0)
97
+ print(f"βœ… {event.event_type}")
98
+ except asyncio.TimeoutError:
99
+ pass
100
+
101
+ # Wait for agent task to complete
102
+ await agent_task
103
+
104
+ print("\n✨ Done!")
105
+
106
+
107
+ if __name__ == "__main__":
108
+ asyncio.run(main())