lite-agent 0.3.0__tar.gz → 0.4.1__tar.gz
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.
Potentially problematic release.
This version of lite-agent might be problematic. Click here for more details.
- lite_agent-0.4.1/.claude/settings.local.json +21 -0
- {lite_agent-0.3.0 → lite_agent-0.4.1}/.vscode/launch.json +1 -1
- {lite_agent-0.3.0 → lite_agent-0.4.1}/CHANGELOG.md +66 -0
- lite_agent-0.4.1/CLAUDE.md +100 -0
- {lite_agent-0.3.0 → lite_agent-0.4.1}/PKG-INFO +2 -2
- {lite_agent-0.3.0 → lite_agent-0.4.1}/examples/basic.py +3 -3
- lite_agent-0.4.1/examples/basic_agent.py +54 -0
- {lite_agent-0.3.0 → lite_agent-0.4.1}/examples/channels/rich_channel.py +16 -17
- lite_agent-0.3.0/examples/rich_helpers_demo.py → lite_agent-0.4.1/examples/chat_display_demo.py +9 -26
- {lite_agent-0.3.0 → lite_agent-0.4.1}/examples/confirm_and_continue.py +2 -2
- {lite_agent-0.3.0 → lite_agent-0.4.1}/examples/consolidate_history.py +2 -2
- {lite_agent-0.3.0 → lite_agent-0.4.1}/examples/context.py +3 -2
- {lite_agent-0.3.0 → lite_agent-0.4.1}/examples/handoffs.py +1 -1
- {lite_agent-0.3.0 → lite_agent-0.4.1}/examples/image.py +1 -1
- {lite_agent-0.3.0 → lite_agent-0.4.1}/examples/message_transfer_example.py +31 -14
- {lite_agent-0.3.0 → lite_agent-0.4.1}/examples/message_transfer_example_new.py +34 -17
- lite_agent-0.4.1/examples/new_message_structure_demo.py +182 -0
- lite_agent-0.4.1/examples/responses.py +58 -0
- {lite_agent-0.3.0 → lite_agent-0.4.1}/examples/set_chat_history_example.py +7 -7
- {lite_agent-0.3.0 → lite_agent-0.4.1}/examples/stop_with_tool_call.py +3 -5
- {lite_agent-0.3.0 → lite_agent-0.4.1}/examples/terminal.py +16 -3
- lite_agent-0.4.1/examples/translate/main.py +49 -0
- lite_agent-0.4.1/examples/translate/prompts/translation_system.md.j2 +1 -0
- {lite_agent-0.3.0 → lite_agent-0.4.1}/examples/type_system_example.py +4 -4
- {lite_agent-0.3.0 → lite_agent-0.4.1}/pyproject.toml +15 -4
- lite_agent-0.4.1/src/lite_agent/__init__.py +8 -0
- {lite_agent-0.3.0 → lite_agent-0.4.1}/src/lite_agent/agent.py +181 -69
- lite_agent-0.4.1/src/lite_agent/chat_display.py +779 -0
- lite_agent-0.4.1/src/lite_agent/client.py +69 -0
- {lite_agent-0.3.0 → lite_agent-0.4.1}/src/lite_agent/message_transfers.py +9 -1
- lite_agent-0.4.1/src/lite_agent/processors/__init__.py +4 -0
- lite_agent-0.4.1/src/lite_agent/processors/completion_event_processor.py +306 -0
- lite_agent-0.4.1/src/lite_agent/processors/response_event_processor.py +205 -0
- lite_agent-0.4.1/src/lite_agent/py.typed +0 -0
- lite_agent-0.4.1/src/lite_agent/runner.py +815 -0
- lite_agent-0.4.1/src/lite_agent/stream_handlers/__init__.py +6 -0
- lite_agent-0.4.1/src/lite_agent/stream_handlers/litellm.py +84 -0
- lite_agent-0.4.1/src/lite_agent/types/__init__.py +129 -0
- lite_agent-0.4.1/src/lite_agent/types/events.py +119 -0
- lite_agent-0.4.1/src/lite_agent/types/messages.py +343 -0
- {lite_agent-0.3.0 → lite_agent-0.4.1}/tests/integration/test_agent_with_mocks.py +9 -9
- {lite_agent-0.3.0 → lite_agent-0.4.1}/tests/integration/test_basic.py +2 -2
- {lite_agent-0.3.0 → lite_agent-0.4.1}/tests/integration/test_mock_litellm.py +1 -1
- {lite_agent-0.3.0 → lite_agent-0.4.1}/tests/mocks/basic/1.jsonl +32 -28
- lite_agent-0.4.1/tests/mocks/confirm_and_continue/1.jsonl +21 -0
- lite_agent-0.4.1/tests/mocks/confirm_and_continue/2.jsonl +37 -0
- lite_agent-0.4.1/tests/mocks/context/1.jsonl +19 -0
- {lite_agent-0.3.0 → lite_agent-0.4.1}/tests/performance/test_set_chat_history_performance.py +8 -6
- lite_agent-0.4.1/tests/test_new_messages.py +157 -0
- {lite_agent-0.3.0 → lite_agent-0.4.1}/tests/unit/test_agent.py +16 -16
- lite_agent-0.4.1/tests/unit/test_agent_additional.py +182 -0
- {lite_agent-0.3.0 → lite_agent-0.4.1}/tests/unit/test_agent_handoffs.py +67 -50
- {lite_agent-0.3.0 → lite_agent-0.4.1}/tests/unit/test_append_message.py +76 -39
- lite_agent-0.4.1/tests/unit/test_chat_display.py +247 -0
- lite_agent-0.4.1/tests/unit/test_chat_display_additional.py +304 -0
- {lite_agent-0.3.0 → lite_agent-0.4.1}/tests/unit/test_completion_condition.py +0 -1
- {lite_agent-0.3.0 → lite_agent-0.4.1}/tests/unit/test_file_recording.py +24 -24
- lite_agent-0.4.1/tests/unit/test_litellm_stream_handler.py +82 -0
- {lite_agent-0.3.0 → lite_agent-0.4.1}/tests/unit/test_message_transfer.py +5 -5
- lite_agent-0.4.1/tests/unit/test_message_transfers_additional.py +334 -0
- {lite_agent-0.3.0 → lite_agent-0.4.1}/tests/unit/test_response_api_format.py +44 -50
- lite_agent-0.4.1/tests/unit/test_response_event_processor.py +635 -0
- {lite_agent-0.3.0 → lite_agent-0.4.1}/tests/unit/test_runner.py +41 -35
- {lite_agent-0.3.0 → lite_agent-0.4.1}/tests/unit/test_set_chat_history.py +50 -51
- lite_agent-0.4.1/tests/unit/test_simple_stream_handlers.py +56 -0
- {lite_agent-0.3.0 → lite_agent-0.4.1}/tests/unit/test_stream_chunk_processor.py +2 -14
- lite_agent-0.4.1/tests/unit/test_stream_handlers_additional.py +262 -0
- {lite_agent-0.3.0 → lite_agent-0.4.1}/tests/utils/mock_litellm.py +58 -3
- {lite_agent-0.3.0 → lite_agent-0.4.1}/uv.lock +338 -275
- lite_agent-0.3.0/examples/responses.py +0 -42
- lite_agent-0.3.0/examples/simple_rich_example.py +0 -44
- lite_agent-0.3.0/pyrightconfig.json +0 -5
- lite_agent-0.3.0/src/lite_agent/__init__.py +0 -8
- lite_agent-0.3.0/src/lite_agent/client.py +0 -34
- lite_agent-0.3.0/src/lite_agent/processors/__init__.py +0 -3
- lite_agent-0.3.0/src/lite_agent/processors/stream_chunk_processor.py +0 -106
- lite_agent-0.3.0/src/lite_agent/rich_helpers.py +0 -503
- lite_agent-0.3.0/src/lite_agent/runner.py +0 -632
- lite_agent-0.3.0/src/lite_agent/stream_handlers/__init__.py +0 -5
- lite_agent-0.3.0/src/lite_agent/stream_handlers/litellm.py +0 -106
- lite_agent-0.3.0/src/lite_agent/types/__init__.py +0 -75
- lite_agent-0.3.0/src/lite_agent/types/chunks.py +0 -89
- lite_agent-0.3.0/src/lite_agent/types/messages.py +0 -135
- lite_agent-0.3.0/tests/mocks/confirm_and_continue/1.jsonl +0 -32
- lite_agent-0.3.0/tests/mocks/confirm_and_continue/2.jsonl +0 -36
- lite_agent-0.3.0/tests/mocks/context/1.jsonl +0 -14
- lite_agent-0.3.0/tests/unit/test_litellm_stream_handler.py +0 -162
- lite_agent-0.3.0/tests/unit/test_rich_helpers.py +0 -129
- {lite_agent-0.3.0 → lite_agent-0.4.1}/.github/workflows/ci.yml +0 -0
- {lite_agent-0.3.0 → lite_agent-0.4.1}/.gitignore +0 -0
- {lite_agent-0.3.0 → lite_agent-0.4.1}/.python-version +0 -0
- {lite_agent-0.3.0 → lite_agent-0.4.1}/README.md +0 -0
- {lite_agent-0.3.0 → lite_agent-0.4.1}/examples/response_api_example.py +0 -0
- /lite_agent-0.3.0/src/lite_agent/py.typed → /lite_agent-0.4.1/examples/translate.py +0 -0
- {lite_agent-0.3.0 → lite_agent-0.4.1}/scripts/record_chat_messages.py +0 -0
- {lite_agent-0.3.0 → lite_agent-0.4.1}/src/lite_agent/loggers.py +0 -0
- {lite_agent-0.3.0 → lite_agent-0.4.1}/src/lite_agent/templates/handoffs_source_instructions.xml.j2 +0 -0
- {lite_agent-0.3.0 → lite_agent-0.4.1}/src/lite_agent/templates/handoffs_target_instructions.xml.j2 +0 -0
- {lite_agent-0.3.0 → lite_agent-0.4.1}/src/lite_agent/templates/wait_for_user_instructions.xml.j2 +0 -0
- {lite_agent-0.3.0 → lite_agent-0.4.1}/src/lite_agent/types/tool_calls.py +0 -0
- {lite_agent-0.3.0 → lite_agent-0.4.1}/tests/mocks/handoffs/1.jsonl +0 -0
- {lite_agent-0.3.0 → lite_agent-0.4.1}/tests/unit/test_message_transfers.py +0 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json.schemastore.org/claude-code-settings.json",
|
|
3
|
+
"permissions": {
|
|
4
|
+
"allow": [
|
|
5
|
+
"Bash(pytest:*)",
|
|
6
|
+
"mcp__context7__resolve-library-id",
|
|
7
|
+
"mcp__context7__get-library-docs",
|
|
8
|
+
"Bash(ruff check:*)",
|
|
9
|
+
"Bash(python:*)",
|
|
10
|
+
"Bash(ruff format:*)",
|
|
11
|
+
"Bash(rm:*)",
|
|
12
|
+
"Bash(grep:*)",
|
|
13
|
+
"mcp__ide__getDiagnostics",
|
|
14
|
+
"Bash(uv run pytest:*)",
|
|
15
|
+
"Bash(timeout:*)",
|
|
16
|
+
"Bash(pyright:*)",
|
|
17
|
+
"Bash(rg:*)"
|
|
18
|
+
],
|
|
19
|
+
"deny": []
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -1,3 +1,69 @@
|
|
|
1
|
+
## v0.4.1
|
|
2
|
+
|
|
3
|
+
[v0.4.0...v0.4.1](https://github.com/Jannchie/lite-agent/compare/v0.4.0...v0.4.1)
|
|
4
|
+
|
|
5
|
+
### :art: Refactors
|
|
6
|
+
|
|
7
|
+
- **runner**: replace if-elif with match-case for chunk handling - By [Jannchie](mailto:jannchie@gmail.com) in [e9a8464](https://github.com/Jannchie/lite-agent/commit/e9a8464)
|
|
8
|
+
|
|
9
|
+
## v0.4.0
|
|
10
|
+
|
|
11
|
+
[v0.3.0...v0.4.0](https://github.com/Jannchie/lite-agent/compare/v0.3.0...v0.4.0)
|
|
12
|
+
|
|
13
|
+
### :rocket: Breaking Changes
|
|
14
|
+
|
|
15
|
+
- **agent**: unify message handling using new messages format - By [Jannchie](mailto:jannchie@gmail.com) in [f31769a](https://github.com/Jannchie/lite-agent/commit/f31769a)
|
|
16
|
+
- **chat-display**: remove display_chat_history usage and exports - By [Jannchie](mailto:jannchie@gmail.com) in [fca6ff7](https://github.com/Jannchie/lite-agent/commit/fca6ff7)
|
|
17
|
+
- **chat-display**: rename rich_helpers to chat_display and update related imports - By [Jannchie](mailto:panjianqi@preferred.jp) in [8bbd83b](https://github.com/Jannchie/lite-agent/commit/8bbd83b)
|
|
18
|
+
- **chunks**: rename tool_call and tool_call_result to function_call and function_call_output - By [Jannchie](mailto:jannchie@gmail.com) in [2821478](https://github.com/Jannchie/lite-agent/commit/2821478)
|
|
19
|
+
- **function-call**: rename function_call_id to call_id - By [Jannchie](mailto:jannchie@gmail.com) in [d415fce](https://github.com/Jannchie/lite-agent/commit/d415fce)
|
|
20
|
+
- **messages**: remove legacy function call messages and migrate to new assistant message structure - By [Jannchie](mailto:jannchie@gmail.com) in [c632629](https://github.com/Jannchie/lite-agent/commit/c632629)
|
|
21
|
+
- **messages**: remove conversion helpers and fully switch to new message format - By [Jannchie](mailto:jannchie@gmail.com) in [75e47bf](https://github.com/Jannchie/lite-agent/commit/75e47bf)
|
|
22
|
+
- **messages**: introduce new structured message types and unified message format - By [Jannchie](mailto:jannchie@gmail.com) in [cb8c091](https://github.com/Jannchie/lite-agent/commit/cb8c091)
|
|
23
|
+
- **processors**: rename stream_chunk_processor to completion_event_processor - By [Jannchie](mailto:jannchie@gmail.com) in [80dedb9](https://github.com/Jannchie/lite-agent/commit/80dedb9)
|
|
24
|
+
- **runner**: remove final_message type and streamline tool call handling - By [Jannchie](mailto:jannchie@gmail.com) in [ba91c29](https://github.com/Jannchie/lite-agent/commit/ba91c29)
|
|
25
|
+
- **types**: rename chunk types to event types and update references - By [Jannchie](mailto:jannchie@gmail.com) in [d1354b3](https://github.com/Jannchie/lite-agent/commit/d1354b3)
|
|
26
|
+
- **types**: remove finalmessagechunk type and usage - By [Jannchie](mailto:jannchie@gmail.com) in [6b3281e](https://github.com/Jannchie/lite-agent/commit/6b3281e)
|
|
27
|
+
|
|
28
|
+
### :sparkles: Features
|
|
29
|
+
|
|
30
|
+
- **chat-display**: add support for new message format - By [Jannchie](mailto:jannchie@gmail.com) in [a3fd1c6](https://github.com/Jannchie/lite-agent/commit/a3fd1c6)
|
|
31
|
+
- **chat-display**: add meta stats, local time, and message performance info to chat display and message types - By [Jannchie](mailto:jannchie@gmail.com) in [bda3346](https://github.com/Jannchie/lite-agent/commit/bda3346)
|
|
32
|
+
- **responses**: support new message format for response api - By [Jannchie](mailto:jannchie@gmail.com) in [e34a2ef](https://github.com/Jannchie/lite-agent/commit/e34a2ef)
|
|
33
|
+
- **responses**: add response streaming support and client methods - By [Jannchie](mailto:jannchie@gmail.com) in [f484530](https://github.com/Jannchie/lite-agent/commit/f484530)
|
|
34
|
+
- **rich-helpers**: add print_messages for compact output - By [Jannchie](mailto:panjianqi@preferred.jp) in [5a49203](https://github.com/Jannchie/lite-agent/commit/5a49203)
|
|
35
|
+
- **runner**: support interactive tool call confirmation in terminal && improve chunk handling - By [Jannchie](mailto:jannchie@gmail.com) in [7164284](https://github.com/Jannchie/lite-agent/commit/7164284)
|
|
36
|
+
|
|
37
|
+
### :adhesive_bandage: Fixes
|
|
38
|
+
|
|
39
|
+
- **agent**: use isinstance for to_llm_dict checks - By [Jannchie](mailto:jannchie@gmail.com) in [e996785](https://github.com/Jannchie/lite-agent/commit/e996785)
|
|
40
|
+
- **examples**: add content checks for dict messages - By [Jannchie](mailto:panjianqi@preferred.jp) in [94afcae](https://github.com/Jannchie/lite-agent/commit/94afcae)
|
|
41
|
+
- **import**: update stream_handler imports && fix response api logic - By [Jannchie](mailto:jannchie@gmail.com) in [be192da](https://github.com/Jannchie/lite-agent/commit/be192da)
|
|
42
|
+
- **input-image**: ensure file_id or image_url present and improve conversion handling - By [Jannchie](mailto:jannchie@gmail.com) in [d0bcdd5](https://github.com/Jannchie/lite-agent/commit/d0bcdd5)
|
|
43
|
+
- **runner**: improve wait_for_user finish detection - By [Jannchie](mailto:jannchie@gmail.com) in [98435b0](https://github.com/Jannchie/lite-agent/commit/98435b0)
|
|
44
|
+
- **runner**: fix final message processing to return responses - By [Jannchie](mailto:jannchie@gmail.com) in [e813f4a](https://github.com/Jannchie/lite-agent/commit/e813f4a)
|
|
45
|
+
- **stream-chunk-processor**: construct usage event with correct usage type - By [Jannchie](mailto:jannchie@gmail.com) in [89b2cbe](https://github.com/Jannchie/lite-agent/commit/89b2cbe)
|
|
46
|
+
- **tests**: improve type hints and patching mocks - By [Jannchie](mailto:jannchie@gmail.com) in [e4dfd64](https://github.com/Jannchie/lite-agent/commit/e4dfd64)
|
|
47
|
+
- **tests**: update patch paths for litellm.acompletion - By [Jannchie](mailto:jannchie@gmail.com) in [897a284](https://github.com/Jannchie/lite-agent/commit/897a284)
|
|
48
|
+
|
|
49
|
+
### :art: Refactors
|
|
50
|
+
|
|
51
|
+
- **examples**: replace final_message with assistant_message in includes - By [Jannchie](mailto:jannchie@gmail.com) in [c5431ab](https://github.com/Jannchie/lite-agent/commit/c5431ab)
|
|
52
|
+
- **runner**: simplify message appending logic && tidy code style - By [Jannchie](mailto:jannchie@gmail.com) in [412a8ec](https://github.com/Jannchie/lite-agent/commit/412a8ec)
|
|
53
|
+
- **runner**: replace api handling with match statement && set default api to responses - By [Jannchie](mailto:jannchie@gmail.com) in [75c823a](https://github.com/Jannchie/lite-agent/commit/75c823a)
|
|
54
|
+
- **stream-handlers**: rename litellm_stream_handler to litellm_completion_stream_handler && update imports and tests - By [Jannchie](mailto:jannchie@gmail.com) in [5b7ac92](https://github.com/Jannchie/lite-agent/commit/5b7ac92)
|
|
55
|
+
- **tests**: rename tool_call types to function_call && remove unused usage tests - By [Jannchie](mailto:jannchie@gmail.com) in [1e0992f](https://github.com/Jannchie/lite-agent/commit/1e0992f)
|
|
56
|
+
|
|
57
|
+
### :memo: Documentation
|
|
58
|
+
|
|
59
|
+
- add claude guidance documentation - By [Jannchie](mailto:panjianqi@preferred.jp) in [a741494](https://github.com/Jannchie/lite-agent/commit/a741494)
|
|
60
|
+
|
|
61
|
+
### :wrench: Chores
|
|
62
|
+
|
|
63
|
+
- **dependencies**: update lock file - By [Jannchie](mailto:jannchie@gmail.com) in [042f6f3](https://github.com/Jannchie/lite-agent/commit/042f6f3)
|
|
64
|
+
- **dev-deps**: add pytest-asyncio to dev dependencies - By [Jannchie](mailto:jannchie@gmail.com) in [57543cd](https://github.com/Jannchie/lite-agent/commit/57543cd)
|
|
65
|
+
- **lint**: remove commented ruff exclude config - By [Jannchie](mailto:jannchie@gmail.com) in [25635dd](https://github.com/Jannchie/lite-agent/commit/25635dd)
|
|
66
|
+
|
|
1
67
|
## v0.3.0
|
|
2
68
|
|
|
3
69
|
[v0.2.0...v0.3.0](https://github.com/Jannchie/lite-agent/compare/v0.2.0...v0.3.0)
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
## Development Commands
|
|
6
|
+
|
|
7
|
+
### Testing
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
pytest # Run all tests
|
|
11
|
+
pytest tests/unit/ # Run only unit tests
|
|
12
|
+
pytest tests/integration/ # Run only integration tests
|
|
13
|
+
pytest --cov # Run with coverage
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
### Linting and Formatting
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
ruff check # Run linter
|
|
20
|
+
ruff format # Format code
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### Package Management
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
uv add lite-agent # Install from PyPI
|
|
27
|
+
uv add --dev lite-agent # Install dev package
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Project Architecture
|
|
31
|
+
|
|
32
|
+
LiteAgent is a lightweight AI agent framework built on top of LiteLLM. The core architecture consists of:
|
|
33
|
+
|
|
34
|
+
### Core Components
|
|
35
|
+
|
|
36
|
+
**Agent (`src/lite_agent/agent.py`)**
|
|
37
|
+
|
|
38
|
+
- Central agent class that manages LLM interactions, tool calls, and message handling
|
|
39
|
+
- Supports tool registration via `funcall` library for type-safe function calling
|
|
40
|
+
- Handles agent handoffs (parent-child relationships) for complex workflows
|
|
41
|
+
- Manages completion conditions ("stop" vs "call" for different termination behaviors)
|
|
42
|
+
- Converts between OpenAI's Response API and Completion API message formats
|
|
43
|
+
|
|
44
|
+
**Runner (`src/lite_agent/runner.py`)**
|
|
45
|
+
|
|
46
|
+
- Orchestrates agent execution with streaming support
|
|
47
|
+
- Manages conversation flow and message history
|
|
48
|
+
- Handles tool call execution and agent transfers
|
|
49
|
+
- Supports continuation from previous states and chat history management
|
|
50
|
+
- Provides both streaming and batch execution modes
|
|
51
|
+
|
|
52
|
+
**Type System (`src/lite_agent/types/`)**
|
|
53
|
+
|
|
54
|
+
- Comprehensive Pydantic models for all message types and chunks
|
|
55
|
+
- Supports both Response API and Completion API formats
|
|
56
|
+
- Type-safe definitions for tool calls, chunks, and messages
|
|
57
|
+
|
|
58
|
+
### Key Features
|
|
59
|
+
|
|
60
|
+
**Tool Integration**
|
|
61
|
+
|
|
62
|
+
- Uses `funcall` library for automatic tool schema generation from Python functions
|
|
63
|
+
- Supports basic types, Pydantic models, and dataclasses as parameters
|
|
64
|
+
- Dynamic tool registration for agent handoffs and control flow
|
|
65
|
+
|
|
66
|
+
**Agent Handoffs**
|
|
67
|
+
|
|
68
|
+
- Parent-child agent relationships for complex task delegation
|
|
69
|
+
- Automatic `transfer_to_agent` and `transfer_to_parent` tool registration
|
|
70
|
+
- Chat history tracking across agent transitions
|
|
71
|
+
|
|
72
|
+
**Message Processing**
|
|
73
|
+
|
|
74
|
+
- Bidirectional conversion between OpenAI API formats
|
|
75
|
+
- Streaming chunk processing with configurable output filtering
|
|
76
|
+
- Message transfer callbacks for preprocessing
|
|
77
|
+
|
|
78
|
+
**Completion Modes**
|
|
79
|
+
|
|
80
|
+
- `"stop"`: Traditional completion until model decides to stop
|
|
81
|
+
- `"call"`: Completion until specific tool (`wait_for_user`) is called
|
|
82
|
+
|
|
83
|
+
### Examples Directory Structure
|
|
84
|
+
|
|
85
|
+
Examples demonstrate various usage patterns:
|
|
86
|
+
|
|
87
|
+
- `basic.py`: Simple agent with tool calling
|
|
88
|
+
- `handoffs.py`: Agent-to-agent transfers
|
|
89
|
+
- `context.py`: Context passing to tools
|
|
90
|
+
- `chat_display_demo.py`: Rich console output formatting
|
|
91
|
+
- `channels/`: Channel-based communication patterns
|
|
92
|
+
|
|
93
|
+
### Testing Architecture
|
|
94
|
+
|
|
95
|
+
- **Unit tests**: Test individual components in isolation
|
|
96
|
+
- **Integration tests**: Test full agent workflows with mocked LLM responses
|
|
97
|
+
- **Performance tests**: Test memory usage and performance characteristics
|
|
98
|
+
- **Mock system**: JSONL-based conversation recording/playback for deterministic testing
|
|
99
|
+
|
|
100
|
+
The framework emphasizes simplicity and extensibility while maintaining full type safety and comprehensive streaming support.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: lite-agent
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.1
|
|
4
4
|
Summary: A lightweight, extensible framework for building AI agent.
|
|
5
5
|
Author-email: Jianqi Pan <jannchie@gmail.com>
|
|
6
6
|
License: MIT
|
|
@@ -18,7 +18,7 @@ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
|
18
18
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
19
19
|
Requires-Python: >=3.10
|
|
20
20
|
Requires-Dist: aiofiles>=24.1.0
|
|
21
|
-
Requires-Dist: funcall>=0.
|
|
21
|
+
Requires-Dist: funcall>=0.10.0
|
|
22
22
|
Requires-Dist: prompt-toolkit>=3.0.51
|
|
23
23
|
Requires-Dist: rich>=14.0.0
|
|
24
24
|
Description-Content-Type: text/markdown
|
|
@@ -4,6 +4,7 @@ import logging
|
|
|
4
4
|
from rich.logging import RichHandler
|
|
5
5
|
|
|
6
6
|
from lite_agent.agent import Agent
|
|
7
|
+
from lite_agent.chat_display import display_messages
|
|
7
8
|
from lite_agent.runner import Runner
|
|
8
9
|
|
|
9
10
|
logging.basicConfig(
|
|
@@ -19,7 +20,6 @@ logger.setLevel(logging.DEBUG)
|
|
|
19
20
|
|
|
20
21
|
async def get_temperature(city: str) -> str:
|
|
21
22
|
"""Get the temperature for a city."""
|
|
22
|
-
await asyncio.sleep(1)
|
|
23
23
|
return f"The temperature in {city} is 25°C."
|
|
24
24
|
|
|
25
25
|
|
|
@@ -35,11 +35,11 @@ async def main():
|
|
|
35
35
|
runner = Runner(agent)
|
|
36
36
|
resp = runner.run(
|
|
37
37
|
"What is the temperature in New York?",
|
|
38
|
-
includes=["
|
|
39
|
-
record_to="tests/mocks/basic/1.jsonl",
|
|
38
|
+
includes=["usage", "assistant_message", "function_call", "function_call_output", "timing"],
|
|
40
39
|
)
|
|
41
40
|
async for chunk in resp:
|
|
42
41
|
logger.info(chunk)
|
|
42
|
+
display_messages(runner.messages)
|
|
43
43
|
print(runner.messages)
|
|
44
44
|
|
|
45
45
|
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
import logging
|
|
3
|
+
|
|
4
|
+
from rich.logging import RichHandler
|
|
5
|
+
|
|
6
|
+
from lite_agent.agent import Agent
|
|
7
|
+
|
|
8
|
+
logging.basicConfig(
|
|
9
|
+
level=logging.WARNING,
|
|
10
|
+
format="%(message)s",
|
|
11
|
+
datefmt="[%X]",
|
|
12
|
+
handlers=[RichHandler(rich_tracebacks=True)],
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
logger = logging.getLogger("lite_agent")
|
|
16
|
+
logger.setLevel(logging.DEBUG)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
async def get_temperature(city: str) -> str:
|
|
20
|
+
"""Get the temperature for a city."""
|
|
21
|
+
await asyncio.sleep(1)
|
|
22
|
+
return f"The temperature in {city} is 25°C."
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
async def get_whether(city: str) -> str:
|
|
26
|
+
"""Get the weather for a city."""
|
|
27
|
+
await asyncio.sleep(1)
|
|
28
|
+
return f"The weather in {city} is sunny with a few clouds."
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
agent = Agent(
|
|
32
|
+
model="gpt-4.1-nano",
|
|
33
|
+
name="Weather Assistant",
|
|
34
|
+
instructions="You are a helpful weather assistant. Before using tools, briefly explain what you are going to do. Provide friendly and informative responses.",
|
|
35
|
+
tools=[get_temperature, get_whether],
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
async def main():
|
|
40
|
+
resp = await agent.completion(
|
|
41
|
+
[
|
|
42
|
+
{
|
|
43
|
+
"role": "user",
|
|
44
|
+
"content": "What is the temperature and whether in New York?",
|
|
45
|
+
},
|
|
46
|
+
],
|
|
47
|
+
)
|
|
48
|
+
async for chunk in resp:
|
|
49
|
+
if chunk.type != "completion_raw":
|
|
50
|
+
logger.info(chunk)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
if __name__ == "__main__":
|
|
54
|
+
asyncio.run(main())
|
|
@@ -1,31 +1,32 @@
|
|
|
1
1
|
from rich.console import Console
|
|
2
2
|
|
|
3
|
-
from lite_agent.types import AgentChunk,
|
|
3
|
+
from lite_agent.types import AgentChunk, ContentDeltaEvent
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
class RichChannel:
|
|
7
7
|
def __init__(self) -> None:
|
|
8
8
|
self.console = Console()
|
|
9
9
|
self.map = {
|
|
10
|
-
"
|
|
11
|
-
"
|
|
12
|
-
"
|
|
13
|
-
"tool_call_delta": self.handle_tool_call_delta,
|
|
10
|
+
"function_call": self.handle_tool_call,
|
|
11
|
+
"function_call_output": self.handle_tool_call_result,
|
|
12
|
+
"function_call_delta": self.handle_function_call_delta,
|
|
14
13
|
"content_delta": self.handle_content_delta,
|
|
15
14
|
"usage": self.handle_usage,
|
|
16
|
-
"require_confirm": self.handle_require_confirm,
|
|
17
15
|
}
|
|
18
|
-
self.
|
|
16
|
+
self._new_turn = True
|
|
19
17
|
|
|
20
18
|
async def handle(self, chunk: AgentChunk):
|
|
21
|
-
handler = self.map
|
|
22
|
-
|
|
19
|
+
handler = self.map.get(chunk.type)
|
|
20
|
+
if handler is None:
|
|
21
|
+
return None
|
|
22
|
+
return await handler(chunk) # type: ignore
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
def new_turn(self):
|
|
25
25
|
print()
|
|
26
|
-
self.
|
|
26
|
+
self._new_turn = True
|
|
27
27
|
|
|
28
28
|
async def handle_tool_call(self, chunk: AgentChunk):
|
|
29
|
+
print()
|
|
29
30
|
name = getattr(chunk, "name", "<unknown>")
|
|
30
31
|
arguments = getattr(chunk, "arguments", "")
|
|
31
32
|
self.console.print(f"🛠️ [green]{name}[/green]([yellow]{arguments}[/yellow])")
|
|
@@ -35,16 +36,14 @@ class RichChannel:
|
|
|
35
36
|
content = getattr(chunk, "content", "")
|
|
36
37
|
self.console.print(f"🛠️ [green]{name}[/green] → [yellow]{content}[/yellow]")
|
|
37
38
|
|
|
38
|
-
async def
|
|
39
|
-
async def handle_content_delta(self, chunk:
|
|
40
|
-
if self.
|
|
39
|
+
async def handle_function_call_delta(self, chunk: AgentChunk): ...
|
|
40
|
+
async def handle_content_delta(self, chunk: ContentDeltaEvent):
|
|
41
|
+
if self._new_turn:
|
|
41
42
|
self.console.print("🤖 ", end="")
|
|
42
|
-
self.
|
|
43
|
+
self._new_turn = False
|
|
43
44
|
print(chunk.delta, end="", flush=True)
|
|
44
45
|
|
|
45
46
|
async def handle_usage(self, chunk: AgentChunk):
|
|
46
47
|
if False:
|
|
47
48
|
usage = chunk.usage
|
|
48
49
|
self.console.print(f"In: {usage.prompt_tokens}, Out: {usage.completion_tokens}, Total: {usage.total_tokens}")
|
|
49
|
-
|
|
50
|
-
async def handle_require_confirm(self, chunk: AgentChunk): ...
|
lite_agent-0.3.0/examples/rich_helpers_demo.py → lite_agent-0.4.1/examples/chat_display_demo.py
RENAMED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
"""
|
|
2
|
-
示例:使用
|
|
2
|
+
示例:使用 chat_display 美观显示聊天记录
|
|
3
3
|
|
|
4
|
-
这个示例展示了如何使用
|
|
4
|
+
这个示例展示了如何使用 chat_display 模块中的函数来美观地显示聊天记录。
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
7
|
import asyncio
|
|
8
8
|
|
|
9
|
+
from lite_agent import display_messages
|
|
9
10
|
from lite_agent.agent import Agent
|
|
10
|
-
from lite_agent.rich_helpers import print_chat_history, print_chat_summary
|
|
11
11
|
from lite_agent.runner import Runner
|
|
12
12
|
|
|
13
13
|
|
|
@@ -53,7 +53,7 @@ async def create_sample_chat_history() -> Runner:
|
|
|
53
53
|
runner.append_message(
|
|
54
54
|
{
|
|
55
55
|
"type": "function_call",
|
|
56
|
-
"
|
|
56
|
+
"call_id": "call_123",
|
|
57
57
|
"name": "get_weather",
|
|
58
58
|
"arguments": '{"city": "Tokyo"}',
|
|
59
59
|
"content": "",
|
|
@@ -76,7 +76,7 @@ async def create_sample_chat_history() -> Runner:
|
|
|
76
76
|
runner.append_message(
|
|
77
77
|
{
|
|
78
78
|
"type": "function_call",
|
|
79
|
-
"
|
|
79
|
+
"call_id": "call_456",
|
|
80
80
|
"name": "calculate",
|
|
81
81
|
"arguments": '{"expression": "25 * 4 + 10"}',
|
|
82
82
|
"content": "",
|
|
@@ -97,32 +97,15 @@ async def create_sample_chat_history() -> Runner:
|
|
|
97
97
|
|
|
98
98
|
|
|
99
99
|
async def main():
|
|
100
|
-
"""主函数:演示
|
|
101
|
-
print("🎨
|
|
100
|
+
"""主函数:演示 chat_display 的使用。"""
|
|
101
|
+
print("🎨 Chat Display Demo\n")
|
|
102
102
|
|
|
103
103
|
# 创建示例聊天历史
|
|
104
104
|
runner = await create_sample_chat_history()
|
|
105
105
|
|
|
106
|
-
#
|
|
107
|
-
|
|
108
|
-
print_chat_summary(runner.messages)
|
|
109
|
-
print()
|
|
110
|
-
|
|
111
|
-
# 2. 渲染完整的聊天历史
|
|
112
|
-
print("💬 Full Chat History:")
|
|
113
|
-
print_chat_history(runner.messages)
|
|
114
|
-
|
|
115
|
-
# 3. 展示不同的渲染选项
|
|
116
|
-
print("\n" + "=" * 60)
|
|
117
|
-
print("🎛️ Different Rendering Options:")
|
|
118
|
-
print("=" * 60)
|
|
119
|
-
|
|
120
|
-
# 不显示时间戳和索引
|
|
121
|
-
print("\n📝 Without timestamps and indices:")
|
|
122
|
-
print_chat_history(
|
|
106
|
+
# print demo
|
|
107
|
+
display_messages(
|
|
123
108
|
runner.messages,
|
|
124
|
-
show_timestamps=False,
|
|
125
|
-
show_indices=False,
|
|
126
109
|
)
|
|
127
110
|
|
|
128
111
|
|
|
@@ -43,13 +43,13 @@ async def main():
|
|
|
43
43
|
runner = Runner(agent)
|
|
44
44
|
resp = runner.run(
|
|
45
45
|
"What is the weather in New York? And what is the temperature there?",
|
|
46
|
-
includes=["
|
|
46
|
+
includes=["usage", "assistant_message", "function_call", "function_call_output"],
|
|
47
47
|
record_to="tests/mocks/confirm_and_continue/1.jsonl",
|
|
48
48
|
)
|
|
49
49
|
async for chunk in resp:
|
|
50
50
|
logger.info(chunk)
|
|
51
51
|
resp = runner.run_continue_stream(
|
|
52
|
-
includes=["
|
|
52
|
+
includes=["usage", "assistant_message", "function_call", "function_call_output"],
|
|
53
53
|
record_to="tests/mocks/confirm_and_continue/2.jsonl",
|
|
54
54
|
)
|
|
55
55
|
async for chunk in resp:
|
|
@@ -26,7 +26,7 @@ def test_consolidate_history():
|
|
|
26
26
|
print("Consolidated messages count:", len(result))
|
|
27
27
|
print("\nConsolidated content:")
|
|
28
28
|
print("=" * 50)
|
|
29
|
-
if result and isinstance(result[0], dict):
|
|
29
|
+
if result and isinstance(result[0], dict) and "content" in result[0]:
|
|
30
30
|
print(result[0]["content"])
|
|
31
31
|
print("=" * 50)
|
|
32
32
|
|
|
@@ -38,7 +38,7 @@ def test_consolidate_history():
|
|
|
38
38
|
single_message = [{"role": "user", "content": "Just a simple test"}]
|
|
39
39
|
single_result = consolidate_history_transfer(single_message)
|
|
40
40
|
print(f"\nSingle message result count: {len(single_result)}")
|
|
41
|
-
if single_result and isinstance(single_result[0], dict):
|
|
41
|
+
if single_result and isinstance(single_result[0], dict) and "content" in single_result[0]:
|
|
42
42
|
print("Single message consolidated content:")
|
|
43
43
|
print(single_result[0]["content"])
|
|
44
44
|
|
|
@@ -2,9 +2,10 @@ import asyncio
|
|
|
2
2
|
import logging
|
|
3
3
|
|
|
4
4
|
from funcall import Context
|
|
5
|
+
from pydantic import BaseModel
|
|
5
6
|
from rich.logging import RichHandler
|
|
6
7
|
|
|
7
|
-
from lite_agent.agent import Agent
|
|
8
|
+
from lite_agent.agent import Agent
|
|
8
9
|
from lite_agent.runner import Runner
|
|
9
10
|
|
|
10
11
|
|
|
@@ -47,7 +48,7 @@ async def main():
|
|
|
47
48
|
runner = Runner(agent)
|
|
48
49
|
resp = runner.run(
|
|
49
50
|
"What is the temperature in current city?",
|
|
50
|
-
includes=["
|
|
51
|
+
includes=["assistant_message", "usage", "function_call", "function_call_output"],
|
|
51
52
|
record_to="tests/mocks/context/1.jsonl",
|
|
52
53
|
context=weather_context,
|
|
53
54
|
)
|
|
@@ -65,7 +65,7 @@ async def main():
|
|
|
65
65
|
runner = Runner(parent)
|
|
66
66
|
resp = runner.run(
|
|
67
67
|
"Hello, I need to check the whether and temperature of Tokyo.",
|
|
68
|
-
includes=["
|
|
68
|
+
includes=["assistant_message", "function_call", "function_call_output"],
|
|
69
69
|
record_to="tests/mocks/handoffs/1.jsonl",
|
|
70
70
|
)
|
|
71
71
|
async for message in resp:
|
|
@@ -10,10 +10,12 @@ import re
|
|
|
10
10
|
from lite_agent.agent import Agent
|
|
11
11
|
from lite_agent.message_transfers import consolidate_history_transfer
|
|
12
12
|
from lite_agent.types import (
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
AssistantTextContent,
|
|
14
|
+
NewAssistantMessage,
|
|
15
|
+
NewSystemMessage,
|
|
16
|
+
NewUserMessage,
|
|
16
17
|
RunnerMessages,
|
|
18
|
+
UserTextContent,
|
|
17
19
|
)
|
|
18
20
|
|
|
19
21
|
|
|
@@ -40,11 +42,13 @@ def example_message_transfer(messages: RunnerMessages) -> RunnerMessages:
|
|
|
40
42
|
processed_messages.append(processed_message)
|
|
41
43
|
else:
|
|
42
44
|
processed_messages.append(message)
|
|
43
|
-
elif isinstance(message,
|
|
45
|
+
elif isinstance(message, NewUserMessage):
|
|
44
46
|
# Handle user message models
|
|
45
47
|
processed_message = message.model_copy()
|
|
46
|
-
|
|
47
|
-
|
|
48
|
+
# Process text content items
|
|
49
|
+
for i, content_item in enumerate(processed_message.content):
|
|
50
|
+
if isinstance(content_item, UserTextContent):
|
|
51
|
+
processed_message.content[i] = UserTextContent(text=f"[PROCESSED] {content_item.text}")
|
|
48
52
|
processed_messages.append(processed_message)
|
|
49
53
|
else:
|
|
50
54
|
# Keep other messages unchanged
|
|
@@ -83,14 +87,27 @@ def privacy_filter_transfer(messages: RunnerMessages) -> RunnerMessages:
|
|
|
83
87
|
processed_messages.append(processed_message)
|
|
84
88
|
else:
|
|
85
89
|
processed_messages.append(message)
|
|
86
|
-
elif isinstance(message,
|
|
87
|
-
# Handle message
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
90
|
+
elif isinstance(message, NewSystemMessage):
|
|
91
|
+
# Handle system message with string content
|
|
92
|
+
processed_message = message.model_copy()
|
|
93
|
+
processed_message.content = filter_content(message.content)
|
|
94
|
+
processed_messages.append(processed_message)
|
|
95
|
+
elif isinstance(message, NewUserMessage):
|
|
96
|
+
# Handle user message models with content list
|
|
97
|
+
processed_message = message.model_copy()
|
|
98
|
+
# Process text content items
|
|
99
|
+
for i, content_item in enumerate(processed_message.content):
|
|
100
|
+
if isinstance(content_item, UserTextContent):
|
|
101
|
+
processed_message.content[i] = UserTextContent(text=filter_content(content_item.text))
|
|
102
|
+
processed_messages.append(processed_message)
|
|
103
|
+
elif isinstance(message, NewAssistantMessage):
|
|
104
|
+
# Handle assistant message models with content list
|
|
105
|
+
processed_message = message.model_copy()
|
|
106
|
+
# Process text content items
|
|
107
|
+
for i, content_item in enumerate(processed_message.content):
|
|
108
|
+
if isinstance(content_item, AssistantTextContent):
|
|
109
|
+
processed_message.content[i] = AssistantTextContent(text=filter_content(content_item.text))
|
|
110
|
+
processed_messages.append(processed_message)
|
|
94
111
|
else:
|
|
95
112
|
# Keep other message types unchanged
|
|
96
113
|
processed_messages.append(message)
|