superresearch-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.
- superresearch_agent-0.1.0/PKG-INFO +241 -0
- superresearch_agent-0.1.0/README.md +229 -0
- superresearch_agent-0.1.0/facade/__init__.py +19 -0
- superresearch_agent-0.1.0/facade/__main__.py +4 -0
- superresearch_agent-0.1.0/facade/autostart.py +375 -0
- superresearch_agent-0.1.0/facade/branding.py +275 -0
- superresearch_agent-0.1.0/facade/bridge.py +1861 -0
- superresearch_agent-0.1.0/facade/cli.py +1358 -0
- superresearch_agent-0.1.0/facade/config.py +132 -0
- superresearch_agent-0.1.0/facade/connect.py +571 -0
- superresearch_agent-0.1.0/facade/devicelogin.py +111 -0
- superresearch_agent-0.1.0/facade/firestore_rest.py +424 -0
- superresearch_agent-0.1.0/facade/logsetup.py +94 -0
- superresearch_agent-0.1.0/facade/prefs.py +216 -0
- superresearch_agent-0.1.0/facade/runview.py +90 -0
- superresearch_agent-0.1.0/facade/session.py +259 -0
- superresearch_agent-0.1.0/facade/skill/SKILL.md +237 -0
- superresearch_agent-0.1.0/facade/skill/scripts/sr.py +736 -0
- superresearch_agent-0.1.0/facade/skill/scripts/sr_attention_poll.py +216 -0
- superresearch_agent-0.1.0/facade/store.py +144 -0
- superresearch_agent-0.1.0/facade/web/icons/chatgpt.png +0 -0
- superresearch_agent-0.1.0/facade/web/icons/claude.png +0 -0
- superresearch_agent-0.1.0/facade/web/icons/notebooklm.png +0 -0
- superresearch_agent-0.1.0/facade/web/login.html +535 -0
- superresearch_agent-0.1.0/pyproject.toml +40 -0
- superresearch_agent-0.1.0/setup.cfg +4 -0
- superresearch_agent-0.1.0/superresearch_agent.egg-info/PKG-INFO +241 -0
- superresearch_agent-0.1.0/superresearch_agent.egg-info/SOURCES.txt +55 -0
- superresearch_agent-0.1.0/superresearch_agent.egg-info/dependency_links.txt +1 -0
- superresearch_agent-0.1.0/superresearch_agent.egg-info/entry_points.txt +3 -0
- superresearch_agent-0.1.0/superresearch_agent.egg-info/requires.txt +6 -0
- superresearch_agent-0.1.0/superresearch_agent.egg-info/top_level.txt +1 -0
- superresearch_agent-0.1.0/tests/test_agent_session.py +317 -0
- superresearch_agent-0.1.0/tests/test_app_plane_unchanged.py +94 -0
- superresearch_agent-0.1.0/tests/test_autostart.py +185 -0
- superresearch_agent-0.1.0/tests/test_branding.py +145 -0
- superresearch_agent-0.1.0/tests/test_bridge.py +109 -0
- superresearch_agent-0.1.0/tests/test_bridge_csrf.py +138 -0
- superresearch_agent-0.1.0/tests/test_bridge_device.py +665 -0
- superresearch_agent-0.1.0/tests/test_bridge_remote_login.py +142 -0
- superresearch_agent-0.1.0/tests/test_bridge_routes.py +361 -0
- superresearch_agent-0.1.0/tests/test_bridge_shutdown.py +26 -0
- superresearch_agent-0.1.0/tests/test_cli_commands.py +760 -0
- superresearch_agent-0.1.0/tests/test_cli_parser.py +141 -0
- superresearch_agent-0.1.0/tests/test_config.py +22 -0
- superresearch_agent-0.1.0/tests/test_connect.py +519 -0
- superresearch_agent-0.1.0/tests/test_devicelogin.py +62 -0
- superresearch_agent-0.1.0/tests/test_e2e_lifecycle.py +209 -0
- superresearch_agent-0.1.0/tests/test_firestore_rest.py +314 -0
- superresearch_agent-0.1.0/tests/test_logsetup.py +65 -0
- superresearch_agent-0.1.0/tests/test_prefs.py +127 -0
- superresearch_agent-0.1.0/tests/test_runview.py +59 -0
- superresearch_agent-0.1.0/tests/test_session.py +92 -0
- superresearch_agent-0.1.0/tests/test_session_custom_token.py +111 -0
- superresearch_agent-0.1.0/tests/test_sr_client.py +446 -0
- superresearch_agent-0.1.0/tests/test_sr_stream.py +189 -0
- superresearch_agent-0.1.0/tests/test_store.py +35 -0
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: superresearch-agent
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Install Super Research into a chat runtime (Hermes / OpenClaw) with `uvx superresearch-agent connect` — an account-authed loopback bridge that drives the user's own Super Research from chat.
|
|
5
|
+
Requires-Python: >=3.11
|
|
6
|
+
Description-Content-Type: text/markdown
|
|
7
|
+
Requires-Dist: requests>=2.31
|
|
8
|
+
Requires-Dist: keyring>=24
|
|
9
|
+
Provides-Extra: dev
|
|
10
|
+
Requires-Dist: pytest>=8; extra == "dev"
|
|
11
|
+
Requires-Dist: ruff>=0.5; extra == "dev"
|
|
12
|
+
|
|
13
|
+
# Super Agent — drive Super Research from chat (Hermes / OpenClaw)
|
|
14
|
+
|
|
15
|
+
Lets a chat runtime (Hermes / OpenClaw) drive **Super Research** as a *headless
|
|
16
|
+
session of your account*. You sign in once with Google (`/sr login`); the bridge
|
|
17
|
+
then enqueues research runs on your account's existing devices, and every run
|
|
18
|
+
shows up in the web app like a normal chat.
|
|
19
|
+
|
|
20
|
+
- **Research-only.** It can run / track / fetch research. It can **never**
|
|
21
|
+
control devices (add / remove / pair / share) — that stays owner-only.
|
|
22
|
+
- **One agent per account** (owner or sharer).
|
|
23
|
+
- **No dedicated worker, no separate logins, no identity minting.** It uses the
|
|
24
|
+
account's existing devices, on the app's normal Firestore plane.
|
|
25
|
+
|
|
26
|
+
Design source of truth: `../SuperAgentRecipe.md`.
|
|
27
|
+
|
|
28
|
+
## The "nothing breaks" contract
|
|
29
|
+
|
|
30
|
+
This package is a **separate process** and never touches the existing app:
|
|
31
|
+
|
|
32
|
+
- No import of, or write to, `research-automate` or `research-app`.
|
|
33
|
+
- Its own secret-store namespace (`super-agent`, `~/.super-agent`) — **never**
|
|
34
|
+
the device daemon's `super-research` keystore. The account refresh token and
|
|
35
|
+
the device refresh token are different Firebase users; isolating them means a
|
|
36
|
+
refresh here can never disturb a paired device.
|
|
37
|
+
- Writes only what a normal account client may write under the **existing**
|
|
38
|
+
Firestore rules: research docs under your own tree + device-queue `start`
|
|
39
|
+
docs where you're a member. No rules change, no keystore change, no queue /
|
|
40
|
+
claim / pipeline change.
|
|
41
|
+
|
|
42
|
+
## Running it (no install)
|
|
43
|
+
|
|
44
|
+
Run the agent as a **`research.py` command** — same front door as the rest of
|
|
45
|
+
the backend, from the repo root, **no install and no editable mode**:
|
|
46
|
+
|
|
47
|
+
```sh
|
|
48
|
+
cd research-automate
|
|
49
|
+
python research.py agent <command> # e.g. agent connect / agent serve / agent login
|
|
50
|
+
python research.py --agent <command> # flag-style alias (consistent with --pair/--serve)
|
|
51
|
+
python research.py agent # bare → smart entry: status if set up, else connect
|
|
52
|
+
python research.py agent --help # the full command list
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
The agent's only deps (`requests`, `keyring`) already ship in the backend's
|
|
56
|
+
`requirements.txt`, so once the backend is set up (`pip install -r
|
|
57
|
+
requirements.txt`) there is **nothing extra to install**. Requires **Python
|
|
58
|
+
3.11+**.
|
|
59
|
+
|
|
60
|
+
> **Throughout this README, `agent <command>` is shorthand for
|
|
61
|
+
> `python research.py agent <command>`.**
|
|
62
|
+
|
|
63
|
+
The code itself lives in this isolated sub-package (`research-automate/agent/`,
|
|
64
|
+
its own process + its own two deps); `research.py` only *fronts* it so it's
|
|
65
|
+
invoked consistently — it never imports the package.
|
|
66
|
+
|
|
67
|
+
<details><summary>Optional — a bare <code>agent</code> command / dev setup</summary>
|
|
68
|
+
|
|
69
|
+
If you'd rather type a bare `agent` (outside the backend) or run the tests:
|
|
70
|
+
|
|
71
|
+
```sh
|
|
72
|
+
cd research-automate/agent
|
|
73
|
+
pip install . # adds a standalone `agent` command (entry point)
|
|
74
|
+
python -m facade <command> # or run module-style, no install
|
|
75
|
+
pip install .[dev] # + test deps (pytest, ruff)
|
|
76
|
+
pip install -r requirements-dev.txt
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
`requirements.txt` / `requirements-dev.txt` here mirror `pyproject.toml` for a
|
|
80
|
+
fresh venv. The `python research.py agent` path above needs none of this.
|
|
81
|
+
</details>
|
|
82
|
+
|
|
83
|
+
## Use it from chat (Hermes / OpenClaw)
|
|
84
|
+
|
|
85
|
+
Install the Super Research skill into your chat runtime, then drive everything
|
|
86
|
+
with slash commands:
|
|
87
|
+
|
|
88
|
+
```sh
|
|
89
|
+
cd research-automate
|
|
90
|
+
python research.py agent connect # branded 4-step flow; detects Windows + WSL runtimes
|
|
91
|
+
# step 4 offers to run the bridge in the background now + on every login
|
|
92
|
+
# then in chat: /reload-skills (once) → /sr login → approve on phone → /sr research <topic>
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
`agent connect` is an interactive, branded flow — **Detect → Choose → Install →
|
|
96
|
+
Go live** — that finds your chat runtime on **Windows** (`~/.hermes`,
|
|
97
|
+
`~/.openclaw`) *and* inside **WSL** (`\\wsl.localhost\<distro>\home\<user>\…`),
|
|
98
|
+
lets you pick when more than one is found, copies a small dependency-free skill
|
|
99
|
+
(a `SKILL.md` + a `scripts/sr.py` client that calls the bridge over loopback)
|
|
100
|
+
into the runtime's skills dir, and offers to pin the always-up bridge.
|
|
101
|
+
|
|
102
|
+
The runtime registers a skill as a single slash command (`/<skill-name>`), so the
|
|
103
|
+
skill is **`/sr`** and the action follows it: `/sr login`, `/sr research <topic>`,
|
|
104
|
+
`/sr status [id]`, `/sr device [use <id>]`, `/sr podcast [id]`, `/sr skip <id>
|
|
105
|
+
<phases>`, `/sr cancel <id>`, `/sr logout`; a bare **`/sr`** is the welcome / help.
|
|
106
|
+
Natural phrasing works too ("research Tesla 2025", "send me the podcast"). It's
|
|
107
|
+
research-only — it can never control devices.
|
|
108
|
+
|
|
109
|
+
> **After connecting, run `/reload-skills` once in your chat** (the gateway caches
|
|
110
|
+
> its skill scan) so `/sr` registers without restarting the runtime.
|
|
111
|
+
|
|
112
|
+
**Reachability — Model A: the bridge runs WITH the runtime.** The bridge binds
|
|
113
|
+
**loopback only**, so it can only be reached by a runtime on its *own* machine —
|
|
114
|
+
which is why `connect` co-locates the bridge with the chat runtime:
|
|
115
|
+
|
|
116
|
+
- **Co-located** (runtime native on the same OS as the bridge — Win+Win,
|
|
117
|
+
Linux+Linux, macOS+macOS) → shares loopback, **zero setup**.
|
|
118
|
+
- **WSL runtime** → the bridge must run **inside WSL** too. `connect` detects a
|
|
119
|
+
WSL runtime and **offers to run connect there for you** — `uvx
|
|
120
|
+
superresearch-agent connect` inside the distro (or prints the command, with a
|
|
121
|
+
`python research.py agent connect` backend-checkout fallback for before the
|
|
122
|
+
package is on PyPI). The bridge then shares WSL's loopback with the runtime —
|
|
123
|
+
no Windows↔WSL networking, no `.wslconfig`.
|
|
124
|
+
- **Different machine** → can't reach a loopback-only bridge → **unsupported by
|
|
125
|
+
design** (exposing the bridge on the network would break its security model).
|
|
126
|
+
|
|
127
|
+
> Each side-effecting step still waits for your Y — `connect` never installs or
|
|
128
|
+
> runs anything inside WSL on its own.
|
|
129
|
+
|
|
130
|
+
**Keep it always-up.** `resurrect` pins a windowless logon autostart (Windows
|
|
131
|
+
Scheduled Task) **and** starts the bridge now, so it returns after a reboot; the
|
|
132
|
+
account session + device selection persist, so a restart resumes without
|
|
133
|
+
re-login. `retire` is the inverse.
|
|
134
|
+
|
|
135
|
+
```sh
|
|
136
|
+
agent resurrect # background + on every login (windowless); starts it now too
|
|
137
|
+
agent retire # stop the background bridge + remove the logon pin
|
|
138
|
+
agent serve # foreground (this terminal) instead of background
|
|
139
|
+
agent stop # stop the running bridge
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
**Disconnect.** `agent disconnect` is a full teardown — it removes the skill from
|
|
143
|
+
the runtime **and** signs out (the CLI twin of the app's **Revoke**). Use
|
|
144
|
+
`agent retire` as well if you also want the background bridge gone.
|
|
145
|
+
|
|
146
|
+
## P0 — connect + prove the plane
|
|
147
|
+
|
|
148
|
+
```sh
|
|
149
|
+
agent serve # start the loopback bridge (127.0.0.1:9876)
|
|
150
|
+
agent login # sign in on the SR web app (superresearch.io); --local = host page
|
|
151
|
+
agent status # → "Signed in as you@…"
|
|
152
|
+
agent doctor # health + token-refresh + connectivity checks
|
|
153
|
+
agent verify # reads your researches + lists reachable devices
|
|
154
|
+
agent verify --enqueue --device <id> --topic "Tesla 2025" # starts a real run
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
`agent verify` (no `--enqueue`) is read-only. With `--enqueue` it creates a
|
|
158
|
+
research doc + a device-queue start doc — a real pipeline run that will appear
|
|
159
|
+
as an app chat.
|
|
160
|
+
|
|
161
|
+
## P1 — remote sign-in + operational logging
|
|
162
|
+
|
|
163
|
+
**Remote sign-in (no localhost needed).** Approve from your phone via the
|
|
164
|
+
Super Research web app — the bridge brokers an OAuth device-style flow and makes
|
|
165
|
+
only outbound calls (see `SuperAgentRecipe.md` §11a):
|
|
166
|
+
|
|
167
|
+
```sh
|
|
168
|
+
agent login --remote --runtime hermes
|
|
169
|
+
# → Open https://superresearch.io/connect-agent and enter code: AB-12
|
|
170
|
+
# (sign in to Super Research on your phone, tap Approve)
|
|
171
|
+
# ✓ Connected as you@…
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
**`agent login` now defaults to the web app** (`superresearch.io` — the same page as
|
|
175
|
+
`/sr login` from chat + the connect Step 4 "Sign in"), so sign-in is one consistent
|
|
176
|
+
flow everywhere. The local Google page (`http://localhost:9876/login`) is the
|
|
177
|
+
`agent login --local` host-local fallback for dev / no-network.
|
|
178
|
+
|
|
179
|
+
**Logging.** `agent serve` writes a durable, rotating operational log to
|
|
180
|
+
`~/.super-agent/bridge.log` (request + run-lifecycle lines; never a token).
|
|
181
|
+
Add `-v` / `--verbose` (before or after the subcommand) for DEBUG.
|
|
182
|
+
|
|
183
|
+
**Pick a device.** List the devices your account can reach and choose which one
|
|
184
|
+
runs your research (the selection persists across restarts in
|
|
185
|
+
`~/.super-agent/prefs.json`):
|
|
186
|
+
|
|
187
|
+
```sh
|
|
188
|
+
agent device # list (→ marks the selected one; (owned)/(shared))
|
|
189
|
+
agent device use <deviceId> # switch the target device
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
`agent research`/`/sr research` resolves the device as: an explicit id → your
|
|
193
|
+
selection → the sole reachable device → an error asking you to pick one.
|
|
194
|
+
|
|
195
|
+
**Run, track, cancel.**
|
|
196
|
+
|
|
197
|
+
```sh
|
|
198
|
+
agent research "Tesla 2025 outlook" # start a run → prints a run id immediately
|
|
199
|
+
agent runs # list recent runs (status + phase)
|
|
200
|
+
agent run [id] # one run's status + links (no id = latest)
|
|
201
|
+
agent watch [id] # stream per-phase links live until it finishes
|
|
202
|
+
agent skip <id> <phases…> # skip phases (1/3/4/5 or brief/podcast/video/report)
|
|
203
|
+
agent cancel <id> # stop a run (queued → dropped; running → stopped)
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
`agent skip` tunes the run's config (Brief / Podcast → `skippedPhases`; Video →
|
|
207
|
+
`videoEnabled` off; Report → `emailEnabled` off); the device applies it when each
|
|
208
|
+
phase is reached.
|
|
209
|
+
|
|
210
|
+
`agent watch` polls and prints each new link (Brief → ChatGPT/Gemini/Claude →
|
|
211
|
+
NotebookLM/Audio → YouTube → Doc) as the device produces it, then stops at a
|
|
212
|
+
terminal status. The same signal feeds a runtime's streaming cron via
|
|
213
|
+
`GET /updates` (account-wide active runs + their current links) — a poller
|
|
214
|
+
dedups by `(runId, kind)`. (No `?since=` watermark: the backend doesn't bump
|
|
215
|
+
`updatedAt` on a per-phase link write, so the current link set is returned every
|
|
216
|
+
poll and deduped client-side.) Cancel writes a single `action:"cancel"` to the
|
|
217
|
+
run's device queue — dropped if queued, stopped if running.
|
|
218
|
+
|
|
219
|
+
> The web app's broker routes (`/api/agent/login/{start,approve,poll}` +
|
|
220
|
+
> `/connect-agent`) are built separately under review; this package is only the
|
|
221
|
+
> outbound client.
|
|
222
|
+
|
|
223
|
+
## Layout
|
|
224
|
+
|
|
225
|
+
```
|
|
226
|
+
facade/
|
|
227
|
+
config.py public Firebase config + bridge host/port/store + FE base
|
|
228
|
+
store.py secure session store (keyring + 0600 file fallback)
|
|
229
|
+
prefs.py non-secret prefs (selected device [uid-bound], runtime)
|
|
230
|
+
session.py AccountSession — refresh-token / custom-token → ID-token
|
|
231
|
+
firestore_rest.py minimal Firestore REST (researches/devices, upsert, enqueue, cancel)
|
|
232
|
+
devicelogin.py remote-login device-flow client (→ the SR web app broker)
|
|
233
|
+
logsetup.py rotating-file + console logging (--verbose)
|
|
234
|
+
runview.py flatten links.{kind} → ordered events; terminal-status set
|
|
235
|
+
connect.py install the skill into a chat runtime
|
|
236
|
+
bridge.py loopback HTTP server (/login, /login/remote/*, /devices,
|
|
237
|
+
/device, /research, /updates, …)
|
|
238
|
+
web/login.html Firebase Web SDK Google sign-in (TOTP MFA aware)
|
|
239
|
+
skill/ the chat-runtime bundle (SKILL.md + scripts/sr.py)
|
|
240
|
+
cli.py the `agent` command
|
|
241
|
+
```
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
# Super Agent — drive Super Research from chat (Hermes / OpenClaw)
|
|
2
|
+
|
|
3
|
+
Lets a chat runtime (Hermes / OpenClaw) drive **Super Research** as a *headless
|
|
4
|
+
session of your account*. You sign in once with Google (`/sr login`); the bridge
|
|
5
|
+
then enqueues research runs on your account's existing devices, and every run
|
|
6
|
+
shows up in the web app like a normal chat.
|
|
7
|
+
|
|
8
|
+
- **Research-only.** It can run / track / fetch research. It can **never**
|
|
9
|
+
control devices (add / remove / pair / share) — that stays owner-only.
|
|
10
|
+
- **One agent per account** (owner or sharer).
|
|
11
|
+
- **No dedicated worker, no separate logins, no identity minting.** It uses the
|
|
12
|
+
account's existing devices, on the app's normal Firestore plane.
|
|
13
|
+
|
|
14
|
+
Design source of truth: `../SuperAgentRecipe.md`.
|
|
15
|
+
|
|
16
|
+
## The "nothing breaks" contract
|
|
17
|
+
|
|
18
|
+
This package is a **separate process** and never touches the existing app:
|
|
19
|
+
|
|
20
|
+
- No import of, or write to, `research-automate` or `research-app`.
|
|
21
|
+
- Its own secret-store namespace (`super-agent`, `~/.super-agent`) — **never**
|
|
22
|
+
the device daemon's `super-research` keystore. The account refresh token and
|
|
23
|
+
the device refresh token are different Firebase users; isolating them means a
|
|
24
|
+
refresh here can never disturb a paired device.
|
|
25
|
+
- Writes only what a normal account client may write under the **existing**
|
|
26
|
+
Firestore rules: research docs under your own tree + device-queue `start`
|
|
27
|
+
docs where you're a member. No rules change, no keystore change, no queue /
|
|
28
|
+
claim / pipeline change.
|
|
29
|
+
|
|
30
|
+
## Running it (no install)
|
|
31
|
+
|
|
32
|
+
Run the agent as a **`research.py` command** — same front door as the rest of
|
|
33
|
+
the backend, from the repo root, **no install and no editable mode**:
|
|
34
|
+
|
|
35
|
+
```sh
|
|
36
|
+
cd research-automate
|
|
37
|
+
python research.py agent <command> # e.g. agent connect / agent serve / agent login
|
|
38
|
+
python research.py --agent <command> # flag-style alias (consistent with --pair/--serve)
|
|
39
|
+
python research.py agent # bare → smart entry: status if set up, else connect
|
|
40
|
+
python research.py agent --help # the full command list
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
The agent's only deps (`requests`, `keyring`) already ship in the backend's
|
|
44
|
+
`requirements.txt`, so once the backend is set up (`pip install -r
|
|
45
|
+
requirements.txt`) there is **nothing extra to install**. Requires **Python
|
|
46
|
+
3.11+**.
|
|
47
|
+
|
|
48
|
+
> **Throughout this README, `agent <command>` is shorthand for
|
|
49
|
+
> `python research.py agent <command>`.**
|
|
50
|
+
|
|
51
|
+
The code itself lives in this isolated sub-package (`research-automate/agent/`,
|
|
52
|
+
its own process + its own two deps); `research.py` only *fronts* it so it's
|
|
53
|
+
invoked consistently — it never imports the package.
|
|
54
|
+
|
|
55
|
+
<details><summary>Optional — a bare <code>agent</code> command / dev setup</summary>
|
|
56
|
+
|
|
57
|
+
If you'd rather type a bare `agent` (outside the backend) or run the tests:
|
|
58
|
+
|
|
59
|
+
```sh
|
|
60
|
+
cd research-automate/agent
|
|
61
|
+
pip install . # adds a standalone `agent` command (entry point)
|
|
62
|
+
python -m facade <command> # or run module-style, no install
|
|
63
|
+
pip install .[dev] # + test deps (pytest, ruff)
|
|
64
|
+
pip install -r requirements-dev.txt
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
`requirements.txt` / `requirements-dev.txt` here mirror `pyproject.toml` for a
|
|
68
|
+
fresh venv. The `python research.py agent` path above needs none of this.
|
|
69
|
+
</details>
|
|
70
|
+
|
|
71
|
+
## Use it from chat (Hermes / OpenClaw)
|
|
72
|
+
|
|
73
|
+
Install the Super Research skill into your chat runtime, then drive everything
|
|
74
|
+
with slash commands:
|
|
75
|
+
|
|
76
|
+
```sh
|
|
77
|
+
cd research-automate
|
|
78
|
+
python research.py agent connect # branded 4-step flow; detects Windows + WSL runtimes
|
|
79
|
+
# step 4 offers to run the bridge in the background now + on every login
|
|
80
|
+
# then in chat: /reload-skills (once) → /sr login → approve on phone → /sr research <topic>
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
`agent connect` is an interactive, branded flow — **Detect → Choose → Install →
|
|
84
|
+
Go live** — that finds your chat runtime on **Windows** (`~/.hermes`,
|
|
85
|
+
`~/.openclaw`) *and* inside **WSL** (`\\wsl.localhost\<distro>\home\<user>\…`),
|
|
86
|
+
lets you pick when more than one is found, copies a small dependency-free skill
|
|
87
|
+
(a `SKILL.md` + a `scripts/sr.py` client that calls the bridge over loopback)
|
|
88
|
+
into the runtime's skills dir, and offers to pin the always-up bridge.
|
|
89
|
+
|
|
90
|
+
The runtime registers a skill as a single slash command (`/<skill-name>`), so the
|
|
91
|
+
skill is **`/sr`** and the action follows it: `/sr login`, `/sr research <topic>`,
|
|
92
|
+
`/sr status [id]`, `/sr device [use <id>]`, `/sr podcast [id]`, `/sr skip <id>
|
|
93
|
+
<phases>`, `/sr cancel <id>`, `/sr logout`; a bare **`/sr`** is the welcome / help.
|
|
94
|
+
Natural phrasing works too ("research Tesla 2025", "send me the podcast"). It's
|
|
95
|
+
research-only — it can never control devices.
|
|
96
|
+
|
|
97
|
+
> **After connecting, run `/reload-skills` once in your chat** (the gateway caches
|
|
98
|
+
> its skill scan) so `/sr` registers without restarting the runtime.
|
|
99
|
+
|
|
100
|
+
**Reachability — Model A: the bridge runs WITH the runtime.** The bridge binds
|
|
101
|
+
**loopback only**, so it can only be reached by a runtime on its *own* machine —
|
|
102
|
+
which is why `connect` co-locates the bridge with the chat runtime:
|
|
103
|
+
|
|
104
|
+
- **Co-located** (runtime native on the same OS as the bridge — Win+Win,
|
|
105
|
+
Linux+Linux, macOS+macOS) → shares loopback, **zero setup**.
|
|
106
|
+
- **WSL runtime** → the bridge must run **inside WSL** too. `connect` detects a
|
|
107
|
+
WSL runtime and **offers to run connect there for you** — `uvx
|
|
108
|
+
superresearch-agent connect` inside the distro (or prints the command, with a
|
|
109
|
+
`python research.py agent connect` backend-checkout fallback for before the
|
|
110
|
+
package is on PyPI). The bridge then shares WSL's loopback with the runtime —
|
|
111
|
+
no Windows↔WSL networking, no `.wslconfig`.
|
|
112
|
+
- **Different machine** → can't reach a loopback-only bridge → **unsupported by
|
|
113
|
+
design** (exposing the bridge on the network would break its security model).
|
|
114
|
+
|
|
115
|
+
> Each side-effecting step still waits for your Y — `connect` never installs or
|
|
116
|
+
> runs anything inside WSL on its own.
|
|
117
|
+
|
|
118
|
+
**Keep it always-up.** `resurrect` pins a windowless logon autostart (Windows
|
|
119
|
+
Scheduled Task) **and** starts the bridge now, so it returns after a reboot; the
|
|
120
|
+
account session + device selection persist, so a restart resumes without
|
|
121
|
+
re-login. `retire` is the inverse.
|
|
122
|
+
|
|
123
|
+
```sh
|
|
124
|
+
agent resurrect # background + on every login (windowless); starts it now too
|
|
125
|
+
agent retire # stop the background bridge + remove the logon pin
|
|
126
|
+
agent serve # foreground (this terminal) instead of background
|
|
127
|
+
agent stop # stop the running bridge
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
**Disconnect.** `agent disconnect` is a full teardown — it removes the skill from
|
|
131
|
+
the runtime **and** signs out (the CLI twin of the app's **Revoke**). Use
|
|
132
|
+
`agent retire` as well if you also want the background bridge gone.
|
|
133
|
+
|
|
134
|
+
## P0 — connect + prove the plane
|
|
135
|
+
|
|
136
|
+
```sh
|
|
137
|
+
agent serve # start the loopback bridge (127.0.0.1:9876)
|
|
138
|
+
agent login # sign in on the SR web app (superresearch.io); --local = host page
|
|
139
|
+
agent status # → "Signed in as you@…"
|
|
140
|
+
agent doctor # health + token-refresh + connectivity checks
|
|
141
|
+
agent verify # reads your researches + lists reachable devices
|
|
142
|
+
agent verify --enqueue --device <id> --topic "Tesla 2025" # starts a real run
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
`agent verify` (no `--enqueue`) is read-only. With `--enqueue` it creates a
|
|
146
|
+
research doc + a device-queue start doc — a real pipeline run that will appear
|
|
147
|
+
as an app chat.
|
|
148
|
+
|
|
149
|
+
## P1 — remote sign-in + operational logging
|
|
150
|
+
|
|
151
|
+
**Remote sign-in (no localhost needed).** Approve from your phone via the
|
|
152
|
+
Super Research web app — the bridge brokers an OAuth device-style flow and makes
|
|
153
|
+
only outbound calls (see `SuperAgentRecipe.md` §11a):
|
|
154
|
+
|
|
155
|
+
```sh
|
|
156
|
+
agent login --remote --runtime hermes
|
|
157
|
+
# → Open https://superresearch.io/connect-agent and enter code: AB-12
|
|
158
|
+
# (sign in to Super Research on your phone, tap Approve)
|
|
159
|
+
# ✓ Connected as you@…
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
**`agent login` now defaults to the web app** (`superresearch.io` — the same page as
|
|
163
|
+
`/sr login` from chat + the connect Step 4 "Sign in"), so sign-in is one consistent
|
|
164
|
+
flow everywhere. The local Google page (`http://localhost:9876/login`) is the
|
|
165
|
+
`agent login --local` host-local fallback for dev / no-network.
|
|
166
|
+
|
|
167
|
+
**Logging.** `agent serve` writes a durable, rotating operational log to
|
|
168
|
+
`~/.super-agent/bridge.log` (request + run-lifecycle lines; never a token).
|
|
169
|
+
Add `-v` / `--verbose` (before or after the subcommand) for DEBUG.
|
|
170
|
+
|
|
171
|
+
**Pick a device.** List the devices your account can reach and choose which one
|
|
172
|
+
runs your research (the selection persists across restarts in
|
|
173
|
+
`~/.super-agent/prefs.json`):
|
|
174
|
+
|
|
175
|
+
```sh
|
|
176
|
+
agent device # list (→ marks the selected one; (owned)/(shared))
|
|
177
|
+
agent device use <deviceId> # switch the target device
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
`agent research`/`/sr research` resolves the device as: an explicit id → your
|
|
181
|
+
selection → the sole reachable device → an error asking you to pick one.
|
|
182
|
+
|
|
183
|
+
**Run, track, cancel.**
|
|
184
|
+
|
|
185
|
+
```sh
|
|
186
|
+
agent research "Tesla 2025 outlook" # start a run → prints a run id immediately
|
|
187
|
+
agent runs # list recent runs (status + phase)
|
|
188
|
+
agent run [id] # one run's status + links (no id = latest)
|
|
189
|
+
agent watch [id] # stream per-phase links live until it finishes
|
|
190
|
+
agent skip <id> <phases…> # skip phases (1/3/4/5 or brief/podcast/video/report)
|
|
191
|
+
agent cancel <id> # stop a run (queued → dropped; running → stopped)
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
`agent skip` tunes the run's config (Brief / Podcast → `skippedPhases`; Video →
|
|
195
|
+
`videoEnabled` off; Report → `emailEnabled` off); the device applies it when each
|
|
196
|
+
phase is reached.
|
|
197
|
+
|
|
198
|
+
`agent watch` polls and prints each new link (Brief → ChatGPT/Gemini/Claude →
|
|
199
|
+
NotebookLM/Audio → YouTube → Doc) as the device produces it, then stops at a
|
|
200
|
+
terminal status. The same signal feeds a runtime's streaming cron via
|
|
201
|
+
`GET /updates` (account-wide active runs + their current links) — a poller
|
|
202
|
+
dedups by `(runId, kind)`. (No `?since=` watermark: the backend doesn't bump
|
|
203
|
+
`updatedAt` on a per-phase link write, so the current link set is returned every
|
|
204
|
+
poll and deduped client-side.) Cancel writes a single `action:"cancel"` to the
|
|
205
|
+
run's device queue — dropped if queued, stopped if running.
|
|
206
|
+
|
|
207
|
+
> The web app's broker routes (`/api/agent/login/{start,approve,poll}` +
|
|
208
|
+
> `/connect-agent`) are built separately under review; this package is only the
|
|
209
|
+
> outbound client.
|
|
210
|
+
|
|
211
|
+
## Layout
|
|
212
|
+
|
|
213
|
+
```
|
|
214
|
+
facade/
|
|
215
|
+
config.py public Firebase config + bridge host/port/store + FE base
|
|
216
|
+
store.py secure session store (keyring + 0600 file fallback)
|
|
217
|
+
prefs.py non-secret prefs (selected device [uid-bound], runtime)
|
|
218
|
+
session.py AccountSession — refresh-token / custom-token → ID-token
|
|
219
|
+
firestore_rest.py minimal Firestore REST (researches/devices, upsert, enqueue, cancel)
|
|
220
|
+
devicelogin.py remote-login device-flow client (→ the SR web app broker)
|
|
221
|
+
logsetup.py rotating-file + console logging (--verbose)
|
|
222
|
+
runview.py flatten links.{kind} → ordered events; terminal-status set
|
|
223
|
+
connect.py install the skill into a chat runtime
|
|
224
|
+
bridge.py loopback HTTP server (/login, /login/remote/*, /devices,
|
|
225
|
+
/device, /research, /updates, …)
|
|
226
|
+
web/login.html Firebase Web SDK Google sign-in (TOTP MFA aware)
|
|
227
|
+
skill/ the chat-runtime bundle (SKILL.md + scripts/sr.py)
|
|
228
|
+
cli.py the `agent` command
|
|
229
|
+
```
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"""research-facade — the Super Agent bridge.
|
|
2
|
+
|
|
3
|
+
A standalone, account-authed client on Super Research's normal Firestore
|
|
4
|
+
plane. It lets a chat runtime (Hermes / OpenClaw) drive Super Research as a
|
|
5
|
+
*headless session of the user's account*: the user signs in once with Google
|
|
6
|
+
(`/login`), and the bridge then enqueues research runs on the account's
|
|
7
|
+
existing devices. Runs surface in the web app as normal chats.
|
|
8
|
+
|
|
9
|
+
Hard boundaries (the "nothing breaks" contract):
|
|
10
|
+
* This package NEVER imports or mutates research-automate or research-app.
|
|
11
|
+
* It uses its OWN secret store namespace ("super-agent"), never the device
|
|
12
|
+
daemon's keystore ("super-research") — so refresh-token rotation here can
|
|
13
|
+
never disturb a paired device.
|
|
14
|
+
* It writes only what a normal account client may write (research docs +
|
|
15
|
+
device-queue start docs), all gated by the existing Firestore rules.
|
|
16
|
+
* Research-only: it can never control devices (add/remove/pair/share).
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
__version__ = "0.0.1"
|