xun-agent 1.0.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.
Files changed (59) hide show
  1. xun_agent-1.0.0/PKG-INFO +216 -0
  2. xun_agent-1.0.0/README.md +189 -0
  3. xun_agent-1.0.0/pyproject.toml +54 -0
  4. xun_agent-1.0.0/pyproject.toml.orig +49 -0
  5. xun_agent-1.0.0/src/xun/__init__.py +25 -0
  6. xun_agent-1.0.0/src/xun/agent.py +295 -0
  7. xun_agent-1.0.0/src/xun/assets/conversation.template.html +134 -0
  8. xun_agent-1.0.0/src/xun/assets/login.template.html +36 -0
  9. xun_agent-1.0.0/src/xun/assets/web/assets/fira-code-latin-400-normal-DGosTW8U.woff2 +0 -0
  10. xun_agent-1.0.0/src/xun/assets/web/assets/fira-code-latin-500-normal-B6gioGu8.woff2 +0 -0
  11. xun_agent-1.0.0/src/xun/assets/web/assets/index-B1sjzEzZ.js +70 -0
  12. xun_agent-1.0.0/src/xun/assets/web/assets/index-DkGPJqYa.css +1 -0
  13. xun_agent-1.0.0/src/xun/assets/web/assets/manrope-latin-400-normal-PaqtzbVb.woff2 +0 -0
  14. xun_agent-1.0.0/src/xun/assets/web/assets/manrope-latin-500-normal-BYYD-dBL.woff2 +0 -0
  15. xun_agent-1.0.0/src/xun/assets/web/assets/manrope-latin-600-normal-4f0koTD-.woff2 +0 -0
  16. xun_agent-1.0.0/src/xun/assets/web/assets/manrope-latin-700-normal-BZp_XxE4.woff2 +0 -0
  17. xun_agent-1.0.0/src/xun/assets/web/assets/newsreader-latin-600-normal-30OJ_TG_.woff2 +0 -0
  18. xun_agent-1.0.0/src/xun/assets/web/index.html +14 -0
  19. xun_agent-1.0.0/src/xun/command.py +260 -0
  20. xun_agent-1.0.0/src/xun/compact.py +182 -0
  21. xun_agent-1.0.0/src/xun/config.py +190 -0
  22. xun_agent-1.0.0/src/xun/conversation.py +453 -0
  23. xun_agent-1.0.0/src/xun/display_abstract.py +306 -0
  24. xun_agent-1.0.0/src/xun/displays/__init__.py +14 -0
  25. xun_agent-1.0.0/src/xun/displays/display.py +191 -0
  26. xun_agent-1.0.0/src/xun/displays/null_display.py +14 -0
  27. xun_agent-1.0.0/src/xun/displays/web_display.py +361 -0
  28. xun_agent-1.0.0/src/xun/displays/web_file.py +319 -0
  29. xun_agent-1.0.0/src/xun/displays/web_service.py +423 -0
  30. xun_agent-1.0.0/src/xun/entrypoint.py +355 -0
  31. xun_agent-1.0.0/src/xun/error_catch.py +37 -0
  32. xun_agent-1.0.0/src/xun/hooks.py +121 -0
  33. xun_agent-1.0.0/src/xun/loop.py +243 -0
  34. xun_agent-1.0.0/src/xun/openai_helper.py +75 -0
  35. xun_agent-1.0.0/src/xun/prompt.py +59 -0
  36. xun_agent-1.0.0/src/xun/running_state.py +85 -0
  37. xun_agent-1.0.0/src/xun/store.py +49 -0
  38. xun_agent-1.0.0/src/xun/supervisor/__init__.py +3 -0
  39. xun_agent-1.0.0/src/xun/supervisor/cli.py +93 -0
  40. xun_agent-1.0.0/src/xun/supervisor/runtime.py +214 -0
  41. xun_agent-1.0.0/src/xun/supervisor/service.py +236 -0
  42. xun_agent-1.0.0/src/xun/supervisor/users.py +73 -0
  43. xun_agent-1.0.0/src/xun/toolbox.py +167 -0
  44. xun_agent-1.0.0/src/xun/toolcall.py +202 -0
  45. xun_agent-1.0.0/src/xun/tools/__init__.py +26 -0
  46. xun_agent-1.0.0/src/xun/tools/_extra.py +68 -0
  47. xun_agent-1.0.0/src/xun/tools/agent_factory.py +118 -0
  48. xun_agent-1.0.0/src/xun/tools/browser.py +788 -0
  49. xun_agent-1.0.0/src/xun/tools/cmd.py +604 -0
  50. xun_agent-1.0.0/src/xun/tools/common.py +272 -0
  51. xun_agent-1.0.0/src/xun/tools/diagnostic.py +152 -0
  52. xun_agent-1.0.0/src/xun/tools/framework.py +54 -0
  53. xun_agent-1.0.0/src/xun/tools/fs.py +441 -0
  54. xun_agent-1.0.0/src/xun/tools/patch.py +274 -0
  55. xun_agent-1.0.0/src/xun/tools/search.py +263 -0
  56. xun_agent-1.0.0/src/xun/tools/system.py +50 -0
  57. xun_agent-1.0.0/src/xun/types.py +93 -0
  58. xun_agent-1.0.0/src/xun/util.py +109 -0
  59. xun_agent-1.0.0/src/xun/workspace.py +103 -0
