ni.agentkit 0.7.0__tar.gz → 0.7.2__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.
Files changed (127) hide show
  1. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/PKG-INFO +4 -7
  2. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/README.md +3 -4
  3. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/__init__.py +1 -1
  4. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/docs/Architecture.md +2 -2
  5. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/docs/QuickStart.md +66 -0
  6. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/docs/README.md +1 -2
  7. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/docs/Reference.md +15 -2
  8. ni_agentkit-0.7.2/docs/TestReport.md +61 -0
  9. ni_agentkit-0.7.2/examples/Skill.md +41 -0
  10. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/examples/ollama/01_basic_chat.py +2 -1
  11. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/examples/ollama/02_tool_calling.py +2 -4
  12. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/examples/ollama/03_skill_usage.py +2 -5
  13. ni_agentkit-0.7.2/examples/ollama/03b_skill_tools_entry.py +45 -0
  14. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/examples/ollama/04_multi_agent.py +6 -7
  15. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/examples/ollama/05_guardrail.py +2 -5
  16. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/examples/ollama/05_human_in_the_loop.py +2 -5
  17. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/examples/ollama/06_orchestration.py +9 -15
  18. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/examples/ollama/07_sync_async_stream.py +2 -9
  19. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/examples/ollama/08_memory.py +3 -12
  20. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/examples/ollama/08a_memory_simple_provider.py +3 -8
  21. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/examples/ollama/08b_memory_mem0_provider.py +2 -9
  22. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/examples/ollama/08c_memory_file_provider.py +2 -6
  23. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/examples/ollama/09a_structured_data_sql.py +2 -1
  24. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/examples/ollama/09b_structured_data_graph.py +2 -1
  25. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/examples/ollama/09c_nebula_graph_tool.py +0 -7
  26. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/examples/ollama/10_skill_lifecycle.py +2 -1
  27. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/examples/ollama/11_orchestration_enhancement.py +2 -1
  28. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/examples/ollama/13_human_in_the_loop.py +2 -1
  29. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/examples/ollama/14_event_standardization.py +8 -9
  30. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/examples/ollama/15_multi_tenant_isolation.py +2 -1
  31. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/examples/ollama/16_lifecycle_hooks.py +2 -1
  32. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/examples/ollama/17_checkpoint_handoff_resume.py +0 -4
  33. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/examples/ollama/18_model_cosplay.py +9 -9
  34. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/examples/ollama/19_hitl_deterministic.py +0 -2
  35. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/examples/ollama/README.md +24 -10
  36. ni_agentkit-0.7.2/examples/ollama/model_config.py +61 -0
  37. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/examples/quickstart.py +2 -4
  38. ni_agentkit-0.7.2/examples/skills/weather-tools-entry/SKILL.md +25 -0
  39. ni_agentkit-0.7.2/examples/skills/weather-tools-entry/tools/weather_tools.py +12 -0
  40. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/examples/standard/01_basic_chat.py +2 -1
  41. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/examples/standard/02_tool_calling.py +2 -4
  42. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/examples/standard/03_skill_usage.py +2 -5
  43. ni_agentkit-0.7.2/examples/standard/03b_skill_tools_entry.py +44 -0
  44. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/examples/standard/04_multi_agent.py +6 -7
  45. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/examples/standard/05_guardrail.py +2 -5
  46. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/examples/standard/06_orchestration.py +9 -11
  47. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/examples/standard/07_sync_async_stream.py +2 -9
  48. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/examples/standard/08_memory.py +3 -7
  49. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/examples/standard/08a_memory_simple_provider.py +2 -5
  50. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/examples/standard/08b_memory_mem0_provider.py +5 -4
  51. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/examples/standard/08c_memory_file_provider.py +2 -4
  52. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/examples/standard/09a_structured_data_sql.py +2 -1
  53. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/examples/standard/09b_structured_data_graph.py +2 -1
  54. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/examples/standard/09c_nebula_graph_tool.py +0 -7
  55. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/examples/standard/10_skill_lifecycle.py +2 -1
  56. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/examples/standard/11_orchestration_enhancement.py +2 -1
  57. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/examples/standard/13_human_in_the_loop.py +2 -1
  58. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/examples/standard/14_event_standardization.py +8 -7
  59. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/examples/standard/15_multi_tenant_isolation.py +2 -1
  60. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/examples/standard/16_lifecycle_hooks.py +2 -1
  61. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/examples/standard/17_checkpoint_handoff_resume.py +0 -4
  62. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/examples/standard/18_model_cosplay.py +8 -9
  63. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/examples/standard/README.md +7 -0
  64. ni_agentkit-0.7.2/examples/standard/model_config.py +53 -0
  65. ni_agentkit-0.7.2/examples/test_standard.py +50 -0
  66. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/ni.agentkit.egg-info/PKG-INFO +4 -7
  67. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/ni.agentkit.egg-info/SOURCES.txt +17 -0
  68. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/ni.agentkit.egg-info/requires.txt +0 -3
  69. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/pyproject.toml +1 -2
  70. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/runner/context_store.py +0 -1
  71. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/safety/permissions.py +1 -1
  72. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/skills/loader.py +1 -0
  73. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/skills/models.py +75 -0
  74. ni_agentkit-0.7.2/tests/test_skill_frontmatter.py +135 -0
  75. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/tools/skill_toolset.py +116 -2
  76. ni_agentkit-0.7.0/docs/TestReport.md +0 -92
  77. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/LICENSE +0 -0
  78. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/_cli.py +0 -0
  79. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/agents/__init__.py +0 -0
  80. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/agents/agent.py +0 -0
  81. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/agents/base_agent.py +0 -0
  82. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/agents/orchestrators.py +0 -0
  83. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/examples/__init__.py +0 -0
  84. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/examples/ollama/12_run_context_serialization.py +0 -0
  85. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/examples/ollama/__init__.py +0 -0
  86. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/examples/standard/12_run_context_serialization.py +0 -0
  87. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/examples/standard/__init__.py +0 -0
  88. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/examples/test_ollama.py +0 -0
  89. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/llm/__init__.py +0 -0
  90. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/llm/adapters/__init__.py +0 -0
  91. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/llm/adapters/anthropic_adapter.py +0 -0
  92. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/llm/adapters/google_adapter.py +0 -0
  93. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/llm/adapters/ollama_adapter.py +0 -0
  94. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/llm/adapters/openai_adapter.py +0 -0
  95. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/llm/adapters/openai_compatible.py +0 -0
  96. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/llm/base.py +0 -0
  97. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/llm/cache.py +0 -0
  98. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/llm/middleware.py +0 -0
  99. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/llm/registry.py +0 -0
  100. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/llm/types.py +0 -0
  101. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/memory/__init__.py +0 -0
  102. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/memory/base.py +0 -0
  103. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/memory/mem0_provider.py +0 -0
  104. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/ni.agentkit.egg-info/dependency_links.txt +0 -0
  105. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/ni.agentkit.egg-info/entry_points.txt +0 -0
  106. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/ni.agentkit.egg-info/top_level.txt +0 -0
  107. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/runner/__init__.py +0 -0
  108. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/runner/context.py +0 -0
  109. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/runner/events.py +0 -0
  110. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/runner/runner.py +0 -0
  111. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/safety/__init__.py +0 -0
  112. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/safety/guardrails.py +0 -0
  113. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/setup.cfg +0 -0
  114. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/skills/__init__.py +0 -0
  115. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/skills/registry.py +0 -0
  116. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/tests/test_after_callback.py +0 -0
  117. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/tests/test_graph_repository.py +0 -0
  118. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/tests/test_quickstart_core.py +0 -0
  119. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/tests/test_runner_checkpoint_resume.py +0 -0
  120. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/tools/__init__.py +0 -0
  121. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/tools/base_tool.py +0 -0
  122. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/tools/function_tool.py +0 -0
  123. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/tools/nebula_tool.py +0 -0
  124. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/tools/sqlite_tool.py +0 -0
  125. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/tools/structured_data.py +0 -0
  126. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/utils/__init__.py +0 -0
  127. {ni_agentkit-0.7.0 → ni_agentkit-0.7.2}/utils/schema.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ni.agentkit
