Skip to content

Commit 3d52224

Browse files
authored
Improved agent processing loop and logger module (#54)
* improved agent * more coverage * nit docstring * more coverage * wip * changelog
1 parent 6af8734 commit 3d52224

File tree

11 files changed

+371
-275
lines changed

11 files changed

+371
-275
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/).
1010

1111
### Changed
1212

13+
- Revised `TaskHandler.get_next_step()` to return `TaskStep | TaskResult` (#54)
1314
- Fixed bug in `OllamaLLM.chat()` where chat history was coming after user message (#51)
1415
- Fixed bug in `TaskHandler.run_step()` where tool names were passed to `llm.chat()` (#46)
1516

1617
### Added
1718

19+
- Add `enable_console_logging` and `disable_console_logging` to not stream logs as a library by default (#54)
20+
- Add first working cookbook for a simple `LLMAgent` and task (#54)
21+
- Add `data_structures.task_handler.GetNextStep` (#54)
1822
- Add `logger.set_log_level()` and logger attribute to `TaskHandler` (#51)
1923
- Added library logger `llm_agents_from_scratch.logger` (#50)
2024
- Remove `OllamaLLM` from root import -- too slow! (#45)

docs/notebooks/first_llm_agent.ipynb

Lines changed: 70 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,7 @@
1515
"metadata": {},
1616
"outputs": [],
1717
"source": [
18-
"from logging import DEBUG\n",
19-
"\n",
20-
"from llm_agents_from_scratch import LLMAgent\n",
21-
"from llm_agents_from_scratch.logger import get_logger, set_log_level\n",
22-
"\n",
23-
"set_log_level(DEBUG)\n",
24-
"nb_logger = get_logger(\"notebook\")"
18+
"from llm_agents_from_scratch import LLMAgent"
2519
]
2620
},
2721
{
@@ -172,16 +166,41 @@
172166
{
173167
"cell_type": "code",
174168
"execution_count": 9,
175-
"id": "4d09a484-9eb7-4525-923e-d00ebfe0434a",
169+
"id": "c3a940e0-3fb0-43e9-8858-f5277a79df37",
176170
"metadata": {},
177171
"outputs": [],
178172
"source": [
179-
"from llm_agents_from_scratch.data_structures.agent import Task"
173+
"LOGGING_ENABLED = True"
180174
]
181175
},
182176
{
183177
"cell_type": "code",
184178
"execution_count": 10,
179+
"id": "bfb51e69-ea36-495d-bcc1-fc7d164b6d40",
180+
"metadata": {},
181+
"outputs": [],
182+
"source": [
183+
"import logging\n",
184+
"\n",
185+
"from llm_agents_from_scratch.logger import enable_console_logging\n",
186+
"\n",
187+
"if LOGGING_ENABLED:\n",
188+
" enable_console_logging(logging.INFO)"
189+
]
190+
},
191+
{
192+
"cell_type": "code",
193+
"execution_count": 11,
194+
"id": "4d09a484-9eb7-4525-923e-d00ebfe0434a",
195+
"metadata": {},
196+
"outputs": [],
197+
"source": [
198+
"from llm_agents_from_scratch.data_structures import Task"
199+
]
200+
},
201+
{
202+
"cell_type": "code",
203+
"execution_count": 12,
185204
"id": "1d5d512e-d400-4398-980f-a4142d367add",
186205
"metadata": {},
187206
"outputs": [],
@@ -193,7 +212,7 @@
193212
},
194213
{
195214
"cell_type": "code",
196-
"execution_count": 11,
215+
"execution_count": 13,
197216
"id": "e99cca54-0d21-4c9d-9a17-bf595d110fe5",
198217
"metadata": {},
199218
"outputs": [
@@ -202,74 +221,12 @@
202221
"output_type": "stream",
203222
"text": [
204223
"INFO (llm_agents_fs.LLMAgent) : 🚀 Starting task: Add one to fifty-five point three. Use an appropriate tool!\n",
205-
"DEBUG (llm_agents_fs.TaskHandler) : 🧵 Rollout: \n",
206-
"INFO (llm_agents_fs.TaskHandler) : 🧠 New Step: Add one to fifty-five point three. Use an appropriate tool!\n",
207224
"INFO (llm_agents_fs.TaskHandler) : ⚙️ Processing Step: Add one to fifty-five point three. Use an appropriate tool!\n",
208-
"DEBUG (llm_agents_fs.TaskHandler) : 🧵 Rollout: \n",
209-
"DEBUG (llm_agents_fs.TaskHandler) : 💬 SYSTEM: You are a helpful assistant.\n",
210-
"DEBUG (llm_agents_fs.TaskHandler) : 💬 USER: Add one to fifty-five point three. Use an appropriate tool!\n",
211-
"DEBUG (llm_agents_fs.TaskHandler) : 💬 ASSISTANT: \n",
212-
"INFO (llm_agents_fs.TaskHandler) : 🛠️ Executing Tool Call: add_one\n",
213-
"INFO (llm_agents_fs.TaskHandler) : ✅ Successful Tool Call: 56.3\n",
214-
"INFO (llm_agents_fs.TaskHandler) : ✅ Step Result: After adding one to fifty-five point three, the result is 56.3.\n",
215-
"DEBUG (llm_agents_fs.TaskHandler) : 🧵 Rollout: user: Add one to fifty-five point three. Use an appropriate tool!\n",
216-
"assistant: I need to make a tool call(s) to add_one\n",
217-
"tool: \n",
218-
"The below is a tool call response for a given tool call.\n",
219-
"<tool-call>\n",
220-
"tool name: add_one\n",
221-
"arguments: {'x': '55.3'}\n",
222-
"</tool-call>\n",
223-
"\n",
224-
"<result>\n",
225-
"56.3\n",
226-
"</result>\n",
227-
"\n",
228-
"assistant: After adding one to fifty-five point three, the result is 56.3.\n",
229-
"INFO (llm_agents_fs.TaskHandler) : 🧠 New Step: There is sufficient context to complete the task within the provided history — another tool call may not even be necessary! Proceed with completion and mark this as the last step. NOTE: that the real user has not seen this dialogue, and so just provide the final task result without referencing it.\n",
230-
"INFO (llm_agents_fs.TaskHandler) : ⚙️ Processing Step: There is sufficient context to complete the task within the provided history — another tool call may not even be necessary! Proceed with completion and mark this as the last step. NOTE: that the real user has not seen this dialogue, and so just provide the final task result without referencing it.\n",
231-
"DEBUG (llm_agents_fs.TaskHandler) : 🧵 Rollout: user: Add one to fifty-five point three. Use an appropriate tool!\n",
232-
"assistant: I need to make a tool call(s) to add_one\n",
233-
"tool: \n",
234-
"The below is a tool call response for a given tool call.\n",
235-
"<tool-call>\n",
236-
"tool name: add_one\n",
237-
"arguments: {'x': '55.3'}\n",
238-
"</tool-call>\n",
239-
"\n",
240-
"<result>\n",
241-
"56.3\n",
242-
"</result>\n",
243-
"\n",
244-
"assistant: After adding one to fifty-five point three, the result is 56.3.\n",
245-
"DEBUG (llm_agents_fs.TaskHandler) : 💬 SYSTEM: You are a helpful assistant.\n",
246-
"\n",
247-
"Here is some past dialogue and context, where another assistant was working\n",
248-
"towards completing the task.\n",
249-
"\n",
250-
"<history>\n",
251-
"user: Add one to fifty-five point three. Use an appropriate tool!\n",
252-
"assistant: I need to make a tool call(s) to add_one\n",
253-
"tool: \n",
254-
"The below is a tool call response for a given tool call.\n",
255-
"<tool-call>\n",
256-
"tool name: add_one\n",
257-
"arguments: {'x': '55.3'}\n",
258-
"</tool-call>\n",
259-
"\n",
260-
"<result>\n",
261-
"56.3\n",
262-
"</result>\n",
263-
"\n",
264-
"assistant: After adding one to fifty-five point three, the result is 56.3.\n",
265-
"</history>\n",
266-
"\n",
267-
"DEBUG (llm_agents_fs.TaskHandler) : 💬 USER: There is sufficient context to complete the task within the provided history — another tool call may not even be necessary! Proceed with completion and mark this as the last step. NOTE: that the real user has not seen this dialogue, and so just provide the final task result without referencing it.\n",
268-
"DEBUG (llm_agents_fs.TaskHandler) : 💬 ASSISTANT: \n",
269225
"INFO (llm_agents_fs.TaskHandler) : 🛠️ Executing Tool Call: add_one\n",
270226
"INFO (llm_agents_fs.TaskHandler) : ✅ Successful Tool Call: 56.3\n",
271-
"INFO (llm_agents_fs.TaskHandler) : ✅ Step Result: After adding one to fifty-five point three, the result is 56.3.\n",
272-
"INFO (llm_agents_fs.LLMAgent) : 🏁 Task completed: After adding one to fifty-five point three, the result is 56.3.\n"
227+
"INFO (llm_agents_fs.TaskHandler) : ✅ Step Result: Adding one to fifty-five point three gives us fifty-six point three.\n",
228+
"INFO (llm_agents_fs.TaskHandler) : No new step required.\n",
229+
"INFO (llm_agents_fs.LLMAgent) : 🏁 Task completed: Adding one to fifty-five point three gives us fifty-six point three.\n"
273230
]
274231
}
275232
],
@@ -279,30 +236,57 @@
279236
},
280237
{
281238
"cell_type": "code",
282-
"execution_count": 12,
239+
"execution_count": 14,
283240
"id": "0fde7c61-f0d9-4ef9-b0b6-90386667bbb8",
284241
"metadata": {},
285242
"outputs": [
286243
{
287-
"data": {
288-
"text/plain": [
289-
"TaskResult(task=Task(instruction='Add one to fifty-five point three. Use an appropriate tool!'), content='After adding one to fifty-five point three, the result is 56.3.', rollout=\"user: Add one to fifty-five point three. Use an appropriate tool!\\nassistant: I need to make a tool call(s) to add_one\\ntool: \\nThe below is a tool call response for a given tool call.\\n<tool-call>\\ntool name: add_one\\narguments: {'x': '55.3'}\\n</tool-call>\\n\\n<result>\\n56.3\\n</result>\\n\\nassistant: After adding one to fifty-five point three, the result is 56.3.user: There is sufficient context to complete the task within the provided history — another tool call may not even be necessary! Proceed with completion and mark this as the last step. NOTE: that the real user has not seen this dialogue, and so just provide the final task result without referencing it.\\nassistant: I need to make a tool call(s) to add_one\\ntool: \\nThe below is a tool call response for a given tool call.\\n<tool-call>\\ntool name: add_one\\narguments: {'x': '55.3'}\\n</tool-call>\\n\\n<result>\\n56.3\\n</result>\\n\\nassistant: After adding one to fifty-five point three, the result is 56.3.\", error=False)"
290-
]
291-
},
292-
"execution_count": 12,
293-
"metadata": {},
294-
"output_type": "execute_result"
244+
"name": "stdout",
245+
"output_type": "stream",
246+
"text": [
247+
"The result is fifty-six point three.\n"
248+
]
295249
}
296250
],
297251
"source": [
298-
"result"
252+
"print(result.task_result)"
299253
]
300254
},
301255
{
302256
"cell_type": "code",
303-
"execution_count": null,
257+
"execution_count": 15,
304258
"id": "93b1cfa1-1ac0-420d-b36e-007de5cdfc7f",
305259
"metadata": {},
260+
"outputs": [
261+
{
262+
"name": "stdout",
263+
"output_type": "stream",
264+
"text": [
265+
"assistant: Add one to fifty-five point three. Use an appropriate tool!\n",
266+
"assistant: I need to make a tool call(s) to add_one\n",
267+
"tool: {\n",
268+
" \"tool_call\": {\n",
269+
" \"tool_name\": \"add_one\",\n",
270+
" \"arguments\": {\n",
271+
" \"x\": \"55.3\"\n",
272+
" }\n",
273+
" },\n",
274+
" \"content\": \"56.3\",\n",
275+
" \"error\": false\n",
276+
"}\n",
277+
"assistant: Adding one to fifty-five point three gives us fifty-six point three.\n"
278+
]
279+
}
280+
],
281+
"source": [
282+
"print(result.rollout)"
283+
]
284+
},
285+
{
286+
"cell_type": "code",
287+
"execution_count": null,
288+
"id": "e1a01698-dcdc-4796-a41b-6029eafa9ab5",
289+
"metadata": {},
306290
"outputs": [],
307291
"source": []
308292
}

src/llm_agents_from_scratch/core/agent.py

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,12 @@
66

77
from llm_agents_from_scratch.base.llm import BaseLLM
88
from llm_agents_from_scratch.base.tool import BaseTool
9-
from llm_agents_from_scratch.data_structures import Task, TaskResult
9+
from llm_agents_from_scratch.data_structures import (
10+
Task,
11+
TaskHandlerResult,
12+
TaskResult,
13+
TaskStep,
14+
)
1015
from llm_agents_from_scratch.logger import get_logger
1116

1217
from .task_handler import TaskHandler
@@ -53,23 +58,29 @@ def run(self, task: Task) -> TaskHandler:
5358
async def _run() -> None:
5459
"""Asynchronously process the task."""
5560
self.logger.info(f"🚀 Starting task: {task.instruction}")
61+
step_result = None
5662
while not task_handler.done():
5763
try:
58-
step = await task_handler.get_next_step()
59-
step_result = await task_handler.run_step(step)
60-
if step.last_step:
61-
async with task_handler._lock:
62-
rollout = task_handler.rollout
63-
64-
task_result = TaskResult(
65-
task=task,
66-
content=step_result.content,
67-
rollout=rollout,
68-
)
69-
task_handler.set_result(task_result)
70-
self.logger.info(
71-
f"🏁 Task completed: {task_result.content}",
72-
)
64+
next_step = await task_handler.get_next_step(step_result)
65+
66+
match next_step:
67+
case TaskStep():
68+
step_result = await task_handler.run_step(
69+
next_step,
70+
)
71+
case TaskResult():
72+
async with task_handler._lock:
73+
rollout = task_handler.rollout
74+
75+
task_handler.set_result(
76+
TaskHandlerResult(
77+
task_result=next_step,
78+
rollout=rollout,
79+
),
80+
)
81+
self.logger.info(
82+
f"🏁 Task completed: {next_step.content}",
83+
)
7384

7485
except Exception as e:
7586
task_handler.set_exception(e)

0 commit comments

Comments
 (0)