orxt 0.1.0__py3-none-any.whl
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.
- orxt/agent/__init__.py +18 -0
- orxt/agent/_categories.py +29 -0
- orxt/agent/_loader.py +61 -0
- orxt/agent/_prompt.py +57 -0
- orxt/agent/_types.py +29 -0
- orxt/agent/py.typed +0 -0
- orxt/cli/__init__.py +0 -0
- orxt/cli/_cli.py +527 -0
- orxt/cli/_formatters.py +108 -0
- orxt/cli/py.typed +0 -0
- orxt/knowledge_module/__init__.py +26 -0
- orxt/knowledge_module/_cognee_import.py +20 -0
- orxt/knowledge_module/_config.py +25 -0
- orxt/knowledge_module/_freshness.py +34 -0
- orxt/knowledge_module/_ingest.py +68 -0
- orxt/knowledge_module/_retrieve.py +57 -0
- orxt/knowledge_module/_types.py +61 -0
- orxt/knowledge_module/py.typed +0 -0
- orxt/mcp/__init__.py +9 -0
- orxt/mcp/_server.py +383 -0
- orxt/mcp/_tools.py +239 -0
- orxt/mcp/py.typed +0 -0
- orxt/notepad/__init__.py +10 -0
- orxt/notepad/_reader.py +45 -0
- orxt/notepad/_types.py +5 -0
- orxt/notepad/py.typed +0 -0
- orxt/overseer/__init__.py +20 -0
- orxt/overseer/_autonomy.py +15 -0
- orxt/overseer/_handoff.py +65 -0
- orxt/overseer/_health.py +81 -0
- orxt/overseer/_inbox.py +28 -0
- orxt/overseer/_knowledge.py +73 -0
- orxt/overseer/_learning.py +95 -0
- orxt/overseer/_memory.py +169 -0
- orxt/overseer/_overseer.py +148 -0
- orxt/overseer/_tools.py +207 -0
- orxt/overseer/prompts/overseer_base.md +162 -0
- orxt/overseer/py.typed +0 -0
- orxt/protocols/__init__.py +94 -0
- orxt/protocols/_autonomy.py +46 -0
- orxt/protocols/_checks.py +51 -0
- orxt/protocols/_constraints.py +26 -0
- orxt/protocols/_errors.py +11 -0
- orxt/protocols/_events.py +113 -0
- orxt/protocols/_execution.py +70 -0
- orxt/protocols/_task.py +118 -0
- orxt/protocols/_tool.py +20 -0
- orxt/protocols/_tools.py +136 -0
- orxt/protocols/py.typed +0 -0
- orxt/scheduler/__init__.py +67 -0
- orxt/scheduler/_agent_execution.py +1177 -0
- orxt/scheduler/_base.py +346 -0
- orxt/scheduler/_enforcement.py +704 -0
- orxt/scheduler/_events.py +50 -0
- orxt/scheduler/_executor.py +1006 -0
- orxt/scheduler/_graph.py +130 -0
- orxt/scheduler/_lifecycle_handlers.py +338 -0
- orxt/scheduler/_loader.py +177 -0
- orxt/scheduler/_locks.py +28 -0
- orxt/scheduler/_overseer.py +636 -0
- orxt/scheduler/_services.py +79 -0
- orxt/scheduler/_task_dispatch.py +491 -0
- orxt/scheduler/_types.py +63 -0
- orxt/scheduler/_validator.py +181 -0
- orxt/scheduler/py.typed +0 -0
- orxt/secrets/__init__.py +3 -0
- orxt/secrets/_registry.py +39 -0
- orxt/secrets/py.typed +0 -0
- orxt/services/__init__.py +62 -0
- orxt/services/_config.py +37 -0
- orxt/services/_events.py +17 -0
- orxt/services/_inbox.py +49 -0
- orxt/services/_run.py +131 -0
- orxt/services/_trace.py +87 -0
- orxt/services/_validate.py +36 -0
- orxt/services/py.typed +0 -0
- orxt/session/__init__.py +13 -0
- orxt/session/_factory.py +56 -0
- orxt/session/_pricing.py +79 -0
- orxt/session/_session.py +243 -0
- orxt/session/py.typed +0 -0
- orxt/tool/__init__.py +91 -0
- orxt/tool/_consult_tool.py +120 -0
- orxt/tool/_exec_tool.py +124 -0
- orxt/tool/_git_tool.py +215 -0
- orxt/tool/_http_tool.py +129 -0
- orxt/tool/_notepad_tool.py +66 -0
- orxt/tool/_path.py +70 -0
- orxt/tool/_pipeline.py +123 -0
- orxt/tool/_preview.py +91 -0
- orxt/tool/_read_tools.py +853 -0
- orxt/tool/_shell_tool.py +147 -0
- orxt/tool/_task_tools.py +335 -0
- orxt/tool/_validation.py +23 -0
- orxt/tool/_write_integration.py +74 -0
- orxt/tool/_write_tools.py +433 -0
- orxt/tool/py.typed +0 -0
- orxt/trace/__init__.py +75 -0
- orxt/trace/_lock.py +54 -0
- orxt/trace/_reader.py +223 -0
- orxt/trace/_recovery.py +88 -0
- orxt/trace/_schema.py +310 -0
- orxt/trace/_transitions.py +57 -0
- orxt/trace/_types.py +120 -0
- orxt/trace/_writer.py +649 -0
- orxt/trace/py.typed +0 -0
- orxt/transport/__init__.py +45 -0
- orxt/transport/_events.py +131 -0
- orxt/transport/_provider.py +48 -0
- orxt/transport/_state_machine.py +23 -0
- orxt/transport/_transport.py +832 -0
- orxt/transport/providers/__init__.py +9 -0
- orxt/transport/providers/_anthropic.py +191 -0
- orxt/transport/providers/_openai.py +172 -0
- orxt/transport/py.typed +0 -0
- orxt/verify/__init__.py +29 -0
- orxt/verify/_execution.py +138 -0
- orxt/verify/_runner.py +49 -0
- orxt/verify/_types.py +23 -0
- orxt/verify/py.typed +0 -0
- orxt/write_safety/__init__.py +16 -0
- orxt/write_safety/_atomic.py +30 -0
- orxt/write_safety/_queue.py +39 -0
- orxt/write_safety/_replay.py +42 -0
- orxt/write_safety/_stale.py +72 -0
- orxt/write_safety/py.typed +0 -0
- orxt-0.1.0.dist-info/METADATA +16 -0
- orxt-0.1.0.dist-info/RECORD +131 -0
- orxt-0.1.0.dist-info/WHEEL +4 -0
- orxt-0.1.0.dist-info/entry_points.txt +2 -0
- orxt-0.1.0.dist-info/licenses/LICENSE +61 -0
orxt/agent/__init__.py
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from orxt.agent._categories import load_categories, resolve_category
|
|
4
|
+
from orxt.agent._loader import load_agent, load_agents
|
|
5
|
+
from orxt.agent._prompt import resolve_includes, resolve_prompt
|
|
6
|
+
from orxt.agent._types import Agent, ExecToolConfig, ShellConfig
|
|
7
|
+
|
|
8
|
+
__all__ = [
|
|
9
|
+
"Agent",
|
|
10
|
+
"ExecToolConfig",
|
|
11
|
+
"ShellConfig",
|
|
12
|
+
"load_agent",
|
|
13
|
+
"load_agents",
|
|
14
|
+
"load_categories",
|
|
15
|
+
"resolve_category",
|
|
16
|
+
"resolve_includes",
|
|
17
|
+
"resolve_prompt",
|
|
18
|
+
]
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import tomllib
|
|
4
|
+
from typing import TYPE_CHECKING
|
|
5
|
+
|
|
6
|
+
if TYPE_CHECKING:
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
|
|
9
|
+
from orxt.agent._types import Agent
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def load_categories(path: Path) -> dict[str, str]:
|
|
13
|
+
if not path.is_file():
|
|
14
|
+
msg = f"Categories file not found: {path}"
|
|
15
|
+
raise FileNotFoundError(msg)
|
|
16
|
+
with path.open("rb") as f:
|
|
17
|
+
data = tomllib.load(f)
|
|
18
|
+
if "categories" not in data:
|
|
19
|
+
msg = f"Missing [categories] section in {path}"
|
|
20
|
+
raise ValueError(msg)
|
|
21
|
+
categories: dict[str, str] = data["categories"]
|
|
22
|
+
return categories
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def resolve_category(agent: Agent, categories: dict[str, str]) -> str:
|
|
26
|
+
if agent.category not in categories:
|
|
27
|
+
msg = f"Unknown category: {agent.category}"
|
|
28
|
+
raise ValueError(msg)
|
|
29
|
+
return categories[agent.category]
|
orxt/agent/_loader.py
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import tomllib
|
|
4
|
+
from typing import TYPE_CHECKING, Any
|
|
5
|
+
|
|
6
|
+
from orxt.agent._prompt import resolve_includes
|
|
7
|
+
from orxt.agent._types import Agent
|
|
8
|
+
|
|
9
|
+
if TYPE_CHECKING:
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def load_agent(path: Path) -> Agent:
|
|
14
|
+
if not path.is_file():
|
|
15
|
+
msg = f"Agent file not found: {path}"
|
|
16
|
+
raise FileNotFoundError(msg)
|
|
17
|
+
with path.open("rb") as f:
|
|
18
|
+
data = tomllib.load(f)
|
|
19
|
+
|
|
20
|
+
agent_section: dict[str, Any] = dict(data.get("agent", {}))
|
|
21
|
+
if "tools" not in data:
|
|
22
|
+
msg = f"Missing [tools] section in {path}"
|
|
23
|
+
raise ValueError(msg)
|
|
24
|
+
tools_section: dict[str, Any] = data["tools"]
|
|
25
|
+
|
|
26
|
+
prompt_rel = agent_section.pop("prompt", "")
|
|
27
|
+
prompt_path = (path.parent / prompt_rel).resolve()
|
|
28
|
+
if not prompt_path.is_file():
|
|
29
|
+
msg = f"Prompt file not found: {prompt_path}"
|
|
30
|
+
raise FileNotFoundError(msg)
|
|
31
|
+
prompt_text = prompt_path.read_text()
|
|
32
|
+
prompt_text = resolve_includes(prompt_text, prompt_path.parent)
|
|
33
|
+
|
|
34
|
+
agent_section["prompt"] = prompt_text
|
|
35
|
+
if "allow" not in tools_section:
|
|
36
|
+
msg = f"Missing 'allow' key in [tools] section in {path}"
|
|
37
|
+
raise ValueError(msg)
|
|
38
|
+
unknown_keys = set(tools_section.keys()) - {"allow"}
|
|
39
|
+
if unknown_keys:
|
|
40
|
+
names = ", ".join(sorted(unknown_keys))
|
|
41
|
+
msg = f"Unknown keys in [tools] section: {names}"
|
|
42
|
+
raise ValueError(msg)
|
|
43
|
+
agent_section["allow"] = tools_section["allow"]
|
|
44
|
+
|
|
45
|
+
exec_configs: list[dict[str, Any]] = data.get("exec", [])
|
|
46
|
+
shell_section: dict[str, Any] | None = data.get("shell")
|
|
47
|
+
agent_section["exec_tools"] = exec_configs
|
|
48
|
+
agent_section["shell_config"] = shell_section
|
|
49
|
+
|
|
50
|
+
return Agent(**agent_section)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def load_agents(directory: Path) -> dict[str, Agent]:
|
|
54
|
+
agents: dict[str, Agent] = {}
|
|
55
|
+
for toml_path in sorted(directory.glob("*.toml")):
|
|
56
|
+
agent = load_agent(toml_path)
|
|
57
|
+
if agent.name in agents:
|
|
58
|
+
msg = f"Duplicate agent name: {agent.name}"
|
|
59
|
+
raise ValueError(msg)
|
|
60
|
+
agents[agent.name] = agent
|
|
61
|
+
return agents
|
orxt/agent/_prompt.py
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import re
|
|
4
|
+
from typing import TYPE_CHECKING
|
|
5
|
+
|
|
6
|
+
if TYPE_CHECKING:
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
|
|
9
|
+
_INCLUDE_RE = re.compile(r"\{include:([^}]+)\}")
|
|
10
|
+
_VAR_RE = re.compile(r"\{([a-zA-Z_][a-zA-Z0-9_]*)\}")
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def resolve_includes(template: str, base_dir: Path) -> str:
|
|
14
|
+
return _resolve_includes(template, base_dir, frozenset())
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def _resolve_includes(
|
|
18
|
+
template: str, base_dir: Path, seen: frozenset[Path]
|
|
19
|
+
) -> str:
|
|
20
|
+
def replacer(match: re.Match[str]) -> str:
|
|
21
|
+
rel_path = match.group(1)
|
|
22
|
+
abs_path = (base_dir / rel_path).resolve()
|
|
23
|
+
if abs_path in seen:
|
|
24
|
+
msg = f"Circular include detected: {abs_path}"
|
|
25
|
+
raise ValueError(msg)
|
|
26
|
+
if not abs_path.is_file():
|
|
27
|
+
msg = f"Include file not found: {abs_path}"
|
|
28
|
+
raise FileNotFoundError(msg)
|
|
29
|
+
content = abs_path.read_text()
|
|
30
|
+
return _resolve_includes(content, abs_path.parent, seen | {abs_path})
|
|
31
|
+
|
|
32
|
+
return _INCLUDE_RE.sub(replacer, template)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def resolve_prompt(template: str, variables: dict[str, str]) -> str:
|
|
36
|
+
placeholders = set(_VAR_RE.findall(template))
|
|
37
|
+
var_keys = set(variables.keys())
|
|
38
|
+
|
|
39
|
+
unresolved = placeholders - var_keys
|
|
40
|
+
if unresolved:
|
|
41
|
+
name = sorted(unresolved)[0]
|
|
42
|
+
msg = f"Unresolved placeholder: {{{name}}}"
|
|
43
|
+
raise ValueError(msg)
|
|
44
|
+
|
|
45
|
+
unused = var_keys - placeholders
|
|
46
|
+
if unused:
|
|
47
|
+
name = sorted(unused)[0]
|
|
48
|
+
msg = f"Unused variable: {name}"
|
|
49
|
+
raise ValueError(msg)
|
|
50
|
+
|
|
51
|
+
if not placeholders:
|
|
52
|
+
return template
|
|
53
|
+
|
|
54
|
+
def replacer(match: re.Match[str]) -> str:
|
|
55
|
+
return variables[match.group(1)]
|
|
56
|
+
|
|
57
|
+
return _VAR_RE.sub(replacer, template)
|
orxt/agent/_types.py
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from pydantic import BaseModel, ConfigDict
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class ExecToolConfig(BaseModel):
|
|
7
|
+
model_config = ConfigDict(frozen=True, strict=True, extra="forbid")
|
|
8
|
+
name: str
|
|
9
|
+
executable: str
|
|
10
|
+
description: str
|
|
11
|
+
timeout_ceiling: int = 300
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class ShellConfig(BaseModel):
|
|
15
|
+
model_config = ConfigDict(frozen=True, strict=True, extra="forbid")
|
|
16
|
+
allowed_binaries: list[str]
|
|
17
|
+
description: str = "Execute shell commands with whitelisted binaries"
|
|
18
|
+
timeout_ceiling: int = 300
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class Agent(BaseModel):
|
|
22
|
+
model_config = ConfigDict(frozen=True, strict=True, extra="forbid")
|
|
23
|
+
name: str
|
|
24
|
+
description: str
|
|
25
|
+
prompt: str
|
|
26
|
+
category: str
|
|
27
|
+
allow: list[str]
|
|
28
|
+
exec_tools: list[ExecToolConfig] = []
|
|
29
|
+
shell_config: ShellConfig | None = None
|
orxt/agent/py.typed
ADDED
|
File without changes
|
orxt/cli/__init__.py
ADDED
|
File without changes
|