seedagent 0.7.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.
- seedagent-0.7.0/.gitignore +13 -0
- seedagent-0.7.0/LICENSE +21 -0
- seedagent-0.7.0/PKG-INFO +355 -0
- seedagent-0.7.0/README.md +318 -0
- seedagent-0.7.0/coding_agent/__init__.py +169 -0
- seedagent-0.7.0/coding_agent/__main__.py +5 -0
- seedagent-0.7.0/coding_agent/backups.py +89 -0
- seedagent-0.7.0/coding_agent/certificates.py +55 -0
- seedagent-0.7.0/coding_agent/cleanup.py +128 -0
- seedagent-0.7.0/coding_agent/cli.py +201 -0
- seedagent-0.7.0/coding_agent/common.py +190 -0
- seedagent-0.7.0/coding_agent/config.py +375 -0
- seedagent-0.7.0/coding_agent/context.py +280 -0
- seedagent-0.7.0/coding_agent/conversation.py +51 -0
- seedagent-0.7.0/coding_agent/credentials.py +56 -0
- seedagent-0.7.0/coding_agent/diagnose.py +81 -0
- seedagent-0.7.0/coding_agent/errors.py +106 -0
- seedagent-0.7.0/coding_agent/guard.py +97 -0
- seedagent-0.7.0/coding_agent/history.py +68 -0
- seedagent-0.7.0/coding_agent/index.py +390 -0
- seedagent-0.7.0/coding_agent/logs.py +133 -0
- seedagent-0.7.0/coding_agent/loop.py +301 -0
- seedagent-0.7.0/coding_agent/memories.py +98 -0
- seedagent-0.7.0/coding_agent/memory.py +210 -0
- seedagent-0.7.0/coding_agent/ocr.py +78 -0
- seedagent-0.7.0/coding_agent/prompts.py +128 -0
- seedagent-0.7.0/coding_agent/schemas.py +887 -0
- seedagent-0.7.0/coding_agent/session.py +121 -0
- seedagent-0.7.0/coding_agent/signin.py +85 -0
- seedagent-0.7.0/coding_agent/skills/ai-engineer/SKILL.md +283 -0
- seedagent-0.7.0/coding_agent/skills/azure-cloud-architect/SKILL.md +112 -0
- seedagent-0.7.0/coding_agent/skills/backend-engineer/SKILL.md +98 -0
- seedagent-0.7.0/coding_agent/skills/database-architect/SKILL.md +85 -0
- seedagent-0.7.0/coding_agent/skills/frontend-engineer/SKILL.md +113 -0
- seedagent-0.7.0/coding_agent/skills/web-browsing/SKILL.md +62 -0
- seedagent-0.7.0/coding_agent/skills.py +137 -0
- seedagent-0.7.0/coding_agent/state.py +94 -0
- seedagent-0.7.0/coding_agent/tools/__init__.py +181 -0
- seedagent-0.7.0/coding_agent/tools/browser.py +238 -0
- seedagent-0.7.0/coding_agent/tools/documents.py +814 -0
- seedagent-0.7.0/coding_agent/tools/excel_add.py +309 -0
- seedagent-0.7.0/coding_agent/tools/excel_look.py +364 -0
- seedagent-0.7.0/coding_agent/tools/excel_script.py +236 -0
- seedagent-0.7.0/coding_agent/tools/excel_xl.py +370 -0
- seedagent-0.7.0/coding_agent/tools/files.py +391 -0
- seedagent-0.7.0/coding_agent/tools/git.py +83 -0
- seedagent-0.7.0/coding_agent/tools/interaction.py +17 -0
- seedagent-0.7.0/coding_agent/tools/mail.py +263 -0
- seedagent-0.7.0/coding_agent/tools/network.py +190 -0
- seedagent-0.7.0/coding_agent/tools/office.py +151 -0
- seedagent-0.7.0/coding_agent/tools/python_runner.py +87 -0
- seedagent-0.7.0/coding_agent/tools/sms.py +86 -0
- seedagent-0.7.0/coding_agent/tools/web.py +619 -0
- seedagent-0.7.0/coding_agent/ui.py +323 -0
- seedagent-0.7.0/coding_agent/usage.py +82 -0
- seedagent-0.7.0/coding_agent/websessions.py +122 -0
- seedagent-0.7.0/pyproject.toml +70 -0
- seedagent-0.7.0/tests/conftest.py +85 -0
- seedagent-0.7.0/tests/fake_xlwings.py +309 -0
- seedagent-0.7.0/tests/test_browser.py +42 -0
- seedagent-0.7.0/tests/test_bundled_skills.py +21 -0
- seedagent-0.7.0/tests/test_certificates.py +24 -0
- seedagent-0.7.0/tests/test_cleanup.py +99 -0
- seedagent-0.7.0/tests/test_credentials.py +57 -0
- seedagent-0.7.0/tests/test_documents.py +559 -0
- seedagent-0.7.0/tests/test_errors.py +113 -0
- seedagent-0.7.0/tests/test_example_env.py +52 -0
- seedagent-0.7.0/tests/test_excel_add.py +217 -0
- seedagent-0.7.0/tests/test_excel_backends.py +260 -0
- seedagent-0.7.0/tests/test_excel_script.py +215 -0
- seedagent-0.7.0/tests/test_files.py +191 -0
- seedagent-0.7.0/tests/test_history.py +53 -0
- seedagent-0.7.0/tests/test_index.py +173 -0
- seedagent-0.7.0/tests/test_logs.py +75 -0
- seedagent-0.7.0/tests/test_loop.py +322 -0
- seedagent-0.7.0/tests/test_mail.py +231 -0
- seedagent-0.7.0/tests/test_memories.py +47 -0
- seedagent-0.7.0/tests/test_network_and_terminal.py +69 -0
- seedagent-0.7.0/tests/test_office.py +163 -0
- seedagent-0.7.0/tests/test_provider.py +166 -0
- seedagent-0.7.0/tests/test_read_folders.py +118 -0
- seedagent-0.7.0/tests/test_register_tool.py +104 -0
- seedagent-0.7.0/tests/test_runtime_config.py +254 -0
- seedagent-0.7.0/tests/test_sandbox_and_git.py +80 -0
- seedagent-0.7.0/tests/test_signin.py +99 -0
- seedagent-0.7.0/tests/test_sms.py +85 -0
- seedagent-0.7.0/tests/test_streaming_ui.py +67 -0
- seedagent-0.7.0/tests/test_usage.py +53 -0
- seedagent-0.7.0/tests/test_web.py +427 -0
seedagent-0.7.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 DemePS
|
|
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.
|
seedagent-0.7.0/PKG-INFO
ADDED
|
@@ -0,0 +1,355 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: seedagent
|
|
3
|
+
Version: 0.7.0
|
|
4
|
+
Summary: A coding and document agent on Claude (Azure / Microsoft Foundry): tools, safety rules, memory and context management, usable from the terminal or as a library
|
|
5
|
+
Project-URL: Homepage, https://github.com/DemePS/CodeAgent
|
|
6
|
+
Project-URL: Source, https://github.com/DemePS/CodeAgent
|
|
7
|
+
Project-URL: Issues, https://github.com/DemePS/CodeAgent/issues
|
|
8
|
+
Author: DemePS
|
|
9
|
+
License-Expression: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: agent,anthropic,azure,claude,excel,foundry,pdf
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: Operating System :: OS Independent
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
17
|
+
Classifier: Topic :: Office/Business :: Financial :: Spreadsheet
|
|
18
|
+
Classifier: Topic :: Software Development
|
|
19
|
+
Requires-Python: >=3.10
|
|
20
|
+
Requires-Dist: anthropic<1,>=0.125.0
|
|
21
|
+
Requires-Dist: azure-identity-broker<2,>=1.3.0; sys_platform == 'win32'
|
|
22
|
+
Requires-Dist: azure-identity<2,>=1.25.3
|
|
23
|
+
Requires-Dist: httpx<1,>=0.28.1
|
|
24
|
+
Requires-Dist: openpyxl<4,>=3.1.5
|
|
25
|
+
Requires-Dist: pillow>=10
|
|
26
|
+
Requires-Dist: pypdf<7,>=6.19.0
|
|
27
|
+
Requires-Dist: pypdfium2<5,>=4.30
|
|
28
|
+
Requires-Dist: pytesseract<1,>=0.3.10
|
|
29
|
+
Requires-Dist: python-dotenv<2,>=1.1.1
|
|
30
|
+
Requires-Dist: truststore<1,>=0.10.0
|
|
31
|
+
Provides-Extra: browser
|
|
32
|
+
Requires-Dist: playwright<2,>=1.63.0; extra == 'browser'
|
|
33
|
+
Provides-Extra: excel
|
|
34
|
+
Requires-Dist: xlwings<1,>=0.33; extra == 'excel'
|
|
35
|
+
Provides-Extra: pdf-image
|
|
36
|
+
Description-Content-Type: text/markdown
|
|
37
|
+
|
|
38
|
+
# CodeAgent
|
|
39
|
+
|
|
40
|
+
A document and coding agent. It reads and edits files, Excel workbooks and PDFs (scans included) in a project
|
|
41
|
+
folder, searches a library of documents, browses the web, writes mail drafts and code, asks before every
|
|
42
|
+
change, and remembers what it learned about each project. The model is Claude (Anthropic's API, or your own
|
|
43
|
+
Azure subscription through Microsoft Foundry) or DeepSeek. Use it from the terminal, or as a library to build
|
|
44
|
+
your own tool on top of it (a desktop app that fills Excel workbooks from invoices, a voice assistant over
|
|
45
|
+
a library of PDFs...).
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
pip install seedagent
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Or from a clone of this repository: `uv sync` installs the package and the `coding-agent` command in `.venv` (`uv run coding-agent`), and
|
|
52
|
+
`uv sync --all-extras` adds the browser and the Excel backend. An application built on it just runs `uv sync` too: its own `pyproject.toml`
|
|
53
|
+
and `uv.lock` say which version of the engine to fetch.
|
|
54
|
+
|
|
55
|
+
The package `seedagent` installs the `coding_agent` Python package and the `coding-agent` command (also available as `seedagent`).
|
|
56
|
+
Python 3.10 or later; Windows, macOS and Linux.
|
|
57
|
+
|
|
58
|
+
## Configure
|
|
59
|
+
|
|
60
|
+
Environment variables, or a `.env` file in the folder you run from (or `~/.coding-agent/.env`):
|
|
61
|
+
|
|
62
|
+
| Variable | Meaning |
|
|
63
|
+
|---|---|
|
|
64
|
+
| `ANTHROPIC_FOUNDRY_ENDPOINT` | `https://<resource>.services.ai.azure.com/anthropic` |
|
|
65
|
+
| `ANTHROPIC_FOUNDRY_DEPLOYMENT` | your Claude deployment name |
|
|
66
|
+
| `ANTHROPIC_FOUNDRY_API_KEY` | an API key; leave unset to sign in with your Microsoft work account |
|
|
67
|
+
|
|
68
|
+
Without an API key, the agent signs in with the account of your Windows session, a developer's
|
|
69
|
+
`az login`, or else the Microsoft sign-in page (once; the account is remembered).
|
|
70
|
+
|
|
71
|
+
**Without Azure**, use Anthropic's own API: leave `ANTHROPIC_FOUNDRY_ENDPOINT` unset and set
|
|
72
|
+
|
|
73
|
+
| Variable | Meaning |
|
|
74
|
+
|---|---|
|
|
75
|
+
| `ANTHROPIC_API_KEY` | an API key from [console.anthropic.com](https://console.anthropic.com) |
|
|
76
|
+
| `ANTHROPIC_MODEL` | a model ID (default `claude-sonnet-5`) |
|
|
77
|
+
|
|
78
|
+
Models: `claude-sonnet-5` (the default, $2/$10 per million input/output tokens), `claude-sonnet-5-5` (same price), `claude-haiku-4-5`
|
|
79
|
+
($1/$5, the cheapest; no effort setting, weaker with tools; good for the two background models `AGENT_MEMORY_MODEL` and
|
|
80
|
+
`AGENT_COMPACT_MODEL`), `claude-opus-5-5` ($4/$20), `claude-opus-5` ($5/$25) and `claude-fable-5-1` ($10/$50, its thinking cannot be turned off).
|
|
81
|
+
|
|
82
|
+
**Thinking and effort** (cost and speed), for the agent's own requests:
|
|
83
|
+
|
|
84
|
+
| Variable | Meaning |
|
|
85
|
+
|---|---|
|
|
86
|
+
| `CODEAGENT_THINKING` | thinking before the answer: `off` (the default), `adaptive`, `between_tools` or `disabled` |
|
|
87
|
+
| `CODEAGENT_EFFORT` | how much the model thinks and writes: `medium` (the default), `low`, `high`, `xhigh`, `max`, or `default` (nothing is sent: the model's own default applies) |
|
|
88
|
+
|
|
89
|
+
`off` means the lowest setting the model accepts: `disabled`, `between_tools` on `claude-sonnet-5-5` (it answers 400 to `disabled`), `adaptive` on
|
|
90
|
+
`claude-opus-5-5` (it answers 400 to both), and
|
|
91
|
+
no thinking field at all on `claude-fable-*` (its thinking cannot be turned off). On Foundry the model is a deployment name, so `off` may guess
|
|
92
|
+
wrong: name `between_tools` or `disabled` yourself. `between_tools` does not work with effort `xhigh` or `max`, and `claude-haiku-*` has no effort
|
|
93
|
+
setting (none is sent). A value that is not allowed is explained, never replaced. An application can also call `configure(effort=...)`.
|
|
94
|
+
`coding-agent --check` shows the thinking and effort it sends. `example.env` lists every variable the agent reads: copy it to `.env`.
|
|
95
|
+
|
|
96
|
+
A Foundry endpoint always wins: with `ANTHROPIC_FOUNDRY_ENDPOINT` set, the agent uses Foundry even if
|
|
97
|
+
`ANTHROPIC_API_KEY` is also set.
|
|
98
|
+
|
|
99
|
+
### DeepSeek instead of Claude
|
|
100
|
+
|
|
101
|
+
DeepSeek offers an Anthropic-compatible API (`https://api.deepseek.com/anthropic`), so the same client and the same tools work with a
|
|
102
|
+
DeepSeek model. Set `DEEPSEEK_API_KEY` (and nothing else: no `ANTHROPIC_API_KEY`, no Foundry endpoint), or `CODEAGENT_PROVIDER=deepseek` to
|
|
103
|
+
choose it over them. `CODEAGENT_PROVIDER=claude` does the opposite: Claude (Anthropic's API or Foundry) is used even when a DeepSeek key is set. The model is `deepseek-flash` by default; `ANTHROPIC_MODEL=deepseek-v4-pro` selects the larger one. Setting
|
|
104
|
+
`ANTHROPIC_API_KEY` to a DeepSeek key with `ANTHROPIC_BASE_URL=https://api.deepseek.com/anthropic` also works and is recognised.
|
|
105
|
+
`coding-agent --check` tests the connection.
|
|
106
|
+
|
|
107
|
+
What DeepSeek does not take, and what the agent does about it: no `web_search` tool (it is left out, `Web search: off`); no `cache_control`
|
|
108
|
+
(DeepSeek caches by itself); no PDF `document` blocks, so `read_pdf` sends pages as rendered images instead (pypdfium2) and scans are read
|
|
109
|
+
by OCR or by looking at the page; thinking is sent as `disabled` for `CODEAGENT_THINKING=off`. `deepseek-flash` looks at images;
|
|
110
|
+
`deepseek-v4-pro` does not (it answers "unsupported image"): the tools that return an image are then not offered and `read_pdf` has no visual
|
|
111
|
+
mode (`AGENT_VISION=on|off` overrides the list for a model that is not in it). Set `AGENT_CONTEXT_WINDOW` to the model's real window (the
|
|
112
|
+
default is 200,000 tokens). An application can hand the key over without any environment variable: `configure(api_key=..., model=...)`.
|
|
113
|
+
|
|
114
|
+
## Use it in the terminal
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
coding-agent -d path/to/project "Add input validation to the CLI"
|
|
118
|
+
coding-agent -d path/to/project # interactive
|
|
119
|
+
coding-agent -d path/to/project -r # resume the last conversation
|
|
120
|
+
coding-agent -d path/to/project --read D:/docs --read //server/share # also read (never write) other folders
|
|
121
|
+
coding-agent --check # Claude not answering? test each step of a call
|
|
122
|
+
coding-agent --help
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
In the interactive mode, the up arrow at the `You:` prompt recalls earlier questions, also from earlier
|
|
126
|
+
runs (kept in `~/.coding-agent/history`; needs `readline`: Linux, macOS, WSL; the Windows console recalls
|
|
127
|
+
the questions of the running session by itself).
|
|
128
|
+
|
|
129
|
+
## Use it as a library
|
|
130
|
+
|
|
131
|
+
```python
|
|
132
|
+
from coding_agent import session
|
|
133
|
+
from coding_agent.ui import TerminalUI # or your own UI (subclass coding_agent.ui.UI)
|
|
134
|
+
|
|
135
|
+
session.open_project("path/to/folder", ui=TerminalUI(),
|
|
136
|
+
tools=["read_excel", "edit_excel", "read_pdf", "ask_human"], # optional subset
|
|
137
|
+
system_prompt=None) # or your own instructions
|
|
138
|
+
ok, message = session.check_connection() # can Claude be reached?
|
|
139
|
+
session.send("Fill costs.xlsx from invoice.pdf")
|
|
140
|
+
session.close()
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
`session.open_project(..., excel_first=True)` (for an application that fills workbooks) refuses `read_pdf`
|
|
144
|
+
until `read_excel` has run, when the instruction mentions a spreadsheet; it is off by default.
|
|
145
|
+
|
|
146
|
+
An application that fills one workbook can also set, after `open_project`: `state.excel_writable = {path}` (no other workbook can be changed
|
|
147
|
+
or created), `state.excel_protect_formulas = True` (a formula can be neither replaced nor cleared), and `state.excel_edit_sheets[path] = {"Sheet1"}`
|
|
148
|
+
(only those sheets). They are checked by the tool, not asked of the model.
|
|
149
|
+
|
|
150
|
+
`session.stop()` stops the running instruction from another thread (e.g. a Stop button);
|
|
151
|
+
`session.add_read_folder(path)` lets the agent read (never write) another folder. Every approval,
|
|
152
|
+
question and progress message goes through the UI object, so a web or desktop front end can show them.
|
|
153
|
+
|
|
154
|
+
### Your own tools
|
|
155
|
+
|
|
156
|
+
An application adds a tool of its own without changing the package:
|
|
157
|
+
|
|
158
|
+
```python
|
|
159
|
+
import coding_agent
|
|
160
|
+
|
|
161
|
+
def say_hello(who: str, loud: bool = False) -> str: # called as handler(**arguments)
|
|
162
|
+
return f"Hello {who}{'!' if loud else ''}"
|
|
163
|
+
|
|
164
|
+
coding_agent.register_tool(
|
|
165
|
+
{"name": "say_hello", "description": "Greet someone.",
|
|
166
|
+
"input_schema": {"type": "object", "properties": {"who": {"type": "string"}, "loud": {"type": "boolean"}}, "required": ["who"]}},
|
|
167
|
+
say_hello)
|
|
168
|
+
session.open_project(folder, ui=ui, tools=["read_file", "say_hello"]) # a tool is offered only when the session lists it
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
The handler gets one keyword argument per property of the `input_schema` and returns a string or a list of content blocks
|
|
172
|
+
(`{"type": "text", ...}`, `{"type": "image", ...}`). To report a failure Claude should see, it raises `coding_agent.common.ToolError`; any other
|
|
173
|
+
exception also reaches Claude as an error result and does not stop the agent. It runs in the agent's thread and can use `coding_agent.state`
|
|
174
|
+
(`state.ui`, `state.workspace`). CodeAgent's path checks and confirmations guard only its own tools: what the handler does is the application's
|
|
175
|
+
responsibility (to read a file the way the built-in tools do, `coding_agent.common.resolve_readable(path)` applies the same rules). A built-in
|
|
176
|
+
tool cannot be replaced, registering the same handler twice does nothing, and a second handler under a taken name is an error.
|
|
177
|
+
|
|
178
|
+
## Tools
|
|
179
|
+
|
|
180
|
+
45 tools; an application offers the subset it wants (`session.open_project(tools=[...])`).
|
|
181
|
+
|
|
182
|
+
| Group | Tools |
|
|
183
|
+
|---|---|
|
|
184
|
+
| Files | `read_file`, `write_file`, `edit_file`, `list_directory`, `change_directory`, `grep`, `copy_path`, `delete_file`, `delete_folder` |
|
|
185
|
+
| Documents | `read_pdf`, `search_pdf`, `search_library`, `view_image`, `read_word`, `read_powerpoint` |
|
|
186
|
+
| Excel | `read_excel`, `edit_excel`, `view_excel`, `format_excel`, `add_chart`, `add_table`, `add_pivot_table`, `restore_backup`, `run_python_excel` |
|
|
187
|
+
| Web | `web_search`, `web_open`, `web_click`, `web_type`, `web_back`, `web_page`, `web_look`, `screenshot_page`, `web_sign_in`, `web_set_token`, `web_close`, `download_file` |
|
|
188
|
+
| Mail and SMS | `mail_login`, `mail_draft`, `send_mail`, `send_sms` |
|
|
189
|
+
| Code | `run_python` (sandboxed), `git` (read-only), `clone_repo` |
|
|
190
|
+
| Other | `load_skill`, `ask_human` |
|
|
191
|
+
|
|
192
|
+
`read_file` reads UTF-8 and, failing that, Windows-1252 (the usual export of Excel and French accounting software; the result says so).
|
|
193
|
+
`grep` cuts a matching line at 300 characters and bounds its whole result, so a minified file cannot flood the conversation.
|
|
194
|
+
|
|
195
|
+
### Documents, scans and the library
|
|
196
|
+
|
|
197
|
+
- `read_pdf` reads **text** by default (page ranges). Its **visual** mode (pages rendered as images, at most 20 per call) is allowed once a
|
|
198
|
+
text read happened in the conversation, to check what a scan or a table really shows; names, dates and amounts taken from a scan should be
|
|
199
|
+
checked that way. A model that cannot see images gets no visual mode.
|
|
200
|
+
- Scanned pages are read by **OCR** (tesseract and its language packs must be installed); the text is kept in `AGENT_OCR_DIR` so a page is
|
|
201
|
+
read once. `coding-agent --ocr PDF...` does it ahead of time.
|
|
202
|
+
- `search_library` searches a library of PDFs, Word and PowerPoint files and text files (the read-only folders and the project) through a full-text index
|
|
203
|
+
(SQLite FTS5; alternatives with `a | b | c`, ranked by the words found). Files that are new or changed are indexed on the way, up to a
|
|
204
|
+
size; bigger ones, and a first indexing with OCR, are done once with `coding-agent --index FOLDER...` (`AGENT_INDEX_DIR` moves the index).
|
|
205
|
+
- `read_word` (.docx: paragraphs and tables) and `read_powerpoint` (.pptx: slides and speaker notes) read the text only, with no extra
|
|
206
|
+
dependency; a long document is read in parts with `start`, a slide alone with `slide`. Both are in the search index (a slide is a page; a
|
|
207
|
+
Word file is cut in blocks, located by character). A picture inside is not read.
|
|
208
|
+
- `read_pdf`, `read_file`, `search_library` and `grep` also read the folders given with `--read` / `session.add_read_folder` (never write).
|
|
209
|
+
|
|
210
|
+
### Browsing the web
|
|
211
|
+
|
|
212
|
+
`web_search` finds pages; `web_open` reads one in a hidden browser that stays open, and lists its text
|
|
213
|
+
and its links, buttons and fields with numbers. The agent goes through a site with `web_click 3` and
|
|
214
|
+
`web_type 5 "weather paris" submit`, reads long pages with `web_page`, goes back with `web_back`, sees
|
|
215
|
+
the page with `web_look` and ends with `web_close`. It needs Playwright and a browser, like
|
|
216
|
+
`screenshot_page` (`uv sync --extra browser`, then `playwright install chromium`; `coding-agent
|
|
217
|
+
--check-browser` tests it).
|
|
218
|
+
|
|
219
|
+
What keeps it safe (in the tools, not only in the prompt):
|
|
220
|
+
|
|
221
|
+
- The first visit to a public site asks you, with the full URL (`[a]ll sites for this session` stops the
|
|
222
|
+
questions until the session ends; `AGENT_WEB_APPROVE=off` never asks, for unattended runs); after that
|
|
223
|
+
the agent can click and type on that site. Links to other sites are refused until the agent opens them with `web_open`,
|
|
224
|
+
which asks you. localhost, private addresses and workspace HTML files need no question.
|
|
225
|
+
- It never types into password, sign-in or payment fields. When a site needs you signed in, `web_sign_in` opens
|
|
226
|
+
a visible window where you type the password yourself; the agent never sees it and keeps only the session
|
|
227
|
+
(cookies) of that site, for 30 days (`AGENT_WEB_SESSION_DAYS`), in `~/.coding-agent/web-sessions` (owner-only
|
|
228
|
+
files). `coding-agent --forget-logins` deletes them (`--forget-logins SITE` for one). A saved session is as
|
|
229
|
+
good as a password until it expires: keep it for sites you are comfortable with.
|
|
230
|
+
- A form that sends data (POST), by a button or by pressing Enter, shows what it sends and asks first.
|
|
231
|
+
- Downloads are blocked, metadata addresses are refused, and nothing is kept on disk (apart from sign-ins you made with `web_sign_in`): cookies and
|
|
232
|
+
history end with the session (`web_close`, or the program ending).
|
|
233
|
+
- The page text reaches Claude marked as untrusted content, and the tools say that pages cannot give
|
|
234
|
+
it instructions.
|
|
235
|
+
|
|
236
|
+
Limits: content inside frames and shadow DOM is not listed, nothing is drawn on a canvas for the text
|
|
237
|
+
view (use `web_look`), and a site that blocks automated browsers will block this one too.
|
|
238
|
+
|
|
239
|
+
### Excel: two backends
|
|
240
|
+
|
|
241
|
+
Who changes, formats and renders workbooks is set by `AGENT_EXCEL_BACKEND`:
|
|
242
|
+
|
|
243
|
+
| | `openpyxl` | `xlwings` (`uv sync --extra excel`) |
|
|
244
|
+
|---|---|---|
|
|
245
|
+
| Runs on | anywhere | Windows or macOS with Excel installed |
|
|
246
|
+
| Saving | rewrites the file: charts, pictures, pivot tables can be damaged (you are warned first) | Excel saves: nothing is lost |
|
|
247
|
+
| Formulas after an edit | old results until the file is opened in Excel | recalculated at once |
|
|
248
|
+
| `view_excel` | a drawing of the cells (needs the `browser` extra); charts listed, not drawn | what Excel prints, charts included |
|
|
249
|
+
| A workbook open in Excel | refused (locked) | written in that window, if it has no unsaved changes |
|
|
250
|
+
| `add_chart`, `add_table` | written by openpyxl | added by Excel |
|
|
251
|
+
| `add_pivot_table` | refused (openpyxl cannot build them) | built by Excel |
|
|
252
|
+
|
|
253
|
+
`auto` (the default) uses xlwings when it is installed and Excel can be started, else openpyxl.
|
|
254
|
+
Reading (`read_excel`) is the same in both: it never changes the file, lists the charts, pictures,
|
|
255
|
+
tables and pivot tables of a sheet, and shows a long cell whole when that one cell is read.
|
|
256
|
+
`scripts/compare_excel_backends.py` runs the same edits, formatting and views with both backends and
|
|
257
|
+
reports what each kept (run it on a PC with Excel: `uv run --extra excel --extra browser python
|
|
258
|
+
scripts/compare_excel_backends.py [your.xlsx ...]`).
|
|
259
|
+
|
|
260
|
+
### Excel scripts (`run_python_excel`)
|
|
261
|
+
|
|
262
|
+
For what no Excel tool does, the agent has `run_python_excel`: a Python
|
|
263
|
+
script run with Excel (xlwings backend only) on a workbook, which it gets as `book`. Excel can do far
|
|
264
|
+
more than the `run_python` sandbox can see (run macros, start programs, open and save any file), so:
|
|
265
|
+
|
|
266
|
+
- the script is checked before it runs, and refused if it uses macros (`Run`, `Evaluate`,
|
|
267
|
+
`VBProject`, `ExecuteExcel4Macro`...), programs or links (`Shell`, `FollowHyperlink`, DDE
|
|
268
|
+
formulas such as `=cmd|...`), other files or workbooks (`save`, `SaveAs`, `Open`, `books`,
|
|
269
|
+
`app`, `Application`, `Parent`), external data (`QueryTables`, `WEBSERVICE`), imports beyond
|
|
270
|
+
`math`, `datetime`, `re`, `collections`... , or ways around the check (`eval`, `exec`, `getattr`
|
|
271
|
+
with a computed name, `_private` attributes);
|
|
272
|
+
- you approve the script (unless autonomous mode is on), and a backup of the workbook is kept first
|
|
273
|
+
(`restore_backup` undoes it);
|
|
274
|
+
- it runs in its own invisible Excel with macros forced off and events off, inside the `run_python`
|
|
275
|
+
sandbox; macros it adds are refused and the workbook is put back;
|
|
276
|
+
- you see what it changed: cells, sheets, charts, tables, pivot tables.
|
|
277
|
+
|
|
278
|
+
The check reads the script; it cannot prove what Excel will do. An application that passes its own
|
|
279
|
+
list of tools (`session.open_project(tools=[...])`) does not get it unless it lists it, and it is
|
|
280
|
+
refused in applications that restrict edits (chosen sheets, protected formulas, no formatting).
|
|
281
|
+
|
|
282
|
+
## Safety
|
|
283
|
+
|
|
284
|
+
- It writes only inside the project folder. Reading elsewhere: in the terminal the agent asks you the first time it wants to read a folder outside the project (`Allow the agent to read (never change) files in ...?`), and remembers the answer for the session; folders given with `--read` need no question. Keys and settings (`~/.ssh`, `~/.aws`, `~/.azure`, `~/.coding-agent`, `.env` files, `*.pem`, `*.key`...) are never read. An application built on the package keeps reading limited to what it was given.
|
|
285
|
+
- Every file or workbook change is shown (a diff, or a cell-by-cell table) and waits for your
|
|
286
|
+
approval; a copy of the previous version of each workbook is kept in `~/.coding-agent/backups/` for 3 days,
|
|
287
|
+
and `restore_backup` puts one back ("undo your changes to costs.xlsx"). Applications can list and
|
|
288
|
+
restore them with `coding_agent.backups` (`versions()`, `restore()`).
|
|
289
|
+
- Deleting always asks, even in autonomous mode; downloads and clones always ask; the agent cannot
|
|
290
|
+
modify its own files; `run_python` cannot start processes or delete files.
|
|
291
|
+
- **No secret reaches code the model wrote.** `run_python` and Excel scripts run with an environment from which every variable that says
|
|
292
|
+
it is a secret (`*KEY*`, `*TOKEN*`, `*SECRET*`, `*PASSWORD*`, `*AUTH*`), the variables of cloud and model services (`ANTHROPIC_*`,
|
|
293
|
+
`DEEPSEEK_*`, `AZURE_*`, `AWS_*`, `GITHUB_*`...) and any copy of an API key are removed, and the output of the script has those values
|
|
294
|
+
hidden. A document that steers the model cannot make it print your keys.
|
|
295
|
+
- The agent never reads `~/.coding-agent` (credentials and its own settings), so a knowledge folder must live elsewhere.
|
|
296
|
+
|
|
297
|
+
## What stays on your machine
|
|
298
|
+
|
|
299
|
+
Everything is in `~/.coding-agent` (`$HOME`, or your user folder on Windows), cleaned automatically
|
|
300
|
+
(`coding_agent/cleanup.py`): once per process, at the start of `coding-agent` and the first time an application
|
|
301
|
+
opens a project (`session.open_project`). `AGENT_CLEANUP=off` switches that off; an application that runs for
|
|
302
|
+
weeks (a server) can call `coding_agent.cleanup.run()` itself, daily (a call counts as the run):
|
|
303
|
+
|
|
304
|
+
| What | Where | Kept |
|
|
305
|
+
|---|---|---|
|
|
306
|
+
| Copies of workbooks before each change | `backups/` | 3 days (`AGENT_BACKUP_DAYS`) |
|
|
307
|
+
| What the agent learned about each project | `memory/<project>-<code>/` | notes capped in size; deleted after 90 days unused (`AGENT_MEMORY_DAYS`) |
|
|
308
|
+
| The saved conversation (`--resume`) | `memory/<project>-<code>/conversation.json` | 30 days (`AGENT_CONVERSATION_DAYS`) |
|
|
309
|
+
|
|
310
|
+
`AGENT_MEMORY=off` stops the agent from writing memory at all.
|
|
311
|
+
|
|
312
|
+
For developers, to see and delete what the agent remembers:
|
|
313
|
+
|
|
314
|
+
```bash
|
|
315
|
+
coding-agent --memories # every project's memory: name, last used, size, notes
|
|
316
|
+
coding-agent --memories myapp # one project's notes, in full
|
|
317
|
+
coding-agent --forget myapp # delete one project's memory (asks first)
|
|
318
|
+
coding-agent --forget . -d path # the memory of that project folder
|
|
319
|
+
coding-agent --forget all # delete every project's memory (asks first)
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
## Development
|
|
323
|
+
|
|
324
|
+
```bash
|
|
325
|
+
uv sync --all-extras # the exact versions the tests ran with (uv.lock), with the browser and Excel extras
|
|
326
|
+
uv run playwright install chromium # the browser tools and their tests need it
|
|
327
|
+
uv run pytest
|
|
328
|
+
uv build # dist/seedagent-<version>.tar.gz and .whl
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
The CI (`.github/workflows/package.yml`) runs the same on Linux and Windows, Python 3.10 and 3.14, with every extra and Chromium
|
|
332
|
+
installed, then installs the built wheel in a fresh environment and runs the tests there. A test must not depend on a `.env`, on the
|
|
333
|
+
order of files or on the repository layout (the wheel's tests run from a copy of `tests/`).
|
|
334
|
+
|
|
335
|
+
## Releasing (maintainers)
|
|
336
|
+
|
|
337
|
+
The workflow (`.github/workflows/package.yml`) publishes to PyPI by trusted publishing (no token stored). The project is `seedagent`; its
|
|
338
|
+
publisher on pypi.org is owner `DemePS`, repository `CodeAgent`, workflow `package.yml`, environment `pypi` (also an environment `pypi` in
|
|
339
|
+
the repository's settings). PyPI refuses a name that equals an existing one once `-`, `_` and `.` are removed (`codeagent` was refused:
|
|
340
|
+
`code-agent` exists), so check a new name against the full list before registering it.
|
|
341
|
+
|
|
342
|
+
To publish a version, tag the commit whose `pyproject.toml` has that version, with CI green, and push the tag:
|
|
343
|
+
|
|
344
|
+
```bash
|
|
345
|
+
git fetch origin
|
|
346
|
+
git tag -a v0.7.0 origin/main -m "v0.7.0"
|
|
347
|
+
git push origin v0.7.0
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
The tag runs the tests and the build, publishes to PyPI and creates a GitHub Release. A tag whose version differs from `pyproject.toml` is
|
|
351
|
+
refused. A published version can never be replaced: fix forward with a new version. Applications then depend on `seedagent==<version>`.
|
|
352
|
+
|
|
353
|
+
## License
|
|
354
|
+
|
|
355
|
+
MIT (see LICENSE).
|