3
- Version: 0.7.0
3
+ Version: 0.7.2
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
@@ -31,8 +31,6 @@ Provides-Extra: google
31
31
  Requires-Dist: google-genai>=1.0.0; extra == "google"
32
32
  Provides-Extra: memory
33
33
  Requires-Dist: mem0ai>=0.1.0; extra == "memory"
34
- Provides-Extra: docker
35
- Requires-Dist: docker>=7.0.0; extra == "docker"
36
34
  Provides-Extra: all
37
35
  Requires-Dist: openai>=1.0.0; extra == "all"
38
36
  Requires-Dist: anthropic>=0.30.0; extra == "all"
@@ -71,7 +69,6 @@ pip install "ni.agentkit[openai]"
71
69
  pip install "ni.agentkit[anthropic]"
72
70
  pip install "ni.agentkit[google]"
73
71
  pip install "ni.agentkit[memory]"
74
- pip install "ni.agentkit[docker]"
75
72
  pip install "ni.agentkit[all]"
76
73
  ```
77
74
 
@@ -119,7 +116,7 @@ print(agentkit.get_examples_dir()) # 示例目录路径
119
116
 
120
117
  ## 🧪 示例
121
118
 
122
- 安装包内含 36 个可运行示例(标准版 × 18 + Ollama 本地版 × 18):
119
+ 安装包内含可运行示例(标准版 24 + Ollama 本地版 26 个):
123
120
 
124
121
  ```bash
125
122
  # Ollama 本地版(无需 API Key)
