openvisio-agent 0.19.12 → 0.20.0
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.
- package/README.md +34 -4
- package/USER_GUIDE.md +174 -0
- package/bin/cli.mjs +9 -0
- package/package.json +7 -3
- package/scenarios/index.mjs +16 -0
- package/scenarios/routing.scenarios.mjs +348 -0
- package/scenarios/runtime.scenarios.mjs +451 -0
- package/scenarios/transport.scenarios.mjs +407 -0
- package/scenarios/workspace.scenarios.mjs +324 -0
- package/scripts/certify.mjs +9 -6
- package/scripts/run-scenarios.mjs +32 -0
- package/src/agent-journal.mjs +138 -0
- package/src/assignment-routing.mjs +19 -7
- package/src/authorization-resume.mjs +1 -1
- package/src/channel-routing.mjs +15 -8
- package/src/codex-mcp-proxy.mjs +63 -18
- package/src/concurrency.mjs +5 -3
- package/src/cycle-queue.mjs +16 -3
- package/src/events.mjs +89 -38
- package/src/mastra-harness.mjs +128 -22
- package/src/mcp-http.mjs +72 -19
- package/src/memory.mjs +15 -2
- package/src/pr-push.mjs +21 -8
- package/src/runner-pool.mjs +14 -3
- package/src/studio-cli.mjs +60 -0
- package/src/studio-server.mjs +224 -0
- package/src/task-types.mjs +3 -2
- package/src/thread-context.mjs +38 -3
- package/src/watch.mjs +345 -116
- package/src/ws.mjs +20 -1
- package/studio/app.mjs +658 -0
- package/studio/guide.html +122 -0
- package/studio/index.html +61 -0
- package/studio/style.css +223 -0
package/src/ws.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// The backend agent WebSocket — a BYO agent's real-time event channel. Connects
|
|
2
2
|
// to the org's API Gateway WS with the agent's api_key + identifier (NOT a JWT),
|
|
3
3
|
// keeps the connection warm with keepalives, auto-reconnects with backoff, and
|
|
4
|
-
// hands targeted dispatches
|
|
4
|
+
// hands targeted dispatches and verified organization fanout to a callback.
|
|
5
5
|
//
|
|
6
6
|
// Uses the built-in global WebSocket (Node >= 21). Zero dependencies — see
|
|
7
7
|
// `assertWebSocket` for the version guard.
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
// Docs: agent-websocket.md
|
|
10
10
|
// wss://<api-gw>.execute-api.<region>.amazonaws.com/<stage>/?api_key=…&identifier=…
|
|
11
11
|
// client → { "type": "keepalive" } (refreshes last_seen_at)
|
|
12
|
+
// client → { "type": "subscribe", "organization_id": 3 } (verified profile only)
|
|
12
13
|
// server → { "k": "<kind>", "d": <payload> }
|
|
13
14
|
|
|
14
15
|
import { stripSlash } from './lib.mjs'
|
|
@@ -45,6 +46,14 @@ export function connectAgentWs({ wsUrl, apiKey, identifier, onEvent, onConnect,
|
|
|
45
46
|
let reconnectTimer = null
|
|
46
47
|
let backoff = BACKOFF_MIN_MS
|
|
47
48
|
let closed = false // set once .close() is called — stops reconnects
|
|
49
|
+
let organizationId = null
|
|
50
|
+
let subscribedOrganizationId = null
|
|
51
|
+
|
|
52
|
+
const subscribe = () => {
|
|
53
|
+
if (closed || organizationId == null || !ws || ws.readyState !== 1 || subscribedOrganizationId === organizationId) return
|
|
54
|
+
try { ws.send(JSON.stringify({ type: 'subscribe', organization_id: organizationId })); subscribedOrganizationId = organizationId }
|
|
55
|
+
catch { /* the retained organization is retried on reconnect */ }
|
|
56
|
+
}
|
|
48
57
|
|
|
49
58
|
const clearKeepalive = () => { if (keepalive) { clearInterval(keepalive); keepalive = null } }
|
|
50
59
|
|
|
@@ -65,6 +74,8 @@ export function connectAgentWs({ wsUrl, apiKey, identifier, onEvent, onConnect,
|
|
|
65
74
|
sock.addEventListener('open', () => {
|
|
66
75
|
if (sock !== ws) return
|
|
67
76
|
backoff = BACKOFF_MIN_MS // healthy connection → reset the backoff ramp
|
|
77
|
+
subscribedOrganizationId = null
|
|
78
|
+
subscribe()
|
|
68
79
|
log(`connected as @${identifier}`)
|
|
69
80
|
try { onConnect && onConnect() } catch { /* reconciliation is best-effort */ }
|
|
70
81
|
clearKeepalive()
|
|
@@ -99,6 +110,14 @@ export function connectAgentWs({ wsUrl, apiKey, identifier, onEvent, onConnect,
|
|
|
99
110
|
open()
|
|
100
111
|
|
|
101
112
|
const api = {
|
|
113
|
+
// Call only with organization identity read from the authenticated agent's
|
|
114
|
+
// own profile, never an incoming message or an arbitrary project record.
|
|
115
|
+
subscribeOrganization(value) {
|
|
116
|
+
if (closed || !((typeof value === 'number' || (typeof value === 'string' && /^\d+$/.test(value))) && Number.isSafeInteger(Number(value)) && Number(value) > 0)) return false
|
|
117
|
+
organizationId = Number(value)
|
|
118
|
+
subscribe()
|
|
119
|
+
return true
|
|
120
|
+
},
|
|
102
121
|
/** Fire-and-forget send (no-op if the socket isn't open). */
|
|
103
122
|
send(obj) { try { if (ws && ws.readyState === 1) ws.send(JSON.stringify(obj)) } catch { /* closing */ } },
|
|
104
123
|
close() {
|