lite-agent 0.5.0__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.

Files changed (97) hide show
  1. {lite_agent-0.5.0 → lite_agent-0.6.0}/.claude/settings.local.json +2 -1
  2. {lite_agent-0.5.0 → lite_agent-0.6.0}/CHANGELOG.md +9 -0
  3. {lite_agent-0.5.0 → lite_agent-0.6.0}/PKG-INFO +1 -1
  4. lite_agent-0.6.0/examples/basic_model.py +53 -0
  5. lite_agent-0.6.0/examples/debug_non_streaming.py +56 -0
  6. lite_agent-0.6.0/examples/debug_with_logging.py +38 -0
  7. lite_agent-0.6.0/examples/llm_config_demo.py +90 -0
  8. lite_agent-0.6.0/examples/non_streaming.py +64 -0
  9. {lite_agent-0.5.0 → lite_agent-0.6.0}/examples/reasoning_example.py +20 -20
  10. lite_agent-0.6.0/examples/simple_debug.py +36 -0
  11. lite_agent-0.6.0/examples/simple_debug2.py +30 -0
  12. lite_agent-0.6.0/examples/streaming_demo.py +73 -0
  13. {lite_agent-0.5.0 → lite_agent-0.6.0}/pyproject.toml +2 -1
  14. {lite_agent-0.5.0 → lite_agent-0.6.0}/src/lite_agent/agent.py +13 -9
  15. {lite_agent-0.5.0 → lite_agent-0.6.0}/src/lite_agent/chat_display.py +1 -1
  16. {lite_agent-0.5.0 → lite_agent-0.6.0}/src/lite_agent/client.py +61 -3
  17. lite_agent-0.6.0/src/lite_agent/response_handlers/__init__.py +10 -0
  18. lite_agent-0.6.0/src/lite_agent/response_handlers/base.py +46 -0
  19. lite_agent-0.6.0/src/lite_agent/response_handlers/completion.py +50 -0
  20. lite_agent-0.6.0/src/lite_agent/response_handlers/responses.py +42 -0
  21. {lite_agent-0.5.0 → lite_agent-0.6.0}/src/lite_agent/runner.py +11 -2
  22. {lite_agent-0.5.0 → lite_agent-0.6.0}/tests/unit/test_agent.py +8 -8
  23. {lite_agent-0.5.0 → lite_agent-0.6.0}/tests/unit/test_message_transfer.py +2 -2
  24. {lite_agent-0.5.0 → lite_agent-0.6.0}/tests/unit/test_runner.py +3 -3
  25. lite_agent-0.6.0/tests/unit/test_streaming_config.py +97 -0
  26. {lite_agent-0.5.0 → lite_agent-0.6.0}/tests/utils/mock_litellm.py +1 -2
  27. {lite_agent-0.5.0 → lite_agent-0.6.0}/uv.lock +185 -185
  28. {lite_agent-0.5.0 → lite_agent-0.6.0}/.github/workflows/ci.yml +0 -0
  29. {lite_agent-0.5.0 → lite_agent-0.6.0}/.gitignore +0 -0
  30. {lite_agent-0.5.0 → lite_agent-0.6.0}/.python-version +0 -0
  31. {lite_agent-0.5.0 → lite_agent-0.6.0}/.vscode/launch.json +0 -0
  32. {lite_agent-0.5.0 → lite_agent-0.6.0}/CLAUDE.md +0 -0
  33. {lite_agent-0.5.0 → lite_agent-0.6.0}/README.md +0 -0
  34. {lite_agent-0.5.0 → lite_agent-0.6.0}/examples/basic.py +0 -0
  35. {lite_agent-0.5.0 → lite_agent-0.6.0}/examples/basic_agent.py +0 -0
  36. {lite_agent-0.5.0 → lite_agent-0.6.0}/examples/channels/rich_channel.py +0 -0
  37. {lite_agent-0.5.0 → lite_agent-0.6.0}/examples/chat_display_demo.py +0 -0
  38. {lite_agent-0.5.0 → lite_agent-0.6.0}/examples/confirm_and_continue.py +0 -0
  39. {lite_agent-0.5.0 → lite_agent-0.6.0}/examples/consolidate_history.py +0 -0
  40. {lite_agent-0.5.0 → lite_agent-0.6.0}/examples/context.py +0 -0
  41. {lite_agent-0.5.0 → lite_agent-0.6.0}/examples/handoffs.py +0 -0
  42. {lite_agent-0.5.0 → lite_agent-0.6.0}/examples/image.py +0 -0
  43. {lite_agent-0.5.0 → lite_agent-0.6.0}/examples/message_transfer_example.py +0 -0
  44. {lite_agent-0.5.0 → lite_agent-0.6.0}/examples/message_transfer_example_new.py +0 -0
  45. {lite_agent-0.5.0 → lite_agent-0.6.0}/examples/new_message_structure_demo.py +0 -0
  46. {lite_agent-0.5.0 → lite_agent-0.6.0}/examples/response_api_example.py +0 -0
  47. {lite_agent-0.5.0 → lite_agent-0.6.0}/examples/responses.py +0 -0
  48. {lite_agent-0.5.0 → lite_agent-0.6.0}/examples/set_chat_history_example.py +0 -0
  49. {lite_agent-0.5.0 → lite_agent-0.6.0}/examples/stop_with_tool_call.py +0 -0
  50. {lite_agent-0.5.0 → lite_agent-0.6.0}/examples/terminal.py +0 -0
  51. {lite_agent-0.5.0 → lite_agent-0.6.0}/examples/translate/main.py +0 -0
  52. {lite_agent-0.5.0 → lite_agent-0.6.0}/examples/translate/prompts/translation_system.md.j2 +0 -0
  53. {lite_agent-0.5.0 → lite_agent-0.6.0}/examples/translate.py +0 -0
  54. {lite_agent-0.5.0 → lite_agent-0.6.0}/examples/type_system_example.py +0 -0
  55. {lite_agent-0.5.0 → lite_agent-0.6.0}/scripts/record_chat_messages.py +0 -0
  56. {lite_agent-0.5.0 → lite_agent-0.6.0}/src/lite_agent/__init__.py +0 -0
  57. {lite_agent-0.5.0 → lite_agent-0.6.0}/src/lite_agent/loggers.py +0 -0
  58. {lite_agent-0.5.0 → lite_agent-0.6.0}/src/lite_agent/message_transfers.py +0 -0
  59. {lite_agent-0.5.0 → lite_agent-0.6.0}/src/lite_agent/processors/__init__.py +0 -0
  60. {lite_agent-0.5.0 → lite_agent-0.6.0}/src/lite_agent/processors/completion_event_processor.py +0 -0
  61. {lite_agent-0.5.0 → lite_agent-0.6.0}/src/lite_agent/processors/response_event_processor.py +0 -0
  62. {lite_agent-0.5.0 → lite_agent-0.6.0}/src/lite_agent/py.typed +0 -0
  63. {lite_agent-0.5.0 → lite_agent-0.6.0}/src/lite_agent/stream_handlers/__init__.py +0 -0
  64. {lite_agent-0.5.0 → lite_agent-0.6.0}/src/lite_agent/stream_handlers/litellm.py +0 -0
  65. {lite_agent-0.5.0 → lite_agent-0.6.0}/src/lite_agent/templates/handoffs_source_instructions.xml.j2 +0 -0
  66. {lite_agent-0.5.0 → lite_agent-0.6.0}/src/lite_agent/templates/handoffs_target_instructions.xml.j2 +0 -0
  67. {lite_agent-0.5.0 → lite_agent-0.6.0}/src/lite_agent/templates/wait_for_user_instructions.xml.j2 +0 -0
  68. {lite_agent-0.5.0 → lite_agent-0.6.0}/src/lite_agent/types/__init__.py +0 -0
  69. {lite_agent-0.5.0 → lite_agent-0.6.0}/src/lite_agent/types/events.py +0 -0
  70. {lite_agent-0.5.0 → lite_agent-0.6.0}/src/lite_agent/types/messages.py +0 -0
  71. {lite_agent-0.5.0 → lite_agent-0.6.0}/src/lite_agent/types/tool_calls.py +0 -0
  72. {lite_agent-0.5.0 → lite_agent-0.6.0}/tests/integration/test_agent_with_mocks.py +0 -0
  73. {lite_agent-0.5.0 → lite_agent-0.6.0}/tests/integration/test_basic.py +0 -0
  74. {lite_agent-0.5.0 → lite_agent-0.6.0}/tests/integration/test_mock_litellm.py +0 -0
  75. {lite_agent-0.5.0 → lite_agent-0.6.0}/tests/mocks/basic/1.jsonl +0 -0
  76. {lite_agent-0.5.0 → lite_agent-0.6.0}/tests/mocks/confirm_and_continue/1.jsonl +0 -0
  77. {lite_agent-0.5.0 → lite_agent-0.6.0}/tests/mocks/confirm_and_continue/2.jsonl +0 -0
  78. {lite_agent-0.5.0 → lite_agent-0.6.0}/tests/mocks/context/1.jsonl +0 -0
  79. {lite_agent-0.5.0 → lite_agent-0.6.0}/tests/mocks/handoffs/1.jsonl +0 -0
  80. {lite_agent-0.5.0 → lite_agent-0.6.0}/tests/performance/test_set_chat_history_performance.py +0 -0
  81. {lite_agent-0.5.0 → lite_agent-0.6.0}/tests/test_new_messages.py +0 -0
  82. {lite_agent-0.5.0 → lite_agent-0.6.0}/tests/unit/test_agent_additional.py +0 -0
  83. {lite_agent-0.5.0 → lite_agent-0.6.0}/tests/unit/test_agent_handoffs.py +0 -0
  84. {lite_agent-0.5.0 → lite_agent-0.6.0}/tests/unit/test_append_message.py +0 -0
  85. {lite_agent-0.5.0 → lite_agent-0.6.0}/tests/unit/test_chat_display.py +0 -0
  86. {lite_agent-0.5.0 → lite_agent-0.6.0}/tests/unit/test_chat_display_additional.py +0 -0
  87. {lite_agent-0.5.0 → lite_agent-0.6.0}/tests/unit/test_completion_condition.py +0 -0
  88. {lite_agent-0.5.0 → lite_agent-0.6.0}/tests/unit/test_file_recording.py +0 -0
  89. {lite_agent-0.5.0 → lite_agent-0.6.0}/tests/unit/test_litellm_stream_handler.py +0 -0
  90. {lite_agent-0.5.0 → lite_agent-0.6.0}/tests/unit/test_message_transfers.py +0 -0
  91. {lite_agent-0.5.0 → lite_agent-0.6.0}/tests/unit/test_message_transfers_additional.py +0 -0
  92. {lite_agent-0.5.0 → lite_agent-0.6.0}/tests/unit/test_response_api_format.py +0 -0
  93. {lite_agent-0.5.0 → lite_agent-0.6.0}/tests/unit/test_response_event_processor.py +0 -0
  94. {lite_agent-0.5.0 → lite_agent-0.6.0}/tests/unit/test_set_chat_history.py +0 -0
  95. {lite_agent-0.5.0 → lite_agent-0.6.0}/tests/unit/test_simple_stream_handlers.py +0 -0
  96. {lite_agent-0.5.0 → lite_agent-0.6.0}/tests/unit/test_stream_chunk_processor.py +0 -0
  97. {lite_agent-0.5.0 → lite_agent-0.6.0}/tests/unit/test_stream_handlers_additional.py +0 -0
