ni.agentkit 0.7.3__tar.gz → 0.8.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.
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/PKG-INFO +3 -3
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/README.md +2 -2
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/__init__.py +1 -1
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/agents/agent.py +7 -4
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/agents/base_agent.py +116 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/docs/Architecture.md +19 -9
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/docs/QuickStart.md +142 -57
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/docs/README.md +3 -3
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/docs/Reference.md +15 -1
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/docs/TestReport.md +31 -31
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/examples/ollama/01_basic_chat.py +2 -2
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/examples/ollama/02_tool_calling.py +2 -2
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/examples/ollama/03_skill_usage.py +2 -2
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/examples/ollama/03b_skill_tools_entry.py +2 -2
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/examples/ollama/04_multi_agent.py +3 -3
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/examples/ollama/05_guardrail.py +4 -4
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/examples/ollama/06_orchestration.py +4 -4
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/examples/ollama/07_sync_async_stream.py +17 -17
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/examples/ollama/08_memory.py +7 -7
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/examples/ollama/08a_memory_simple_provider.py +3 -3
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/examples/ollama/08b_memory_mem0_provider.py +3 -3
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/examples/ollama/08c_memory_file_provider.py +3 -3
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/examples/ollama/09a_structured_data_sql.py +2 -2
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/examples/ollama/09b_structured_data_graph.py +2 -2
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/examples/ollama/10_skill_lifecycle.py +2 -2
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/examples/ollama/11_orchestration_enhancement.py +3 -3
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/examples/ollama/14_event_standardization.py +2 -2
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/examples/ollama/15_multi_tenant_isolation.py +4 -5
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/examples/ollama/16_lifecycle_hooks.py +3 -4
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/examples/ollama/18_model_cosplay.py +3 -3
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/examples/ollama/20_simple_rag_agent.py +2 -2
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/examples/quickstart.py +8 -8
- ni_agentkit-0.8.0/examples/rag/app.py +99 -0
- ni_agentkit-0.8.0/examples/rag/cli.py +72 -0
- ni_agentkit-0.8.0/examples/rag/core.py +95 -0
- ni_agentkit-0.8.0/examples/rag/web.py +14 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/examples/standard/01_basic_chat.py +2 -2
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/examples/standard/02_tool_calling.py +2 -2
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/examples/standard/03_skill_usage.py +2 -2
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/examples/standard/03b_skill_tools_entry.py +2 -2
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/examples/standard/04_multi_agent.py +3 -3
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/examples/standard/05_guardrail.py +4 -4
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/examples/standard/06_orchestration.py +4 -4
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/examples/standard/07_sync_async_stream.py +17 -17
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/examples/standard/08_memory.py +7 -7
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/examples/standard/08a_memory_simple_provider.py +3 -3
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/examples/standard/08b_memory_mem0_provider.py +3 -3
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/examples/standard/08c_memory_file_provider.py +3 -3
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/examples/standard/09a_structured_data_sql.py +2 -2
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/examples/standard/09b_structured_data_graph.py +2 -2
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/examples/standard/10_skill_lifecycle.py +2 -2
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/examples/standard/11_orchestration_enhancement.py +3 -3
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/examples/standard/14_event_standardization.py +2 -2
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/examples/standard/15_multi_tenant_isolation.py +3 -4
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/examples/standard/16_lifecycle_hooks.py +2 -3
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/examples/standard/18_model_cosplay.py +3 -3
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/examples/standard/20_simple_rag_agent.py +2 -2
- ni_agentkit-0.8.0/examples/test_standard.py +120 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/llm/cache.py +19 -3
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/llm/registry.py +16 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/ni.agentkit.egg-info/PKG-INFO +3 -3
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/ni.agentkit.egg-info/SOURCES.txt +13 -0
- ni_agentkit-0.8.0/ni.agentkit.egg-info/dependency_links.txt +1 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/pyproject.toml +1 -1
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/rag/file_memory_provider.py +32 -6
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/rag/sqlite_store.py +11 -2
- ni_agentkit-0.8.0/tests/test_default_model_env.py +15 -0
- ni_agentkit-0.8.0/utils/env.py +86 -0
- ni_agentkit-0.7.3/examples/test_standard.py +0 -60
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/LICENSE +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/_cli.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/agents/__init__.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/agents/orchestrators.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/examples/Skill.md +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/examples/__init__.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/examples/ollama/05_human_in_the_loop.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/examples/ollama/09c_nebula_graph_tool.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/examples/ollama/12_run_context_serialization.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/examples/ollama/13_human_in_the_loop.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/examples/ollama/17_checkpoint_handoff_resume.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/examples/ollama/19_hitl_deterministic.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/examples/ollama/README.md +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/examples/ollama/__init__.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/examples/ollama/model_config.py +0 -0
- /ni_agentkit-0.7.3/ni.agentkit.egg-info/dependency_links.txt → /ni_agentkit-0.8.0/examples/rag/__init__.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/examples/skills/weather-tools-entry/SKILL.md +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/examples/skills/weather-tools-entry/tools/weather_tools.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/examples/standard/05_human_in_the_loop.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/examples/standard/09c_nebula_graph_tool.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/examples/standard/12_run_context_serialization.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/examples/standard/13_human_in_the_loop.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/examples/standard/17_checkpoint_handoff_resume.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/examples/standard/19_hitl_deterministic.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/examples/standard/README.md +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/examples/standard/__init__.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/examples/standard/model_config.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/examples/test_ollama.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/llm/__init__.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/llm/adapters/__init__.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/llm/adapters/anthropic_adapter.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/llm/adapters/google_adapter.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/llm/adapters/ollama_adapter.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/llm/adapters/openai_adapter.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/llm/adapters/openai_compatible.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/llm/base.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/llm/middleware.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/llm/types.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/memory/__init__.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/memory/base.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/memory/mem0_provider.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/ni.agentkit.egg-info/entry_points.txt +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/ni.agentkit.egg-info/requires.txt +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/ni.agentkit.egg-info/top_level.txt +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/rag/__init__.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/rag/document_store.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/rag/loaders.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/rag/retrievers.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/rag/simple_rag_agent.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/rag/types.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/runner/__init__.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/runner/context.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/runner/context_store.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/runner/events.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/runner/runner.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/safety/__init__.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/safety/guardrails.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/safety/permissions.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/setup.cfg +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/skills/__init__.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/skills/loader.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/skills/models.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/skills/registry.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/tests/test_after_callback.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/tests/test_graph_repository.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/tests/test_quickstart_core.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/tests/test_runner_checkpoint_resume.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/tests/test_simple_rag.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/tests/test_skill_frontmatter.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/tools/__init__.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/tools/base_tool.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/tools/function_tool.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/tools/nebula_tool.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/tools/skill_toolset.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/tools/sqlite_tool.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/tools/structured_data.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/utils/__init__.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.8.0}/utils/schema.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ni.agentkit
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.8.0
|
|
4
4
|
Summary: A Python-native Agent framework with first-class Skill support and multi-LLM adapter
|
|
5
5
|
Author-email: Krix Tam <krix.tam@qq.com>
|
|
6
6
|
License: MIT
|
|
@@ -155,8 +155,8 @@ python "$(python -c "import agentkit, os; print(os.path.join(agentkit.get_exampl
|
|
|
155
155
|
|
|
156
156
|
```bash
|
|
157
157
|
dist/
|
|
158
|
-
├── ni_agentkit-0.7.
|
|
159
|
-
└── ni_agentkit-0.7.
|
|
158
|
+
├── ni_agentkit-0.7.4-py3-none-any.whl # pip install 用这个
|
|
159
|
+
└── ni_agentkit-0.7.4.tar.gz # 源码分发
|
|
160
160
|
```
|
|
161
161
|
|
|
162
162
|
## 📄 License
|
|
@@ -112,8 +112,8 @@ python "$(python -c "import agentkit, os; print(os.path.join(agentkit.get_exampl
|
|
|
112
112
|
|
|
113
113
|
```bash
|
|
114
114
|
dist/
|
|
115
|
-
├── ni_agentkit-0.7.
|
|
116
|
-
└── ni_agentkit-0.7.
|
|
115
|
+
├── ni_agentkit-0.7.4-py3-none-any.whl # pip install 用这个
|
|
116
|
+
└── ni_agentkit-0.7.4.tar.gz # 源码分发
|
|
117
117
|
```
|
|
118
118
|
|
|
119
119
|
## 📄 License
|
|
@@ -33,7 +33,7 @@ from .tools.function_tool import FunctionTool, function_tool
|
|
|
33
33
|
from .tools.structured_data import ResultFormatter, StructuredDataTool
|
|
34
34
|
from .tools.sqlite_tool import SQLiteTool, SQLiteResultFormatter
|
|
35
35
|
|
|
36
|
-
__version__ = "0.
|
|
36
|
+
__version__ = "0.8.0"
|
|
37
37
|
|
|
38
38
|
|
|
39
39
|
def get_docs_dir() -> str:
|
|
@@ -153,8 +153,7 @@ class Agent(BaseAgent):
|
|
|
153
153
|
|
|
154
154
|
async def _invoke(**kwargs: Any) -> Any:
|
|
155
155
|
input_text = kwargs.get("input", "")
|
|
156
|
-
|
|
157
|
-
result = await Runner.run(agent_ref, input=str(input_text))
|
|
156
|
+
result = await agent_ref.ainvoke(input=str(input_text))
|
|
158
157
|
return result.final_output
|
|
159
158
|
|
|
160
159
|
return FunctionTool(
|
|
@@ -293,11 +292,12 @@ class Agent(BaseAgent):
|
|
|
293
292
|
|
|
294
293
|
# 5. 调用 LLM(支持缓存)
|
|
295
294
|
cached = False
|
|
295
|
+
cache_key: str | None = None
|
|
296
296
|
|
|
297
297
|
# 检查缓存
|
|
298
298
|
if self.enable_cache:
|
|
299
299
|
cache = self._get_cache()
|
|
300
|
-
cached_response = cache.
|
|
300
|
+
cache_key, cached_response = cache.get_with_key(messages, tool_defs if tool_defs else None)
|
|
301
301
|
if cached_response is not None:
|
|
302
302
|
response = cached_response
|
|
303
303
|
cached = True
|
|
@@ -318,7 +318,10 @@ class Agent(BaseAgent):
|
|
|
318
318
|
|
|
319
319
|
# 写入缓存
|
|
320
320
|
if self.enable_cache:
|
|
321
|
-
|
|
321
|
+
if cache_key is not None:
|
|
322
|
+
cache.put_with_key(cache_key, response)
|
|
323
|
+
else:
|
|
324
|
+
cache.put(messages, tool_defs if tool_defs else None, response)
|
|
322
325
|
|
|
323
326
|
cache_key_ms = 0.0
|
|
324
327
|
if self.enable_cache:
|
|
@@ -96,6 +96,122 @@ class BaseAgent(BaseModel):
|
|
|
96
96
|
elif result is not None:
|
|
97
97
|
yield Event(agent=self.name, type="callback", data={"result": result, "duration": duration})
|
|
98
98
|
|
|
99
|
+
async def stream(
|
|
100
|
+
self,
|
|
101
|
+
input: str,
|
|
102
|
+
context: Any = None,
|
|
103
|
+
user_id: str | None = None,
|
|
104
|
+
session_id: str | None = None,
|
|
105
|
+
max_turns: int = 10,
|
|
106
|
+
) -> AsyncGenerator[Event, None]:
|
|
107
|
+
import uuid
|
|
108
|
+
|
|
109
|
+
from ..runner.context import RunContext
|
|
110
|
+
from ..runner.events import EventType
|
|
111
|
+
from ..runner.runner import Runner
|
|
112
|
+
|
|
113
|
+
ctx = RunContext(
|
|
114
|
+
input=input,
|
|
115
|
+
shared_context=context,
|
|
116
|
+
user_id=user_id,
|
|
117
|
+
session_id=session_id or str(uuid.uuid4()),
|
|
118
|
+
)
|
|
119
|
+
current_agent: BaseAgent = self
|
|
120
|
+
handoff_agent_cache: dict[str, BaseAgent | None] = {}
|
|
121
|
+
|
|
122
|
+
for _ in range(max_turns):
|
|
123
|
+
input_guardrails = getattr(current_agent, "input_guardrails", None)
|
|
124
|
+
if input_guardrails:
|
|
125
|
+
for guardrail in input_guardrails:
|
|
126
|
+
result = await guardrail.check(ctx)
|
|
127
|
+
if result.triggered:
|
|
128
|
+
yield Event(agent=current_agent.name, type=EventType.ERROR, data=f"输入被安全护栏拦截: {result.reason}")
|
|
129
|
+
return
|
|
130
|
+
|
|
131
|
+
async for event in current_agent.run(ctx):
|
|
132
|
+
yield event
|
|
133
|
+
|
|
134
|
+
if event.type == EventType.FINAL_OUTPUT:
|
|
135
|
+
output_guardrails = getattr(current_agent, "output_guardrails", None)
|
|
136
|
+
if output_guardrails:
|
|
137
|
+
for guardrail in output_guardrails:
|
|
138
|
+
result = await guardrail.check(ctx, event.data)
|
|
139
|
+
if result.triggered:
|
|
140
|
+
yield Event(agent=current_agent.name, type=EventType.ERROR, data=f"输出被安全护栏拦截: {result.reason}")
|
|
141
|
+
return
|
|
142
|
+
return
|
|
143
|
+
|
|
144
|
+
if event.type == EventType.HANDOFF:
|
|
145
|
+
target_name = event.data.get("target", "") if isinstance(event.data, dict) else ""
|
|
146
|
+
if target_name in handoff_agent_cache:
|
|
147
|
+
new_agent = handoff_agent_cache[target_name]
|
|
148
|
+
else:
|
|
149
|
+
new_agent = Runner._find_agent(self, target_name)
|
|
150
|
+
handoff_agent_cache[target_name] = new_agent
|
|
151
|
+
|
|
152
|
+
if new_agent:
|
|
153
|
+
current_agent = new_agent
|
|
154
|
+
break
|
|
155
|
+
|
|
156
|
+
yield Event(agent=current_agent.name, type=EventType.ERROR, data=f"Handoff 目标 '{target_name}' 未找到")
|
|
157
|
+
return
|
|
158
|
+
|
|
159
|
+
if event.type == EventType.ERROR:
|
|
160
|
+
return
|
|
161
|
+
|
|
162
|
+
yield Event(agent=current_agent.name, type=EventType.ERROR, data=f"超过最大轮次 {max_turns}")
|
|
163
|
+
|
|
164
|
+
async def ainvoke(
|
|
165
|
+
self,
|
|
166
|
+
input: str,
|
|
167
|
+
context: Any = None,
|
|
168
|
+
user_id: str | None = None,
|
|
169
|
+
session_id: str | None = None,
|
|
170
|
+
max_turns: int = 10,
|
|
171
|
+
) -> Any:
|
|
172
|
+
from ..runner.events import EventType, RunResult
|
|
173
|
+
|
|
174
|
+
events: list[Event] = []
|
|
175
|
+
final_output = None
|
|
176
|
+
error = None
|
|
177
|
+
last_agent = self.name
|
|
178
|
+
|
|
179
|
+
async for event in self.stream(
|
|
180
|
+
input=input,
|
|
181
|
+
context=context,
|
|
182
|
+
user_id=user_id,
|
|
183
|
+
session_id=session_id,
|
|
184
|
+
max_turns=max_turns,
|
|
185
|
+
):
|
|
186
|
+
events.append(event)
|
|
187
|
+
last_agent = event.agent
|
|
188
|
+
if event.type == EventType.FINAL_OUTPUT:
|
|
189
|
+
final_output = event.data
|
|
190
|
+
elif event.type == EventType.ERROR:
|
|
191
|
+
error = str(event.data)
|
|
192
|
+
|
|
193
|
+
return RunResult(final_output=final_output, error=error, events=events, last_agent=last_agent)
|
|
194
|
+
|
|
195
|
+
def invoke(
|
|
196
|
+
self,
|
|
197
|
+
input: str,
|
|
198
|
+
context: Any = None,
|
|
199
|
+
user_id: str | None = None,
|
|
200
|
+
session_id: str | None = None,
|
|
201
|
+
max_turns: int = 10,
|
|
202
|
+
) -> Any:
|
|
203
|
+
import asyncio
|
|
204
|
+
|
|
205
|
+
return asyncio.run(
|
|
206
|
+
self.ainvoke(
|
|
207
|
+
input=input,
|
|
208
|
+
context=context,
|
|
209
|
+
user_id=user_id,
|
|
210
|
+
session_id=session_id,
|
|
211
|
+
max_turns=max_turns,
|
|
212
|
+
)
|
|
213
|
+
)
|
|
214
|
+
|
|
99
215
|
@abstractmethod
|
|
100
216
|
async def _run_impl(self, ctx: "RunContext") -> AsyncGenerator[Event, None]:
|
|
101
217
|
raise NotImplementedError
|
|
@@ -91,7 +91,14 @@ Application → Agent → Skill → Tool → Foundation
|
|
|
91
91
|
|
|
92
92
|
## 核心执行流程
|
|
93
93
|
|
|
94
|
-
|
|
94
|
+
虽然 Agent 现在具备了独立执行的能力(`agent.invoke` / `agent.stream` 等),但 `Runner` 依然作为底层编排引擎存在,提供复杂场景下的能力:
|
|
95
|
+
|
|
96
|
+
- 统一的事件与 Hooks 调度
|
|
97
|
+
- 多 Agent `Handoff` 接力
|
|
98
|
+
- 异常兜底与错误报告
|
|
99
|
+
- Human-in-the-loop 挂起(Checkpoint)与恢复(Resume)
|
|
100
|
+
|
|
101
|
+
当你调用 `agent.invoke(input="...")` 时,它内部实际上也是通过委托 `Runner` 来完成的完整流程:
|
|
95
102
|
|
|
96
103
|
```
|
|
97
104
|
用户输入
|
|
@@ -99,7 +106,7 @@ Application → Agent → Skill → Tool → Foundation
|
|
|
99
106
|
▼
|
|
100
107
|
Runner.run()
|
|
101
108
|
│
|
|
102
|
-
├─
|
|
109
|
+
├─ 初始化 RunContext
|
|
103
110
|
│
|
|
104
111
|
├─ 检查输入护栏(InputGuardrail)
|
|
105
112
|
│ └─ 如果触发 → 返回错误
|
|
@@ -225,18 +232,20 @@ Agent.run() ← 异步生成器(async generator,yield Event
|
|
|
225
232
|
|
|
226
233
|
### 三种运行方式
|
|
227
234
|
|
|
235
|
+
AgentKit 提供了三种执行方式,你可以直接在 Agent 对象上调用:
|
|
236
|
+
|
|
228
237
|
| 方式 | API | 适用场景 |
|
|
229
238
|
|------|-----|---------|
|
|
230
|
-
| **同步** | `
|
|
231
|
-
| **异步** | `await
|
|
232
|
-
| **流式** | `async for event in
|
|
239
|
+
| **同步** | `agent.invoke(input=...)` | 脚本、快速测试、简单场景 |
|
|
240
|
+
| **异步** | `await agent.ainvoke(input=...)` | Web 服务、并发任务、生产环境 |
|
|
241
|
+
| **流式** | `async for event in agent.stream(input=...)` | 实时展示进度、逐 token 输出 |
|
|
233
242
|
|
|
234
243
|
### 为什么选择异步优先?
|
|
235
244
|
|
|
236
245
|
1. **LLM 调用是 I/O 密集型**:一次 LLM 调用可能耗时几秒到几十秒,异步可以在等待期间处理其他请求
|
|
237
246
|
2. **并行 Agent 需要并发**:`ParallelAgent` 并行执行多个子 Agent,必须用 `asyncio.gather`
|
|
238
247
|
3. **工具可能涉及网络**:调用外部 API、数据库查询等都是异步操作
|
|
239
|
-
4. **`
|
|
248
|
+
4. **`invoke()` 兜底**:不熟悉异步的用户可以直接用同步入口,零学习成本
|
|
240
249
|
|
|
241
250
|
### 流式运行示例
|
|
242
251
|
|
|
@@ -244,7 +253,7 @@ Agent.run() ← 异步生成器(async generator,yield Event
|
|
|
244
253
|
from agentkit.runner.events import EventType
|
|
245
254
|
|
|
246
255
|
async def main():
|
|
247
|
-
async for event in
|
|
256
|
+
async for event in agent.stream(input="你好"):
|
|
248
257
|
# 推荐使用 EventType 枚举匹配标准事件类型
|
|
249
258
|
if event.type == EventType.LLM_RESPONSE:
|
|
250
259
|
print("LLM 思考中...")
|
|
@@ -417,8 +426,8 @@ AgentKit 的记忆系统遵循**可选、可插拔、自动化**三个原则:
|
|
|
417
426
|
|
|
418
427
|
```python
|
|
419
428
|
# 不同用户的记忆互不干扰
|
|
420
|
-
await
|
|
421
|
-
await
|
|
429
|
+
await agent.ainvoke(input="我喜欢咖啡", user_id="user_A")
|
|
430
|
+
await agent.ainvoke(input="我喜欢茶", user_id="user_B")
|
|
422
431
|
```
|
|
423
432
|
|
|
424
433
|
---
|
|
@@ -471,6 +480,7 @@ agent.clear_cache()
|
|
|
471
480
|
> - 缓存仅在单 Agent 实例内有效,重新创建 Agent 会清空缓存
|
|
472
481
|
> - 默认最大 128 条缓存,LRU 淘汰最久未使用的条目
|
|
473
482
|
> - 缓存实现内置 key 生成统计:`key_gen_calls / key_gen_total_ms / key_gen_last_ms / key_gen_avg_ms`
|
|
483
|
+
> - 缓存实现对同一轮的缓存 key 计算做了复用(避免 miss 场景下重复算 key)
|
|
474
484
|
|
|
475
485
|
### 3. 记忆异步写入
|
|
476
486
|
|