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.
Files changed (116) hide show
  1. ene_agent-0.1.0/LICENSE +21 -0
  2. ene_agent-0.1.0/PKG-INFO +90 -0
  3. ene_agent-0.1.0/README.md +58 -0
  4. ene_agent-0.1.0/ene/__init__.py +5 -0
  5. ene_agent-0.1.0/ene/api.py +107 -0
  6. ene_agent-0.1.0/ene/backend/__init__.py +1716 -0
  7. ene_agent-0.1.0/ene/backend/batch.py +107 -0
  8. ene_agent-0.1.0/ene/backend/commands.py +806 -0
  9. ene_agent-0.1.0/ene/backend/sessions.py +578 -0
  10. ene_agent-0.1.0/ene/backend/skill_commands.py +191 -0
  11. ene_agent-0.1.0/ene/bundled_personas/chat/PERSONA.md +35 -0
  12. ene_agent-0.1.0/ene/bundled_personas/coder/PERSONA.md +38 -0
  13. ene_agent-0.1.0/ene/bundled_personas/orchestrator/PERSONA.md +284 -0
  14. ene_agent-0.1.0/ene/bundled_personas/reviewer/PERSONA.md +72 -0
  15. ene_agent-0.1.0/ene/bundled_skills/batch/SKILL.md +82 -0
  16. ene_agent-0.1.0/ene/bundled_skills/batch/tools.py +406 -0
  17. ene_agent-0.1.0/ene/bundled_skills/browser/SKILL.md +44 -0
  18. ene_agent-0.1.0/ene/bundled_skills/browser/tools.py +800 -0
  19. ene_agent-0.1.0/ene/bundled_skills/code-review/SKILL.md +46 -0
  20. ene_agent-0.1.0/ene/bundled_skills/lean/SKILL.md +49 -0
  21. ene_agent-0.1.0/ene/bundled_skills/library/SKILL.md +43 -0
  22. ene_agent-0.1.0/ene/bundled_skills/monitor/SKILL.md +57 -0
  23. ene_agent-0.1.0/ene/bundled_skills/pdf-reading/SKILL.md +61 -0
  24. ene_agent-0.1.0/ene/bundled_skills/pdf-reading/scripts/parse_pdf.py +195 -0
  25. ene_agent-0.1.0/ene/bundled_skills/persona-creator/SKILL.md +74 -0
  26. ene_agent-0.1.0/ene/bundled_skills/plan/SKILL.md +39 -0
  27. ene_agent-0.1.0/ene/bundled_skills/project-info/SKILL.md +43 -0
  28. ene_agent-0.1.0/ene/bundled_skills/skill-creator/SKILL.md +100 -0
  29. ene_agent-0.1.0/ene/bundled_skills/skill-creator/assets/SKILL.template.md +43 -0
  30. ene_agent-0.1.0/ene/bundled_skills/skill-creator/references/native-tools.md +70 -0
  31. ene_agent-0.1.0/ene/bundled_skills/skill-creator/references/skill-format.md +80 -0
  32. ene_agent-0.1.0/ene/bundled_skills/skill-creator/scripts/validate_skill.py +88 -0
  33. ene_agent-0.1.0/ene/bundled_skills/subagent/SKILL.md +116 -0
  34. ene_agent-0.1.0/ene/bundled_skills/subagent/scripts/run_subagent.py +83 -0
  35. ene_agent-0.1.0/ene/cli.py +543 -0
  36. ene_agent-0.1.0/ene/config.py +27 -0
  37. ene_agent-0.1.0/ene/context.py +1470 -0
  38. ene_agent-0.1.0/ene/frontend/dist/assets/index-RtdlPdeK.js +91 -0
  39. ene_agent-0.1.0/ene/frontend/dist/assets/index-qli6R3YA.css +1 -0
  40. ene_agent-0.1.0/ene/frontend/dist/favicon.svg +21 -0
  41. ene_agent-0.1.0/ene/frontend/dist/index.html +16 -0
  42. ene_agent-0.1.0/ene/hub.py +843 -0
  43. ene_agent-0.1.0/ene/hubclient.py +241 -0
  44. ene_agent-0.1.0/ene/library.py +674 -0
  45. ene_agent-0.1.0/ene/library_cli.py +206 -0
  46. ene_agent-0.1.0/ene/models.py +99 -0
  47. ene_agent-0.1.0/ene/personas.py +339 -0
  48. ene_agent-0.1.0/ene/providers/__init__.py +38 -0
  49. ene_agent-0.1.0/ene/providers/auth.py +127 -0
  50. ene_agent-0.1.0/ene/providers/openai_codex.py +581 -0
  51. ene_agent-0.1.0/ene/providers/openai_codex_oauth.py +384 -0
  52. ene_agent-0.1.0/ene/providers/openai_compatible.py +171 -0
  53. ene_agent-0.1.0/ene/providers/registry.py +41 -0
  54. ene_agent-0.1.0/ene/providers/types.py +118 -0
  55. ene_agent-0.1.0/ene/session_store.py +659 -0
  56. ene_agent-0.1.0/ene/skills.py +297 -0
  57. ene_agent-0.1.0/ene/terminal.py +817 -0
  58. ene_agent-0.1.0/ene/tools/__init__.py +78 -0
  59. ene_agent-0.1.0/ene/tools/builtin_descriptions.py +189 -0
  60. ene_agent-0.1.0/ene/tools/commands.py +262 -0
  61. ene_agent-0.1.0/ene/tools/constants.py +38 -0
  62. ene_agent-0.1.0/ene/tools/control.py +38 -0
  63. ene_agent-0.1.0/ene/tools/executor.py +153 -0
  64. ene_agent-0.1.0/ene/tools/files.py +466 -0
  65. ene_agent-0.1.0/ene/tools/formatting.py +247 -0
  66. ene_agent-0.1.0/ene/tools/process_manager.py +556 -0
  67. ene_agent-0.1.0/ene/tools/process_supervisor.py +116 -0
  68. ene_agent-0.1.0/ene/tools/process_util.py +210 -0
  69. ene_agent-0.1.0/ene/tools/registry.py +287 -0
  70. ene_agent-0.1.0/ene/tools/results.py +170 -0
  71. ene_agent-0.1.0/ene/tools/schemas.py +389 -0
  72. ene_agent-0.1.0/ene/tools/search.py +439 -0
  73. ene_agent-0.1.0/ene/tools/session.py +74 -0
  74. ene_agent-0.1.0/ene/tools/web.py +284 -0
  75. ene_agent-0.1.0/ene/ui.py +1443 -0
  76. ene_agent-0.1.0/ene/utils/__init__.py +5 -0
  77. ene_agent-0.1.0/ene/utils/frontmatter.py +34 -0
  78. ene_agent-0.1.0/ene/utils/interrupt.py +210 -0
  79. ene_agent-0.1.0/ene/utils/io.py +533 -0
  80. ene_agent-0.1.0/ene/utils/paths.py +19 -0
  81. ene_agent-0.1.0/ene/utils/persistence.py +97 -0
  82. ene_agent-0.1.0/ene/utils/rewind.py +177 -0
  83. ene_agent-0.1.0/ene/utils/storage.py +84 -0
  84. ene_agent-0.1.0/ene/utils/streaming.py +161 -0
  85. ene_agent-0.1.0/ene_agent.egg-info/PKG-INFO +90 -0
  86. ene_agent-0.1.0/ene_agent.egg-info/SOURCES.txt +114 -0
  87. ene_agent-0.1.0/ene_agent.egg-info/dependency_links.txt +1 -0
  88. ene_agent-0.1.0/ene_agent.egg-info/entry_points.txt +2 -0
  89. ene_agent-0.1.0/ene_agent.egg-info/requires.txt +17 -0
  90. ene_agent-0.1.0/ene_agent.egg-info/top_level.txt +1 -0
  91. ene_agent-0.1.0/pyproject.toml +56 -0
  92. ene_agent-0.1.0/setup.cfg +4 -0
  93. ene_agent-0.1.0/tests/test_api.py +133 -0
  94. ene_agent-0.1.0/tests/test_backend.py +1120 -0
  95. ene_agent-0.1.0/tests/test_batch.py +843 -0
  96. ene_agent-0.1.0/tests/test_cli.py +187 -0
  97. ene_agent-0.1.0/tests/test_cli_update.py +70 -0
  98. ene_agent-0.1.0/tests/test_codex.py +486 -0
  99. ene_agent-0.1.0/tests/test_completer.py +370 -0
  100. ene_agent-0.1.0/tests/test_config.py +33 -0
  101. ene_agent-0.1.0/tests/test_context_policy.py +562 -0
  102. ene_agent-0.1.0/tests/test_hub.py +318 -0
  103. ene_agent-0.1.0/tests/test_io.py +193 -0
  104. ene_agent-0.1.0/tests/test_library.py +249 -0
  105. ene_agent-0.1.0/tests/test_personas.py +268 -0
  106. ene_agent-0.1.0/tests/test_prompt_driver.py +124 -0
  107. ene_agent-0.1.0/tests/test_providers.py +165 -0
  108. ene_agent-0.1.0/tests/test_rewind_ui.py +227 -0
  109. ene_agent-0.1.0/tests/test_safety_context.py +1054 -0
  110. ene_agent-0.1.0/tests/test_session_store.py +507 -0
  111. ene_agent-0.1.0/tests/test_skills.py +303 -0
  112. ene_agent-0.1.0/tests/test_storage.py +83 -0
  113. ene_agent-0.1.0/tests/test_streaming.py +92 -0
  114. ene_agent-0.1.0/tests/test_subagent_skill.py +108 -0
  115. ene_agent-0.1.0/tests/test_tools.py +1216 -0
  116. ene_agent-0.1.0/tests/test_ui.py +289 -0
@@ -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.
@@ -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
+ &nbsp;&nbsp;&bull;&nbsp;&nbsp;
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
+ &nbsp;&nbsp;&bull;&nbsp;&nbsp;
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,5 @@
1
+ """ene — terminal-based AI agent with tool-use, web access, and shell execution."""
2
+
3
+ from .api import AgentRunResult, TurnOutcome, run_agent
4
+
5
+ __all__ = ["AgentRunResult", "TurnOutcome", "run_agent"]
@@ -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"]