@@ -0,0 +1,216 @@
1
+ Metadata-Version: 2.3
2
+ Name: xun-agent
3
+ Version: 1.0.0
4
+ Summary: An autonomous mini LLM agent with tooling.
5
+ Keywords: agent,llm,llm-agent
6
+ Author: limengxun
7
+ Author-email: limengxun <limengxun45@outlook.com>
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: Programming Language :: Python :: 3.12
10
+ Requires-Dist: aiohttp>=3.12.0
11
+ Requires-Dist: docker>=7.1.0
12
+ Requires-Dist: html-to-markdown>=3.12.2
13
+ Requires-Dist: jinja2>=3.1.6
14
+ Requires-Dist: json-repair>=0.63.4
15
+ Requires-Dist: markdown>=3.10.3
16
+ Requires-Dist: openai>=3.8.0
17
+ Requires-Dist: pillow>=12.3.0
18
+ Requires-Dist: playwright>=1.62.0
19
+ Requires-Dist: puremagic>=2.2.0
20
+ Requires-Dist: pydantic>=2.13.5
21
+ Requires-Dist: python-dotenv>=1.2.3
22
+ Requires-Dist: rich>=15.0.0
23
+ Requires-Dist: typing-extensions>=4.16.0
24
+ Requires-Dist: fastapi[standard]>=0.141.1
25
+ Requires-Python: >=3.12
26
+ Description-Content-Type: text/markdown
27
+
28
+ # Xun
29
+
30
+ A mini LLM agent framework with function-based tools and sub-agent spawning.
31
+
32
+ The core codebase is compact: about 3000 lines in `src/xun/*.py` (mostly hand written), with comprehensive type hints.
33
+
34
+ <!-- <details>
35
+ <summary>Why this name?</summary>
36
+
37
+ 取此名称有两点考虑。其一是技术含义:智能体的执行过程本身即一种搜索,在可
38
+ 用工具与不断变化的会话状态中检索、试探与回退,直至任务收敛,模型侧的优化
39
+ 过程同样可作此理解;其同音字“询”对应以对话问询驱动的交互方式,“训”对应以
40
+ 指令与工具配置约束并扩展智能体行为的方式。
41
+
42
+ 其二是使用便利:xun 为单音节三字母拼音,在命令行中无需切换输入法即可连续
43
+ 键入,符合本软件以命令行与终端交互为主要入口的使用习惯。
44
+
45
+ </details> -->
46
+
47
+
48
+ ## Quick Start
49
+
50
+ Requires Python 3.12+ (PEP 695)
51
+
52
+ ```bash
53
+ # 1. Install dependencies
54
+ pip install git+https://github.com/MenxLi/xun.git
55
+
56
+ # 2. Install Playwright browsers (if using the default browser tools)
57
+ playwright install
58
+
59
+ # 3. Configure environment variables (see `Configuration` section below)
60
+ vim .env
61
+
62
+ # 4. Run the agent in interactive mode
63
+ xun
64
+ ```
65
+
66
+ Optionally, run the agent in web mode:
67
+ ```sh
68
+ # - Build the web frontend (if using the web display)
69
+ make build-web
70
+ # - Start the web server at current directory
71
+ xuns .
72
+ # - Use a temporary workspace instead
73
+ xuns
74
+ ```
75
+
76
+ `xuns` accepts at most one workspace directory: every session shares it, or each session gets its own temporary workspace if omitted. Session management is on by default; disable it with `--no-manage-sessions`.
77
+
78
+ ## Usage
79
+
80
+
81
+ **Basic**: Quickly set up an agent with plain functions as tools — no decorators, no classes needed.
82
+
83
+ ```python
84
+ from xun import setup_agent
85
+
86
+ def add(a: int, b: int) -> int:
87
+ """Add two numbers."""
88
+ return a + b
89
+
90
+ agent = setup_agent(tools = [add])
91
+ agent.instruct("Add 2 and 3.").execute()
92
+ ```
93
+
94
+ **Advanced**: The framework is flexible and extensible.
95
+ Additional features are shown in [demo.ipynb](demo.ipynb), including:
96
+ - `Agent` configuration
97
+ - Display extension
98
+ - Output validation
99
+ - Tool attributes
100
+ - Context injection
101
+ - Type-state transition
102
+ - Sub-agent spawning
103
+ - Lifecycle hooks
104
+ - ...
105
+
106
+ Do check out [demo.ipynb](demo.ipynb) for detailed examples.
107
+
108
+ ## CLI
109
+
110
+ Run `xun` in your terminal to start an interactive session.
111
+ You can also pass a prompt as an argument to begin with a specific instruction.
112
+ ```bash
113
+ xun "Write a hello world python script and save it to hello.py"
114
+ ```
115
+
116
+ Image attachments are supported in the format of `[image:path_or_url]`. For example:
117
+ ```
118
+ >>> [image:cat.png image:https://example.com/dog.png] compare them.
119
+ ```
120
+
121
+ Input `/help` to see the full list of commands.
122
+
123
+ ## Web
124
+
125
+ `web_session` starts the same managed web experience available through `xuns`:
126
+
127
+ ```python
128
+ from xun import web_session
129
+
130
+ web_session(workdir=".", base_path="/xun", manage_sessions=True)
131
+ ```
132
+
133
+ `WebDisplay` provides lower-level access to the interactive web interface for custom service composition.
134
+ It can be used as a chat-based web application, or as a backend for other applications.
135
+
136
+ ```python
137
+ from xun import WebDisplay, WebDisplayService, setup_agent
138
+
139
+ display = WebDisplay(expose_files=True)
140
+ agent = setup_agent(display=display, default_tools=True)
141
+ service = WebDisplayService().mount("/", display)
142
+ service.start(blocking=True)
143
+ ```
144
+
145
+ Open any tokenized URL printed at startup; the query token is exchanged for an HttpOnly cookie, so the browser reaches every mounted display without logging in again. API clients can use `Authorization: Bearer <token>`. File browsing, upload, download, and deletion require `expose_files=True`.
146
+
147
+ Multiple displays can share one authenticated service, each keeping its own agents, event history, and file policy:
148
+
149
+ ```python
150
+ service = WebDisplayService()
151
+ service.mount("/research", research_display)
152
+ service.mount("/coding", coding_display)
153
+ service.start(blocking=True)
154
+ ```
155
+
156
+ `display.build_routes()` and `display.build_app()` do not add authentication — use `WebDisplayService`, or provide your own in a custom ASGI host.
157
+
158
+ ## Docker
159
+
160
+ ```bash
161
+ make build-docker # builds the web frontend, then the `xun` image
162
+
163
+ xunc # sandbox: temporary workspace inside the container
164
+ xunc . # bind mount the current directory as /workspace
165
+ xunc --copy . # copy the current directory into /workspace instead
166
+ ```
167
+
168
+ `xunc` runs `xuns --host 0.0.0.0` in the container and publishes port 18960 (bridge mode), so the web UI is reachable from the host at the tokenized URL printed at startup. Other options: `--exec CMD` (e.g. `--exec bash`), `--port LIST`, `--network host` (avoid on macOS — not reachable from a host browser), `--env PATTERNS` (extra env vars to forward; `XUN_*`/`_XUN_*` are always forwarded), `--image` / `--name`.
169
+
170
+ ### Multiplexed server
171
+
172
+ `xunx` runs one temporary container per registered user, proxied through one public server:
173
+
174
+ ```bash
175
+ xunx user-add alice # prints the access token
176
+ xunx user-list
177
+ xunx user-del alice # disconnects the user and removes its container
178
+ xunx serve --host 0.0.0.0 --port 18960 --port-range 20000-20100
179
+ ```
180
+
181
+ Open `http://localhost:18960/alice?token=TOKEN`. Users live in `$XUN_HOME/x/xunx.db`; container ports are drawn randomly from `--port-range` and bound to host loopback only. Workspaces are temporary, and managed containers are cleaned up on shutdown (stale ones on next start). `XUN_*`/`_XUN_*` env vars except `XUN_HOME` are forwarded into each container.
182
+
183
+ <details>
184
+ <summary>Frontend development</summary>
185
+ The frontend development command starts both the backend and Vite with Vue DevTools:
186
+
187
+ ```bash
188
+ cd web
189
+ npm install
190
+ npm run dev
191
+ ```
192
+
193
+ Open `http://127.0.0.1:5173`. Build a production bundle with `npm run build`. See [web/README.md](web/README.md) for connecting the UI to a separately managed backend.
194
+ </details>
195
+
196
+ ## Configuration
197
+
198
+ xun reads optional configuration from `.xun/config.json` (override the location with `XUN_HOME`); missing fields fall back to built-in defaults. Include only the fields you want to change, for example to override the model:
199
+
200
+ ```json
201
+ {
202
+ "model": {
203
+ "name": "my-model"
204
+ }
205
+ }
206
+ ```
207
+
208
+ The config supports `${XUN_...}` placeholders which are substituted from environment variables (e.g. `${XUN_OPENAI_API_KEY}`), so secrets can live in a `.env` file instead. A placeholder with no matching environment variable causes a startup error.
209
+
210
+ | Config field | Environment variable | Description |
211
+ |---|---|---|
212
+ | `provider.openai_base_url` | `${XUN_OPENAI_BASE_URL}` | OpenAI-compatible API endpoint. |
213
+ | `provider.openai_api_key` | `${XUN_OPENAI_API_KEY}` | API key. |
214
+ | `model.name` | `${XUN_OPENAI_MODEL}` (empty) | Model identifier. If the resolved value is empty, available models are auto-detected from the API. |
215
+
216
+ More configuration options are available; see the source code at [src/xun/config.py](src/xun/config.py).
@@ -0,0 +1,189 @@
1
+ # Xun
2
+
3
+ A mini LLM agent framework with function-based tools and sub-agent spawning.
4
+
5
+ The core codebase is compact: about 3000 lines in `src/xun/*.py` (mostly hand written), with comprehensive type hints.
6
+
7
+ <!-- <details>
8
+ <summary>Why this name?</summary>
9
+
10
+ 取此名称有两点考虑。其一是技术含义:智能体的执行过程本身即一种搜索,在可
11
+ 用工具与不断变化的会话状态中检索、试探与回退,直至任务收敛,模型侧的优化
12
+ 过程同样可作此理解;其同音字“询”对应以对话问询驱动的交互方式,“训”对应以
13
+ 指令与工具配置约束并扩展智能体行为的方式。
14
+
15
+ 其二是使用便利:xun 为单音节三字母拼音,在命令行中无需切换输入法即可连续
16
+ 键入,符合本软件以命令行与终端交互为主要入口的使用习惯。
17
+
18
+ </details> -->
19
+
20
+
21
+ ## Quick Start
22
+
23
+ Requires Python 3.12+ (PEP 695)
24
+
25
+ ```bash
26
+ # 1. Install dependencies
27
+ pip install git+https://github.com/MenxLi/xun.git
28
+
29
+ # 2. Install Playwright browsers (if using the default browser tools)
30
+ playwright install
31
+
32
+ # 3. Configure environment variables (see `Configuration` section below)
33
+ vim .env
34
+
35
+ # 4. Run the agent in interactive mode
36
+ xun
37
+ ```
38
+
39
+ Optionally, run the agent in web mode:
40
+ ```sh
41
+ # - Build the web frontend (if using the web display)
42
+ make build-web
43
+ # - Start the web server at current directory
44
+ xuns .
45
+ # - Use a temporary workspace instead
46
+ xuns
47
+ ```
48
+
49
+ `xuns` accepts at most one workspace directory: every session shares it, or each session gets its own temporary workspace if omitted. Session management is on by default; disable it with `--no-manage-sessions`.
50
+
51
+ ## Usage
52
+
53
+
54
+ **Basic**: Quickly set up an agent with plain functions as tools — no decorators, no classes needed.
55
+
56
+ ```python
57
+ from xun import setup_agent
58
+
59
+ def add(a: int, b: int) -> int:
60
+ """Add two numbers."""
61
+ return a + b
62
+
63
+ agent = setup_agent(tools = [add])
64
+ agent.instruct("Add 2 and 3.").execute()
65
+ ```
66
+
67
+ **Advanced**: The framework is flexible and extensible.
68
+ Additional features are shown in [demo.ipynb](demo.ipynb), including:
69
+ - `Agent` configuration
70
+ - Display extension
71
+ - Output validation
72
+ - Tool attributes
73
+ - Context injection
74
+ - Type-state transition
75
+ - Sub-agent spawning
76
+ - Lifecycle hooks
77
+ - ...
78
+
79
+ Do check out [demo.ipynb](demo.ipynb) for detailed examples.
80
+
81
+ ## CLI
82
+
83
+ Run `xun` in your terminal to start an interactive session.
84
+ You can also pass a prompt as an argument to begin with a specific instruction.
85
+ ```bash
86
+ xun "Write a hello world python script and save it to hello.py"
87
+ ```
88
+
89
+ Image attachments are supported in the format of `[image:path_or_url]`. For example:
90
+ ```
91
+ >>> [image:cat.png image:https://example.com/dog.png] compare them.
92
+ ```
93
+
94
+ Input `/help` to see the full list of commands.
95
+
96
+ ## Web
97
+
98
+ `web_session` starts the same managed web experience available through `xuns`:
99
+
100
+ ```python
101
+ from xun import web_session
102
+
103
+ web_session(workdir=".", base_path="/xun", manage_sessions=True)
104
+ ```
105
+
106
+ `WebDisplay` provides lower-level access to the interactive web interface for custom service composition.
107
+ It can be used as a chat-based web application, or as a backend for other applications.
108
+
109
+ ```python
110
+ from xun import WebDisplay, WebDisplayService, setup_agent
111
+
112
+ display = WebDisplay(expose_files=True)
113
+ agent = setup_agent(display=display, default_tools=True)
114
+ service = WebDisplayService().mount("/", display)
115
+ service.start(blocking=True)
116
+ ```
117
+
118
+ Open any tokenized URL printed at startup; the query token is exchanged for an HttpOnly cookie, so the browser reaches every mounted display without logging in again. API clients can use `Authorization: Bearer <token>`. File browsing, upload, download, and deletion require `expose_files=True`.
119
+
120
+ Multiple displays can share one authenticated service, each keeping its own agents, event history, and file policy:
121
+
122
+ ```python
123
+ service = WebDisplayService()
124
+ service.mount("/research", research_display)
125
+ service.mount("/coding", coding_display)
126
+ service.start(blocking=True)
127
+ ```
128
+
129
+ `display.build_routes()` and `display.build_app()` do not add authentication — use `WebDisplayService`, or provide your own in a custom ASGI host.
130
+
131
+ ## Docker
132
+
133
+ ```bash
134
+ make build-docker # builds the web frontend, then the `xun` image
135
+
136
+ xunc # sandbox: temporary workspace inside the container
137
+ xunc . # bind mount the current directory as /workspace
138
+ xunc --copy . # copy the current directory into /workspace instead
139
+ ```
140
+
141
+ `xunc` runs `xuns --host 0.0.0.0` in the container and publishes port 18960 (bridge mode), so the web UI is reachable from the host at the tokenized URL printed at startup. Other options: `--exec CMD` (e.g. `--exec bash`), `--port LIST`, `--network host` (avoid on macOS — not reachable from a host browser), `--env PATTERNS` (extra env vars to forward; `XUN_*`/`_XUN_*` are always forwarded), `--image` / `--name`.
142
+
143
+ ### Multiplexed server
144
+
145
+ `xunx` runs one temporary container per registered user, proxied through one public server:
146
+
147
+ ```bash
148
+ xunx user-add alice # prints the access token
149
+ xunx user-list
150
+ xunx user-del alice # disconnects the user and removes its container
151
+ xunx serve --host 0.0.0.0 --port 18960 --port-range 20000-20100
152
+ ```
153
+
154
+ Open `http://localhost:18960/alice?token=TOKEN`. Users live in `$XUN_HOME/x/xunx.db`; container ports are drawn randomly from `--port-range` and bound to host loopback only. Workspaces are temporary, and managed containers are cleaned up on shutdown (stale ones on next start). `XUN_*`/`_XUN_*` env vars except `XUN_HOME` are forwarded into each container.
155
+
156
+ <details>
157
+ <summary>Frontend development</summary>
158
+ The frontend development command starts both the backend and Vite with Vue DevTools:
159
+
160
+ ```bash
161
+ cd web
162
+ npm install
163
+ npm run dev
164
+ ```
165
+
166
+ Open `http://127.0.0.1:5173`. Build a production bundle with `npm run build`. See [web/README.md](web/README.md) for connecting the UI to a separately managed backend.
167
+ </details>
168
+
169
+ ## Configuration
170
+
171
+ xun reads optional configuration from `.xun/config.json` (override the location with `XUN_HOME`); missing fields fall back to built-in defaults. Include only the fields you want to change, for example to override the model:
172
+
173
+ ```json
174
+ {
175
+ "model": {
176
+ "name": "my-model"
177
+ }
178
+ }
179
+ ```
180
+
181
+ The config supports `${XUN_...}` placeholders which are substituted from environment variables (e.g. `${XUN_OPENAI_API_KEY}`), so secrets can live in a `.env` file instead. A placeholder with no matching environment variable causes a startup error.
182
+
183
+ | Config field | Environment variable | Description |
184
+ |---|---|---|
185
+ | `provider.openai_base_url` | `${XUN_OPENAI_BASE_URL}` | OpenAI-compatible API endpoint. |
186
+ | `provider.openai_api_key` | `${XUN_OPENAI_API_KEY}` | API key. |
187
+ | `model.name` | `${XUN_OPENAI_MODEL}` (empty) | Model identifier. If the resolved value is empty, available models are auto-detected from the API. |
188
+
189
+ More configuration options are available; see the source code at [src/xun/config.py](src/xun/config.py).
@@ -0,0 +1,54 @@
1
+ [project]
2
+ name = "xun-agent"
3
+ version = "1.0.0"
4
+ description = "An autonomous mini LLM agent with tooling."
5
+ readme = "README.md"
6
+ keywords = [
7
+ "agent",
8
+ "llm",
9
+ "llm-agent",
10
+ ]
11
+ classifiers = [
12
+ "Programming Language :: Python :: 3",
13
+ "Programming Language :: Python :: 3.12",
14
+ ]
15
+ requires-python = ">=3.12"
16
+ dependencies = [
17
+ "aiohttp>=3.12.0",
18
+ "docker>=7.1.0",
19
+ "html-to-markdown>=3.12.2",
20
+ "jinja2>=3.1.6",
21
+ "json-repair>=0.63.4",
22
+ "markdown>=3.10.3",
23
+ "openai>=3.8.0",
24
+ "pillow>=12.3.0",
25
+ "playwright>=1.62.0",
26
+ "puremagic>=2.2.0",
27
+ "pydantic>=2.13.5",
28
+ "python-dotenv>=1.2.3",
29
+ "rich>=15.0.0",
30
+ "typing-extensions>=4.16.0",
31
+ "fastapi[standard]>=0.141.1",
32
+ ]
33
+
34
+ [[project.authors]]
35
+ name = "limengxun"
36
+ email = "limengxun45@outlook.com"
37
+
38
+ [project.scripts]
39
+ xun = "xun:main"
40
+ xuns = "xun:main_serve"
41
+ xunc = "xun:main_container"
42
+ xunx = "xun.supervisor:main"
43
+
44
+ [[tool.uv.index]]
45
+ url = "https://pypi.tuna.tsinghua.edu.cn/simple"
46
+ default = true
47
+
48
+ [tool.uv.build-backend]
49
+ module-root = "src"
50
+ module-name = "xun"
51
+
52
+ [build-system]
53
+ requires = ["uv_build"]
54
+ build-backend = "uv_build"
@@ -0,0 +1,49 @@
1
+ [project]
2
+ name = "xun-agent"
3
+ version = "1.0.0"
4
+ description = "An autonomous mini LLM agent with tooling."
5
+ readme = "README.md"
6
+ keywords = ["agent", "llm", "llm-agent"]
7
+ classifiers = [
8
+ "Programming Language :: Python :: 3",
9
+ "Programming Language :: Python :: 3.12",
10
+ ]
11
+ authors = [
12
+ { name = "limengxun", email = "limengxun45@outlook.com" }
13
+ ]
14
+ requires-python = ">=3.12"
15
+ dependencies = [
16
+ "aiohttp>=3.12.0",
17
+ "docker>=7.1.0",
18
+ "html-to-markdown>=3.12.2",
19
+ "jinja2>=3.1.6",
20
+ "json-repair>=0.63.4",
21
+ "markdown>=3.10.3",
22
+ "openai>=3.8.0",
23
+ "pillow>=12.3.0",
24
+ "playwright>=1.62.0",
25
+ "puremagic>=2.2.0",
26
+ "pydantic>=2.13.5",
27
+ "python-dotenv>=1.2.3",
28
+ "rich>=15.0.0",
29
+ "typing-extensions>=4.16.0",
30
+ "fastapi[standard]>=0.141.1",
31
+ ]
32
+
33
+ [project.scripts]
34
+ xun = "xun:main"
35
+ xuns = "xun:main_serve"
36
+ xunc = "xun:main_container"
37
+ xunx = "xun.supervisor:main"
38
+
39
+ [[tool.uv.index]]
40
+ url = "https://pypi.tuna.tsinghua.edu.cn/simple"
41
+ default = true
42
+
43
+ [build-system]
44
+ requires = ["uv_build"]
45
+ build-backend = "uv_build"
46
+
47
+ [tool.uv.build-backend]
48
+ module-root = "src"
49
+ module-name = "xun"
@@ -0,0 +1,25 @@
1
+ from .entrypoint import setup_agent, interactive_session, web_session, main, main_serve, main_container
2
+ from .display_abstract import DisplayAbstract
3
+ from .displays import Display, NullDisplay, WebDisplay, WebDisplayService
4
+ from .types import Result, ToolResultType, ErrorInfo, CancelledError
5
+ from .hooks import HookArgs, Hooks
6
+ from .command import Command, CommandRegistry
7
+ from .compact import CompactorAbstract, AutoCompactor
8
+ from .toolbox import ToolBox, ToolCallContext
9
+ from .toolcall import tool_attr
10
+ from .config import AgentConfig
11
+ from .workspace import Workspace
12
+ from .agent import Agent
13
+
14
+ __all__ = [
15
+ "Agent", "AgentConfig",
16
+ "Workspace",
17
+ "tool_attr", "ToolBox", "ToolCallContext",
18
+ "DisplayAbstract", "Display", "NullDisplay", "WebDisplay", "WebDisplayService",
19
+ "Command", "CommandRegistry",
20
+ "HookArgs", "Hooks",
21
+ "CompactorAbstract", "AutoCompactor",
22
+ "setup_agent", "interactive_session", "web_session",
23
+ "main", "main_serve", "main_container",
24
+ "Result", "ToolResultType", "ErrorInfo", "CancelledError",
25
+ ]