ni.agentkit 0.7.3__tar.gz → 0.7.4__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.7.4}/PKG-INFO +3 -3
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/README.md +2 -2
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/agents/agent.py +6 -2
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/docs/Architecture.md +1 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/docs/README.md +1 -1
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/docs/Reference.md +14 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/docs/TestReport.md +31 -31
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/llm/cache.py +19 -3
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/llm/registry.py +16 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/ni.agentkit.egg-info/PKG-INFO +3 -3
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/ni.agentkit.egg-info/SOURCES.txt +3 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/pyproject.toml +1 -1
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/rag/file_memory_provider.py +32 -6
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/rag/sqlite_store.py +11 -2
- ni_agentkit-0.7.4/tests/test_default_model_env.py +15 -0
- ni_agentkit-0.7.4/utils/env.py +72 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/LICENSE +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/__init__.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/_cli.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/agents/__init__.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/agents/base_agent.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/agents/orchestrators.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/docs/QuickStart.md +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/examples/Skill.md +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/examples/__init__.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/examples/ollama/01_basic_chat.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/examples/ollama/02_tool_calling.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/examples/ollama/03_skill_usage.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/examples/ollama/03b_skill_tools_entry.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/examples/ollama/04_multi_agent.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/examples/ollama/05_guardrail.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/examples/ollama/05_human_in_the_loop.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/examples/ollama/06_orchestration.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/examples/ollama/07_sync_async_stream.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/examples/ollama/08_memory.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/examples/ollama/08a_memory_simple_provider.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/examples/ollama/08b_memory_mem0_provider.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/examples/ollama/08c_memory_file_provider.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/examples/ollama/09a_structured_data_sql.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/examples/ollama/09b_structured_data_graph.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/examples/ollama/09c_nebula_graph_tool.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/examples/ollama/10_skill_lifecycle.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/examples/ollama/11_orchestration_enhancement.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/examples/ollama/12_run_context_serialization.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/examples/ollama/13_human_in_the_loop.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/examples/ollama/14_event_standardization.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/examples/ollama/15_multi_tenant_isolation.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/examples/ollama/16_lifecycle_hooks.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/examples/ollama/17_checkpoint_handoff_resume.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/examples/ollama/18_model_cosplay.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/examples/ollama/19_hitl_deterministic.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/examples/ollama/20_simple_rag_agent.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/examples/ollama/README.md +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/examples/ollama/__init__.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/examples/ollama/model_config.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/examples/quickstart.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/examples/skills/weather-tools-entry/SKILL.md +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/examples/skills/weather-tools-entry/tools/weather_tools.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/examples/standard/01_basic_chat.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/examples/standard/02_tool_calling.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/examples/standard/03_skill_usage.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/examples/standard/03b_skill_tools_entry.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/examples/standard/04_multi_agent.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/examples/standard/05_guardrail.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/examples/standard/05_human_in_the_loop.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/examples/standard/06_orchestration.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/examples/standard/07_sync_async_stream.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/examples/standard/08_memory.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/examples/standard/08a_memory_simple_provider.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/examples/standard/08b_memory_mem0_provider.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/examples/standard/08c_memory_file_provider.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/examples/standard/09a_structured_data_sql.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/examples/standard/09b_structured_data_graph.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/examples/standard/09c_nebula_graph_tool.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/examples/standard/10_skill_lifecycle.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/examples/standard/11_orchestration_enhancement.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/examples/standard/12_run_context_serialization.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/examples/standard/13_human_in_the_loop.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/examples/standard/14_event_standardization.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/examples/standard/15_multi_tenant_isolation.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/examples/standard/16_lifecycle_hooks.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/examples/standard/17_checkpoint_handoff_resume.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/examples/standard/18_model_cosplay.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/examples/standard/19_hitl_deterministic.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/examples/standard/20_simple_rag_agent.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/examples/standard/README.md +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/examples/standard/__init__.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/examples/standard/model_config.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/examples/test_ollama.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/examples/test_standard.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/llm/__init__.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/llm/adapters/__init__.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/llm/adapters/anthropic_adapter.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/llm/adapters/google_adapter.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/llm/adapters/ollama_adapter.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/llm/adapters/openai_adapter.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/llm/adapters/openai_compatible.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/llm/base.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/llm/middleware.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/llm/types.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/memory/__init__.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/memory/base.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/memory/mem0_provider.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/ni.agentkit.egg-info/dependency_links.txt +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/ni.agentkit.egg-info/entry_points.txt +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/ni.agentkit.egg-info/requires.txt +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/ni.agentkit.egg-info/top_level.txt +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/rag/__init__.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/rag/document_store.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/rag/loaders.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/rag/retrievers.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/rag/simple_rag_agent.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/rag/types.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/runner/__init__.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/runner/context.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/runner/context_store.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/runner/events.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/runner/runner.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/safety/__init__.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/safety/guardrails.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/safety/permissions.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/setup.cfg +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/skills/__init__.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/skills/loader.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/skills/models.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/skills/registry.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/tests/test_after_callback.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/tests/test_graph_repository.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/tests/test_quickstart_core.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/tests/test_runner_checkpoint_resume.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/tests/test_simple_rag.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/tests/test_skill_frontmatter.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/tools/__init__.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/tools/base_tool.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/tools/function_tool.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/tools/nebula_tool.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/tools/skill_toolset.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/tools/sqlite_tool.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/tools/structured_data.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/utils/__init__.py +0 -0
- {ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/utils/schema.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ni.agentkit
|
|
3
|
-
Version: 0.7.
|
|
3
|
+
Version: 0.7.4
|
|
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
|
|
@@ -293,11 +293,12 @@ class Agent(BaseAgent):
|
|
|
293
293
|
|
|
294
294
|
# 5. 调用 LLM(支持缓存)
|
|
295
295
|
cached = False
|
|
296
|
+
cache_key: str | None = None
|
|
296
297
|
|
|
297
298
|
# 检查缓存
|
|
298
299
|
if self.enable_cache:
|
|
299
300
|
cache = self._get_cache()
|
|
300
|
-
cached_response = cache.
|
|
301
|
+
cache_key, cached_response = cache.get_with_key(messages, tool_defs if tool_defs else None)
|
|
301
302
|
if cached_response is not None:
|
|
302
303
|
response = cached_response
|
|
303
304
|
cached = True
|
|
@@ -318,7 +319,10 @@ class Agent(BaseAgent):
|
|
|
318
319
|
|
|
319
320
|
# 写入缓存
|
|
320
321
|
if self.enable_cache:
|
|
321
|
-
|
|
322
|
+
if cache_key is not None:
|
|
323
|
+
cache.put_with_key(cache_key, response)
|
|
324
|
+
else:
|
|
325
|
+
cache.put(messages, tool_defs if tool_defs else None, response)
|
|
322
326
|
|
|
323
327
|
cache_key_ms = 0.0
|
|
324
328
|
if self.enable_cache:
|
|
@@ -471,6 +471,7 @@ agent.clear_cache()
|
|
|
471
471
|
> - 缓存仅在单 Agent 实例内有效,重新创建 Agent 会清空缓存
|
|
472
472
|
> - 默认最大 128 条缓存,LRU 淘汰最久未使用的条目
|
|
473
473
|
> - 缓存实现内置 key 生成统计:`key_gen_calls / key_gen_total_ms / key_gen_last_ms / key_gen_avg_ms`
|
|
474
|
+
> - 缓存实现对同一轮的缓存 key 计算做了复用(避免 miss 场景下重复算 key)
|
|
474
475
|
|
|
475
476
|
### 3. 记忆异步写入
|
|
476
477
|
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
> Python 原生的 Agent 开发框架,内置一等公民级别的 Skill 支持和自研多模型适配层。
|
|
4
4
|
|
|
5
5
|
[](https://python.org)
|
|
6
|
-
[]()
|
|
7
7
|
[]()
|
|
8
8
|
|
|
9
9
|
---
|
|
@@ -577,6 +577,20 @@ from agentkit import LLMRegistry
|
|
|
577
577
|
| `LLMRegistry.create_default()` | 创建默认模型实例 |
|
|
578
578
|
| `LLMRegistry.register(prefix, adapter_class)` | 注册自定义适配器 |
|
|
579
579
|
|
|
580
|
+
默认模型解析优先级:
|
|
581
|
+
|
|
582
|
+
1. 若代码中调用过 `LLMRegistry.set_default(...)`,优先使用该默认配置。
|
|
583
|
+
2. 否则会尝试从环境变量(或本地 `.env/.evn`)读取:`AGENTKIT_MODEL` → `AGENTKIT_DEFAULT_MODEL` → `AGENTKIT_STANDARD_MODEL` → `AGENTKIT_OLLAMA_MODEL`。
|
|
584
|
+
3. 都未配置时回退到内置默认值。
|
|
585
|
+
|
|
586
|
+
示例:
|
|
587
|
+
|
|
588
|
+
```bash
|
|
589
|
+
export AGENTKIT_DEFAULT_MODEL="ollama/qwen3.5:cloud"
|
|
590
|
+
# 或在项目根目录写入 .env(无需额外依赖)
|
|
591
|
+
# AGENTKIT_DEFAULT_MODEL=ollama/qwen3.5:cloud
|
|
592
|
+
```
|
|
593
|
+
|
|
580
594
|
**前缀路由表**:
|
|
581
595
|
|
|
582
596
|
| 前缀 | 适配器 | 需要的包 |
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
> 测试时间:`2026-06-15`
|
|
4
4
|
> 测试环境:`macOS (Apple Silicon)`
|
|
5
5
|
> 模型:`qwen/qwen3.6-flash` (DashScope)
|
|
6
|
-
> AgentKit 版本:v0.7.
|
|
6
|
+
> AgentKit 版本:v0.7.4
|
|
7
7
|
> Thinking 模式:开启(默认)
|
|
8
8
|
> LLM 调用模式:非流式(默认)
|
|
9
9
|
> 缓存:开启(默认)
|
|
@@ -16,39 +16,39 @@
|
|
|
16
16
|
|
|
17
17
|
| # | 示例 | 文件 | 耗时 | 状态 | 说明 |
|
|
18
18
|
|---|------|------|-----:|:----:|------|
|
|
19
|
-
| 1 | 01_basic_chat | `01_basic_chat.py` |
|
|
20
|
-
| 2 | 02_tool_calling | `02_tool_calling.py` | 10.
|
|
21
|
-
| 3 | 03_skill_usage | `03_skill_usage.py` |
|
|
22
|
-
| 4 | 03b_skill_tools_entry | `03b_skill_tools_entry.py` | 7.
|
|
23
|
-
| 5 | 04_multi_agent | `04_multi_agent.py` |
|
|
24
|
-
| 6 | 05_guardrail | `05_guardrail.py` |
|
|
25
|
-
| 7 | 05_human_in_the_loop | `05_human_in_the_loop.py` | 0.
|
|
26
|
-
| 8 | 06_orchestration | `06_orchestration.py` |
|
|
27
|
-
| 9 | 07_sync_async_stream | `07_sync_async_stream.py` |
|
|
28
|
-
| 10 | 08_memory | `08_memory.py` |
|
|
29
|
-
| 11 | 08a_memory_simple_provider | `08a_memory_simple_provider.py` |
|
|
30
|
-
| 12 | 08b_memory_mem0_provider | `08b_memory_mem0_provider.py` | 0.
|
|
31
|
-
| 13 | 08c_memory_file_provider | `08c_memory_file_provider.py` |
|
|
32
|
-
| 14 | 09a_structured_data_sql | `09a_structured_data_sql.py` | 6.
|
|
33
|
-
| 15 | 09b_structured_data_graph | `09b_structured_data_graph.py` |
|
|
34
|
-
| 16 | 09c_nebula_graph_tool | `09c_nebula_graph_tool.py` | 0.
|
|
35
|
-
| 17 | 10_skill_lifecycle | `10_skill_lifecycle.py` | 2.
|
|
36
|
-
| 18 | 11_orchestration_enhancement | `11_orchestration_enhancement.py` | 3.
|
|
37
|
-
| 19 | 12_run_context_serialization | `12_run_context_serialization.py` | 0.
|
|
38
|
-
| 20 | 13_human_in_the_loop | `13_human_in_the_loop.py` |
|
|
39
|
-
| 21 | 14_event_standardization | `14_event_standardization.py` |
|
|
40
|
-
| 22 | 15_multi_tenant_isolation | `15_multi_tenant_isolation.py` |
|
|
41
|
-
| 23 | 16_lifecycle_hooks | `16_lifecycle_hooks.py` |
|
|
42
|
-
| 24 | 17_checkpoint_handoff_resume | `17_checkpoint_handoff_resume.py` | 0.
|
|
43
|
-
| 25 | 18_model_cosplay | `18_model_cosplay.py` | 0.
|
|
44
|
-
| 26 | 19_hitl_deterministic | `19_hitl_deterministic.py` | 0.
|
|
45
|
-
| | **合计** | | **
|
|
19
|
+
| 1 | 01_basic_chat | `01_basic_chat.py` | 5.63s | ✅ | 运行通过 |
|
|
20
|
+
| 2 | 02_tool_calling | `02_tool_calling.py` | 10.70s | ✅ | 运行通过 |
|
|
21
|
+
| 3 | 03_skill_usage | `03_skill_usage.py` | 15.31s | ✅ | 运行通过 |
|
|
22
|
+
| 4 | 03b_skill_tools_entry | `03b_skill_tools_entry.py` | 7.79s | ✅ | 运行通过 |
|
|
23
|
+
| 5 | 04_multi_agent | `04_multi_agent.py` | 39.61s | ✅ | 运行通过 |
|
|
24
|
+
| 6 | 05_guardrail | `05_guardrail.py` | 7.09s | ✅ | 运行通过 |
|
|
25
|
+
| 7 | 05_human_in_the_loop | `05_human_in_the_loop.py` | 0.31s | ✅ | 运行通过 |
|
|
26
|
+
| 8 | 06_orchestration | `06_orchestration.py` | 36.54s | ✅ | 运行通过 |
|
|
27
|
+
| 9 | 07_sync_async_stream | `07_sync_async_stream.py` | 21.68s | ✅ | 运行通过 |
|
|
28
|
+
| 10 | 08_memory | `08_memory.py` | 35.79s | ✅ | 运行通过 |
|
|
29
|
+
| 11 | 08a_memory_simple_provider | `08a_memory_simple_provider.py` | 9.05s | ✅ | 运行通过 |
|
|
30
|
+
| 12 | 08b_memory_mem0_provider | `08b_memory_mem0_provider.py` | 0.29s | ✅ | 运行通过 |
|
|
31
|
+
| 13 | 08c_memory_file_provider | `08c_memory_file_provider.py` | 11.53s | ✅ | 运行通过 |
|
|
32
|
+
| 14 | 09a_structured_data_sql | `09a_structured_data_sql.py` | 6.91s | ✅ | 运行通过 |
|
|
33
|
+
| 15 | 09b_structured_data_graph | `09b_structured_data_graph.py` | 5.44s | ✅ | 运行通过 |
|
|
34
|
+
| 16 | 09c_nebula_graph_tool | `09c_nebula_graph_tool.py` | 0.45s | ✅ | 运行通过 |
|
|
35
|
+
| 17 | 10_skill_lifecycle | `10_skill_lifecycle.py` | 2.38s | ✅ | 运行通过 |
|
|
36
|
+
| 18 | 11_orchestration_enhancement | `11_orchestration_enhancement.py` | 3.16s | ✅ | 运行通过 |
|
|
37
|
+
| 19 | 12_run_context_serialization | `12_run_context_serialization.py` | 0.23s | ✅ | 运行通过 |
|
|
38
|
+
| 20 | 13_human_in_the_loop | `13_human_in_the_loop.py` | 5.88s | ✅ | 运行通过 |
|
|
39
|
+
| 21 | 14_event_standardization | `14_event_standardization.py` | 3.84s | ✅ | 运行通过 |
|
|
40
|
+
| 22 | 15_multi_tenant_isolation | `15_multi_tenant_isolation.py` | 6.93s | ✅ | 运行通过 |
|
|
41
|
+
| 23 | 16_lifecycle_hooks | `16_lifecycle_hooks.py` | 6.70s | ✅ | 运行通过 |
|
|
42
|
+
| 24 | 17_checkpoint_handoff_resume | `17_checkpoint_handoff_resume.py` | 0.22s | ✅ | 运行通过 |
|
|
43
|
+
| 25 | 18_model_cosplay | `18_model_cosplay.py` | 0.26s | ✅ | 运行通过 |
|
|
44
|
+
| 26 | 19_hitl_deterministic | `19_hitl_deterministic.py` | 0.25s | ✅ | 运行通过 |
|
|
45
|
+
| | **合计** | | **243.97s** | **26/26** | |
|
|
46
46
|
|
|
47
47
|
## 耗时分析
|
|
48
48
|
|
|
49
|
-
- **最快示例**:
|
|
50
|
-
- **最慢示例**:04_multi_agent (
|
|
51
|
-
- **性能改进**:本次批跑合计
|
|
49
|
+
- **最快示例**:17_checkpoint_handoff_resume (0.22s)
|
|
50
|
+
- **最慢示例**:04_multi_agent (39.61s)
|
|
51
|
+
- **性能改进**:本次批跑合计 243.97s,耗时主要集中在 04_multi_agent / 06_orchestration / 08_memory 等编排类示例。
|
|
52
52
|
|
|
53
53
|
## 已知问题
|
|
54
54
|
|
|
@@ -107,12 +107,21 @@ class LLMCache:
|
|
|
107
107
|
tools: list[ToolDefinition] | None = None,
|
|
108
108
|
) -> Optional[LLMResponse]:
|
|
109
109
|
"""查询缓存,命中返回 LLMResponse,未命中返回 None"""
|
|
110
|
+
_, res = self.get_with_key(messages, tools)
|
|
111
|
+
return res
|
|
112
|
+
|
|
113
|
+
def get_with_key(
|
|
114
|
+
self,
|
|
115
|
+
messages: list[Message],
|
|
116
|
+
tools: list[ToolDefinition] | None = None,
|
|
117
|
+
) -> tuple[str, Optional[LLMResponse]]:
|
|
118
|
+
"""查询缓存并返回 (key, response_or_none)"""
|
|
110
119
|
key = self._make_key(messages, tools)
|
|
111
120
|
entry = self._cache.get(key)
|
|
112
121
|
|
|
113
122
|
if entry is None:
|
|
114
123
|
self._misses += 1
|
|
115
|
-
return None
|
|
124
|
+
return key, None
|
|
116
125
|
|
|
117
126
|
timestamp, response = entry
|
|
118
127
|
|
|
@@ -120,12 +129,12 @@ class LLMCache:
|
|
|
120
129
|
if self._ttl > 0 and (time.time() - timestamp) > self._ttl:
|
|
121
130
|
del self._cache[key]
|
|
122
131
|
self._misses += 1
|
|
123
|
-
return None
|
|
132
|
+
return key, None
|
|
124
133
|
|
|
125
134
|
# 命中:移到末尾(LRU)
|
|
126
135
|
self._cache.move_to_end(key)
|
|
127
136
|
self._hits += 1
|
|
128
|
-
return response
|
|
137
|
+
return key, response
|
|
129
138
|
|
|
130
139
|
def put(
|
|
131
140
|
self,
|
|
@@ -139,6 +148,13 @@ class LLMCache:
|
|
|
139
148
|
return
|
|
140
149
|
|
|
141
150
|
key = self._make_key(messages, tools)
|
|
151
|
+
self.put_with_key(key, response)
|
|
152
|
+
|
|
153
|
+
def put_with_key(self, key: str, response: LLMResponse) -> None:
|
|
154
|
+
"""写入缓存(key 由外部预计算)。"""
|
|
155
|
+
if response.has_tool_calls:
|
|
156
|
+
return
|
|
157
|
+
|
|
142
158
|
self._cache[key] = (time.time(), response)
|
|
143
159
|
self._cache.move_to_end(key)
|
|
144
160
|
|
|
@@ -14,6 +14,7 @@ from typing import Any
|
|
|
14
14
|
|
|
15
15
|
from .base import BaseLLM
|
|
16
16
|
from .types import LLMConfig
|
|
17
|
+
from ..utils.env import load_env
|
|
17
18
|
|
|
18
19
|
|
|
19
20
|
class LLMRegistry:
|
|
@@ -75,8 +76,23 @@ class LLMRegistry:
|
|
|
75
76
|
def create_default(cls) -> BaseLLM:
|
|
76
77
|
if cls._default_config:
|
|
77
78
|
return cls.create(cls._default_config)
|
|
79
|
+
env_model = cls._get_default_model_from_env()
|
|
80
|
+
if env_model:
|
|
81
|
+
return cls.create(env_model)
|
|
78
82
|
return cls.create(cls._default_model)
|
|
79
83
|
|
|
84
|
+
@classmethod
|
|
85
|
+
def _get_default_model_from_env(cls) -> str | None:
|
|
86
|
+
load_env()
|
|
87
|
+
for key in ("AGENTKIT_MODEL", "AGENTKIT_DEFAULT_MODEL", "AGENTKIT_STANDARD_MODEL", "AGENTKIT_OLLAMA_MODEL"):
|
|
88
|
+
value = (os.environ.get(key) or "").strip()
|
|
89
|
+
if not value:
|
|
90
|
+
continue
|
|
91
|
+
if key == "AGENTKIT_OLLAMA_MODEL" and not value.startswith("ollama/"):
|
|
92
|
+
value = f"ollama/{value}"
|
|
93
|
+
return value
|
|
94
|
+
return None
|
|
95
|
+
|
|
80
96
|
# ------------------------------------------------------------------
|
|
81
97
|
|
|
82
98
|
@classmethod
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ni.agentkit
|
|
3
|
-
Version: 0.7.
|
|
3
|
+
Version: 0.7.4
|
|
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
|
|
@@ -124,6 +124,7 @@ pyproject.toml
|
|
|
124
124
|
./tools/sqlite_tool.py
|
|
125
125
|
./tools/structured_data.py
|
|
126
126
|
./utils/__init__.py
|
|
127
|
+
./utils/env.py
|
|
127
128
|
./utils/schema.py
|
|
128
129
|
agents/__init__.py
|
|
129
130
|
agents/agent.py
|
|
@@ -243,6 +244,7 @@ skills/loader.py
|
|
|
243
244
|
skills/models.py
|
|
244
245
|
skills/registry.py
|
|
245
246
|
tests/test_after_callback.py
|
|
247
|
+
tests/test_default_model_env.py
|
|
246
248
|
tests/test_graph_repository.py
|
|
247
249
|
tests/test_quickstart_core.py
|
|
248
250
|
tests/test_runner_checkpoint_resume.py
|
|
@@ -256,4 +258,5 @@ tools/skill_toolset.py
|
|
|
256
258
|
tools/sqlite_tool.py
|
|
257
259
|
tools/structured_data.py
|
|
258
260
|
utils/__init__.py
|
|
261
|
+
utils/env.py
|
|
259
262
|
utils/schema.py
|
|
@@ -15,13 +15,20 @@ class SQLiteMemoryProvider(BaseMemoryProvider):
|
|
|
15
15
|
|
|
16
16
|
def __init__(self, db_path: str = ".agentkit/rag/index.db") -> None:
|
|
17
17
|
self._db_path = db_path
|
|
18
|
+
self._token_cache: dict[str, set[str]] = {}
|
|
18
19
|
|
|
19
20
|
@staticmethod
|
|
20
21
|
def _to_memory(record: dict, *, score: float = 0.0) -> Memory:
|
|
22
|
+
metadata = record.get("metadata", {})
|
|
23
|
+
if isinstance(metadata, str):
|
|
24
|
+
try:
|
|
25
|
+
metadata = json.loads(metadata or "{}")
|
|
26
|
+
except Exception:
|
|
27
|
+
metadata = {}
|
|
21
28
|
return Memory(
|
|
22
29
|
id=str(record["id"]),
|
|
23
30
|
content=str(record["content"]),
|
|
24
|
-
metadata=dict(
|
|
31
|
+
metadata=dict(metadata),
|
|
25
32
|
created_at=record.get("created_at"),
|
|
26
33
|
score=score,
|
|
27
34
|
)
|
|
@@ -48,14 +55,21 @@ class SQLiteMemoryProvider(BaseMemoryProvider):
|
|
|
48
55
|
return [self._to_memory(record)]
|
|
49
56
|
|
|
50
57
|
async def search(self, query, *, user_id=None, agent_id=None, limit=10):
|
|
51
|
-
records = self._query_records(user_id=user_id, agent_id=agent_id)
|
|
58
|
+
records = self._query_records(user_id=user_id, agent_id=agent_id, decode_metadata=False)
|
|
52
59
|
query_tokens = tokenize(str(query))
|
|
53
60
|
query_set = set(query_tokens) if query_tokens else set(str(query))
|
|
54
61
|
ranked: list[tuple[float, dict]] = []
|
|
55
62
|
for record in records:
|
|
56
63
|
content = str(record.get("content", ""))
|
|
57
|
-
|
|
58
|
-
|
|
64
|
+
cache_key = str(record.get("id", ""))
|
|
65
|
+
cached_set = self._token_cache.get(cache_key)
|
|
66
|
+
if cached_set is None:
|
|
67
|
+
content_tokens = tokenize(content)
|
|
68
|
+
cached_set = set(content_tokens) if content_tokens else set(content)
|
|
69
|
+
self._token_cache[cache_key] = cached_set
|
|
70
|
+
if len(self._token_cache) > 4096:
|
|
71
|
+
self._token_cache.clear()
|
|
72
|
+
content_set = cached_set
|
|
59
73
|
overlap = len(query_set & content_set)
|
|
60
74
|
if overlap <= 0:
|
|
61
75
|
continue
|
|
@@ -73,7 +87,7 @@ class SQLiteMemoryProvider(BaseMemoryProvider):
|
|
|
73
87
|
conn.commit()
|
|
74
88
|
return cursor.rowcount > 0
|
|
75
89
|
|
|
76
|
-
def _query_records(self, *, user_id=None, agent_id=None) -> list[dict]:
|
|
90
|
+
def _query_records(self, *, user_id=None, agent_id=None, decode_metadata: bool = True) -> list[dict]:
|
|
77
91
|
clauses: list[str] = []
|
|
78
92
|
params: list[str | None] = []
|
|
79
93
|
if user_id is not None:
|
|
@@ -90,13 +104,25 @@ class SQLiteMemoryProvider(BaseMemoryProvider):
|
|
|
90
104
|
|
|
91
105
|
with connect(self._db_path) as conn:
|
|
92
106
|
rows = conn.execute(sql, params).fetchall()
|
|
107
|
+
if decode_metadata:
|
|
108
|
+
return [
|
|
109
|
+
{
|
|
110
|
+
"id": str(row["id"]),
|
|
111
|
+
"content": row["content"],
|
|
112
|
+
"user_id": row["user_id"],
|
|
113
|
+
"agent_id": row["agent_id"],
|
|
114
|
+
"metadata": json.loads(row["metadata"] or "{}"),
|
|
115
|
+
"created_at": row["created_at"],
|
|
116
|
+
}
|
|
117
|
+
for row in rows
|
|
118
|
+
]
|
|
93
119
|
return [
|
|
94
120
|
{
|
|
95
121
|
"id": str(row["id"]),
|
|
96
122
|
"content": row["content"],
|
|
97
123
|
"user_id": row["user_id"],
|
|
98
124
|
"agent_id": row["agent_id"],
|
|
99
|
-
"metadata":
|
|
125
|
+
"metadata": row["metadata"] or "{}",
|
|
100
126
|
"created_at": row["created_at"],
|
|
101
127
|
}
|
|
102
128
|
for row in rows
|
|
@@ -3,17 +3,26 @@
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
5
|
import sqlite3
|
|
6
|
+
import threading
|
|
6
7
|
from pathlib import Path
|
|
7
8
|
|
|
9
|
+
_schema_lock = threading.Lock()
|
|
10
|
+
_schema_initialized: set[str] = set()
|
|
11
|
+
|
|
8
12
|
|
|
9
13
|
def connect(db_path: str) -> sqlite3.Connection:
|
|
10
14
|
"""创建启用外键与行字典访问的 SQLite 连接。"""
|
|
11
|
-
path = Path(db_path)
|
|
15
|
+
path = Path(db_path).expanduser().resolve()
|
|
12
16
|
path.parent.mkdir(parents=True, exist_ok=True)
|
|
13
17
|
conn = sqlite3.connect(path)
|
|
14
18
|
conn.row_factory = sqlite3.Row
|
|
15
19
|
conn.execute("PRAGMA foreign_keys = ON")
|
|
16
|
-
|
|
20
|
+
key = str(path)
|
|
21
|
+
if key not in _schema_initialized:
|
|
22
|
+
with _schema_lock:
|
|
23
|
+
if key not in _schema_initialized:
|
|
24
|
+
initialize_schema(conn)
|
|
25
|
+
_schema_initialized.add(key)
|
|
17
26
|
return conn
|
|
18
27
|
|
|
19
28
|
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
5
|
+
from agentkit.llm.registry import LLMRegistry
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def test_llmregistry_create_default_uses_env_from_dotenv(tmp_path: Path, monkeypatch):
|
|
9
|
+
monkeypatch.chdir(tmp_path)
|
|
10
|
+
(tmp_path / ".env").write_text("AGENTKIT_OLLAMA_MODEL=qwen3.5:cloud\n", encoding="utf-8")
|
|
11
|
+
|
|
12
|
+
llm = LLMRegistry.create_default()
|
|
13
|
+
assert llm.__class__.__name__ == "OllamaAdapter"
|
|
14
|
+
assert llm.config.model == "qwen3.5:cloud"
|
|
15
|
+
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
|
|
6
|
+
_NEAREST_DOTENV_CACHE: dict[str, Path | None] = {}
|
|
7
|
+
_DOTENV_LOAD_CACHE: dict[str, tuple[int, dict[str, str]]] = {}
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def load_env(dotenv_path: str | None = None) -> dict[str, str]:
|
|
11
|
+
path = Path(dotenv_path).expanduser().resolve() if dotenv_path else _find_nearest_dotenv()
|
|
12
|
+
if path is None or not path.exists() or not path.is_file():
|
|
13
|
+
return {}
|
|
14
|
+
|
|
15
|
+
stat = path.stat()
|
|
16
|
+
cache_key = str(path)
|
|
17
|
+
cached = _DOTENV_LOAD_CACHE.get(cache_key)
|
|
18
|
+
if cached and cached[0] == stat.st_mtime_ns:
|
|
19
|
+
loaded = cached[1]
|
|
20
|
+
for k, v in loaded.items():
|
|
21
|
+
if k not in os.environ:
|
|
22
|
+
os.environ[k] = v
|
|
23
|
+
return dict(loaded)
|
|
24
|
+
|
|
25
|
+
loaded: dict[str, str] = {}
|
|
26
|
+
for raw in path.read_text(encoding="utf-8").splitlines():
|
|
27
|
+
line = raw.strip()
|
|
28
|
+
if not line or line.startswith("#"):
|
|
29
|
+
continue
|
|
30
|
+
if line.startswith("export "):
|
|
31
|
+
line = line[len("export ") :].strip()
|
|
32
|
+
if "=" not in line:
|
|
33
|
+
continue
|
|
34
|
+
|
|
35
|
+
key, value = line.split("=", 1)
|
|
36
|
+
key = key.strip()
|
|
37
|
+
if not key:
|
|
38
|
+
continue
|
|
39
|
+
|
|
40
|
+
value = value.strip()
|
|
41
|
+
if (value.startswith('"') and value.endswith('"')) or (value.startswith("'") and value.endswith("'")):
|
|
42
|
+
value = value[1:-1]
|
|
43
|
+
|
|
44
|
+
if key not in os.environ:
|
|
45
|
+
os.environ[key] = value
|
|
46
|
+
loaded[key] = value
|
|
47
|
+
|
|
48
|
+
_DOTENV_LOAD_CACHE[cache_key] = (stat.st_mtime_ns, dict(loaded))
|
|
49
|
+
return loaded
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def _find_nearest_dotenv() -> Path | None:
|
|
53
|
+
cwd = Path.cwd().resolve()
|
|
54
|
+
cached = _NEAREST_DOTENV_CACHE.get(str(cwd))
|
|
55
|
+
if cached is not None:
|
|
56
|
+
return cached
|
|
57
|
+
|
|
58
|
+
candidates: list[Path] = []
|
|
59
|
+
for base in [cwd, *cwd.parents]:
|
|
60
|
+
candidates.append(base / ".env")
|
|
61
|
+
candidates.append(base / ".evn")
|
|
62
|
+
|
|
63
|
+
seen: set[Path] = set()
|
|
64
|
+
for path in candidates:
|
|
65
|
+
if path in seen:
|
|
66
|
+
continue
|
|
67
|
+
seen.add(path)
|
|
68
|
+
if path.exists() and path.is_file():
|
|
69
|
+
_NEAREST_DOTENV_CACHE[str(cwd)] = path
|
|
70
|
+
return path
|
|
71
|
+
_NEAREST_DOTENV_CACHE[str(cwd)] = None
|
|
72
|
+
return None
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ni_agentkit-0.7.3 → ni_agentkit-0.7.4}/examples/skills/weather-tools-entry/tools/weather_tools.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|