operator-agent 0.2.0__tar.gz → 0.4.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.
- {operator_agent-0.2.0/src/operator_agent.egg-info → operator_agent-0.4.0}/PKG-INFO +1 -1
- {operator_agent-0.2.0 → operator_agent-0.4.0}/pyproject.toml +4 -1
- {operator_agent-0.2.0 → operator_agent-0.4.0}/src/operator_agent/cli.py +1 -0
- {operator_agent-0.2.0 → operator_agent-0.4.0}/src/operator_agent/core.py +23 -0
- {operator_agent-0.2.0 → operator_agent-0.4.0}/src/operator_agent/providers/codex.py +3 -0
- {operator_agent-0.2.0 → operator_agent-0.4.0}/src/operator_agent/providers/gemini.py +3 -0
- operator_agent-0.4.0/src/operator_agent/system_prompt.md +19 -0
- {operator_agent-0.2.0 → operator_agent-0.4.0}/src/operator_agent/transports/telegram.py +28 -0
- {operator_agent-0.2.0 → operator_agent-0.4.0/src/operator_agent.egg-info}/PKG-INFO +1 -1
- {operator_agent-0.2.0 → operator_agent-0.4.0}/src/operator_agent.egg-info/SOURCES.txt +1 -0
- {operator_agent-0.2.0 → operator_agent-0.4.0}/LICENSE +0 -0
- {operator_agent-0.2.0 → operator_agent-0.4.0}/README.md +0 -0
- {operator_agent-0.2.0 → operator_agent-0.4.0}/setup.cfg +0 -0
- {operator_agent-0.2.0 → operator_agent-0.4.0}/src/operator_agent/__init__.py +0 -0
- {operator_agent-0.2.0 → operator_agent-0.4.0}/src/operator_agent/config.py +0 -0
- {operator_agent-0.2.0 → operator_agent-0.4.0}/src/operator_agent/providers/__init__.py +0 -0
- {operator_agent-0.2.0 → operator_agent-0.4.0}/src/operator_agent/providers/claude.py +0 -0
- {operator_agent-0.2.0 → operator_agent-0.4.0}/src/operator_agent/transports/__init__.py +0 -0
- {operator_agent-0.2.0 → operator_agent-0.4.0}/src/operator_agent.egg-info/dependency_links.txt +0 -0
- {operator_agent-0.2.0 → operator_agent-0.4.0}/src/operator_agent.egg-info/entry_points.txt +0 -0
- {operator_agent-0.2.0 → operator_agent-0.4.0}/src/operator_agent.egg-info/requires.txt +0 -0
- {operator_agent-0.2.0 → operator_agent-0.4.0}/src/operator_agent.egg-info/top_level.txt +0 -0
- {operator_agent-0.2.0 → operator_agent-0.4.0}/tests/test_integration.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: operator-agent
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.0
|
|
4
4
|
Summary: Personal AI agent that bridges Telegram to CLI agents (Claude, Codex, Gemini) running on your machine.
|
|
5
5
|
Author-email: Gavin Vickery <gavin@geekforbrains.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "operator-agent"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.4.0"
|
|
4
4
|
description = "Personal AI agent that bridges Telegram to CLI agents (Claude, Codex, Gemini) running on your machine."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
license = "MIT"
|
|
@@ -40,6 +40,9 @@ build-backend = "setuptools.build_meta"
|
|
|
40
40
|
[tool.setuptools.packages.find]
|
|
41
41
|
where = ["src"]
|
|
42
42
|
|
|
43
|
+
[tool.setuptools.package-data]
|
|
44
|
+
operator_agent = ["system_prompt.md"]
|
|
45
|
+
|
|
43
46
|
[tool.ruff]
|
|
44
47
|
target-version = "py310"
|
|
45
48
|
line-length = 100
|
|
@@ -4,6 +4,7 @@ from __future__ import annotations
|
|
|
4
4
|
|
|
5
5
|
import asyncio
|
|
6
6
|
import contextlib
|
|
7
|
+
import importlib.resources
|
|
7
8
|
import json
|
|
8
9
|
import logging
|
|
9
10
|
import os
|
|
@@ -65,6 +66,28 @@ class Runtime:
|
|
|
65
66
|
"""Ensure config directory exists."""
|
|
66
67
|
os.makedirs(CONFIG_DIR, exist_ok=True)
|
|
67
68
|
|
|
69
|
+
def install_system_prompts(self):
|
|
70
|
+
"""Write CLAUDE.md / AGENTS.md / GEMINI.md into the working directory.
|
|
71
|
+
|
|
72
|
+
Each CLI agent reads its own convention file from the cwd to understand
|
|
73
|
+
its role and behaviour. We ship the canonical prompt as package data
|
|
74
|
+
and materialise it on every ``serve`` so it stays current across
|
|
75
|
+
package upgrades.
|
|
76
|
+
"""
|
|
77
|
+
source = importlib.resources.files("operator_agent").joinpath("system_prompt.md")
|
|
78
|
+
content = source.read_text(encoding="utf-8")
|
|
79
|
+
|
|
80
|
+
for name in ("CLAUDE.md", "AGENTS.md", "GEMINI.md"):
|
|
81
|
+
target = os.path.join(self.working_dir, name)
|
|
82
|
+
if os.path.exists(target):
|
|
83
|
+
continue
|
|
84
|
+
try:
|
|
85
|
+
with open(target, "w") as f:
|
|
86
|
+
f.write(content)
|
|
87
|
+
log.info("Wrote %s to %s", name, self.working_dir)
|
|
88
|
+
except OSError:
|
|
89
|
+
log.warning("Could not write %s to %s", name, self.working_dir, exc_info=True)
|
|
90
|
+
|
|
68
91
|
# --- State persistence ---
|
|
69
92
|
|
|
70
93
|
def save_state(self):
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Operator
|
|
2
|
+
|
|
3
|
+
Operator proxies messages from a chat platform (Telegram, Slack, etc.)
|
|
4
|
+
to a CLI agent (Claude, Codex, Gemini) running on the user's machine.
|
|
5
|
+
The user sends a message, Operator invokes your CLI, and your response
|
|
6
|
+
is sent back to the chat. You have full access to the machine you're
|
|
7
|
+
running on — act accordingly.
|
|
8
|
+
|
|
9
|
+
## Behaviour
|
|
10
|
+
|
|
11
|
+
- **Bias to action.** Attempt the task first; only ask questions when
|
|
12
|
+
you genuinely cannot proceed or when the action is destructive.
|
|
13
|
+
- **Confirm before destructive/irreversible actions only:** deleting
|
|
14
|
+
files or data, security-sensitive changes (credentials, permissions,
|
|
15
|
+
keys), force-pushing, or anything that affects shared/remote state.
|
|
16
|
+
- **Everything else:** just do it. Don't ask for permission to read
|
|
17
|
+
files, run commands, install tools, or explore the system.
|
|
18
|
+
- Get creative with shell commands or install new tools as needed.
|
|
19
|
+
- Control the desktop, keyboard and mouse if you have to. Take screenshots.
|
|
@@ -150,6 +150,7 @@ class TelegramTransport:
|
|
|
150
150
|
"!clear - Clear current provider session\n"
|
|
151
151
|
"!clear all - Clear all provider sessions\n"
|
|
152
152
|
"!restart - Restart the bot\n"
|
|
153
|
+
"!logs - Show last 25 log entries\n"
|
|
153
154
|
"!help - Show this message"
|
|
154
155
|
)
|
|
155
156
|
return
|
|
@@ -159,6 +160,10 @@ class TelegramTransport:
|
|
|
159
160
|
asyncio.get_event_loop().call_later(1, _restart)
|
|
160
161
|
return
|
|
161
162
|
|
|
163
|
+
if text == "!logs":
|
|
164
|
+
await self._handle_logs(update)
|
|
165
|
+
return
|
|
166
|
+
|
|
162
167
|
if text.startswith("!"):
|
|
163
168
|
await update.message.reply_text("Unknown command. Try !help")
|
|
164
169
|
return
|
|
@@ -414,3 +419,26 @@ class TelegramTransport:
|
|
|
414
419
|
rt.save_state()
|
|
415
420
|
msg = "Cleared all providers!" if clear_all else "Cleared current provider!"
|
|
416
421
|
await update.message.reply_text(f"{msg}\n" + "\n".join(parts))
|
|
422
|
+
|
|
423
|
+
async def _handle_logs(self, update: Update):
|
|
424
|
+
log_path = os.path.join(os.path.expanduser("~/.operator"), "operator.log")
|
|
425
|
+
if not os.path.exists(log_path):
|
|
426
|
+
await update.message.reply_text("No log file found.")
|
|
427
|
+
return
|
|
428
|
+
|
|
429
|
+
try:
|
|
430
|
+
with open(log_path, "rb") as f:
|
|
431
|
+
# Read last ~32KB to find the last 25 lines
|
|
432
|
+
f.seek(0, 2)
|
|
433
|
+
size = f.tell()
|
|
434
|
+
f.seek(max(0, size - 32768))
|
|
435
|
+
tail = f.read().decode(errors="replace")
|
|
436
|
+
|
|
437
|
+
lines = tail.splitlines()[-25:]
|
|
438
|
+
text = "\n".join(lines) if lines else "(empty)"
|
|
439
|
+
# Telegram message limit is 4096 chars
|
|
440
|
+
if len(text) > 4000:
|
|
441
|
+
text = text[-4000:]
|
|
442
|
+
await update.message.reply_text(text)
|
|
443
|
+
except Exception as exc:
|
|
444
|
+
await update.message.reply_text(f"Error reading logs: {exc}")
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: operator-agent
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.0
|
|
4
4
|
Summary: Personal AI agent that bridges Telegram to CLI agents (Claude, Codex, Gemini) running on your machine.
|
|
5
5
|
Author-email: Gavin Vickery <gavin@geekforbrains.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -5,6 +5,7 @@ src/operator_agent/__init__.py
|
|
|
5
5
|
src/operator_agent/cli.py
|
|
6
6
|
src/operator_agent/config.py
|
|
7
7
|
src/operator_agent/core.py
|
|
8
|
+
src/operator_agent/system_prompt.md
|
|
8
9
|
src/operator_agent.egg-info/PKG-INFO
|
|
9
10
|
src/operator_agent.egg-info/SOURCES.txt
|
|
10
11
|
src/operator_agent.egg-info/dependency_links.txt
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{operator_agent-0.2.0 → operator_agent-0.4.0}/src/operator_agent.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|