dots-agent 0.1.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.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 duyongan
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,298 @@
1
+ Metadata-Version: 2.4
2
+ Name: dots-agent
3
+ Version: 0.1.0
4
+ Summary: 常驻主动式 agent —— 给一个目标,它自己在后台推
5
+ License: MIT
6
+ Project-URL: Homepage, https://github.com/duyongan/dots-agent
7
+ Project-URL: Source, https://github.com/duyongan/dots-agent
8
+ Project-URL: Issues, https://github.com/duyongan/dots-agent/issues
9
+ Keywords: agent,llm,deepagents,automation,proactive,langgraph
10
+ Classifier: Development Status :: 3 - Alpha
11
+ Classifier: Environment :: Console
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Operating System :: OS Independent
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Programming Language :: Python :: 3.13
18
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
19
+ Requires-Python: >=3.11
20
+ Description-Content-Type: text/markdown
21
+ License-File: LICENSE
22
+ Requires-Dist: deepagents>=0.6
23
+ Requires-Dist: langgraph-checkpoint-sqlite>=2.0
24
+ Requires-Dist: python-dateutil>=2.8
25
+ Requires-Dist: langchain-openai>=0.3
26
+ Provides-Extra: test
27
+ Requires-Dist: cryptography>=41; extra == "test"
28
+ Requires-Dist: pytest>=8; extra == "test"
29
+ Dynamic: license-file
30
+
31
+ # dots-agent
32
+
33
+ 常驻主动式 agent。给一个目标,它自己在后台反复推,没人看着也跑。
34
+
35
+ 包名 `dots-agent`,命令是 `dot`(装完就有)。每个目标由「一个 dot」来跑,
36
+ 它也能把目标交给别的 bot —— 名字就是这个来历。
37
+
38
+ ## 安装
39
+
40
+ ```bash
41
+ pip install dots-agent
42
+ ```
43
+
44
+ 或者不装,直接在仓库里跑(两种方式命令都通用):
45
+
46
+ ```bash
47
+ git clone https://github.com/duyongan/dots-agent
48
+ cd dots-agent
49
+ python -m dot serve
50
+ ```
51
+
52
+ ## 快速开始
53
+
54
+ ```bash
55
+ dot init # 生成 dot.toml,自动探测你环境里的 API key
56
+ dot doctor # 体检一下
57
+ dot goal "把 inbox 里的东西整理成一份报告"
58
+ dot serve --web # 常驻跑起来,同时开活动视图
59
+ ```
60
+
61
+ 打开 http://127.0.0.1:8765/ 看它在干什么。
62
+
63
+ 想先不配模型试一遍:
64
+
65
+ ```bash
66
+ dot selftest # 不联网、不调模型
67
+ ```
68
+
69
+ ## 命令
70
+
71
+ | 命令 | 干什么 |
72
+ |---|---|
73
+ | `dot init` | 在当前目录生成 `dot.toml`,扫环境变量自动配好 `[model]` |
74
+ | `dot doctor` | 体检:配置、密钥、模型、目录、数据库、事件源逐项查 |
75
+ | `dot goal "..."` | 下一个目标。`--bot <名>` 指定交给谁做 |
76
+ | `dot serve` | 常驻跑。`--web` 开活动视图,`--once` 只跑一轮,`--dry-run` 不真发邮件 |
77
+ | `dot tick` | 手动跑一轮就退(调试用) |
78
+ | `dot ls` | 列目标。`--status <状态>` 过滤 |
79
+ | `dot log` | 活动流水。`-n 50` 条数,`--goal <id>` 只看一个 |
80
+ | `dot approve <token>` | 批准一个挂起的动作 |
81
+ | `dot reject <token>` | 拒绝一个挂起的动作 |
82
+ | `dot cost` | token 用量 |
83
+ | `dot learn "..."` | 把一段材料总结成技能 |
84
+ | `dot skills` | 列出技能库 |
85
+ | `dot skill show <名>` | 看技能正文 |
86
+ | `dot skill rm <名>` | 删掉技能 |
87
+ | `dot curate` | 让 agent 整理技能库:合并重复、删掉没价值的 |
88
+ | `dot selftest` | 不联网不调模型跑一遍自检 |
89
+
90
+ 全局参数:`-c, --config <路径>`,默认 `./dot.toml`。
91
+
92
+ ## 配置
93
+
94
+ `dot init` 生成一份 `dot.toml`,所有相对路径都相对这个文件所在目录。
95
+ **密钥只写环境变量名,不写进文件。**
96
+
97
+ ### `[dot]`
98
+
99
+ ```toml
100
+ [dot]
101
+ tick_seconds = 60 # 心跳间隔。这就是「主动」的节拍
102
+ workspace = "workspace" # agent 的工作目录 = 沙箱
103
+ db = "dot.db"
104
+ ```
105
+
106
+ ### `[model]`
107
+
108
+ `dot init` 会自动探测,一般不用手改。支持的 key:
109
+
110
+ DeepSeek / Kimi / 通义 / 智谱 / 豆包 / 硅基流动 / Claude / OpenAI / Gemini。
111
+
112
+ 第三方端点要三件套:
113
+
114
+ ```toml
115
+ [model]
116
+ name = "openai:deepseek-chat"
117
+ base_url = "https://api.deepseek.com"
118
+ api_key_env = "DEEPSEEK_API_KEY"
119
+ max_tokens = 4096
120
+ temperature = 0.2
121
+ ```
122
+
123
+ ### `[smtp]`
124
+
125
+ 审批邮件和汇报从这里发出去。不配也能跑,审批退化成 `dot approve`。
126
+
127
+ ```toml
128
+ [smtp]
129
+ host = "smtp.example.com"
130
+ port = 587
131
+ user = "me@example.com"
132
+ sender = "me@example.com"
133
+ to = "me@example.com" # 审批邮件发给谁(通常就是你自己)
134
+ password_env = "DOT_SMTP_PASSWORD"
135
+ use_tls = true
136
+ ```
137
+
138
+ ### `[sources.*]` 事件源
139
+
140
+ 决定「没人说话的时候,什么唤醒它」。至少开一个。
141
+
142
+ ```toml
143
+ [sources.fs]
144
+ enabled = true
145
+ paths = ["inbox"] # workspace 下的相对目录
146
+ interval = 120
147
+ ```
148
+
149
+ ```toml
150
+ [sources.imap]
151
+ enabled = true
152
+ host = "imap.example.com"
153
+ port = 993
154
+ user = "me@example.com"
155
+ folder = "INBOX"
156
+ password_env = "DOT_IMAP_PASSWORD"
157
+ interval = 300
158
+ verify_tls = true # 自建 Dovecot 用自签证书就设 false
159
+ ```
160
+
161
+ ```toml
162
+ [sources.ical]
163
+ enabled = true
164
+ url = "https://example.com/cal.ics"
165
+ interval = 900
166
+ ```
167
+
168
+ ### `[approval]` 审批
169
+
170
+ ```toml
171
+ [approval]
172
+ subject_prefix = "[dot#"
173
+ timeout_hours = 72 # 超时没人批就按拒绝处理。0 = 永远等
174
+
175
+ [approval.rules]
176
+ send_email = "ask" # ask = 挂起等你批
177
+ run_shell = "deny" # deny = 永不执行
178
+ save_skill = "allow" # allow = 直接放行
179
+ # fs_* = "allow" # 支持通配
180
+ ```
181
+
182
+ 三个值:`allow` 直接执行、`ask` 挂起等你、`deny` 永不执行。
183
+ **没写到的动作一律 ask。**
184
+
185
+ ### `[skills]` 技能
186
+
187
+ ```toml
188
+ [skills]
189
+ enabled = true
190
+ dir = "skills" # workspace 下的相对目录
191
+ ```
192
+
193
+ ### `[bots.*]` 多 bot
194
+
195
+ ```toml
196
+ [bots.ops]
197
+ prompt = "你是执行侧..."
198
+ tools = ["send_email"] # 只给这些工具;留空 = 给全部
199
+ ```
200
+
201
+ `dot` 这个 bot 永远存在,不用配。
202
+
203
+ ### `[handoff]` 交接
204
+
205
+ ```toml
206
+ [handoff]
207
+ max_hops = 3 # 一个目标最多被交接几次
208
+ ```
209
+
210
+ ### `[safety]` 成本
211
+
212
+ ```toml
213
+ [safety]
214
+ daily_token_budget = 0 # 0 = 不限。填了数字,超了当天就不再跑新目标
215
+ ```
216
+
217
+ ## 常见用法
218
+
219
+ ### 让文件触发它
220
+
221
+ 往 `workspace/inbox/` 扔个文件,下一轮 tick 它自己就会发现并处理。
222
+
223
+ ```bash
224
+ printf '把这三件事排个优先级\n- 修打印机\n- 回邮件\n- 整理数据\n' > workspace/inbox/todo.txt
225
+ dot tick
226
+ dot ls
227
+ ```
228
+
229
+ ### 用邮件审批
230
+
231
+ 配好 `[smtp]` 和 `[sources.imap]` 后,它想执行 `ask` 的动作会给你发一封邮件,
232
+ 主题里带一个编号:
233
+
234
+ ```
235
+ [dot#a7f3] 发邮件给 alice: 周会改到周四
236
+ ```
237
+
238
+ **回复这封邮件**,第一行写 `y` / `同意` 或 `n` / `拒绝` 即可。
239
+
240
+ 没配邮件也能用 CLI。`dot ls` 会把等审批的目标和编号直接列出来:
241
+
242
+ ```bash
243
+ dot ls
244
+ # ID STATUS TOKEN TOKENS UPDATED TEXT
245
+ # 43e86d interrupted a7f3 29,047 12s 给 alice 发一封邮件...
246
+ #
247
+ # 1 个在等你。批准:dot approve <编号> 拒绝:dot reject <编号>
248
+
249
+ dot log --goal 43e86d # 先看它到底想干什么
250
+ dot approve a7f3
251
+ ```
252
+
253
+ ### 攒技能
254
+
255
+ 它干活的时候会自己把可复用的流程记下来。你也可以喂材料:
256
+
257
+ ```bash
258
+ dot learn "workspace/weekly-template.md 里的周报模板,以后按这个格式写周报"
259
+ dot tick
260
+ dot skills
261
+ ```
262
+
263
+ 技能存在 `workspace/skills/<名>/SKILL.md`,是普通 markdown 文件,可以手改。
264
+
265
+ ### 交接给别的 bot
266
+
267
+ ```bash
268
+ dot goal --bot ops "把报告发给 alice"
269
+ ```
270
+
271
+ 跑起来之后它也能自己换人,你在 `dot log` 里会看到 `handoff` 那一条。
272
+
273
+ ### 看活动视图
274
+
275
+ ```bash
276
+ dot serve --web --web-port 8765
277
+ ```
278
+
279
+ 三张表:待批准、目标(带结论和证据)、最近的流水。10 秒自刷新。
280
+ 只听本机,没有鉴权,别绑到 `0.0.0.0`。
281
+
282
+ ### 常驻跑
283
+
284
+ ```bash
285
+ dot serve
286
+ ```
287
+
288
+ Ctrl-C 停。没跑完的目标留在库里,下次启动接着跑。
289
+
290
+ ## 一个提醒
291
+
292
+ 每次运行都会重新过一遍系统提示和工具描述,固定开销不小 —— 往 `inbox/`
293
+ 扔一个文件大约几万 token 起。先让 `daily_token_budget = 0` 跑一天,
294
+ 用 `dot cost` 看真实数字,再决定填多少。
295
+
296
+ ## 许可
297
+
298
+ MIT
@@ -0,0 +1,268 @@
1
+ # dots-agent
2
+
3
+ 常驻主动式 agent。给一个目标,它自己在后台反复推,没人看着也跑。
4
+
5
+ 包名 `dots-agent`,命令是 `dot`(装完就有)。每个目标由「一个 dot」来跑,
6
+ 它也能把目标交给别的 bot —— 名字就是这个来历。
7
+
8
+ ## 安装
9
+
10
+ ```bash
11
+ pip install dots-agent
12
+ ```
13
+
14
+ 或者不装,直接在仓库里跑(两种方式命令都通用):
15
+
16
+ ```bash
17
+ git clone https://github.com/duyongan/dots-agent
18
+ cd dots-agent
19
+ python -m dot serve
20
+ ```
21
+
22
+ ## 快速开始
23
+
24
+ ```bash
25
+ dot init # 生成 dot.toml,自动探测你环境里的 API key
26
+ dot doctor # 体检一下
27
+ dot goal "把 inbox 里的东西整理成一份报告"
28
+ dot serve --web # 常驻跑起来,同时开活动视图
29
+ ```
30
+
31
+ 打开 http://127.0.0.1:8765/ 看它在干什么。
32
+
33
+ 想先不配模型试一遍:
34
+
35
+ ```bash
36
+ dot selftest # 不联网、不调模型
37
+ ```
38
+
39
+ ## 命令
40
+
41
+ | 命令 | 干什么 |
42
+ |---|---|
43
+ | `dot init` | 在当前目录生成 `dot.toml`,扫环境变量自动配好 `[model]` |
44
+ | `dot doctor` | 体检:配置、密钥、模型、目录、数据库、事件源逐项查 |
45
+ | `dot goal "..."` | 下一个目标。`--bot <名>` 指定交给谁做 |
46
+ | `dot serve` | 常驻跑。`--web` 开活动视图,`--once` 只跑一轮,`--dry-run` 不真发邮件 |
47
+ | `dot tick` | 手动跑一轮就退(调试用) |
48
+ | `dot ls` | 列目标。`--status <状态>` 过滤 |
49
+ | `dot log` | 活动流水。`-n 50` 条数,`--goal <id>` 只看一个 |
50
+ | `dot approve <token>` | 批准一个挂起的动作 |
51
+ | `dot reject <token>` | 拒绝一个挂起的动作 |
52
+ | `dot cost` | token 用量 |
53
+ | `dot learn "..."` | 把一段材料总结成技能 |
54
+ | `dot skills` | 列出技能库 |
55
+ | `dot skill show <名>` | 看技能正文 |
56
+ | `dot skill rm <名>` | 删掉技能 |
57
+ | `dot curate` | 让 agent 整理技能库:合并重复、删掉没价值的 |
58
+ | `dot selftest` | 不联网不调模型跑一遍自检 |
59
+
60
+ 全局参数:`-c, --config <路径>`,默认 `./dot.toml`。
61
+
62
+ ## 配置
63
+
64
+ `dot init` 生成一份 `dot.toml`,所有相对路径都相对这个文件所在目录。
65
+ **密钥只写环境变量名,不写进文件。**
66
+
67
+ ### `[dot]`
68
+
69
+ ```toml
70
+ [dot]
71
+ tick_seconds = 60 # 心跳间隔。这就是「主动」的节拍
72
+ workspace = "workspace" # agent 的工作目录 = 沙箱
73
+ db = "dot.db"
74
+ ```
75
+
76
+ ### `[model]`
77
+
78
+ `dot init` 会自动探测,一般不用手改。支持的 key:
79
+
80
+ DeepSeek / Kimi / 通义 / 智谱 / 豆包 / 硅基流动 / Claude / OpenAI / Gemini。
81
+
82
+ 第三方端点要三件套:
83
+
84
+ ```toml
85
+ [model]
86
+ name = "openai:deepseek-chat"
87
+ base_url = "https://api.deepseek.com"
88
+ api_key_env = "DEEPSEEK_API_KEY"
89
+ max_tokens = 4096
90
+ temperature = 0.2
91
+ ```
92
+
93
+ ### `[smtp]`
94
+
95
+ 审批邮件和汇报从这里发出去。不配也能跑,审批退化成 `dot approve`。
96
+
97
+ ```toml
98
+ [smtp]
99
+ host = "smtp.example.com"
100
+ port = 587
101
+ user = "me@example.com"
102
+ sender = "me@example.com"
103
+ to = "me@example.com" # 审批邮件发给谁(通常就是你自己)
104
+ password_env = "DOT_SMTP_PASSWORD"
105
+ use_tls = true
106
+ ```
107
+
108
+ ### `[sources.*]` 事件源
109
+
110
+ 决定「没人说话的时候,什么唤醒它」。至少开一个。
111
+
112
+ ```toml
113
+ [sources.fs]
114
+ enabled = true
115
+ paths = ["inbox"] # workspace 下的相对目录
116
+ interval = 120
117
+ ```
118
+
119
+ ```toml
120
+ [sources.imap]
121
+ enabled = true
122
+ host = "imap.example.com"
123
+ port = 993
124
+ user = "me@example.com"
125
+ folder = "INBOX"
126
+ password_env = "DOT_IMAP_PASSWORD"
127
+ interval = 300
128
+ verify_tls = true # 自建 Dovecot 用自签证书就设 false
129
+ ```
130
+
131
+ ```toml
132
+ [sources.ical]
133
+ enabled = true
134
+ url = "https://example.com/cal.ics"
135
+ interval = 900
136
+ ```
137
+
138
+ ### `[approval]` 审批
139
+
140
+ ```toml
141
+ [approval]
142
+ subject_prefix = "[dot#"
143
+ timeout_hours = 72 # 超时没人批就按拒绝处理。0 = 永远等
144
+
145
+ [approval.rules]
146
+ send_email = "ask" # ask = 挂起等你批
147
+ run_shell = "deny" # deny = 永不执行
148
+ save_skill = "allow" # allow = 直接放行
149
+ # fs_* = "allow" # 支持通配
150
+ ```
151
+
152
+ 三个值:`allow` 直接执行、`ask` 挂起等你、`deny` 永不执行。
153
+ **没写到的动作一律 ask。**
154
+
155
+ ### `[skills]` 技能
156
+
157
+ ```toml
158
+ [skills]
159
+ enabled = true
160
+ dir = "skills" # workspace 下的相对目录
161
+ ```
162
+
163
+ ### `[bots.*]` 多 bot
164
+
165
+ ```toml
166
+ [bots.ops]
167
+ prompt = "你是执行侧..."
168
+ tools = ["send_email"] # 只给这些工具;留空 = 给全部
169
+ ```
170
+
171
+ `dot` 这个 bot 永远存在,不用配。
172
+
173
+ ### `[handoff]` 交接
174
+
175
+ ```toml
176
+ [handoff]
177
+ max_hops = 3 # 一个目标最多被交接几次
178
+ ```
179
+
180
+ ### `[safety]` 成本
181
+
182
+ ```toml
183
+ [safety]
184
+ daily_token_budget = 0 # 0 = 不限。填了数字,超了当天就不再跑新目标
185
+ ```
186
+
187
+ ## 常见用法
188
+
189
+ ### 让文件触发它
190
+
191
+ 往 `workspace/inbox/` 扔个文件,下一轮 tick 它自己就会发现并处理。
192
+
193
+ ```bash
194
+ printf '把这三件事排个优先级\n- 修打印机\n- 回邮件\n- 整理数据\n' > workspace/inbox/todo.txt
195
+ dot tick
196
+ dot ls
197
+ ```
198
+
199
+ ### 用邮件审批
200
+
201
+ 配好 `[smtp]` 和 `[sources.imap]` 后,它想执行 `ask` 的动作会给你发一封邮件,
202
+ 主题里带一个编号:
203
+
204
+ ```
205
+ [dot#a7f3] 发邮件给 alice: 周会改到周四
206
+ ```
207
+
208
+ **回复这封邮件**,第一行写 `y` / `同意` 或 `n` / `拒绝` 即可。
209
+
210
+ 没配邮件也能用 CLI。`dot ls` 会把等审批的目标和编号直接列出来:
211
+
212
+ ```bash
213
+ dot ls
214
+ # ID STATUS TOKEN TOKENS UPDATED TEXT
215
+ # 43e86d interrupted a7f3 29,047 12s 给 alice 发一封邮件...
216
+ #
217
+ # 1 个在等你。批准:dot approve <编号> 拒绝:dot reject <编号>
218
+
219
+ dot log --goal 43e86d # 先看它到底想干什么
220
+ dot approve a7f3
221
+ ```
222
+
223
+ ### 攒技能
224
+
225
+ 它干活的时候会自己把可复用的流程记下来。你也可以喂材料:
226
+
227
+ ```bash
228
+ dot learn "workspace/weekly-template.md 里的周报模板,以后按这个格式写周报"
229
+ dot tick
230
+ dot skills
231
+ ```
232
+
233
+ 技能存在 `workspace/skills/<名>/SKILL.md`,是普通 markdown 文件,可以手改。
234
+
235
+ ### 交接给别的 bot
236
+
237
+ ```bash
238
+ dot goal --bot ops "把报告发给 alice"
239
+ ```
240
+
241
+ 跑起来之后它也能自己换人,你在 `dot log` 里会看到 `handoff` 那一条。
242
+
243
+ ### 看活动视图
244
+
245
+ ```bash
246
+ dot serve --web --web-port 8765
247
+ ```
248
+
249
+ 三张表:待批准、目标(带结论和证据)、最近的流水。10 秒自刷新。
250
+ 只听本机,没有鉴权,别绑到 `0.0.0.0`。
251
+
252
+ ### 常驻跑
253
+
254
+ ```bash
255
+ dot serve
256
+ ```
257
+
258
+ Ctrl-C 停。没跑完的目标留在库里,下次启动接着跑。
259
+
260
+ ## 一个提醒
261
+
262
+ 每次运行都会重新过一遍系统提示和工具描述,固定开销不小 —— 往 `inbox/`
263
+ 扔一个文件大约几万 token 起。先让 `daily_token_budget = 0` 跑一天,
264
+ 用 `dot cost` 看真实数字,再决定填多少。
265
+
266
+ ## 许可
267
+
268
+ MIT
@@ -0,0 +1,3 @@
1
+ """dot —— 常驻主动式 agent。"""
2
+
3
+ __version__ = "0.1.0"
@@ -0,0 +1,4 @@
1
+ from dot.cli import main
2
+
3
+ if __name__ == "__main__":
4
+ raise SystemExit(main())