lite-agent 0.4.1__tar.gz → 0.6.0__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 → lite_agent-0.6.0}/.claude/settings.local.json +2 -1
- {lite_agent-0.4.1 → lite_agent-0.6.0}/CHANGELOG.md +25 -0
- {lite_agent-0.4.1 → lite_agent-0.6.0}/CLAUDE.md +47 -6
- {lite_agent-0.4.1 → lite_agent-0.6.0}/PKG-INFO +1 -1
- lite_agent-0.6.0/examples/basic_model.py +53 -0
- lite_agent-0.6.0/examples/debug_non_streaming.py +56 -0
- lite_agent-0.6.0/examples/debug_with_logging.py +38 -0
- lite_agent-0.6.0/examples/llm_config_demo.py +90 -0
- lite_agent-0.6.0/examples/non_streaming.py +64 -0
- lite_agent-0.6.0/examples/reasoning_example.py +113 -0
- lite_agent-0.6.0/examples/simple_debug.py +36 -0
- lite_agent-0.6.0/examples/simple_debug2.py +30 -0
- lite_agent-0.6.0/examples/streaming_demo.py +73 -0
- {lite_agent-0.4.1 → lite_agent-0.6.0}/pyproject.toml +2 -1
- {lite_agent-0.4.1 → lite_agent-0.6.0}/src/lite_agent/agent.py +35 -13
- {lite_agent-0.4.1 → lite_agent-0.6.0}/src/lite_agent/chat_display.py +1 -1
- lite_agent-0.6.0/src/lite_agent/client.py +236 -0
- lite_agent-0.6.0/src/lite_agent/response_handlers/__init__.py +10 -0
- lite_agent-0.6.0/src/lite_agent/response_handlers/base.py +46 -0
- lite_agent-0.6.0/src/lite_agent/response_handlers/completion.py +50 -0
- lite_agent-0.6.0/src/lite_agent/response_handlers/responses.py +42 -0
- {lite_agent-0.4.1 → lite_agent-0.6.0}/src/lite_agent/runner.py +35 -10
- {lite_agent-0.4.1 → lite_agent-0.6.0}/tests/unit/test_agent.py +8 -8
- {lite_agent-0.4.1 → lite_agent-0.6.0}/tests/unit/test_message_transfer.py +2 -2
- {lite_agent-0.4.1 → lite_agent-0.6.0}/tests/unit/test_runner.py +3 -18
- lite_agent-0.6.0/tests/unit/test_streaming_config.py +97 -0
- {lite_agent-0.4.1 → lite_agent-0.6.0}/tests/utils/mock_litellm.py +1 -2
- {lite_agent-0.4.1 → lite_agent-0.6.0}/uv.lock +438 -423
- lite_agent-0.4.1/src/lite_agent/client.py +0 -69
- {lite_agent-0.4.1 → lite_agent-0.6.0}/.github/workflows/ci.yml +0 -0
- {lite_agent-0.4.1 → lite_agent-0.6.0}/.gitignore +0 -0
- {lite_agent-0.4.1 → lite_agent-0.6.0}/.python-version +0 -0
- {lite_agent-0.4.1 → lite_agent-0.6.0}/.vscode/launch.json +0 -0
- {lite_agent-0.4.1 → lite_agent-0.6.0}/README.md +0 -0
- {lite_agent-0.4.1 → lite_agent-0.6.0}/examples/basic.py +0 -0
- {lite_agent-0.4.1 → lite_agent-0.6.0}/examples/basic_agent.py +0 -0
- {lite_agent-0.4.1 → lite_agent-0.6.0}/examples/channels/rich_channel.py +0 -0
- {lite_agent-0.4.1 → lite_agent-0.6.0}/examples/chat_display_demo.py +0 -0
- {lite_agent-0.4.1 → lite_agent-0.6.0}/examples/confirm_and_continue.py +0 -0
- {lite_agent-0.4.1 → lite_agent-0.6.0}/examples/consolidate_history.py +0 -0
- {lite_agent-0.4.1 → lite_agent-0.6.0}/examples/context.py +0 -0
- {lite_agent-0.4.1 → lite_agent-0.6.0}/examples/handoffs.py +0 -0
- {lite_agent-0.4.1 → lite_agent-0.6.0}/examples/image.py +0 -0
- {lite_agent-0.4.1 → lite_agent-0.6.0}/examples/message_transfer_example.py +0 -0
- {lite_agent-0.4.1 → lite_agent-0.6.0}/examples/message_transfer_example_new.py +0 -0
- {lite_agent-0.4.1 → lite_agent-0.6.0}/examples/new_message_structure_demo.py +0 -0
- {lite_agent-0.4.1 → lite_agent-0.6.0}/examples/response_api_example.py +0 -0
- {lite_agent-0.4.1 → lite_agent-0.6.0}/examples/responses.py +0 -0
- {lite_agent-0.4.1 → lite_agent-0.6.0}/examples/set_chat_history_example.py +0 -0
- {lite_agent-0.4.1 → lite_agent-0.6.0}/examples/stop_with_tool_call.py +0 -0
- {lite_agent-0.4.1 → lite_agent-0.6.0}/examples/terminal.py +0 -0
- {lite_agent-0.4.1 → lite_agent-0.6.0}/examples/translate/main.py +0 -0
- {lite_agent-0.4.1 → lite_agent-0.6.0}/examples/translate/prompts/translation_system.md.j2 +0 -0
- {lite_agent-0.4.1 → lite_agent-0.6.0}/examples/translate.py +0 -0
- {lite_agent-0.4.1 → lite_agent-0.6.0}/examples/type_system_example.py +0 -0
- {lite_agent-0.4.1 → lite_agent-0.6.0}/scripts/record_chat_messages.py +0 -0
- {lite_agent-0.4.1 → lite_agent-0.6.0}/src/lite_agent/__init__.py +0 -0
- {lite_agent-0.4.1 → lite_agent-0.6.0}/src/lite_agent/loggers.py +0 -0
- {lite_agent-0.4.1 → lite_agent-0.6.0}/src/lite_agent/message_transfers.py +0 -0
- {lite_agent-0.4.1 → lite_agent-0.6.0}/src/lite_agent/processors/__init__.py +0 -0
- {lite_agent-0.4.1 → lite_agent-0.6.0}/src/lite_agent/processors/completion_event_processor.py +0 -0
- {lite_agent-0.4.1 → lite_agent-0.6.0}/src/lite_agent/processors/response_event_processor.py +0 -0
- {lite_agent-0.4.1 → lite_agent-0.6.0}/src/lite_agent/py.typed +0 -0
- {lite_agent-0.4.1 → lite_agent-0.6.0}/src/lite_agent/stream_handlers/__init__.py +0 -0
- {lite_agent-0.4.1 → lite_agent-0.6.0}/src/lite_agent/stream_handlers/litellm.py +0 -0
- {lite_agent-0.4.1 → lite_agent-0.6.0}/src/lite_agent/templates/handoffs_source_instructions.xml.j2 +0 -0
- {lite_agent-0.4.1 → lite_agent-0.6.0}/src/lite_agent/templates/handoffs_target_instructions.xml.j2 +0 -0
- {lite_agent-0.4.1 → lite_agent-0.6.0}/src/lite_agent/templates/wait_for_user_instructions.xml.j2 +0 -0
- {lite_agent-0.4.1 → lite_agent-0.6.0}/src/lite_agent/types/__init__.py +0 -0
- {lite_agent-0.4.1 → lite_agent-0.6.0}/src/lite_agent/types/events.py +0 -0
- {lite_agent-0.4.1 → lite_agent-0.6.0}/src/lite_agent/types/messages.py +0 -0
- {lite_agent-0.4.1 → lite_agent-0.6.0}/src/lite_agent/types/tool_calls.py +0 -0
- {lite_agent-0.4.1 → lite_agent-0.6.0}/tests/integration/test_agent_with_mocks.py +0 -0
- {lite_agent-0.4.1 → lite_agent-0.6.0}/tests/integration/test_basic.py +0 -0
- {lite_agent-0.4.1 → lite_agent-0.6.0}/tests/integration/test_mock_litellm.py +0 -0
- {lite_agent-0.4.1 → lite_agent-0.6.0}/tests/mocks/basic/1.jsonl +0 -0
- {lite_agent-0.4.1 → lite_agent-0.6.0}/tests/mocks/confirm_and_continue/1.jsonl +0 -0
- {lite_agent-0.4.1 → lite_agent-0.6.0}/tests/mocks/confirm_and_continue/2.jsonl +0 -0
- {lite_agent-0.4.1 → lite_agent-0.6.0}/tests/mocks/context/1.jsonl +0 -0
- {lite_agent-0.4.1 → lite_agent-0.6.0}/tests/mocks/handoffs/1.jsonl +0 -0
- {lite_agent-0.4.1 → lite_agent-0.6.0}/tests/performance/test_set_chat_history_performance.py +0 -0
- {lite_agent-0.4.1 → lite_agent-0.6.0}/tests/test_new_messages.py +0 -0
- {lite_agent-0.4.1 → lite_agent-0.6.0}/tests/unit/test_agent_additional.py +0 -0
- {lite_agent-0.4.1 → lite_agent-0.6.0}/tests/unit/test_agent_handoffs.py +0 -0
- {lite_agent-0.4.1 → lite_agent-0.6.0}/tests/unit/test_append_message.py +0 -0
- {lite_agent-0.4.1 → lite_agent-0.6.0}/tests/unit/test_chat_display.py +0 -0
- {lite_agent-0.4.1 → lite_agent-0.6.0}/tests/unit/test_chat_display_additional.py +0 -0
- {lite_agent-0.4.1 → lite_agent-0.6.0}/tests/unit/test_completion_condition.py +0 -0
- {lite_agent-0.4.1 → lite_agent-0.6.0}/tests/unit/test_file_recording.py +0 -0
- {lite_agent-0.4.1 → lite_agent-0.6.0}/tests/unit/test_litellm_stream_handler.py +0 -0
- {lite_agent-0.4.1 → lite_agent-0.6.0}/tests/unit/test_message_transfers.py +0 -0
- {lite_agent-0.4.1 → lite_agent-0.6.0}/tests/unit/test_message_transfers_additional.py +0 -0
- {lite_agent-0.4.1 → lite_agent-0.6.0}/tests/unit/test_response_api_format.py +0 -0
- {lite_agent-0.4.1 → lite_agent-0.6.0}/tests/unit/test_response_event_processor.py +0 -0
- {lite_agent-0.4.1 → lite_agent-0.6.0}/tests/unit/test_set_chat_history.py +0 -0
- {lite_agent-0.4.1 → lite_agent-0.6.0}/tests/unit/test_simple_stream_handlers.py +0 -0
- {lite_agent-0.4.1 → lite_agent-0.6.0}/tests/unit/test_stream_chunk_processor.py +0 -0
- {lite_agent-0.4.1 → lite_agent-0.6.0}/tests/unit/test_stream_handlers_additional.py +0 -0
|
@@ -1,3 +1,28 @@
|
|
|
1
|
+
## v0.6.0
|
|
2
|
+
|
|
3
|
+
[v0.5.0...v0.6.0](https://github.com/Jannchie/lite-agent/compare/v0.5.0...v0.6.0)
|
|
4
|
+
|
|
5
|
+
### :sparkles: Features
|
|
6
|
+
|
|
7
|
+
- **examples**: add basic and llm config usage examples - By [Jannchie](mailto:jannchie@gmail.com) in [ea4112f](https://github.com/Jannchie/lite-agent/commit/ea4112f)
|
|
8
|
+
- **streaming**: add unified streaming and non-streaming response handling - By [Jannchie](mailto:jannchie@gmail.com) in [53daf42](https://github.com/Jannchie/lite-agent/commit/53daf42)
|
|
9
|
+
|
|
10
|
+
## v0.5.0
|
|
11
|
+
|
|
12
|
+
[v0.4.1...v0.5.0](https://github.com/Jannchie/lite-agent/compare/v0.4.1...v0.5.0)
|
|
13
|
+
|
|
14
|
+
### :sparkles: Features
|
|
15
|
+
|
|
16
|
+
- **reasoning**: add unified reasoning config for agent and runner - By [Jannchie](mailto:jannchie@gmail.com) in [1ede077](https://github.com/Jannchie/lite-agent/commit/1ede077)
|
|
17
|
+
|
|
18
|
+
### :adhesive_bandage: Fixes
|
|
19
|
+
|
|
20
|
+
- **runner**: remove redundant last message check - By [Jannchie](mailto:jannchie@gmail.com) in [0037b96](https://github.com/Jannchie/lite-agent/commit/0037b96)
|
|
21
|
+
|
|
22
|
+
### :memo: Documentation
|
|
23
|
+
|
|
24
|
+
- **claude-guide**: expand testing linting and dev instructions - By [Jannchie](mailto:jannchie@gmail.com) in [d9136c2](https://github.com/Jannchie/lite-agent/commit/d9136c2)
|
|
25
|
+
|
|
1
26
|
## v0.4.1
|
|
2
27
|
|
|
3
28
|
[v0.4.0...v0.4.1](https://github.com/Jannchie/lite-agent/compare/v0.4.0...v0.4.1)
|
|
@@ -10,21 +10,40 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
|
|
|
10
10
|
pytest # Run all tests
|
|
11
11
|
pytest tests/unit/ # Run only unit tests
|
|
12
12
|
pytest tests/integration/ # Run only integration tests
|
|
13
|
+
pytest tests/performance/ # Run performance tests
|
|
13
14
|
pytest --cov # Run with coverage
|
|
15
|
+
pytest -v # Verbose output
|
|
16
|
+
pytest -k "test_name" # Run specific test
|
|
14
17
|
```
|
|
15
18
|
|
|
16
19
|
### Linting and Formatting
|
|
17
20
|
|
|
18
21
|
```bash
|
|
19
22
|
ruff check # Run linter
|
|
23
|
+
ruff check --fix # Run linter and auto-fix issues
|
|
20
24
|
ruff format # Format code
|
|
25
|
+
pyright # Type checking (optional)
|
|
21
26
|
```
|
|
22
27
|
|
|
23
28
|
### Package Management
|
|
24
29
|
|
|
25
30
|
```bash
|
|
26
|
-
uv
|
|
27
|
-
uv add
|
|
31
|
+
uv install # Install all dependencies
|
|
32
|
+
uv add <package> # Add a new dependency
|
|
33
|
+
uv add --dev <package> # Add a development dependency
|
|
34
|
+
uv sync # Sync dependencies from lock file
|
|
35
|
+
uv run <command> # Run command in project environment
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### Running Examples
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
uv run python examples/basic.py
|
|
42
|
+
uv run python examples/handoffs.py
|
|
43
|
+
uv run python examples/chat_display_demo.py
|
|
44
|
+
uv run python examples/context.py
|
|
45
|
+
uv run python examples/terminal.py
|
|
46
|
+
uv run python examples/translate/main.py
|
|
28
47
|
```
|
|
29
48
|
|
|
30
49
|
## Project Architecture
|
|
@@ -92,9 +111,31 @@ Examples demonstrate various usage patterns:
|
|
|
92
111
|
|
|
93
112
|
### Testing Architecture
|
|
94
113
|
|
|
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
|
|
114
|
+
- **Unit tests**: Test individual components in isolation (`tests/unit/`)
|
|
115
|
+
- **Integration tests**: Test full agent workflows with mocked LLM responses (`tests/integration/`)
|
|
116
|
+
- **Performance tests**: Test memory usage and performance characteristics (`tests/performance/`)
|
|
117
|
+
- **Mock system**: JSONL-based conversation recording/playback for deterministic testing (`tests/mocks/`)
|
|
118
|
+
|
|
119
|
+
**Recording Mock Conversations**: Use `scripts/record_chat_messages.py` to capture real LLM interactions for test scenarios
|
|
120
|
+
|
|
121
|
+
### API Compatibility
|
|
122
|
+
|
|
123
|
+
The framework supports two OpenAI API modes:
|
|
124
|
+
|
|
125
|
+
- **Response API** (default): Modern structured response format
|
|
126
|
+
- **Completion API**: Legacy completion format for backward compatibility
|
|
127
|
+
|
|
128
|
+
Set via `Runner(agent, api="completion")` or `Runner(agent, api="responses")`.
|
|
129
|
+
|
|
130
|
+
### Development Notes
|
|
131
|
+
|
|
132
|
+
- Project uses strict ruff linting with `select = ["ALL"]` and specific ignores
|
|
133
|
+
- All functions require full type annotations
|
|
134
|
+
- Uses `uv` for package management and dependency resolution
|
|
135
|
+
- Mock conversations stored in `tests/mocks/` as JSONL files for reproducible testing
|
|
136
|
+
- Examples in `examples/` directory demonstrate various usage patterns
|
|
137
|
+
- Template system uses Jinja2 for dynamic instruction generation (`src/lite_agent/templates/`)
|
|
138
|
+
- Requires `litellm` as core dependency for LLM interactions
|
|
139
|
+
- Chat display functionality uses `rich` library for formatted console output
|
|
99
140
|
|
|
100
141
|
The framework emphasizes simplicity and extensibility while maintaining full type safety and comprehensive streaming support.
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
import logging
|
|
3
|
+
|
|
4
|
+
from rich.logging import RichHandler
|
|
5
|
+
|
|
6
|
+
from lite_agent.agent import Agent
|
|
7
|
+
from lite_agent.chat_display import display_messages
|
|
8
|
+
from lite_agent.client import LiteLLMClient
|
|
9
|
+
from lite_agent.runner import Runner
|
|
10
|
+
|
|
11
|
+
logging.basicConfig(
|
|
12
|
+
level=logging.WARNING,
|
|
13
|
+
format="%(message)s",
|
|
14
|
+
datefmt="[%X]",
|
|
15
|
+
handlers=[RichHandler(rich_tracebacks=True)],
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
logger = logging.getLogger("lite_agent")
|
|
19
|
+
logger.setLevel(logging.DEBUG)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
async def get_temperature(city: str) -> str:
|
|
23
|
+
"""Get the temperature for a city."""
|
|
24
|
+
return f"The temperature in {city} is 25°C."
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
agent = Agent(
|
|
28
|
+
model=LiteLLMClient(
|
|
29
|
+
model="gpt-4o-mini",
|
|
30
|
+
temperature=0.7,
|
|
31
|
+
max_tokens=150,
|
|
32
|
+
top_p=0.9,
|
|
33
|
+
),
|
|
34
|
+
name="Weather Assistant",
|
|
35
|
+
instructions="You are a helpful weather assistant. Before using tools, briefly explain what you are going to do. Provide friendly and informative responses.",
|
|
36
|
+
tools=[get_temperature],
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
async def main():
|
|
41
|
+
runner = Runner(agent)
|
|
42
|
+
resp = runner.run(
|
|
43
|
+
"What is the temperature in New York?",
|
|
44
|
+
includes=["usage", "assistant_message", "function_call", "function_call_output", "timing"],
|
|
45
|
+
)
|
|
46
|
+
async for chunk in resp:
|
|
47
|
+
logger.info(chunk)
|
|
48
|
+
display_messages(runner.messages)
|
|
49
|
+
print(runner.messages)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
if __name__ == "__main__":
|
|
53
|
+
asyncio.run(main())
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Debug example to investigate non-streaming mode issues.
|
|
3
|
+
"""
|
|
4
|
+
import asyncio
|
|
5
|
+
import logging
|
|
6
|
+
|
|
7
|
+
from lite_agent import Agent, Runner
|
|
8
|
+
|
|
9
|
+
# Enable debug logging
|
|
10
|
+
logging.basicConfig(level=logging.DEBUG)
|
|
11
|
+
logger = logging.getLogger("lite_agent")
|
|
12
|
+
logger.setLevel(logging.DEBUG)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
async def main():
|
|
16
|
+
# Create an agent
|
|
17
|
+
agent = Agent(
|
|
18
|
+
name="DebugAgent",
|
|
19
|
+
model="gpt-4o-mini",
|
|
20
|
+
instructions="You are a helpful assistant.",
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
print("=== Debug Non-Streaming Mode ===")
|
|
24
|
+
|
|
25
|
+
# Test with streaming=False
|
|
26
|
+
runner = Runner(agent, streaming=False)
|
|
27
|
+
|
|
28
|
+
print("Running in non-streaming mode...")
|
|
29
|
+
chunks = []
|
|
30
|
+
|
|
31
|
+
async for chunk in runner.run("Hello, please say hi back."):
|
|
32
|
+
print(f"Received chunk: {chunk}")
|
|
33
|
+
print(f"Chunk type: {chunk.type}")
|
|
34
|
+
if hasattr(chunk, "message"):
|
|
35
|
+
print(f"Chunk message: {chunk.message}")
|
|
36
|
+
if hasattr(chunk, "content"):
|
|
37
|
+
print(f"Chunk content: {chunk.content}")
|
|
38
|
+
chunks.append(chunk)
|
|
39
|
+
|
|
40
|
+
print(f"\nTotal chunks received: {len(chunks)}")
|
|
41
|
+
|
|
42
|
+
# Compare with streaming mode
|
|
43
|
+
print("\n=== Compare with Streaming Mode ===")
|
|
44
|
+
runner_streaming = Runner(agent, streaming=True)
|
|
45
|
+
|
|
46
|
+
streaming_chunks = []
|
|
47
|
+
async for chunk in runner_streaming.run("Hello, please say hi back too."):
|
|
48
|
+
streaming_chunks.append(chunk)
|
|
49
|
+
if chunk.type == "content_delta":
|
|
50
|
+
print(chunk.delta, end="", flush=True)
|
|
51
|
+
|
|
52
|
+
print(f"\nStreaming chunks received: {len(streaming_chunks)}")
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
if __name__ == "__main__":
|
|
56
|
+
asyncio.run(main())
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Debug with full logging enabled.
|
|
3
|
+
"""
|
|
4
|
+
import asyncio
|
|
5
|
+
import logging
|
|
6
|
+
|
|
7
|
+
from lite_agent import Agent, Runner
|
|
8
|
+
|
|
9
|
+
# Configure logging
|
|
10
|
+
logging.basicConfig(
|
|
11
|
+
level=logging.DEBUG,
|
|
12
|
+
format="%(name)s - %(levelname)s - %(message)s",
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
# Enable specific loggers
|
|
16
|
+
logging.getLogger("lite_agent").setLevel(logging.DEBUG)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
async def main():
|
|
20
|
+
agent = Agent(
|
|
21
|
+
name="TestAgent",
|
|
22
|
+
model="gpt-4o-mini",
|
|
23
|
+
instructions="You are helpful.",
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
print("=== Testing Non-Streaming ===")
|
|
27
|
+
runner = Runner(agent, streaming=False)
|
|
28
|
+
|
|
29
|
+
chunks = []
|
|
30
|
+
async for chunk in runner.run("Hello"):
|
|
31
|
+
chunks.append(chunk)
|
|
32
|
+
print(f"Got chunk: {chunk.type}")
|
|
33
|
+
|
|
34
|
+
print(f"Total chunks: {len(chunks)}")
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
if __name__ == "__main__":
|
|
38
|
+
asyncio.run(main())
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
import logging
|
|
3
|
+
|
|
4
|
+
from rich.logging import RichHandler
|
|
5
|
+
|
|
6
|
+
from lite_agent.agent import Agent
|
|
7
|
+
from lite_agent.chat_display import display_messages
|
|
8
|
+
from lite_agent.client import LiteLLMClient, LLMConfig
|
|
9
|
+
from lite_agent.runner import Runner
|
|
10
|
+
|
|
11
|
+
logging.basicConfig(
|
|
12
|
+
level=logging.WARNING,
|
|
13
|
+
format="%(message)s",
|
|
14
|
+
datefmt="[%X]",
|
|
15
|
+
handlers=[RichHandler(rich_tracebacks=True)],
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
logger = logging.getLogger("lite_agent")
|
|
19
|
+
logger.setLevel(logging.DEBUG)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
async def get_weather(city: str) -> str:
|
|
23
|
+
"""Get the current weather for a city."""
|
|
24
|
+
return f"The weather in {city} is sunny, 25°C."
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
# Method 1: Using individual parameters
|
|
28
|
+
agent1 = Agent(
|
|
29
|
+
model=LiteLLMClient(
|
|
30
|
+
model="gpt-4o-mini",
|
|
31
|
+
temperature=0.3,
|
|
32
|
+
max_tokens=100,
|
|
33
|
+
top_p=0.8,
|
|
34
|
+
frequency_penalty=0.1,
|
|
35
|
+
presence_penalty=0.1,
|
|
36
|
+
stop=["END"],
|
|
37
|
+
),
|
|
38
|
+
name="Weather Bot (Individual Params)",
|
|
39
|
+
instructions="You are a weather assistant. Keep responses brief and factual.",
|
|
40
|
+
tools=[get_weather],
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
# Method 2: Using LLMConfig object
|
|
44
|
+
llm_config = LLMConfig(
|
|
45
|
+
temperature=0.8,
|
|
46
|
+
max_tokens=200,
|
|
47
|
+
top_p=0.9,
|
|
48
|
+
frequency_penalty=0.0,
|
|
49
|
+
presence_penalty=0.0,
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
agent2 = Agent(
|
|
53
|
+
model=LiteLLMClient(
|
|
54
|
+
model="gpt-4o-mini",
|
|
55
|
+
llm_config=llm_config,
|
|
56
|
+
),
|
|
57
|
+
name="Weather Bot (LLMConfig)",
|
|
58
|
+
instructions="You are a creative weather assistant. Add some personality to your responses.",
|
|
59
|
+
tools=[get_weather],
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
async def main():
|
|
64
|
+
# Test agent with conservative settings (low temperature, short responses)
|
|
65
|
+
print("=== Testing Agent 1 (Conservative Settings) ===")
|
|
66
|
+
runner1 = Runner(agent1)
|
|
67
|
+
resp1 = runner1.run(
|
|
68
|
+
"What's the weather like in Tokyo?",
|
|
69
|
+
includes=["assistant_message"],
|
|
70
|
+
)
|
|
71
|
+
async for chunk in resp1:
|
|
72
|
+
logger.info(chunk)
|
|
73
|
+
display_messages(runner1.messages)
|
|
74
|
+
|
|
75
|
+
print("\n" + "="*50 + "\n")
|
|
76
|
+
|
|
77
|
+
# Test agent with creative settings (high temperature, longer responses)
|
|
78
|
+
print("=== Testing Agent 2 (Creative Settings) ===")
|
|
79
|
+
runner2 = Runner(agent2)
|
|
80
|
+
resp2 = runner2.run(
|
|
81
|
+
"What's the weather like in Tokyo?",
|
|
82
|
+
includes=["assistant_message"],
|
|
83
|
+
)
|
|
84
|
+
async for chunk in resp2:
|
|
85
|
+
logger.info(chunk)
|
|
86
|
+
display_messages(runner2.messages)
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
if __name__ == "__main__":
|
|
90
|
+
asyncio.run(main())
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Simple example demonstrating non-streaming mode in LiteAgent.
|
|
3
|
+
"""
|
|
4
|
+
import asyncio
|
|
5
|
+
|
|
6
|
+
from lite_agent import Agent, Runner
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
async def main():
|
|
10
|
+
# Create an agent
|
|
11
|
+
agent = Agent(
|
|
12
|
+
name="NonStreamingDemo",
|
|
13
|
+
model="gpt-4o-mini",
|
|
14
|
+
instructions="You are a helpful assistant.",
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
# Create runner with non-streaming mode
|
|
18
|
+
runner = Runner(agent, streaming=False)
|
|
19
|
+
|
|
20
|
+
print("=== Non-Streaming Mode Example ===")
|
|
21
|
+
print("Question: Explain what Python is in one sentence.")
|
|
22
|
+
print("Response: ", end="", flush=True)
|
|
23
|
+
|
|
24
|
+
# In non-streaming mode, you get the complete response at once
|
|
25
|
+
async for chunk in runner.run("Explain what Python is in one sentence."):
|
|
26
|
+
if chunk.type == "assistant_message":
|
|
27
|
+
# Non-streaming mode typically yields one complete message
|
|
28
|
+
print(chunk.message.content[0].text)
|
|
29
|
+
|
|
30
|
+
print("\n=== Tool Usage with Non-Streaming ===")
|
|
31
|
+
|
|
32
|
+
# Example with a simple tool
|
|
33
|
+
def get_time() -> str:
|
|
34
|
+
"""Get the current time."""
|
|
35
|
+
from datetime import datetime
|
|
36
|
+
return f"Current time: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}"
|
|
37
|
+
|
|
38
|
+
agent_with_tools = Agent(
|
|
39
|
+
name="TimeAgent",
|
|
40
|
+
model="gpt-4o-mini",
|
|
41
|
+
instructions="You help users with time-related queries. Use the get_time tool when asked about time.",
|
|
42
|
+
tools=[get_time],
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
runner_with_tools = Runner(agent_with_tools, streaming=False)
|
|
46
|
+
|
|
47
|
+
print("Question: What time is it now?")
|
|
48
|
+
print("Response:")
|
|
49
|
+
|
|
50
|
+
async for chunk in runner_with_tools.run("What time is it now?"):
|
|
51
|
+
if chunk.type == "assistant_message":
|
|
52
|
+
print(chunk.message.content[0].text)
|
|
53
|
+
elif chunk.type == "function_call_output":
|
|
54
|
+
print(f"Tool output: {chunk.content}")
|
|
55
|
+
|
|
56
|
+
print("\n=== Benefits of Non-Streaming Mode ===")
|
|
57
|
+
print("1. Simpler processing - get complete responses")
|
|
58
|
+
print("2. Easier for batch processing")
|
|
59
|
+
print("3. Better for APIs that need complete responses")
|
|
60
|
+
print("4. Lower overhead for short interactions")
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
if __name__ == "__main__":
|
|
64
|
+
asyncio.run(main())
|
|
@@ -0,0 +1,113 @@
|
|
|
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 analyze_complex_problem(problem_description: str) -> str:
|
|
20
|
+
"""Analyze a complex problem and return insights."""
|
|
21
|
+
return f"Analysis for: {problem_description}\n- Key factors identified\n- Potential solutions outlined\n- Risk assessment completed"
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
async def demo_reasoning_configurations():
|
|
25
|
+
"""演示不同的推理配置方法。"""
|
|
26
|
+
print("=== 推理配置演示 ===\n")
|
|
27
|
+
|
|
28
|
+
# 1. 使用reasoning参数设置推理强度(字符串形式)
|
|
29
|
+
print("1. 使用reasoning参数设置推理强度:")
|
|
30
|
+
agent_with_reasoning = Agent(
|
|
31
|
+
model="gpt-4o-mini",
|
|
32
|
+
name="推理助手",
|
|
33
|
+
instructions="你是一个深度分析助手,使用仔细的推理来提供全面的分析。",
|
|
34
|
+
reasoning="high", # 高强度推理
|
|
35
|
+
)
|
|
36
|
+
print(f" Agent推理配置: {agent_with_reasoning.reasoning}")
|
|
37
|
+
print(f" 客户端推理努力程度: {agent_with_reasoning.client.reasoning_effort}")
|
|
38
|
+
print(f" 客户端思考配置: {agent_with_reasoning.client.thinking_config}")
|
|
39
|
+
|
|
40
|
+
# 2. 使用reasoning参数进行更精细的控制(字典形式)
|
|
41
|
+
print("\n2. 使用reasoning参数进行精细控制:")
|
|
42
|
+
agent_with_thinking = Agent(
|
|
43
|
+
model="claude-3-5-sonnet-20241022", # Anthropic模型支持thinking
|
|
44
|
+
name="思考助手",
|
|
45
|
+
instructions="你是一个深思熟虑的助手。",
|
|
46
|
+
reasoning={"type": "enabled", "budget_tokens": 2048}, # 使用字典形式
|
|
47
|
+
)
|
|
48
|
+
print(f" Agent推理配置: {agent_with_thinking.reasoning}")
|
|
49
|
+
print(f" 客户端推理努力程度: {agent_with_thinking.client.reasoning_effort}")
|
|
50
|
+
print(f" 客户端思考配置: {agent_with_thinking.client.thinking_config}")
|
|
51
|
+
|
|
52
|
+
# 3. 使用布尔值设置推理(会默认使用medium级别)
|
|
53
|
+
print("\n3. 使用布尔值启用推理:")
|
|
54
|
+
agent_bool_reasoning = Agent(
|
|
55
|
+
model="o1-mini", # OpenAI推理模型
|
|
56
|
+
name="布尔推理助手",
|
|
57
|
+
instructions="你是一个高级推理助手。",
|
|
58
|
+
reasoning=True, # 布尔值,会使用默认的medium级别
|
|
59
|
+
)
|
|
60
|
+
print(f" Agent推理配置: {agent_bool_reasoning.reasoning}")
|
|
61
|
+
print(f" 客户端推理努力程度: {agent_bool_reasoning.client.reasoning_effort}")
|
|
62
|
+
print(f" 客户端思考配置: {agent_bool_reasoning.client.thinking_config}")
|
|
63
|
+
|
|
64
|
+
# 4. 演示运行时覆盖推理参数
|
|
65
|
+
print("\n4. 运行时覆盖推理参数:")
|
|
66
|
+
print(" - Agent默认使用 reasoning='high'")
|
|
67
|
+
print(" - 运行时可通过 agent_kwargs 覆盖:")
|
|
68
|
+
print(" runner.run(query, agent_kwargs={'reasoning': 'minimal'})")
|
|
69
|
+
|
|
70
|
+
# 注意:由于没有实际的API密钥,我们不运行真实的API调用
|
|
71
|
+
print("\n✓ 所有推理配置功能已成功设置!")
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
async def main():
|
|
75
|
+
"""主演示函数。"""
|
|
76
|
+
await demo_reasoning_configurations()
|
|
77
|
+
|
|
78
|
+
print("\n" + "="*60)
|
|
79
|
+
print("推理配置使用说明:")
|
|
80
|
+
print("="*60)
|
|
81
|
+
print("""
|
|
82
|
+
1. reasoning_effort 参数 (OpenAI兼容):
|
|
83
|
+
- "minimal": 最小推理,快速响应
|
|
84
|
+
- "low": 低强度推理
|
|
85
|
+
- "medium": 中等推理(推荐)
|
|
86
|
+
- "high": 高强度推理,更深入分析
|
|
87
|
+
|
|
88
|
+
2. thinking_config 参数 (Anthropic兼容):
|
|
89
|
+
- {"type": "enabled", "budget_tokens": N}
|
|
90
|
+
- N 可以是 1024, 2048, 4096 等
|
|
91
|
+
|
|
92
|
+
3. 使用方法:
|
|
93
|
+
a) Agent初始化时设置: Agent(..., reasoning_effort="high")
|
|
94
|
+
b) 运行时覆盖: runner.run(query, agent_kwargs={"reasoning_effort": "low"})
|
|
95
|
+
|
|
96
|
+
4. 模型兼容性:
|
|
97
|
+
- OpenAI: o1, o3, o4-mini 系列
|
|
98
|
+
- Anthropic: claude-3.5-sonnet 等
|
|
99
|
+
- 其他: 通过LiteLLM自动转换
|
|
100
|
+
|
|
101
|
+
5. 示例代码:
|
|
102
|
+
```python
|
|
103
|
+
agent = Agent(
|
|
104
|
+
model="gpt-4o-mini",
|
|
105
|
+
reasoning_effort="medium",
|
|
106
|
+
thinking_config={"type": "enabled", "budget_tokens": 2048}
|
|
107
|
+
)
|
|
108
|
+
```
|
|
109
|
+
""")
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
if __name__ == "__main__":
|
|
113
|
+
asyncio.run(main())
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Simple debug to check non-streaming response.
|
|
3
|
+
"""
|
|
4
|
+
import asyncio
|
|
5
|
+
|
|
6
|
+
from lite_agent import Agent, Runner
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
async def main():
|
|
10
|
+
agent = Agent(
|
|
11
|
+
name="TestAgent",
|
|
12
|
+
model="gpt-4o-mini",
|
|
13
|
+
instructions="You are helpful.",
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
# Test non-streaming
|
|
17
|
+
print("Testing non-streaming...")
|
|
18
|
+
runner = Runner(agent, streaming=False)
|
|
19
|
+
|
|
20
|
+
try:
|
|
21
|
+
chunks = []
|
|
22
|
+
async for chunk in runner.run("Say hello"):
|
|
23
|
+
chunks.append(chunk)
|
|
24
|
+
print(f"Received chunk type: {chunk.type}")
|
|
25
|
+
|
|
26
|
+
print(f"Total chunks: {len(chunks)}")
|
|
27
|
+
if chunks:
|
|
28
|
+
print(f"First chunk: {chunks[0]}")
|
|
29
|
+
except Exception as e:
|
|
30
|
+
print(f"Error: {e}")
|
|
31
|
+
import traceback
|
|
32
|
+
traceback.print_exc()
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
if __name__ == "__main__":
|
|
36
|
+
asyncio.run(main())
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Simple debug to check which API is being used.
|
|
3
|
+
"""
|
|
4
|
+
import asyncio
|
|
5
|
+
|
|
6
|
+
from lite_agent import Agent, Runner
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
async def main():
|
|
10
|
+
agent = Agent(
|
|
11
|
+
name="TestAgent",
|
|
12
|
+
model="gpt-4o-mini",
|
|
13
|
+
instructions="You are helpful.",
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
# Test non-streaming with explicit API
|
|
17
|
+
print("Testing non-streaming with responses API...")
|
|
18
|
+
runner = Runner(agent, api="responses", streaming=False)
|
|
19
|
+
print(f"Runner API: {runner.api}")
|
|
20
|
+
print(f"Runner streaming: {runner.streaming}")
|
|
21
|
+
|
|
22
|
+
# Test with completion API
|
|
23
|
+
print("\nTesting non-streaming with completion API...")
|
|
24
|
+
runner2 = Runner(agent, api="completion", streaming=False)
|
|
25
|
+
print(f"Runner API: {runner2.api}")
|
|
26
|
+
print(f"Runner streaming: {runner2.streaming}")
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
if __name__ == "__main__":
|
|
30
|
+
asyncio.run(main())
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Demo script showing streaming vs non-streaming configuration in LiteAgent.
|
|
3
|
+
"""
|
|
4
|
+
import asyncio
|
|
5
|
+
import time
|
|
6
|
+
|
|
7
|
+
from lite_agent import Agent, Runner
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
async def main():
|
|
11
|
+
# Create an agent
|
|
12
|
+
agent = Agent(
|
|
13
|
+
name="StreamingDemo",
|
|
14
|
+
model="gpt-4o-mini",
|
|
15
|
+
instructions="You are a helpful assistant. Always respond concisely.",
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
print("=== Streaming Mode (Default) ===")
|
|
19
|
+
# Default streaming=True
|
|
20
|
+
runner_streaming = Runner(agent, streaming=True)
|
|
21
|
+
|
|
22
|
+
chunks = []
|
|
23
|
+
print("Question: What is the capital of France?")
|
|
24
|
+
print("Response: ", end="", flush=True)
|
|
25
|
+
async for chunk in runner_streaming.run("What is the capital of France?"):
|
|
26
|
+
chunks.append(chunk)
|
|
27
|
+
if chunk.type == "content_delta":
|
|
28
|
+
print(chunk.delta, end="", flush=True)
|
|
29
|
+
print(f"\nReceived {len(chunks)} chunks in streaming mode\n")
|
|
30
|
+
|
|
31
|
+
print("=== Non-Streaming Mode ===")
|
|
32
|
+
# Set streaming=False
|
|
33
|
+
runner_non_streaming = Runner(agent, streaming=False)
|
|
34
|
+
|
|
35
|
+
chunks = []
|
|
36
|
+
print("Question: What is the capital of Germany?")
|
|
37
|
+
print("Response: ", end="", flush=True)
|
|
38
|
+
async for chunk in runner_non_streaming.run("What is the capital of Germany?"):
|
|
39
|
+
chunks.append(chunk)
|
|
40
|
+
if chunk.type == "assistant_message":
|
|
41
|
+
print(chunk.message.content[0].text)
|
|
42
|
+
print(f"Received {len(chunks)} chunks in non-streaming mode\n")
|
|
43
|
+
|
|
44
|
+
print("=== Comparing Performance ===")
|
|
45
|
+
|
|
46
|
+
# Time streaming
|
|
47
|
+
start = time.time()
|
|
48
|
+
runner_streaming = Runner(agent, streaming=True)
|
|
49
|
+
chunks = []
|
|
50
|
+
async for chunk in runner_streaming.run("What is 2+2?"):
|
|
51
|
+
chunks.append(chunk)
|
|
52
|
+
streaming_time = time.time() - start
|
|
53
|
+
|
|
54
|
+
# Time non-streaming
|
|
55
|
+
start = time.time()
|
|
56
|
+
runner_non_streaming = Runner(agent, streaming=False)
|
|
57
|
+
chunks = []
|
|
58
|
+
async for chunk in runner_non_streaming.run("What is 3+3?"):
|
|
59
|
+
chunks.append(chunk)
|
|
60
|
+
non_streaming_time = time.time() - start
|
|
61
|
+
|
|
62
|
+
print(f"Streaming mode: {streaming_time:.2f}s")
|
|
63
|
+
print(f"Non-streaming mode: {non_streaming_time:.2f}s")
|
|
64
|
+
|
|
65
|
+
print("\n=== Usage Guide ===")
|
|
66
|
+
print("To use non-streaming mode:")
|
|
67
|
+
print(" runner = Runner(agent, streaming=False)")
|
|
68
|
+
print("To use streaming mode (default):")
|
|
69
|
+
print(" runner = Runner(agent, streaming=True) # or just Runner(agent)")
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
if __name__ == "__main__":
|
|
73
|
+
asyncio.run(main())
|