@@ -14,7 +14,8 @@
14
14
  "Bash(uv run pytest:*)",
15
15
  "Bash(timeout:*)",
16
16
  "Bash(pyright:*)",
17
- "Bash(rg:*)"
17
+ "Bash(rg:*)",
18
+ "Bash(uv run:*)"
18
19
  ],
19
20
  "deny": []
20
21
  }
@@ -1,3 +1,12 @@
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
+
1
10
  ## v0.5.0
2
11
 
3
12
  [v0.4.1...v0.5.0](https://github.com/Jannchie/lite-agent/compare/v0.4.1...v0.5.0)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: lite-agent
3
- Version: 0.5.0
3
+ Version: 0.6.0
4
4
  Summary: A lightweight, extensible framework for building AI agent.
5
5
  Author-email: Jianqi Pan <jannchie@gmail.com>
6
6
  License: MIT
@@ -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())
@@ -4,7 +4,6 @@ import logging
4
4
  from rich.logging import RichHandler
5
5
 
6
6
  from lite_agent.agent import Agent
7
- from lite_agent.runner import Runner
8
7
 
9
8
  logging.basicConfig(
10
9
  level=logging.WARNING,
@@ -26,46 +25,47 @@ async def demo_reasoning_configurations():
26
25
  """演示不同的推理配置方法。"""
27
26
  print("=== 推理配置演示 ===\n")
28
27
 
29
- # 1. 在Agent初始化时设置推理参数
30
- print("1. Agent初始化时设置reasoning_effort:")
28
+ # 1. 使用reasoning参数设置推理强度(字符串形式)
29
+ print("1. 使用reasoning参数设置推理强度:")
31
30
  agent_with_reasoning = Agent(
32
31
  model="gpt-4o-mini",
33
32
  name="推理助手",
34
33
  instructions="你是一个深度分析助手,使用仔细的推理来提供全面的分析。",
35
- reasoning_effort="high", # 高强度推理
34
+ reasoning="high", # 高强度推理
36
35
  )
37
- print(f" Agent推理努力程度: {agent_with_reasoning.reasoning_effort}")
36
+ print(f" Agent推理配置: {agent_with_reasoning.reasoning}")
38
37
  print(f" 客户端推理努力程度: {agent_with_reasoning.client.reasoning_effort}")
38
+ print(f" 客户端思考配置: {agent_with_reasoning.client.thinking_config}")
39
39
 
40
- # 2. 使用thinking_config进行更精细的控制
41
- print("\n2. 使用thinking_config进行精细控制:")
40
+ # 2. 使用reasoning参数进行更精细的控制(字典形式)
41
+ print("\n2. 使用reasoning参数进行精细控制:")
42
42
  agent_with_thinking = Agent(
43
43
  model="claude-3-5-sonnet-20241022", # Anthropic模型支持thinking
44
44
  name="思考助手",
45
45
  instructions="你是一个深思熟虑的助手。",
46
- thinking_config={"type": "enabled", "budget_tokens": 2048},
46
+ reasoning={"type": "enabled", "budget_tokens": 2048}, # 使用字典形式
47
47
  )
48
- print(f" Agent思考配置: {agent_with_thinking.thinking_config}")
48
+ print(f" Agent推理配置: {agent_with_thinking.reasoning}")
49
+ print(f" 客户端推理努力程度: {agent_with_thinking.client.reasoning_effort}")
49
50
  print(f" 客户端思考配置: {agent_with_thinking.client.thinking_config}")
50
51
 
51
- # 3. 同时设置reasoning_effort和thinking_config
52
- print("\n3. 同时设置多种推理参数:")
53
- agent_full_config = Agent(
52
+ # 3. 使用布尔值设置推理(会默认使用medium级别)
53
+ print("\n3. 使用布尔值启用推理:")
54
+ agent_bool_reasoning = Agent(
54
55
  model="o1-mini", # OpenAI推理模型
55
- name="全配置推理助手",
56
+ name="布尔推理助手",
56
57
  instructions="你是一个高级推理助手。",
57
- reasoning_effort="medium",
58
- thinking_config={"type": "enabled", "budget_tokens": 1024},
58
+ reasoning=True, # 布尔值,会使用默认的medium级别
59
59
  )
60
- print(f" 推理努力程度: {agent_full_config.reasoning_effort}")
61
- print(f" 思考配置: {agent_full_config.thinking_config}")
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}")
62
63
 
63
64
  # 4. 演示运行时覆盖推理参数
64
65
  print("\n4. 运行时覆盖推理参数:")
65
- runner = Runner(agent_with_reasoning)
66
- print(" - Agent默认使用 reasoning_effort='high'")
66
+ print(" - Agent默认使用 reasoning='high'")
67
67
  print(" - 运行时可通过 agent_kwargs 覆盖:")
68
- print(" runner.run(query, agent_kwargs={'reasoning_effort': 'minimal'})")
68
+ print(" runner.run(query, agent_kwargs={'reasoning': 'minimal'})")
69
69
 
70
70
  # 注意:由于没有实际的API密钥,我们不运行真实的API调用
71
71
  print("\n✓ 所有推理配置功能已成功设置!")
@@ -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())
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "lite-agent"
3
- version = "0.5.0"
3
+ version = "0.6.0"
4
4
  description = "A lightweight, extensible framework for building AI agent."
