base-agentkit 0.1.0__py3-none-any.whl
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.
- agentkit/__init__.py +35 -0
- agentkit/agent/__init__.py +7 -0
- agentkit/agent/agent.py +368 -0
- agentkit/agent/budgets.py +48 -0
- agentkit/agent/report.py +166 -0
- agentkit/agent/tool_runtime.py +77 -0
- agentkit/cli/__init__.py +5 -0
- agentkit/cli/main.py +108 -0
- agentkit/config/__init__.py +23 -0
- agentkit/config/loader.py +108 -0
- agentkit/config/provider_defaults.py +96 -0
- agentkit/config/schema.py +148 -0
- agentkit/constants.py +21 -0
- agentkit/errors.py +58 -0
- agentkit/llm/__init__.py +53 -0
- agentkit/llm/base.py +36 -0
- agentkit/llm/factory.py +27 -0
- agentkit/llm/providers/__init__.py +15 -0
- agentkit/llm/providers/anthropic_provider.py +371 -0
- agentkit/llm/providers/gemini_provider.py +396 -0
- agentkit/llm/providers/openai_provider.py +881 -0
- agentkit/llm/providers/qwen_provider.py +34 -0
- agentkit/llm/providers/vllm_provider.py +47 -0
- agentkit/llm/types.py +215 -0
- agentkit/llm/usage.py +72 -0
- agentkit/py.typed +0 -0
- agentkit/runlog/__init__.py +15 -0
- agentkit/runlog/events.py +67 -0
- agentkit/runlog/jsonl.py +90 -0
- agentkit/runlog/recorder.py +94 -0
- agentkit/runlog/sinks.py +15 -0
- agentkit/tools/__init__.py +16 -0
- agentkit/tools/base.py +139 -0
- agentkit/tools/library/__init__.py +8 -0
- agentkit/tools/library/_fs_common.py +330 -0
- agentkit/tools/library/create_file.py +168 -0
- agentkit/tools/library/fs_tools.py +21 -0
- agentkit/tools/library/str_replace.py +241 -0
- agentkit/tools/library/view.py +372 -0
- agentkit/tools/library/word_count.py +138 -0
- agentkit/tools/loader.py +81 -0
- agentkit/tools/registry.py +284 -0
- agentkit/tools/types.py +98 -0
- agentkit/workspace/__init__.py +6 -0
- agentkit/workspace/fs.py +288 -0
- agentkit/workspace/layout.py +33 -0
- base_agentkit-0.1.0.dist-info/METADATA +142 -0
- base_agentkit-0.1.0.dist-info/RECORD +51 -0
- base_agentkit-0.1.0.dist-info/WHEEL +4 -0
- base_agentkit-0.1.0.dist-info/entry_points.txt +3 -0
- base_agentkit-0.1.0.dist-info/licenses/LICENSE +183 -0
agentkit/workspace/fs.py
ADDED
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
"""Workspace filesystem facade with strict path isolation."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import json
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
from typing import Any
|
|
8
|
+
|
|
9
|
+
from agentkit.errors import WorkspaceError
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class WorkspaceFS:
|
|
13
|
+
"""Read/write operations scoped to a single workspace root."""
|
|
14
|
+
|
|
15
|
+
def __init__(self, root: str | Path) -> None:
|
|
16
|
+
"""Create a workspace filesystem facade and ensure root exists.
|
|
17
|
+
|
|
18
|
+
Args:
|
|
19
|
+
root: Workspace root directory.
|
|
20
|
+
|
|
21
|
+
Returns:
|
|
22
|
+
None
|
|
23
|
+
"""
|
|
24
|
+
self.root = Path(root).expanduser().resolve()
|
|
25
|
+
self.root.mkdir(parents=True, exist_ok=True)
|
|
26
|
+
|
|
27
|
+
def resolve_path(self, path: str | Path) -> Path:
|
|
28
|
+
"""Resolve a path and enforce workspace containment.
|
|
29
|
+
|
|
30
|
+
Args:
|
|
31
|
+
path: Absolute or workspace-relative path.
|
|
32
|
+
|
|
33
|
+
Returns:
|
|
34
|
+
pathlib.Path: Fully resolved path within the workspace root.
|
|
35
|
+
|
|
36
|
+
Raises:
|
|
37
|
+
agentkit.errors.WorkspaceError: If the resolved path escapes workspace
|
|
38
|
+
boundaries.
|
|
39
|
+
"""
|
|
40
|
+
candidate = Path(path)
|
|
41
|
+
if not candidate.is_absolute():
|
|
42
|
+
candidate = self.root / candidate
|
|
43
|
+
resolved = candidate.expanduser().resolve(strict=False)
|
|
44
|
+
|
|
45
|
+
if resolved != self.root and self.root not in resolved.parents:
|
|
46
|
+
raise WorkspaceError(f"Path escapes workspace: {path}")
|
|
47
|
+
return resolved
|
|
48
|
+
|
|
49
|
+
def exists(self, path: str | Path) -> bool:
|
|
50
|
+
"""Check whether a path exists inside the workspace.
|
|
51
|
+
|
|
52
|
+
Args:
|
|
53
|
+
path: Absolute or workspace-relative path.
|
|
54
|
+
|
|
55
|
+
Returns:
|
|
56
|
+
bool: ``True`` when the resolved path exists.
|
|
57
|
+
|
|
58
|
+
Raises:
|
|
59
|
+
agentkit.errors.WorkspaceError: If the path escapes workspace boundaries.
|
|
60
|
+
"""
|
|
61
|
+
return self.resolve_path(path).exists()
|
|
62
|
+
|
|
63
|
+
def is_file(self, path: str | Path) -> bool:
|
|
64
|
+
"""Check whether a path points to a file inside the workspace.
|
|
65
|
+
|
|
66
|
+
Args:
|
|
67
|
+
path: Absolute or workspace-relative path.
|
|
68
|
+
|
|
69
|
+
Returns:
|
|
70
|
+
bool: ``True`` when the resolved path exists and is a file.
|
|
71
|
+
|
|
72
|
+
Raises:
|
|
73
|
+
agentkit.errors.WorkspaceError: If the path escapes workspace boundaries.
|
|
74
|
+
"""
|
|
75
|
+
return self.resolve_path(path).is_file()
|
|
76
|
+
|
|
77
|
+
def is_dir(self, path: str | Path) -> bool:
|
|
78
|
+
"""Check whether a path points to a directory inside the workspace.
|
|
79
|
+
|
|
80
|
+
Args:
|
|
81
|
+
path: Absolute or workspace-relative path.
|
|
82
|
+
|
|
83
|
+
Returns:
|
|
84
|
+
bool: ``True`` when the resolved path exists and is a directory.
|
|
85
|
+
|
|
86
|
+
Raises:
|
|
87
|
+
agentkit.errors.WorkspaceError: If the path escapes workspace boundaries.
|
|
88
|
+
"""
|
|
89
|
+
return self.resolve_path(path).is_dir()
|
|
90
|
+
|
|
91
|
+
def mkdir(
|
|
92
|
+
self, path: str | Path, *, parents: bool = True, exist_ok: bool = True
|
|
93
|
+
) -> Path:
|
|
94
|
+
"""Create a directory inside the workspace.
|
|
95
|
+
|
|
96
|
+
Args:
|
|
97
|
+
path: Absolute or workspace-relative directory path.
|
|
98
|
+
parents: Whether to create missing parent directories.
|
|
99
|
+
exist_ok: Whether existing directory is allowed.
|
|
100
|
+
|
|
101
|
+
Returns:
|
|
102
|
+
pathlib.Path: Resolved directory path.
|
|
103
|
+
|
|
104
|
+
Raises:
|
|
105
|
+
agentkit.errors.WorkspaceError: If the path escapes workspace boundaries.
|
|
106
|
+
FileExistsError: If target exists and ``exist_ok`` is ``False``.
|
|
107
|
+
"""
|
|
108
|
+
target = self.resolve_path(path)
|
|
109
|
+
target.mkdir(parents=parents, exist_ok=exist_ok)
|
|
110
|
+
return target
|
|
111
|
+
|
|
112
|
+
def list_dir(self, path: str | Path = ".") -> list[str]:
|
|
113
|
+
"""List entries in a workspace directory.
|
|
114
|
+
|
|
115
|
+
Args:
|
|
116
|
+
path: Absolute or workspace-relative directory path.
|
|
117
|
+
|
|
118
|
+
Returns:
|
|
119
|
+
list[str]: Sorted entry names.
|
|
120
|
+
|
|
121
|
+
Raises:
|
|
122
|
+
agentkit.errors.WorkspaceError: If path is outside workspace, missing, or
|
|
123
|
+
not a directory.
|
|
124
|
+
"""
|
|
125
|
+
target = self.resolve_path(path)
|
|
126
|
+
if not target.exists():
|
|
127
|
+
raise WorkspaceError(f"Directory does not exist: {path}")
|
|
128
|
+
if not target.is_dir():
|
|
129
|
+
raise WorkspaceError(f"Not a directory: {path}")
|
|
130
|
+
return sorted(entry.name for entry in target.iterdir())
|
|
131
|
+
|
|
132
|
+
def read_text(self, path: str | Path, *, encoding: str = "utf-8") -> str:
|
|
133
|
+
"""Read UTF-8 text from a workspace file.
|
|
134
|
+
|
|
135
|
+
Args:
|
|
136
|
+
path: Absolute or workspace-relative file path.
|
|
137
|
+
encoding: Text encoding used for reading.
|
|
138
|
+
|
|
139
|
+
Returns:
|
|
140
|
+
str: File content.
|
|
141
|
+
|
|
142
|
+
Raises:
|
|
143
|
+
agentkit.errors.WorkspaceError: If path is outside workspace, missing, or
|
|
144
|
+
not a file.
|
|
145
|
+
"""
|
|
146
|
+
target = self.resolve_path(path)
|
|
147
|
+
if not target.exists():
|
|
148
|
+
raise WorkspaceError(f"File does not exist: {path}")
|
|
149
|
+
if not target.is_file():
|
|
150
|
+
raise WorkspaceError(f"Not a file: {path}")
|
|
151
|
+
return target.read_text(encoding=encoding)
|
|
152
|
+
|
|
153
|
+
def write_text(
|
|
154
|
+
self,
|
|
155
|
+
path: str | Path,
|
|
156
|
+
text: str,
|
|
157
|
+
*,
|
|
158
|
+
encoding: str = "utf-8",
|
|
159
|
+
overwrite: bool = True,
|
|
160
|
+
) -> None:
|
|
161
|
+
"""Write text to a workspace file.
|
|
162
|
+
|
|
163
|
+
Args:
|
|
164
|
+
path: Absolute or workspace-relative file path.
|
|
165
|
+
text: Text content to persist.
|
|
166
|
+
encoding: Text encoding used for writing.
|
|
167
|
+
overwrite: Whether existing files may be replaced.
|
|
168
|
+
|
|
169
|
+
Returns:
|
|
170
|
+
None
|
|
171
|
+
|
|
172
|
+
Raises:
|
|
173
|
+
agentkit.errors.WorkspaceError: If path escapes workspace or overwrite is
|
|
174
|
+
disallowed for an existing file.
|
|
175
|
+
"""
|
|
176
|
+
target = self.resolve_path(path)
|
|
177
|
+
if target.exists() and not overwrite:
|
|
178
|
+
raise WorkspaceError(f"File already exists and overwrite=False: {path}")
|
|
179
|
+
target.parent.mkdir(parents=True, exist_ok=True)
|
|
180
|
+
target.write_text(text, encoding=encoding)
|
|
181
|
+
|
|
182
|
+
def append_text(
|
|
183
|
+
self, path: str | Path, text: str, *, encoding: str = "utf-8"
|
|
184
|
+
) -> None:
|
|
185
|
+
"""Append text to a workspace file, creating it if needed.
|
|
186
|
+
|
|
187
|
+
Args:
|
|
188
|
+
path: Absolute or workspace-relative file path.
|
|
189
|
+
text: Text content to append.
|
|
190
|
+
encoding: Text encoding used for writing.
|
|
191
|
+
|
|
192
|
+
Returns:
|
|
193
|
+
None
|
|
194
|
+
|
|
195
|
+
Raises:
|
|
196
|
+
agentkit.errors.WorkspaceError: If path escapes workspace boundaries.
|
|
197
|
+
"""
|
|
198
|
+
target = self.resolve_path(path)
|
|
199
|
+
target.parent.mkdir(parents=True, exist_ok=True)
|
|
200
|
+
with target.open("a", encoding=encoding) as f:
|
|
201
|
+
f.write(text)
|
|
202
|
+
|
|
203
|
+
def edit_text(
|
|
204
|
+
self,
|
|
205
|
+
path: str | Path,
|
|
206
|
+
old: str,
|
|
207
|
+
new: str,
|
|
208
|
+
*,
|
|
209
|
+
count: int | None = None,
|
|
210
|
+
encoding: str = "utf-8",
|
|
211
|
+
) -> int:
|
|
212
|
+
"""Replace text occurrences in a workspace file.
|
|
213
|
+
|
|
214
|
+
Args:
|
|
215
|
+
path: Absolute or workspace-relative file path.
|
|
216
|
+
old: Substring to replace.
|
|
217
|
+
new: Replacement substring.
|
|
218
|
+
count: Optional maximum number of replacements.
|
|
219
|
+
encoding: Text encoding used for read/write operations.
|
|
220
|
+
|
|
221
|
+
Returns:
|
|
222
|
+
int: Number of replacements applied.
|
|
223
|
+
|
|
224
|
+
Raises:
|
|
225
|
+
agentkit.errors.WorkspaceError: If ``old`` is empty, ``count`` is
|
|
226
|
+
negative, or the path is invalid.
|
|
227
|
+
"""
|
|
228
|
+
if old == "":
|
|
229
|
+
raise WorkspaceError("edit_text 'old' pattern must not be empty.")
|
|
230
|
+
|
|
231
|
+
content = self.read_text(path, encoding=encoding)
|
|
232
|
+
occurrences = content.count(old)
|
|
233
|
+
if occurrences == 0:
|
|
234
|
+
return 0
|
|
235
|
+
|
|
236
|
+
if count is None:
|
|
237
|
+
updated = content.replace(old, new)
|
|
238
|
+
replaced = occurrences
|
|
239
|
+
else:
|
|
240
|
+
if count < 0:
|
|
241
|
+
raise WorkspaceError("edit_text 'count' must be >= 0 when provided.")
|
|
242
|
+
updated = content.replace(old, new, count)
|
|
243
|
+
replaced = min(occurrences, count)
|
|
244
|
+
|
|
245
|
+
self.write_text(path, updated, encoding=encoding, overwrite=True)
|
|
246
|
+
return replaced
|
|
247
|
+
|
|
248
|
+
def read_json(self, path: str | Path) -> Any:
|
|
249
|
+
"""Read and decode JSON from a workspace file.
|
|
250
|
+
|
|
251
|
+
Args:
|
|
252
|
+
path: Absolute or workspace-relative JSON file path.
|
|
253
|
+
|
|
254
|
+
Returns:
|
|
255
|
+
Any: Decoded JSON payload.
|
|
256
|
+
|
|
257
|
+
Raises:
|
|
258
|
+
agentkit.errors.WorkspaceError: If the path is invalid.
|
|
259
|
+
json.JSONDecodeError: If file content is not valid JSON.
|
|
260
|
+
"""
|
|
261
|
+
return json.loads(self.read_text(path))
|
|
262
|
+
|
|
263
|
+
def write_json(
|
|
264
|
+
self,
|
|
265
|
+
path: str | Path,
|
|
266
|
+
data: Any,
|
|
267
|
+
*,
|
|
268
|
+
ensure_ascii: bool = False,
|
|
269
|
+
indent: int = 2,
|
|
270
|
+
) -> None:
|
|
271
|
+
"""Encode and write JSON to a workspace file.
|
|
272
|
+
|
|
273
|
+
Args:
|
|
274
|
+
path: Absolute or workspace-relative destination path.
|
|
275
|
+
data: JSON-serializable payload.
|
|
276
|
+
ensure_ascii: Whether to escape non-ASCII characters.
|
|
277
|
+
indent: Pretty-print indentation size.
|
|
278
|
+
|
|
279
|
+
Returns:
|
|
280
|
+
None
|
|
281
|
+
|
|
282
|
+
Raises:
|
|
283
|
+
agentkit.errors.WorkspaceError: If path is invalid.
|
|
284
|
+
TypeError: If ``data`` contains non-serializable values.
|
|
285
|
+
"""
|
|
286
|
+
self.write_text(
|
|
287
|
+
path, json.dumps(data, ensure_ascii=ensure_ascii, indent=indent)
|
|
288
|
+
)
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"""Workspace folder layout helpers."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
from typing import Iterable
|
|
7
|
+
|
|
8
|
+
from agentkit.constants import DEFAULT_WORKSPACE_DIRS
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def init_workspace_layout(
|
|
12
|
+
root: str | Path,
|
|
13
|
+
*,
|
|
14
|
+
extra_dirs: Iterable[str] | None = None,
|
|
15
|
+
) -> Path:
|
|
16
|
+
"""Create default workspace directories under the given root.
|
|
17
|
+
|
|
18
|
+
Args:
|
|
19
|
+
root: Workspace root directory path.
|
|
20
|
+
extra_dirs: Optional additional directory names to create.
|
|
21
|
+
|
|
22
|
+
Returns:
|
|
23
|
+
pathlib.Path: Resolved workspace root path.
|
|
24
|
+
"""
|
|
25
|
+
root_path = Path(root).expanduser().resolve()
|
|
26
|
+
root_path.mkdir(parents=True, exist_ok=True)
|
|
27
|
+
|
|
28
|
+
dirs = list(DEFAULT_WORKSPACE_DIRS)
|
|
29
|
+
if extra_dirs:
|
|
30
|
+
dirs.extend(extra_dirs)
|
|
31
|
+
for item in dirs:
|
|
32
|
+
(root_path / item).mkdir(parents=True, exist_ok=True)
|
|
33
|
+
return root_path
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: base-agentkit
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Workspace-isolated Python framework for building tool-using LLM agents.
|
|
5
|
+
Keywords: agents,llm,tool-calling,workspace,ai
|
|
6
|
+
Author: sii-nyc
|
|
7
|
+
Author-email: sii-nyc <253108120111@sii.edu.cn>
|
|
8
|
+
License-Expression: Apache-2.0
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Classifier: Development Status :: 3 - Alpha
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
16
|
+
Classifier: Typing :: Typed
|
|
17
|
+
Requires-Dist: openai>=2.21.0
|
|
18
|
+
Requires-Dist: pydantic>=2.12.5
|
|
19
|
+
Requires-Dist: pyyaml>=6.0.3
|
|
20
|
+
Requires-Dist: requests>=2.32.5
|
|
21
|
+
Requires-Python: >=3.12
|
|
22
|
+
Project-URL: Homepage, https://github.com/Inkjourney/agentkit
|
|
23
|
+
Project-URL: Repository, https://github.com/Inkjourney/agentkit
|
|
24
|
+
Project-URL: Documentation, https://github.com/Inkjourney/agentkit/tree/main/docs/agentkit
|
|
25
|
+
Project-URL: Issues, https://github.com/Inkjourney/agentkit/issues
|
|
26
|
+
Description-Content-Type: text/markdown
|
|
27
|
+
|
|
28
|
+
# AgentKit
|
|
29
|
+
|
|
30
|
+
一个基于 LLM 的通用 Agent 框架,支持 workspace 隔离、统一 LLM 抽象、工具调用循环、CLI 与 Python SDK。
|
|
31
|
+
|
|
32
|
+
## 当前能力
|
|
33
|
+
|
|
34
|
+
- workspace 强隔离:所有读写通过 `WorkspaceFS`
|
|
35
|
+
- 统一 LLM 抽象:`ConversationItem` / `ConversationState` / `UnifiedLLMRequest` / `UnifiedLLMResponse`
|
|
36
|
+
- Provider 支持(同步、非流式、文本)
|
|
37
|
+
- OpenAI (`responses` / `chat_completions`)
|
|
38
|
+
- Anthropic (`messages`)
|
|
39
|
+
- Gemini (`generateContent`)
|
|
40
|
+
- Qwen(OpenAI-compatible `chat_completions`)
|
|
41
|
+
- vLLM(OpenAI-compatible `chat_completions`)
|
|
42
|
+
- 工具系统:注册式工具机制,工具模块放在 `src/agentkit/tools/library/`
|
|
43
|
+
- Agent loop:模型推理与工具执行闭环,受 step/time budget 约束
|
|
44
|
+
- runlog:每次任务写入 `workspace/logs/run_<run_id>.jsonl`
|
|
45
|
+
|
|
46
|
+
## 状态
|
|
47
|
+
|
|
48
|
+
- 当前仓库包含针对 Agent loop、CLI、工具系统、runlog 以及 OpenAI / Anthropic / Gemini / Qwen / vLLM provider 适配层的单元测试
|
|
49
|
+
- 尚未提供针对真实上游 API 的集成 smoke test,因此正式发布前仍建议用目标模型做一次端到端验证
|
|
50
|
+
|
|
51
|
+
## 文档
|
|
52
|
+
|
|
53
|
+
详细使用说明和完整文档见 `docs/agentkit/`。
|
|
54
|
+
|
|
55
|
+
## 从源码安装
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
uv sync
|
|
59
|
+
uv run agentkit --help
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## 从 PyPI 安装
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
pip install base-agentkit
|
|
66
|
+
agentkit --help
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
安装后的导入路径和 CLI 名称保持不变:
|
|
70
|
+
|
|
71
|
+
```python
|
|
72
|
+
from agentkit import create_agent
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## 配置示例
|
|
76
|
+
|
|
77
|
+
### vLLM
|
|
78
|
+
|
|
79
|
+
```yaml
|
|
80
|
+
workspace:
|
|
81
|
+
root: "./vllm_workspace"
|
|
82
|
+
|
|
83
|
+
provider:
|
|
84
|
+
kind: "vllm"
|
|
85
|
+
model: "glm-5"
|
|
86
|
+
openai_api_variant: "chat_completions"
|
|
87
|
+
conversation_mode: "auto"
|
|
88
|
+
base_url: "http://localhost:8000/v1"
|
|
89
|
+
api_key: "empty"
|
|
90
|
+
temperature: 0.8
|
|
91
|
+
timeout_s: 600
|
|
92
|
+
retries: 2
|
|
93
|
+
enable_thinking: true
|
|
94
|
+
|
|
95
|
+
agent:
|
|
96
|
+
system_prompt: "You are a helpful agent. Use tools when needed."
|
|
97
|
+
budget:
|
|
98
|
+
max_steps: 200
|
|
99
|
+
time_budget_s: 1800
|
|
100
|
+
max_input_chars: 180000
|
|
101
|
+
|
|
102
|
+
tools:
|
|
103
|
+
allowed:
|
|
104
|
+
- "view"
|
|
105
|
+
- "create_file"
|
|
106
|
+
- "str_replace"
|
|
107
|
+
- "word_count"
|
|
108
|
+
|
|
109
|
+
runlog:
|
|
110
|
+
enabled: true
|
|
111
|
+
redact: true
|
|
112
|
+
max_text_chars: 20000
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## CLI 运行
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
export OPENAI_API_KEY="your-key"
|
|
119
|
+
uv run agentkit --config path/to/config.yaml run --task "列出当前 workspace 的文件"
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## Python SDK
|
|
123
|
+
|
|
124
|
+
```python
|
|
125
|
+
from agentkit import create_agent
|
|
126
|
+
|
|
127
|
+
agent = create_agent("path/to/config.yaml")
|
|
128
|
+
report = agent.run("在 workspace 里新建 notes/todo.txt 并写入今天计划")
|
|
129
|
+
print(report.final_output)
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
## 项目结构
|
|
133
|
+
|
|
134
|
+
核心实现位于 `src/agentkit/`:
|
|
135
|
+
|
|
136
|
+
- `config/`: 配置结构与加载
|
|
137
|
+
- `workspace/`: 强隔离文件系统和目录布局
|
|
138
|
+
- `llm/`: 统一抽象、provider base/factory 与四平台 adapter
|
|
139
|
+
- `tools/`: 工具抽象、注册表与自动加载
|
|
140
|
+
- `agent/`: budget、report、runtime、Agent loop
|
|
141
|
+
- `runlog/`: 结构化事件、event sink 与 JSONL runlog
|
|
142
|
+
- `cli/`: 命令行入口
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
agentkit/__init__.py,sha256=uvPo2sQhLsW9w4OhwlwVwNloHF6UJgqInHX-q59112M,960
|
|
2
|
+
agentkit/agent/__init__.py,sha256=XwEe83HEobpihELZZR-gGjjjS4_LHGuOtuKibibNo0g,189
|
|
3
|
+
agentkit/agent/agent.py,sha256=lNHA9YNpbOcp2doqKHTMYCPDddXzJ4oOINk6S_CU8EY,13237
|
|
4
|
+
agentkit/agent/budgets.py,sha256=imnIWbO9u3hbeldlfvWFBrOhUm-FCcz7KEp5uOkDuio,1516
|
|
5
|
+
agentkit/agent/report.py,sha256=U9ncOPd1LpghN-pycnH9KU89PxuWwmTTt2ev3tTslkc,5849
|
|
6
|
+
agentkit/agent/tool_runtime.py,sha256=HXt8IkDCDPlsjWEJPLfRyAykGk_v-3sK9zSKVL0uWZc,3004
|
|
7
|
+
agentkit/cli/__init__.py,sha256=ehsfo9JFja2dwYRH0NSZB9DPesATUHcF_gTIy1jlwA4,80
|
|
8
|
+
agentkit/cli/main.py,sha256=uco0Wyr4MF04DZakv1LSF3mDxVc2Vpb2Nt4JX6PXszM,3022
|
|
9
|
+
agentkit/config/__init__.py,sha256=q0bAMgLAxOGN3d-bVZWtpxbR8ZO77zV5S_VeKAQ1ylU,420
|
|
10
|
+
agentkit/config/loader.py,sha256=pBX3eQGXhUayCqzMp5t-yqz_wzItLZVGvsUpChmVVLc,3232
|
|
11
|
+
agentkit/config/provider_defaults.py,sha256=HQehlBljMFswBB9oh6GBoTjpkE7kA-BQ2iGgyNyPdeg,3095
|
|
12
|
+
agentkit/config/schema.py,sha256=8K0KUpyfsdKotPkgeyIyEOdU0XBKnI31rCvv3cPBzwc,4995
|
|
13
|
+
agentkit/constants.py,sha256=R6o6ycmzQLvQTyZjhOn1cUu_3BXRgyC6IDXnugNZwTw,422
|
|
14
|
+
agentkit/errors.py,sha256=yQ7MQ_lAOl_tDRl21d9Z0wnty2uykDJT0oW0HlHpkZ0,1515
|
|
15
|
+
agentkit/llm/__init__.py,sha256=1LDpEx1izf6MIwQSaoLqKPuOFPmkU7frYhgvpMNCYZs,1237
|
|
16
|
+
agentkit/llm/base.py,sha256=bFz6QJJYrVuqHvgG7FhZDB7EDHBnH2h7wM3Z4Fzc7DQ,977
|
|
17
|
+
agentkit/llm/factory.py,sha256=L5HtP39llds8NqmO5B9sPB-xBJcD6IPJAW-fSn7Ch7A,1103
|
|
18
|
+
agentkit/llm/providers/__init__.py,sha256=iQcnrkBfqaa4cMARSEQFKmBz9HjR9WkVVnTI6Yvn9M4,389
|
|
19
|
+
agentkit/llm/providers/anthropic_provider.py,sha256=VPldD0l14kDR-Z6jpIMwSq6gf9oxHxB2VhcWPDXvIE0,12537
|
|
20
|
+
agentkit/llm/providers/gemini_provider.py,sha256=ZABSvjjLZavVHYtburT39g56sBUPtB0mUYhnsHcZHKs,14122
|
|
21
|
+
agentkit/llm/providers/openai_provider.py,sha256=LinoXstrWtmYiY2vSDM_jfHyCXvQadz-99l9utwqWDU,31693
|
|
22
|
+
agentkit/llm/providers/qwen_provider.py,sha256=k_QnwnqO0wzlbn0LGqVIEIXU1irPRCYe7E97GC0ZS0E,1180
|
|
23
|
+
agentkit/llm/providers/vllm_provider.py,sha256=zViTsue8B4ZwJll-NJdg9QNxd8qkGpQh7vnTvy3A3L8,1622
|
|
24
|
+
agentkit/llm/types.py,sha256=ltFTvdpvBSsEDrhLzYWx4IGG1w50EkYmCzNnawYIqDQ,6741
|
|
25
|
+
agentkit/llm/usage.py,sha256=JP6lfgKOAqmEG0AU8Q0juDrlEEHQrrET_FSu1a8P0Fo,2631
|
|
26
|
+
agentkit/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
27
|
+
agentkit/runlog/__init__.py,sha256=G0WeFurv3s9Q-hJJ_gULIDS6MMvUZV5G18RAO_0oPio,348
|
|
28
|
+
agentkit/runlog/events.py,sha256=apK0aC2Uc-5uAlZumnMxy_UK_0yh8874qcTjO-PX3Pk,1698
|
|
29
|
+
agentkit/runlog/jsonl.py,sha256=hsQvHuR8QcYgoP9vIbXpTXxdVnP5K-2c0BbiUStCdNQ,3557
|
|
30
|
+
agentkit/runlog/recorder.py,sha256=G5DM-H2j9BbTZqQQep0oAEcFZhsSdaPz4Yn3r47qVYM,2806
|
|
31
|
+
agentkit/runlog/sinks.py,sha256=nMophq_23jAhuTvLaph_cSrAGAFqVfu51sJ5gQc3Y04,384
|
|
32
|
+
agentkit/tools/__init__.py,sha256=dwRU6OXsbSfNFgw1s9BbF2wLIaZKyYhsKKva8TTnQ4w,401
|
|
33
|
+
agentkit/tools/base.py,sha256=DOasFvdpAicIycefwsli320tXdctn3laBdjnfkxoM7E,4592
|
|
34
|
+
agentkit/tools/library/__init__.py,sha256=KlE_0uCQBJkdqwXKEm6R_lo2qkE97Spq8JglrNC_4ek,256
|
|
35
|
+
agentkit/tools/library/_fs_common.py,sha256=tWNi4K1wdeSNxg3R6Sz9UjnnJn_gvZKRFtZQD0A_PRI,11709
|
|
36
|
+
agentkit/tools/library/create_file.py,sha256=O_S_k3fV8864Pmwyy0sOZlF8bKQ_Oq8KU1RMI7oOWaM,6942
|
|
37
|
+
agentkit/tools/library/fs_tools.py,sha256=q-JkUles2HGyRbu2XHjbokmY8hLRO5_89qkY0L1NrJ8,608
|
|
38
|
+
agentkit/tools/library/str_replace.py,sha256=Rx-y9Cj-8ckyWnSMMnOA4QBJXQCFjkYoo9g1h3gOvwQ,9939
|
|
39
|
+
agentkit/tools/library/view.py,sha256=FbBQwbVvke5usdAs4-111uC4C0l33fax1IgQ4CwuCJE,15137
|
|
40
|
+
agentkit/tools/library/word_count.py,sha256=y0RE5GMoL-4xackze5BA_702eeHTkAtB5b1sNjkvFCM,4975
|
|
41
|
+
agentkit/tools/loader.py,sha256=yeTRqepnmWCqTHwMUUxo4OQD83aKxcsVtE7hJE5kas8,2665
|
|
42
|
+
agentkit/tools/registry.py,sha256=5NvSczLj1Xx9qY62edLHACtm-IOZm7oYS37glOaEuJg,9824
|
|
43
|
+
agentkit/tools/types.py,sha256=34pyZKVDOs6Cx2hntcfnzywywZq90g-7v2y6uwWBA10,2988
|
|
44
|
+
agentkit/workspace/__init__.py,sha256=G59NG5d4iz5k2oyLnDECgxvkZgn1DApPfg8S2m1LNSA,166
|
|
45
|
+
agentkit/workspace/fs.py,sha256=wK04_2ntuoZKXz5EvnDvOYa1fD1DGkLmHQGpkMkV1ZI,9155
|
|
46
|
+
agentkit/workspace/layout.py,sha256=qqqAMT8KJgJEvfAIEgPvmugvYIpV2dtvehCmWVg67DY,857
|
|
47
|
+
base_agentkit-0.1.0.dist-info/licenses/LICENSE,sha256=H_yPvvR29lIsDtuLNx8fxmomlOhH2sGB6kVFK5dpq10,10258
|
|
48
|
+
base_agentkit-0.1.0.dist-info/WHEEL,sha256=mydTeHxOpFHo-DnYhAd_3ATePms-g4rrYvM7wJK8P-U,80
|
|
49
|
+
base_agentkit-0.1.0.dist-info/entry_points.txt,sha256=RHNxUMQqoYnK5ZP4Ukw-cfU7JX9g7ZESDvHC2mriUz4,53
|
|
50
|
+
base_agentkit-0.1.0.dist-info/METADATA,sha256=X4ubZwq-_XtTqOlHLo5v8o2hYEKOGa0cYEiBuKwLlsc,3930
|
|
51
|
+
base_agentkit-0.1.0.dist-info/RECORD,,
|