ene-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.
- ene_agent-0.1.0/LICENSE +21 -0
- ene_agent-0.1.0/PKG-INFO +90 -0
- ene_agent-0.1.0/README.md +58 -0
- ene_agent-0.1.0/ene/__init__.py +5 -0
- ene_agent-0.1.0/ene/api.py +107 -0
- ene_agent-0.1.0/ene/backend/__init__.py +1716 -0
- ene_agent-0.1.0/ene/backend/batch.py +107 -0
- ene_agent-0.1.0/ene/backend/commands.py +806 -0
- ene_agent-0.1.0/ene/backend/sessions.py +578 -0
- ene_agent-0.1.0/ene/backend/skill_commands.py +191 -0
- ene_agent-0.1.0/ene/bundled_personas/chat/PERSONA.md +35 -0
- ene_agent-0.1.0/ene/bundled_personas/coder/PERSONA.md +38 -0
- ene_agent-0.1.0/ene/bundled_personas/orchestrator/PERSONA.md +284 -0
- ene_agent-0.1.0/ene/bundled_personas/reviewer/PERSONA.md +72 -0
- ene_agent-0.1.0/ene/bundled_skills/batch/SKILL.md +82 -0
- ene_agent-0.1.0/ene/bundled_skills/batch/tools.py +406 -0
- ene_agent-0.1.0/ene/bundled_skills/browser/SKILL.md +44 -0
- ene_agent-0.1.0/ene/bundled_skills/browser/tools.py +800 -0
- ene_agent-0.1.0/ene/bundled_skills/code-review/SKILL.md +46 -0
- ene_agent-0.1.0/ene/bundled_skills/lean/SKILL.md +49 -0
- ene_agent-0.1.0/ene/bundled_skills/library/SKILL.md +43 -0
- ene_agent-0.1.0/ene/bundled_skills/monitor/SKILL.md +57 -0
- ene_agent-0.1.0/ene/bundled_skills/pdf-reading/SKILL.md +61 -0
- ene_agent-0.1.0/ene/bundled_skills/pdf-reading/scripts/parse_pdf.py +195 -0
- ene_agent-0.1.0/ene/bundled_skills/persona-creator/SKILL.md +74 -0
- ene_agent-0.1.0/ene/bundled_skills/plan/SKILL.md +39 -0
- ene_agent-0.1.0/ene/bundled_skills/project-info/SKILL.md +43 -0
- ene_agent-0.1.0/ene/bundled_skills/skill-creator/SKILL.md +100 -0
- ene_agent-0.1.0/ene/bundled_skills/skill-creator/assets/SKILL.template.md +43 -0
- ene_agent-0.1.0/ene/bundled_skills/skill-creator/references/native-tools.md +70 -0
- ene_agent-0.1.0/ene/bundled_skills/skill-creator/references/skill-format.md +80 -0
- ene_agent-0.1.0/ene/bundled_skills/skill-creator/scripts/validate_skill.py +88 -0
- ene_agent-0.1.0/ene/bundled_skills/subagent/SKILL.md +116 -0
- ene_agent-0.1.0/ene/bundled_skills/subagent/scripts/run_subagent.py +83 -0
- ene_agent-0.1.0/ene/cli.py +543 -0
- ene_agent-0.1.0/ene/config.py +27 -0
- ene_agent-0.1.0/ene/context.py +1470 -0
- ene_agent-0.1.0/ene/frontend/dist/assets/index-RtdlPdeK.js +91 -0
- ene_agent-0.1.0/ene/frontend/dist/assets/index-qli6R3YA.css +1 -0
- ene_agent-0.1.0/ene/frontend/dist/favicon.svg +21 -0
- ene_agent-0.1.0/ene/frontend/dist/index.html +16 -0
- ene_agent-0.1.0/ene/hub.py +843 -0
- ene_agent-0.1.0/ene/hubclient.py +241 -0
- ene_agent-0.1.0/ene/library.py +674 -0
- ene_agent-0.1.0/ene/library_cli.py +206 -0
- ene_agent-0.1.0/ene/models.py +99 -0
- ene_agent-0.1.0/ene/personas.py +339 -0
- ene_agent-0.1.0/ene/providers/__init__.py +38 -0
- ene_agent-0.1.0/ene/providers/auth.py +127 -0
- ene_agent-0.1.0/ene/providers/openai_codex.py +581 -0
- ene_agent-0.1.0/ene/providers/openai_codex_oauth.py +384 -0
- ene_agent-0.1.0/ene/providers/openai_compatible.py +171 -0
- ene_agent-0.1.0/ene/providers/registry.py +41 -0
- ene_agent-0.1.0/ene/providers/types.py +118 -0
- ene_agent-0.1.0/ene/session_store.py +659 -0
- ene_agent-0.1.0/ene/skills.py +297 -0
- ene_agent-0.1.0/ene/terminal.py +817 -0
- ene_agent-0.1.0/ene/tools/__init__.py +78 -0
- ene_agent-0.1.0/ene/tools/builtin_descriptions.py +189 -0
- ene_agent-0.1.0/ene/tools/commands.py +262 -0
- ene_agent-0.1.0/ene/tools/constants.py +38 -0
- ene_agent-0.1.0/ene/tools/control.py +38 -0
- ene_agent-0.1.0/ene/tools/executor.py +153 -0
- ene_agent-0.1.0/ene/tools/files.py +466 -0
- ene_agent-0.1.0/ene/tools/formatting.py +247 -0
- ene_agent-0.1.0/ene/tools/process_manager.py +556 -0
- ene_agent-0.1.0/ene/tools/process_supervisor.py +116 -0
- ene_agent-0.1.0/ene/tools/process_util.py +210 -0
- ene_agent-0.1.0/ene/tools/registry.py +287 -0
- ene_agent-0.1.0/ene/tools/results.py +170 -0
- ene_agent-0.1.0/ene/tools/schemas.py +389 -0
- ene_agent-0.1.0/ene/tools/search.py +439 -0
- ene_agent-0.1.0/ene/tools/session.py +74 -0
- ene_agent-0.1.0/ene/tools/web.py +284 -0
- ene_agent-0.1.0/ene/ui.py +1443 -0
- ene_agent-0.1.0/ene/utils/__init__.py +5 -0
- ene_agent-0.1.0/ene/utils/frontmatter.py +34 -0
- ene_agent-0.1.0/ene/utils/interrupt.py +210 -0
- ene_agent-0.1.0/ene/utils/io.py +533 -0
- ene_agent-0.1.0/ene/utils/paths.py +19 -0
- ene_agent-0.1.0/ene/utils/persistence.py +97 -0
- ene_agent-0.1.0/ene/utils/rewind.py +177 -0
- ene_agent-0.1.0/ene/utils/storage.py +84 -0
- ene_agent-0.1.0/ene/utils/streaming.py +161 -0
- ene_agent-0.1.0/ene_agent.egg-info/PKG-INFO +90 -0
- ene_agent-0.1.0/ene_agent.egg-info/SOURCES.txt +114 -0
- ene_agent-0.1.0/ene_agent.egg-info/dependency_links.txt +1 -0
- ene_agent-0.1.0/ene_agent.egg-info/entry_points.txt +2 -0
- ene_agent-0.1.0/ene_agent.egg-info/requires.txt +17 -0
- ene_agent-0.1.0/ene_agent.egg-info/top_level.txt +1 -0
- ene_agent-0.1.0/pyproject.toml +56 -0
- ene_agent-0.1.0/setup.cfg +4 -0
- ene_agent-0.1.0/tests/test_api.py +133 -0
- ene_agent-0.1.0/tests/test_backend.py +1120 -0
- ene_agent-0.1.0/tests/test_batch.py +843 -0
- ene_agent-0.1.0/tests/test_cli.py +187 -0
- ene_agent-0.1.0/tests/test_cli_update.py +70 -0
- ene_agent-0.1.0/tests/test_codex.py +486 -0
- ene_agent-0.1.0/tests/test_completer.py +370 -0
- ene_agent-0.1.0/tests/test_config.py +33 -0
- ene_agent-0.1.0/tests/test_context_policy.py +562 -0
- ene_agent-0.1.0/tests/test_hub.py +318 -0
- ene_agent-0.1.0/tests/test_io.py +193 -0
- ene_agent-0.1.0/tests/test_library.py +249 -0
- ene_agent-0.1.0/tests/test_personas.py +268 -0
- ene_agent-0.1.0/tests/test_prompt_driver.py +124 -0
- ene_agent-0.1.0/tests/test_providers.py +165 -0
- ene_agent-0.1.0/tests/test_rewind_ui.py +227 -0
- ene_agent-0.1.0/tests/test_safety_context.py +1054 -0
- ene_agent-0.1.0/tests/test_session_store.py +507 -0
- ene_agent-0.1.0/tests/test_skills.py +303 -0
- ene_agent-0.1.0/tests/test_storage.py +83 -0
- ene_agent-0.1.0/tests/test_streaming.py +92 -0
- ene_agent-0.1.0/tests/test_subagent_skill.py +108 -0
- ene_agent-0.1.0/tests/test_tools.py +1216 -0
- ene_agent-0.1.0/tests/test_ui.py +289 -0
ene_agent-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 ashawkey
|
|
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.
|
ene_agent-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: ene-agent
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Terminal-based AI coding agent with reusable skills, personas, and a Web UI
|
|
5
|
+
Author: ashawkey
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/ashawkey/ene
|
|
8
|
+
Project-URL: Repository, https://github.com/ashawkey/ene
|
|
9
|
+
Project-URL: Issues, https://github.com/ashawkey/ene/issues
|
|
10
|
+
Project-URL: Documentation, https://ashawkey.github.io/ene/
|
|
11
|
+
Requires-Python: >=3.10
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
License-File: LICENSE
|
|
14
|
+
Requires-Dist: beautifulsoup4
|
|
15
|
+
Requires-Dist: ddgs
|
|
16
|
+
Requires-Dist: fastapi
|
|
17
|
+
Requires-Dist: filelock
|
|
18
|
+
Requires-Dist: httpcore
|
|
19
|
+
Requires-Dist: httpx[socks]
|
|
20
|
+
Requires-Dist: markdown-it-py
|
|
21
|
+
Requires-Dist: openai
|
|
22
|
+
Requires-Dist: pathspec
|
|
23
|
+
Requires-Dist: prompt-toolkit
|
|
24
|
+
Requires-Dist: pygments
|
|
25
|
+
Requires-Dist: pyyaml
|
|
26
|
+
Requires-Dist: questionary
|
|
27
|
+
Requires-Dist: rich
|
|
28
|
+
Requires-Dist: starlette
|
|
29
|
+
Requires-Dist: uvicorn
|
|
30
|
+
Requires-Dist: websockets
|
|
31
|
+
Dynamic: license-file
|
|
32
|
+
|
|
33
|
+
<p align="center">
|
|
34
|
+
<picture>
|
|
35
|
+
<img alt="logo" src="docs/public/favicon.svg" width="10%">
|
|
36
|
+
</picture>
|
|
37
|
+
</br>
|
|
38
|
+
<b>Ene</b>
|
|
39
|
+
</br>
|
|
40
|
+
<code>pip install ene-agent</code>
|
|
41
|
+
•
|
|
42
|
+
<a href="https://ene.kiui.moe/">Documentation</a>
|
|
43
|
+
</p>
|
|
44
|
+
|
|
45
|
+
An experimental agent harness for personal use.
|
|
46
|
+
It's as powerful as other modern agents, but also pythonic and educational for you to understand what happens behind each tool/skill.
|
|
47
|
+
|
|
48
|
+
## Features
|
|
49
|
+
|
|
50
|
+
- **Nothing is Unknown**: Explicit context and system prompt, no unexpected memory: You know the agent.
|
|
51
|
+
- **Skill-first Design**: Hierarhical skill loading makes the core small, but capacity large. Memory is also skill.
|
|
52
|
+
- **Optimized Bundled Skills**: Plan, review, clean up, create skills, background processes, pdf-reading, ...
|
|
53
|
+
- **Personal Skill Library**: Use a github repository to easily synchronize your skills.
|
|
54
|
+
- **Terminal-Native & Web UI**: Native terminal experience, while also attached to a modern web UI.
|
|
55
|
+
|
|
56
|
+
## Quick Start
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
pip install ene-agent
|
|
60
|
+
|
|
61
|
+
# or from github source
|
|
62
|
+
pip install git+https://github.com/ashawkey/ene.git
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Configure a model in `~/.ene.yaml`, then start chatting:
|
|
66
|
+
|
|
67
|
+
```yaml
|
|
68
|
+
openai: # openai-compatible
|
|
69
|
+
deepseek: # model alias
|
|
70
|
+
model: deepseek-v4-pro # model name
|
|
71
|
+
base_url: https://api.deepseek.com # base URL
|
|
72
|
+
api_key: ... # your API key
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
It also supports codex subscription login, please check the documentation for details.
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
ene # start the terminal UI to chat
|
|
79
|
+
ene --resume # resume a previous session
|
|
80
|
+
|
|
81
|
+
ene list # list available modelss
|
|
82
|
+
ene status # check the status of the .ene folder
|
|
83
|
+
ene clean # remove disposable data such as tool results and scratch files
|
|
84
|
+
ene clean --history # also remove saved conversation sessions
|
|
85
|
+
ene hub # start web UI hub (need to run in background)
|
|
86
|
+
ene update # update to the latest source code from github
|
|
87
|
+
ene lib # skill library management
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
WARNING: it has the same permission as the shell user and NO safety guard, use at your own risk.
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<picture>
|
|
3
|
+
<img alt="logo" src="docs/public/favicon.svg" width="10%">
|
|
4
|
+
</picture>
|
|
5
|
+
</br>
|
|
6
|
+
<b>Ene</b>
|
|
7
|
+
</br>
|
|
8
|
+
<code>pip install ene-agent</code>
|
|
9
|
+
•
|
|
10
|
+
<a href="https://ene.kiui.moe/">Documentation</a>
|
|
11
|
+
</p>
|
|
12
|
+
|
|
13
|
+
An experimental agent harness for personal use.
|
|
14
|
+
It's as powerful as other modern agents, but also pythonic and educational for you to understand what happens behind each tool/skill.
|
|
15
|
+
|
|
16
|
+
## Features
|
|
17
|
+
|
|
18
|
+
- **Nothing is Unknown**: Explicit context and system prompt, no unexpected memory: You know the agent.
|
|
19
|
+
- **Skill-first Design**: Hierarhical skill loading makes the core small, but capacity large. Memory is also skill.
|
|
20
|
+
- **Optimized Bundled Skills**: Plan, review, clean up, create skills, background processes, pdf-reading, ...
|
|
21
|
+
- **Personal Skill Library**: Use a github repository to easily synchronize your skills.
|
|
22
|
+
- **Terminal-Native & Web UI**: Native terminal experience, while also attached to a modern web UI.
|
|
23
|
+
|
|
24
|
+
## Quick Start
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
pip install ene-agent
|
|
28
|
+
|
|
29
|
+
# or from github source
|
|
30
|
+
pip install git+https://github.com/ashawkey/ene.git
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Configure a model in `~/.ene.yaml`, then start chatting:
|
|
34
|
+
|
|
35
|
+
```yaml
|
|
36
|
+
openai: # openai-compatible
|
|
37
|
+
deepseek: # model alias
|
|
38
|
+
model: deepseek-v4-pro # model name
|
|
39
|
+
base_url: https://api.deepseek.com # base URL
|
|
40
|
+
api_key: ... # your API key
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
It also supports codex subscription login, please check the documentation for details.
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
ene # start the terminal UI to chat
|
|
47
|
+
ene --resume # resume a previous session
|
|
48
|
+
|
|
49
|
+
ene list # list available modelss
|
|
50
|
+
ene status # check the status of the .ene folder
|
|
51
|
+
ene clean # remove disposable data such as tool results and scratch files
|
|
52
|
+
ene clean --history # also remove saved conversation sessions
|
|
53
|
+
ene hub # start web UI hub (need to run in background)
|
|
54
|
+
ene update # update to the latest source code from github
|
|
55
|
+
ene lib # skill library management
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
WARNING: it has the same permission as the shell user and NO safety guard, use at your own risk.
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
"""Public Python API for one-shot ene agent runs."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from contextlib import nullcontext
|
|
6
|
+
from dataclasses import dataclass
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
|
|
9
|
+
from ene.config import CONFIG_PATH, conf
|
|
10
|
+
from ene.backend import LLMAgent
|
|
11
|
+
from ene.models import ReasoningEffort
|
|
12
|
+
from ene.providers import provider_names
|
|
13
|
+
from ene.ui import AgentConsole
|
|
14
|
+
from ene.utils.interrupt import TurnOutcome
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@dataclass(frozen=True)
|
|
18
|
+
class AgentRunResult:
|
|
19
|
+
"""Result of a completed :func:`run_agent` invocation."""
|
|
20
|
+
|
|
21
|
+
response: str | None
|
|
22
|
+
outcome: TurnOutcome
|
|
23
|
+
token_usage: dict[str, int]
|
|
24
|
+
error: str | None = None
|
|
25
|
+
|
|
26
|
+
@property
|
|
27
|
+
def success(self) -> bool:
|
|
28
|
+
return self.outcome == TurnOutcome.COMPLETED
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def run_agent(
|
|
32
|
+
task: str,
|
|
33
|
+
*,
|
|
34
|
+
model_alias: str | None = None,
|
|
35
|
+
persona: str | None = None,
|
|
36
|
+
work_dir: str | Path | None = None,
|
|
37
|
+
reasoning_effort: ReasoningEffort | None = None,
|
|
38
|
+
stream: bool = False,
|
|
39
|
+
verbose: bool = False,
|
|
40
|
+
quiet: bool = True,
|
|
41
|
+
console: AgentConsole | None = None,
|
|
42
|
+
) -> AgentRunResult:
|
|
43
|
+
"""Run one independent, non-interactive agent task.
|
|
44
|
+
|
|
45
|
+
``model_alias`` selects an entry under ``openai`` in the loaded ene
|
|
46
|
+
configuration; omitting it selects the first configured model. The run has
|
|
47
|
+
a fresh conversation, does not create an interactive session or rewind
|
|
48
|
+
history, and always releases provider, process, and skill resources before
|
|
49
|
+
returning.
|
|
50
|
+
|
|
51
|
+
Progress output is suppressed by default. Pass ``quiet=False`` to observe
|
|
52
|
+
normal output, optionally through a custom ``console``. Configuration and
|
|
53
|
+
construction errors are raised; provider failures and interruptions are
|
|
54
|
+
represented by ``AgentRunResult.outcome``.
|
|
55
|
+
"""
|
|
56
|
+
if not isinstance(task, str) or not task.strip():
|
|
57
|
+
raise ValueError("task must be a non-empty string")
|
|
58
|
+
|
|
59
|
+
model_configs = conf.get("openai", {})
|
|
60
|
+
if not isinstance(model_configs, dict) or not model_configs:
|
|
61
|
+
raise ValueError(f"No models found in config: {CONFIG_PATH}")
|
|
62
|
+
|
|
63
|
+
alias = model_alias or next(iter(model_configs))
|
|
64
|
+
if alias not in model_configs:
|
|
65
|
+
available = ", ".join(model_configs)
|
|
66
|
+
raise ValueError(f"Model '{alias}' not found in config. Available: {available}")
|
|
67
|
+
|
|
68
|
+
model_conf = model_configs[alias]
|
|
69
|
+
provider_name = model_conf.get("provider", "openai")
|
|
70
|
+
if provider_name not in provider_names():
|
|
71
|
+
available = ", ".join(provider_names())
|
|
72
|
+
raise ValueError(f"Unknown provider '{provider_name}'. Available: {available}")
|
|
73
|
+
|
|
74
|
+
run_console = console or AgentConsole()
|
|
75
|
+
agent = LLMAgent(
|
|
76
|
+
model=model_conf.get("model", alias),
|
|
77
|
+
api_key=model_conf.get("api_key", ""),
|
|
78
|
+
base_url=model_conf.get("base_url", ""),
|
|
79
|
+
provider_name=provider_name,
|
|
80
|
+
model_alias=alias,
|
|
81
|
+
verbose=verbose,
|
|
82
|
+
stream=stream,
|
|
83
|
+
reasoning_effort=reasoning_effort
|
|
84
|
+
or model_conf.get("reasoning_effort", "high"),
|
|
85
|
+
context_length=model_conf.get("context_length"),
|
|
86
|
+
max_output_tokens=model_conf.get("max_output_tokens"),
|
|
87
|
+
persona=persona,
|
|
88
|
+
exec_mode=True,
|
|
89
|
+
work_dir=str(work_dir) if work_dir is not None else None,
|
|
90
|
+
console=run_console,
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
try:
|
|
94
|
+
output_context = run_console.suppressed() if quiet else nullcontext()
|
|
95
|
+
with output_context:
|
|
96
|
+
response = agent.execute(task)
|
|
97
|
+
return AgentRunResult(
|
|
98
|
+
response=response,
|
|
99
|
+
outcome=agent._last_turn_outcome,
|
|
100
|
+
token_usage=dict(agent.token_totals),
|
|
101
|
+
error=agent._last_error,
|
|
102
|
+
)
|
|
103
|
+
finally:
|
|
104
|
+
agent.close()
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
__all__ = ["AgentRunResult", "TurnOutcome", "run_agent"]
|