@@ -153,8 +150,8 @@ python "$(python -c "import agentkit, os; print(os.path.join(agentkit.get_exampl
153
150
 
154
151
  ```bash
155
152
  dist/
156
- ├── ni_agentkit-0.7.0-py3-none-any.whl # pip install 用这个
157
- └── ni_agentkit-0.7.0.tar.gz # 源码分发
153
+ ├── ni_agentkit-0.7.2-py3-none-any.whl # pip install 用这个
154
+ └── ni_agentkit-0.7.2.tar.gz # 源码分发
158
155
  ```
159
156
 
160
157
  ## 📄 License
@@ -29,7 +29,6 @@ pip install "ni.agentkit[openai]"
29
29
  pip install "ni.agentkit[anthropic]"
30
30
  pip install "ni.agentkit[google]"
31
31
  pip install "ni.agentkit[memory]"
32
- pip install "ni.agentkit[docker]"
33
32
  pip install "ni.agentkit[all]"
34
33
  ```
35
34
 
@@ -77,7 +76,7 @@ print(agentkit.get_examples_dir()) # 示例目录路径
77
76
 
78
77
  ## 🧪 示例
79
78
 
80
- 安装包内含 36 个可运行示例(标准版 × 18 + Ollama 本地版 × 18):
79
+ 安装包内含可运行示例(标准版 24 + Ollama 本地版 26 个):
81
80
 
82
81
  ```bash
83
82
  # Ollama 本地版(无需 API Key)
@@ -111,8 +110,8 @@ python "$(python -c "import agentkit, os; print(os.path.join(agentkit.get_exampl
111
110
 
112
111
  ```bash
113
112
  dist/
114
- ├── ni_agentkit-0.7.0-py3-none-any.whl # pip install 用这个
115
- └── ni_agentkit-0.7.0.tar.gz # 源码分发
113
+ ├── ni_agentkit-0.7.2-py3-none-any.whl # pip install 用这个
114
+ └── ni_agentkit-0.7.2.tar.gz # 源码分发
116
115
  ```
117
116
 
118
117
  ## 📄 License
@@ -31,7 +31,7 @@ from .tools.function_tool import FunctionTool, function_tool
31
31
  from .tools.structured_data import ResultFormatter, StructuredDataTool
32
32
  from .tools.sqlite_tool import SQLiteTool, SQLiteResultFormatter
33
33
 
34
- __version__ = "0.7.0"
34
+ __version__ = "0.7.2"
35
35
 
36
36
 
37
37
  def get_docs_dir() -> str:
@@ -620,8 +620,8 @@ agentkit/
620
620
  │ └── schema.py # 函数签名 → JSON Schema
621
621
 
622
622
  ├── examples/ # 示例
623
- │ ├── standard/ # 标准版示例(01-18,含 8A/8B/8C、9A/9B/9C)
624
- │ ├── ollama/ # Ollama 版示例(01-19,含 8A/8B/8C、9A/9B/9C)
623
+ │ ├── standard/ # 标准版示例(24 个:01-18 + 03B,含 8A/8B/8C、9A/9B/9C)
624
+ │ ├── ollama/ # Ollama 版示例(26 个:01-19 + 03B + 05_human_in_the_loop,含 8A/8B/8C、9A/9B/9C)
625
625
  │ ├── quickstart.py
626
626
  │ └── test_ollama.py
627
627
 
@@ -308,6 +308,66 @@ agent = Agent(
308
308
  )
309
309
  ```
310
310
 
311
+ ### 方式 C:通过 `SKILL.md` 的 `tools.entry` 动态注册工具
312
+
313
+ 当 Skill 需要自带工具实现时,可以在 `tools` 字段中声明 `entry`。Skill 激活后,AgentKit 会按 `entry` 自动发现并注册工具。
314
+
315
+ Skill 目录结构:
316
+
317
+ ```text
318
+ skills/weather-tools-entry/
319
+ ├── SKILL.md
320
+ └── tools/
321
+ └── weather_tools.py
322
+ ```
323
+
324
+ `SKILL.md`(关键片段):
325
+
326
+ ```yaml
327
+ ---
328
+ name: weather-tools-entry
329
+ description: 通过 SKILL.md 的 tools.entry 动态注册天气查询工具
330
+ tools:
331
+ - name: weather_lookup
332
+ description: 查询城市天气并给出简要信息
333
+ entry: tools/weather_tools.py:weather_lookup
334
+ parameters:
335
+ city: { type: string, description: "城市名称,如北京/上海/深圳" }
336
+ ---
337
+ ```
338
+
339
+ `tools/weather_tools.py`:
340
+
341
+ ```python
342
+ def weather_lookup(city: str) -> str:
343
+ data = {"北京": "晴,25°C", "深圳": "阵雨,28°C"}
344
+ return data.get(city, f"{city}:暂无数据")
345
+ ```
346
+
347
+ 加载并使用(无需手动把 `weather_lookup` 放入 `Agent.tools`):
348
+
349
+ ```python
350
+ from pathlib import Path
351
+ from agentkit import Agent, Runner, load_skill_from_dir
352
+
353
+ skill_dir = Path("./skills/weather-tools-entry")
354
+ skill = load_skill_from_dir(skill_dir)
355
+
356
+ agent = Agent(
357
+ name="skill-tools-entry-agent",
358
+ instructions="你是天气助手。遇到天气问题优先加载并使用 weather-tools-entry Skill。",
359
+ model="ollama/qwen3.5:cloud",
360
+ skills=[skill],
361
+ )
362
+
363
+ result = Runner.run_sync(agent, input="深圳今天适合穿什么?")
364
+ print(result.final_output)
365
+ ```
366
+
367
+ > 可运行示例:
368
+ > - `examples/standard/03b_skill_tools_entry.py`
369
+ > - `examples/ollama/03b_skill_tools_entry.py`
370
+
311
371
  ### Skill 三级加载机制
312
372
 
313
373
  AgentKit 的 Skill 采用三级渐进式加载,避免浪费 token:
@@ -1234,10 +1294,12 @@ agent = Agent(name="assistant", instructions="...")
1234
1294
  | [`01_basic_chat.py`](../examples/standard/01_basic_chat.py) | 示例 1:最简 Agent |
1235
1295
  | [`02_tool_calling.py`](../examples/standard/02_tool_calling.py) | 示例 2:工具调用 |
1236
1296
  | [`03_skill_usage.py`](../examples/standard/03_skill_usage.py) | 示例 3:Skill 使用 |
1297
+ | [`03b_skill_tools_entry.py`](../examples/standard/03b_skill_tools_entry.py) | 示例 3B:Skill tools.entry 动态注册/发现 |
1237
1298
  | [`04_multi_agent.py`](../examples/standard/04_multi_agent.py) | 示例 4:多 Agent 协作 |
1238
1299
  | [`05_guardrail.py`](../examples/standard/05_guardrail.py) | 示例 5:安全护栏 |
1239
1300
  | [`06_orchestration.py`](../examples/standard/06_orchestration.py) | 示例 6:编排 Agent |
1240
1301
  | [`07_sync_async_stream.py`](../examples/standard/07_sync_async_stream.py) | 示例 7:同步/异步/流式运行 |
1302
+ | [`08_memory.py`](../examples/standard/08_memory.py) | 示例 8:记忆系统(综合) |
1241
1303
  | [`08a_memory_simple_provider.py`](../examples/standard/08a_memory_simple_provider.py) | 示例 8A:记忆系统(SimpleMemory) |
1242
1304
  | [`08b_memory_mem0_provider.py`](../examples/standard/08b_memory_mem0_provider.py) | 示例 8B:记忆系统(Mem0Provider) |
1243
1305
  | [`08c_memory_file_provider.py`](../examples/standard/08c_memory_file_provider.py) | 示例 8C:记忆系统(文件持久化) |
@@ -1261,10 +1323,13 @@ agent = Agent(name="assistant", instructions="...")
1261
1323
  | [`01_basic_chat.py`](../examples/ollama/01_basic_chat.py) | 示例 1:最简 Agent |
1262
1324
  | [`02_tool_calling.py`](../examples/ollama/02_tool_calling.py) | 示例 2:工具调用 |
1263
1325
  | [`03_skill_usage.py`](../examples/ollama/03_skill_usage.py) | 示例 3:Skill 使用 |
1326
+ | [`03b_skill_tools_entry.py`](../examples/ollama/03b_skill_tools_entry.py) | 示例 3B:Skill tools.entry 动态注册/发现 |
1264
1327
  | [`04_multi_agent.py`](../examples/ollama/04_multi_agent.py) | 示例 4:多 Agent 协作 |
1265
1328
  | [`05_guardrail.py`](../examples/ollama/05_guardrail.py) | 示例 5:安全护栏 |
1329
+ | [`05_human_in_the_loop.py`](../examples/ollama/05_human_in_the_loop.py) | 扩展示例:HITL 工具触发(Playground) |
1266
1330
  | [`06_orchestration.py`](../examples/ollama/06_orchestration.py) | 示例 6:编排 Agent |
1267
1331
  | [`07_sync_async_stream.py`](../examples/ollama/07_sync_async_stream.py) | 示例 7:同步/异步/流式运行 |
1332
+ | [`08_memory.py`](../examples/ollama/08_memory.py) | 示例 8:记忆系统(综合) |
1268
1333
  | [`08a_memory_simple_provider.py`](../examples/ollama/08a_memory_simple_provider.py) | 示例 8A:记忆系统(SimpleMemory) |
1269
1334
  | [`08b_memory_mem0_provider.py`](../examples/ollama/08b_memory_mem0_provider.py) | 示例 8B:记忆系统(Mem0Provider) |
1270
1335
  | [`08c_memory_file_provider.py`](../examples/ollama/08c_memory_file_provider.py) | 示例 8C:记忆系统(文件持久化) |
@@ -1280,6 +1345,7 @@ agent = Agent(name="assistant", instructions="...")
1280
1345
  | [`16_lifecycle_hooks.py`](../examples/ollama/16_lifecycle_hooks.py) | 示例 16:生命周期 Hooks 与 Callbacks |
1281
1346
  | [`17_checkpoint_handoff_resume.py`](../examples/ollama/17_checkpoint_handoff_resume.py) | 示例 17:Checkpoint 深度恢复(Handoff + Resume) |
1282
1347
  | [`18_model_cosplay.py`](../examples/ollama/18_model_cosplay.py) | 示例 18:ModelCosplay(运行时改写预设模型) |
1348
+ | [`19_hitl_deterministic.py`](../examples/ollama/19_hitl_deterministic.py) | 示例 19:HITL 确定性触发 |
1283
1349
 
1284
1350
  ---
1285
1351
 
@@ -3,7 +3,7 @@
3
3
  > Python 原生的 Agent 开发框架,内置一等公民级别的 Skill 支持和自研多模型适配层。
4
4
 
5
5
  [![Python](https://img.shields.io/badge/Python-≥3.11-blue.svg)](https://python.org)
6
- [![Version](https://img.shields.io/badge/Version-0.7.0-green.svg)]()
6
+ [![Version](https://img.shields.io/badge/Version-0.7.2-green.svg)]()
7
7
  [![License](https://img.shields.io/badge/License-MIT-yellow.svg)]()
8
8
 
9
9
  ---
@@ -35,7 +35,6 @@ pip install "ni.agentkit[openai]" # OpenAI + 国内兼容厂商
35
35
  pip install "ni.agentkit[anthropic]" # Anthropic Claude
36
36
  pip install "ni.agentkit[google]" # Google Gemini
37
37
  pip install "ni.agentkit[memory]" # 记忆系统 (mem0)
38
- pip install "ni.agentkit[docker]" # 预留:SandboxExecutor Docker 扩展依赖
39
38
  pip install "ni.agentkit[all]" # 安装所有可选依赖
40
39
  ```
41
40
 
@@ -505,7 +505,7 @@ from agentkit import Skill, SkillFrontmatter, SkillResources
505
505
  | `on_load_hook` | `Callable \| None` | **生命周期钩子**:在 Agent 执行前加载资源 |
506
506
  | `on_unload_hook` | `Callable \| None` | **生命周期钩子**:在 Agent 执行后释放资源 |
507
507
 
508
- **便捷属性**:`skill.name`、`skill.description`、`skill.additional_tools`、`skill.llm_config`
508
+ **便捷属性**:`skill.name`、`skill.description`、`skill.additional_tools`、`skill.triggers`、`skill.dependencies`、`skill.tools`、`skill.tool_specs`、`skill.llm_config`
509
509
 
510
510
  ---
511
511
 
@@ -516,7 +516,20 @@ from agentkit import Skill, SkillFrontmatter, SkillResources
516
516
  | `name` | `str` | kebab-case 标识符(≤64 字符) |
517
517
  | `description` | `str` | 描述(≤1024 字符) |
518
518
  | `license` | `str \| None` | 许可证 |
519
- | `metadata` | `dict` | 扩展元数据,可含 `additional_tools` `llm_config` |
519
+ | `compatibility` | `str \| None` | 可选兼容性标记(版本/平台约束) |
520
+ | `triggers` | `list[str]` | 触发关键词列表,用于描述 Skill 的适用场景 |
521
+ | `dependencies` | `list[str]` | Skill 运行依赖声明(如三方包/外部能力) |
522
+ | `tools` | `list[SkillToolSpec]` | Skill 声明的工具列表;支持字符串简写和对象写法,最终归一化为 `SkillToolSpec` |
523
+ | `metadata` | `dict` | 扩展元数据,可含 `additional_tools`(兼容旧写法)和 `llm_config` |
524
+
525
+ `SkillToolSpec` 字段:
526
+
527
+ | 字段 | 类型 | 说明 |
528
+ |------|------|------|
529
+ | `name` | `str` | 工具名称(必填) |
530
+ | `description` | `str \| None` | 工具描述 |
531
+ | `entry` | `str \| None` | 动态加载入口,格式 `module:attr` 或相对 Skill 目录的 `path.py:attr` |
532
+ | `parameters` | `dict[str, Any]` | 参数 Schema 片段,用于构建工具 JSON Schema |
520
533
 
521
534
  ---
522
535
 
@@ -0,0 +1,61 @@
1
+ # AgentKit 示例测试报告
2
+
3
+ > 测试时间:`2026-05-05`
4
+ > 测试环境:`macOS (Apple Silicon)`
5
+ > 模型:`qwen/qwen3.5-flash` (DashScope)
6
+ > AgentKit 版本:v0.7.2
7
+ > Thinking 模式:开启(默认)
8
+ > LLM 调用模式:非流式(默认)
9
+ > 缓存:开启(默认)
10
+ > 执行脚本:`examples/test_standard.py`
11
+
12
+ ---
13
+
14
+ ## 测试结果
15
+
16
+ | # | 示例 | 文件 | 耗时 | 状态 | 说明 |
17
+ |---|------|------|-----:|:----:|------|
18
+ | 1 | 基础对话 | `01_basic_chat.py` | 11.89s | ✅ | 运行通过 |
19
+ | 2 | 工具调用 | `02_tool_calling.py` | 5.47s | ✅ | 运行通过 |
20
+ | 3 | Skill 使用 | `03_skill_usage.py` | 8.80s | ✅ | 运行通过 |
21
+ | 3B | Skill tools.entry 动态注册/发现 | `03b_skill_tools_entry.py` | 5.83s | ✅ | 运行通过 |
22
+ | 4 | 多 Agent 协作 | `04_multi_agent.py` | 34.73s | ✅ | 运行通过 |
23
+ | 5 | 安全护栏 | `05_guardrail.py` | 4.80s | ✅ | 运行通过 |
24
+ | 6 | 编排 Agent | `06_orchestration.py` | 84.79s | ✅ | 运行通过 |
25
+ | 7 | 同步/异步/流式 | `07_sync_async_stream.py` | 5.88s | ✅ | 运行通过 |
26
+ | 8 | 记忆系统(综合) | `08_memory.py` | 77.63s | ✅ | 运行通过 |
27
+ | 8A | SimpleMemory | `08a_memory_simple_provider.py` | 13.58s | ✅ | 运行通过 |
28
+ | 8B | Mem0Provider | `08b_memory_mem0_provider.py` | 0.21s | ✅ | 未配置 OPENAI_API_KEY,自动跳过 |
29
+ | 8C | 文件持久化 Memory | `08c_memory_file_provider.py` | 19.65s | ✅ | 运行通过 |
30
+ | 9A | 结构化数据(SQL) | `09a_structured_data_sql.py` | 2.41s | ✅ | 运行通过 |
31
+ | 9B | 结构化数据(图) | `09b_structured_data_graph.py` | 2.48s | ✅ | 运行通过 |
32
+ | 9C | NebulaGraphTool(直调) | `09c_nebula_graph_tool.py` | 0.32s | ✅ | 运行通过 |
33
+ | 10 | Skill 生命周期 | `10_skill_lifecycle.py` | 1.53s | ✅ | 运行通过 |
34
+ | 11 | 编排增强 | `11_orchestration_enhancement.py` | 17.11s | ✅ | 运行通过 |
35
+ | 12 | 序列化协议 | `12_run_context_serialization.py` | 0.31s | ✅ | 运行通过 |
36
+ | 13 | Human in the Loop | `13_human_in_the_loop.py` | 4.39s | ✅ | 运行通过 |
37
+ | 14 | Event 标准化 | `14_event_standardization.py` | 5.13s | ✅ | 运行通过 |
38
+ | 15 | 多租户隔离 | `15_multi_tenant_isolation.py` | 4.58s | ✅ | 运行通过 |
39
+ | 16 | 生命周期 Hooks | `16_lifecycle_hooks.py` | 4.74s | ✅ | 运行通过 |
40
+ | 17 | Checkpoint + Handoff + Resume | `17_checkpoint_handoff_resume.py` | 0.17s | ✅ | 运行通过 |
41
+ | 18 | ModelCosplay | `18_model_cosplay.py` | 0.18s | ✅ | 运行通过 |
42
+ | | **合计** | | **316.61s** | **24/24** | |
43
+
44
+ ## 耗时分析
45
+
46
+ - **最快示例**:17 Checkpoint + Handoff + Resume (0.17s)
47
+ - **最慢示例**:06 编排 Agent (84.79s)
48
+ - **性能改进**:相比 Ollama 运行,DashScope 接口响应更快,且在大规模编排和记忆检索场景下稳定性更好。
49
+
50
+ ## 已知问题
51
+
52
+ | 问题 | 严重程度 | 说明 |
53
+ |------|:--------:|------|
54
+ | 运行异常 | - | 无,24 个示例全部通过 |
55
+
56
+ ## 运行方式
57
+
58
+ ```bash
59
+ # 在 agentkit 目录执行
60
+ python examples/test_standard.py
61
+ ```
@@ -0,0 +1,41 @@
1
+ ---
2
+ name: "skill_name"
3
+ version: "1.0.0"
4
+ description: "一句话说明技能用途"
5
+ author: "your_name"
6
+ license: "MIT"
7
+ triggers:
8
+ - "触发词1"
9
+ - "触发词2"
10
+ dependencies:
11
+ - package1>=1.0
12
+ - package2
13
+ tools:
14
+ - name: "tool_name"
15
+ description: "工具功能简述"
16
+ entry: "tools/tool_module.py:tool_function"
17
+ parameters:
18
+ param1: { type: string, description: "参数说明" }
19
+ param2: { type: integer, default: 10, description: "可选参数" }
20
+ metadata:
21
+ additional_tools:
22
+ - "extra_tool_name"
23
+ sandbox_required: true
24
+ timeout: 30
25
+ ---
26
+
27
+ # 🛠️ 技能名称
28
+
29
+ ## 🎯 能力边界
30
+ - ✅ 支持:...
31
+ - ❌ 不支持:...
32
+ - ⚠️ 限制:...
33
+
34
+ ## 💡 调用示例
35
+ **用户**: "请执行 XX 操作"
36
+ **Agent**:
37
+ ```json
38
+ {
39
+ "tool": "tool_name",
40
+ "arguments": { "param1": "value", "param2": 5 }
41
+ }
@@ -12,12 +12,13 @@ import sys, os
12
12
  sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "..", ".."))
13
13
 
14
14
  from agentkit import Agent, Runner
15
+ from model_config import resolve_model
15
16
 
16
17
  # 创建最简 Agent —— 使用本地 Ollama 模型
17
18
  agent = Agent(
18
19
  name="assistant",
19
20
  instructions="你是一个有帮助的中文助手。回答尽量简洁。",
20
- model="ollama/qwen3.5:cloud", # 本地 Ollama 模型,无需 API Key
21
+ model=resolve_model("qwen3.5:cloud"), # 本地 Ollama 模型,无需 API Key
21
22
  )
22
23
 
23
24
  # 同步运行
@@ -14,7 +14,7 @@ import sys, os
14
14
  sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "..", ".."))
15
15
 
16
16
  from agentkit import Agent, Runner, function_tool
17
-
17
+ from model_config import resolve_model
18
18
 
19
19
  # ===== 定义工具 =====
20
20
 
@@ -38,17 +38,15 @@ def get_weather(city: str) -> str:
38
38
  }
39
39
  return weather_data.get(city, f"{city}:暂无数据")
40
40
 
41
-
42
41
  # ===== 创建 Agent =====
43
42
 
44
43
  agent = Agent(
45
44
  name="smart-assistant",
46
45
  instructions="你是一个全能助手。可以做数学计算和查天气。根据用户需求选择合适的工具。回答简洁。",
47
- model="ollama/qwen3.5:cloud",
46
+ model=resolve_model("qwen3.5:cloud"),
48
47
  tools=[add, multiply, get_weather],
49
48
  )
50
49
 
51
-
52
50
  # ===== 运行测试 =====
53
51
 
54
52
  queries = [
@@ -14,7 +14,7 @@ import sys, os
14
14
  sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "..", ".."))
15
15
 
16
16
  from agentkit import Agent, Runner, Skill, SkillFrontmatter, function_tool
17
-
17
+ from model_config import resolve_model
18
18
 
19
19
  # ===== 定义工具 =====
20
20
 
@@ -30,7 +30,6 @@ def get_weather(city: str) -> str:
30
30
  }
31
31
  return weather_data.get(city, f"{city}:暂无数据")
32
32
 
33
-
34
33
  # ===== 定义 Skill =====
35
34
 
36
35
  weather_skill = Skill(
@@ -49,18 +48,16 @@ weather_skill = Skill(
49
48
  4. 用简洁的中文回复用户""",
50
49
  )
51
50
 
52
-
53
51
  # ===== 创建带 Skill 的 Agent =====
54
52
 
55
53
  agent = Agent(
56
54
  name="skill-agent",
57
55
  instructions="你是一个智能助手,可以使用专业技能来完成任务。",
58
- model="ollama/qwen3.5:cloud",
56
+ model=resolve_model("qwen3.5:cloud"),
59
57
  skills=[weather_skill],
60
58
  tools=[get_weather],
61
59
  )
62
60
 
63
-
64
61
  # ===== 运行测试 =====
65
62
 
66
63
  queries = [
@@ -0,0 +1,45 @@
1
+ """
2
+ 示例 3B:SKILL.md tools.entry 动态工具注册/发现(Ollama 版)
3
+
4
+ 运行前请确保:
5
+ ollama serve
6
+ ollama pull qwen3.5:cloud
7
+
8
+ 运行:
9
+ python examples/ollama/03b_skill_tools_entry.py
10
+ """
11
+ import os
12
+ import sys
13
+ from pathlib import Path
14
+
15
+ sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "..", ".."))
16
+
17
+ from agentkit import Agent, Runner, load_skill_from_dir
18
+ from model_config import resolve_model
19
+
20
+ skill_dir = Path(__file__).resolve().parents[1] / "skills" / "weather-tools-entry"
21
+ weather_skill = load_skill_from_dir(skill_dir)
22
+
23
+ agent = Agent(
24
+ name="skill-tools-entry-agent",
25
+ instructions="你是天气助手。遇到天气问题优先加载并使用 weather-tools-entry Skill。",
26
+ model=resolve_model(),
27
+ skills=[weather_skill],
28
+ )
29
+
30
+ queries = [
31
+ "深圳今天适合穿什么?",
32
+ "广州今天需要带伞吗?",
33
+ ]
34
+
35
+ for q in queries:
36
+ print(f"\n用户: {q}")
37
+ result = Runner.run_sync(agent, input=q)
38
+ if result.success:
39
+ print(f"助手: {result.final_output}")
40
+ else:
41
+ print(f"❌ 错误: {result.error}")
42
+
43
+ for event in result.events:
44
+ if event.type == "tool_result":
45
+ print(f" 🔧 {event.data.get('tool')}: {event.data.get('result')}")
@@ -14,7 +14,7 @@ import sys, os
14
14
  sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "..", ".."))
15
15
 
16
16
  from agentkit import Agent, Runner
17
-
17
+ from model_config import resolve_model
18
18
 
19
19
  # ============================================================
20
20
  # 模式 A:as_tool(委派)
@@ -27,13 +27,13 @@ print("=" * 50)
27
27
  researcher = Agent(
28
28
  name="researcher",
29
29
  instructions="你是一个研究助手。收到问题后,给出简短的研究结论(不超过 3 句话)。",
30
- model="ollama/qwen3.5:cloud",
30
+ model=resolve_model("qwen3.5:cloud"),
31
31
  )
32
32
 
33
33
  manager = Agent(
34
34
  name="manager",
35
35
  instructions="你是项目经理。需要研究信息时调用 research 工具。综合研究结果给出你的建议。",
36
- model="ollama/qwen3.5:cloud",
36
+ model=resolve_model("qwen3.5:cloud"),
37
37
  tools=[
38
38
  researcher.as_tool("research", "调用研究助手获取研究信息"),
39
39
  ],
@@ -49,7 +49,6 @@ for event in result.events:
49
49
  if event.type == "tool_result":
50
50
  print(f" 🔧 研究员返回: {str(event.data)[:100]}")
51
51
 
52
-
53
52
  # ============================================================
54
53
  # 模式 B:Handoff(转介)
55
54
  # ============================================================
@@ -61,19 +60,19 @@ print("=" * 50)
61
60
  billing_agent = Agent(
62
61
  name="billing",
63
62
  instructions="你是账单专家。处理所有账单相关的问题,给出专业的解答。",
64
- model="ollama/qwen3.5:cloud",
63
+ model=resolve_model("qwen3.5:cloud"),
65
64
  )
66
65
 
67
66
  tech_agent = Agent(
68
67
  name="tech",
69
68
  instructions="你是技术支持专家。处理所有技术相关的问题。",
70
- model="ollama/qwen3.5:cloud",
69
+ model=resolve_model("qwen3.5:cloud"),
71
70
  )
72
71
 
73
72
  triage_agent = Agent(
74
73
  name="triage",
75
74
  instructions="你是客服分诊员。根据用户问题类型,转交给合适的专家:账单问题转给 billing,技术问题转给 tech。",
76
- model="ollama/qwen3.5:cloud",
75
+ model=resolve_model("qwen3.5:cloud"),
77
76
  handoffs=[billing_agent, tech_agent],
78
77
  )
79
78
 
@@ -18,7 +18,7 @@ from agentkit import (
18
18
  input_guardrail, output_guardrail, GuardrailResult,
19
19
  PermissionPolicy,
20
20
  )
21
-
21
+ from model_config import resolve_model
22
22
 
23
23
  # ===== 定义工具 =====
24
24
 
@@ -32,7 +32,6 @@ def delete_file(filename: str) -> str:
32
32
  """删除文件"""
33
33
  return f"[模拟] 已删除文件 {filename}"
34
34
 
35
-
36
35
  # ===== 定义护栏 =====
37
36
 
38
37
  @input_guardrail
@@ -54,13 +53,12 @@ async def check_output_safety(ctx, output):
54
53
  return GuardrailResult(triggered=True, reason=f"输出包含危险内容: {word}")
55
54
  return GuardrailResult(triggered=False)
56
55
 
57
-
58
56
  # ===== 创建带安全护栏的 Agent =====
59
57
 
60
58
  agent = Agent(
61
59
  name="safe-agent",
62
60
  instructions="你是一个安全的助手。可以帮用户读取文件,但不能删除文件。",
63
- model="ollama/qwen3.5:cloud",
61
+ model=resolve_model("qwen3.5:cloud"),
64
62
  tools=[read_file, delete_file],
65
63
  input_guardrails=[block_sensitive_words],
66
64
  output_guardrails=[check_output_safety],
@@ -70,7 +68,6 @@ agent = Agent(
70
68
  ),
71
69
  )
72
70
 
73
-
74
71
  # ===== 运行测试 =====
75
72
 
76
73
  print("=" * 50)
@@ -13,22 +13,19 @@ sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "..", ".."))
13
13
  from agentkit import Agent
14
14
  from agentkit.tools.base_tool import request_human_input
15
15
  from agentkit.tools.function_tool import FunctionTool
16
-
16
+ from model_config import resolve_model
17
17
 
18
18
  def confirm_action(action: str) -> str:
19
19
  """敏感操作执行前请求人工确认。"""
20
20
  request_human_input(f"即将执行敏感操作: {action},请确认 (approve/reject)")
21
21
 
22
-
23
22
  def execute_action(action: str) -> str:
24
23
  """执行操作(示例返回)。"""
25
24
  return f"操作 '{action}' 已执行。"
26
25
 
27
-
28
26
  confirm_tool = FunctionTool.from_function(confirm_action)
29
27
  execute_tool = FunctionTool.from_function(execute_action)
30
28
 
31
-
32
29
  agent = Agent(
33
30
  name="hitl-agent",
34
31
  instructions=(
@@ -37,6 +34,6 @@ agent = Agent(
37
34
  "收到确认后再调用 execute_action。"
38
35
  ),
39
36
  # 使用纯本地模型,避免 cloud 变体在未鉴权/网络抖动时触发远端 502。
40
- model="ollama/qwen3.5:4b",
37
+ model=resolve_model(),
41
38
  tools=[confirm_tool, execute_tool],
42
39
  )