5
5
  readme = "README.md"
6
6
  authors = [{ name = "Jianqi Pan", email = "jannchie@gmail.com" }]
@@ -69,6 +69,7 @@ ignore = [
69
69
  "ANN204",
70
70
  "C901",
71
71
  "PLR0912",
72
+ "PLR0913",
72
73
  "PLR0915",
73
74
  "RUF001",
74
75
  ]
@@ -5,11 +5,10 @@ from typing import Any, Optional
5
5
 
6
6
  from funcall import Funcall
7
7
  from jinja2 import Environment, FileSystemLoader
8
- from litellm import CustomStreamWrapper
9
8
 
10
9
  from lite_agent.client import BaseLLMClient, LiteLLMClient, ReasoningConfig
11
10
  from lite_agent.loggers import logger
12
- from lite_agent.stream_handlers import litellm_completion_stream_handler, litellm_response_stream_handler
11
+ from lite_agent.response_handlers import CompletionResponseHandler, ResponsesAPIHandler
13
12
  from lite_agent.types import AgentChunk, FunctionCallEvent, FunctionCallOutputEvent, RunnerMessages, ToolCall, message_to_llm_dict, system_message_to_llm_dict
14
13
  from lite_agent.types.messages import NewAssistantMessage, NewSystemMessage, NewUserMessage
15
14
 
@@ -22,7 +21,7 @@ WAIT_FOR_USER_INSTRUCTIONS_TEMPLATE = jinja_env.get_template("wait_for_user_inst
22
21
 
23
22
 
24
23
  class Agent:
25
- def __init__( # noqa: PLR0913
24
+ def __init__(
26
25
  self,
27
26
  *,
28
27
  model: str | BaseLLMClient,
@@ -280,6 +279,7 @@ class Agent:
280
279
  messages: RunnerMessages,
281
280
  record_to_file: Path | None = None,
282
281
  reasoning: ReasoningConfig = None,
282
+ streaming: bool = True,
283
283
  ) -> AsyncGenerator[AgentChunk, None]:
284
284
  # Apply message transfer callback if provided - always use legacy format for LLM compatibility
285
285
  processed_messages = messages
@@ -296,19 +296,19 @@ class Agent:
296
296
  tools=tools,
297
297
  tool_choice="auto", # TODO: make this configurable
298
298
  reasoning=reasoning,
299
+ streaming=streaming,
299
300
  )
300
301
 
301
- # Ensure resp is a CustomStreamWrapper
302
- if isinstance(resp, CustomStreamWrapper):
303
- return litellm_completion_stream_handler(resp, record_to=record_to_file)
304
- msg = "Response is not a CustomStreamWrapper, cannot stream chunks."
305
- raise TypeError(msg)
302
+ # Use response handler for unified processing
303
+ handler = CompletionResponseHandler()
304
+ return handler.handle(resp, streaming, record_to_file)
306
305
 
307
306
  async def responses(
308
307
  self,
309
308
  messages: RunnerMessages,
310
309
  record_to_file: Path | None = None,
311
310
  reasoning: ReasoningConfig = None,
311
+ streaming: bool = True,
312
312
  ) -> AsyncGenerator[AgentChunk, None]:
313
313
  # Apply message transfer callback if provided - always use legacy format for LLM compatibility
314
314
  processed_messages = messages
@@ -324,8 +324,11 @@ class Agent:
324
324
  tools=tools,
325
325
  tool_choice="auto", # TODO: make this configurable
326
326
  reasoning=reasoning,
327
+ streaming=streaming,
327
328
  )
328
- return litellm_response_stream_handler(resp, record_to=record_to_file)
329
+ # Use response handler for unified processing
330
+ handler = ResponsesAPIHandler()
331
+ return handler.handle(resp, streaming, record_to_file)
329
332
 
330
333
  async def list_require_confirm_tools(self, tool_calls: Sequence[ToolCall] | None) -> Sequence[ToolCall]:
331
334
  if not tool_calls:
@@ -539,3 +542,4 @@ class Agent:
539
542
  required=[],
540
543
  handler=wait_for_user_handler,
541
544
  )
545
+
@@ -437,7 +437,7 @@ def display_messages(
437
437
  )
438
438
 
439
439
 
440
- def _display_single_message_compact( # noqa: PLR0913
440
+ def _display_single_message_compact(
441
441
  message: FlexibleRunnerMessage,
442
442
  *,
443
443
  index: int | None = None,