zooid 0.15.0 → 0.16.1
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 +1 -1
- package/dist/bin.js +49 -2
- package/dist/bin.js.map +1 -1
- package/dist/{chunk-35IKQPC5.js → chunk-HE7DVDJA.js} +1294 -772
- package/dist/chunk-HE7DVDJA.js.map +1 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +1 -1
- package/package.json +10 -10
- package/src/build-registry.context.test.ts +1 -0
- package/src/build-registry.test.ts +1 -0
- package/src/build-registry.ts +3 -0
- package/src/build-registry.zod043.test.ts +1 -0
- package/src/build-registry.zod044.test.ts +1 -0
- package/src/commands/dev.ts +3 -0
- package/src/commands/start.ts +2 -0
- package/src/daemon/start-daemon.ts +3 -0
- package/src/observability/capture-agent.ts +35 -1
- package/src/observability/lifecycle-log.test.ts +48 -0
- package/src/observability/lifecycle-log.ts +29 -0
- package/src/observability/observability.integration.test.ts +22 -0
- package/src/web/static.test.ts +14 -0
- package/src/web/static.ts +3 -0
- package/dist/chunk-35IKQPC5.js.map +0 -1
package/README.md
CHANGED
|
@@ -42,7 +42,7 @@ zooid dev
|
|
|
42
42
|
|
|
43
43
|
> **Prerequisite:** `zooid dev` runs Tuwunel inside a container, so you need a container engine installed and running first — either **Docker** (with the daemon started) or **Podman** aliased as `docker`.
|
|
44
44
|
|
|
45
|
-
`zooid dev` starts a Tuwunel Matrix homeserver in a container, generates the Application Service registration, registers an `admin:admin` user, runs the daemon, and serves the [Zooid web client](https://github.com/zooid-ai/clients).
|
|
45
|
+
`zooid dev` starts a Tuwunel Matrix homeserver in a container, generates the Application Service registration, registers an `admin:admin` user, runs the daemon, and serves the [Zooid web client](https://github.com/zooid-ai/clients). The client's runtime settings come from a generated `/config.json`; its `workforce_space` field is the `matrix.space` alias localpart from `zooid.yaml` (default `dev`). A static deployment sets `workforce_space` in the `config.json` it serves beside the bundle — there is no build-time variable.
|
|
46
46
|
|
|
47
47
|
Open `http://localhost:5173`, log in as `admin` / `admin`, join `#welcome`, and `@`-mention your agent.
|
|
48
48
|
|
package/dist/bin.js
CHANGED
|
@@ -20,7 +20,7 @@ import {
|
|
|
20
20
|
renderTemplate,
|
|
21
21
|
startAgentSocketServers,
|
|
22
22
|
startWorkforcePublisher
|
|
23
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-HE7DVDJA.js";
|
|
24
24
|
|
|
25
25
|
// src/bin.ts
|
|
26
26
|
import { resolve as resolve8 } from "path";
|
|
@@ -1113,6 +1113,7 @@ async function startDaemon(opts = {}) {
|
|
|
1113
1113
|
const registry = buildAcpRegistry(config, {
|
|
1114
1114
|
approvals,
|
|
1115
1115
|
onTap: opts.onTap,
|
|
1116
|
+
onLifecycle: opts.onLifecycle,
|
|
1116
1117
|
agentsDir: opts.agentsDir,
|
|
1117
1118
|
contextSpawnRegistry,
|
|
1118
1119
|
daemonSockPaths: contextSockets.paths,
|
|
@@ -1658,6 +1659,7 @@ function webStatic(opts) {
|
|
|
1658
1659
|
"/config.json",
|
|
1659
1660
|
(c) => c.json({
|
|
1660
1661
|
homeserver_url: opts.homeserverUrl,
|
|
1662
|
+
...opts.workforceSpace ? { workforce_space: opts.workforceSpace } : {},
|
|
1661
1663
|
...opts.pushGatewayUrl ? { push_gateway_url: opts.pushGatewayUrl } : {},
|
|
1662
1664
|
...opts.vapidPublicKey ? { vapid_public_key: opts.vapidPublicKey } : {}
|
|
1663
1665
|
})
|
|
@@ -1894,6 +1896,12 @@ function wireAgentCapture(opts) {
|
|
|
1894
1896
|
const sink = new JsonlSink(opts.paths.agentTap(opts.agent));
|
|
1895
1897
|
const now = opts.now ?? (() => /* @__PURE__ */ new Date());
|
|
1896
1898
|
const pending = [];
|
|
1899
|
+
const counters = {
|
|
1900
|
+
closeAttempts: 0,
|
|
1901
|
+
closeSuccesses: 0,
|
|
1902
|
+
sessionsReclaimed: 0,
|
|
1903
|
+
recoveries: { cached: 0, resume: 0, load: 0, new: 0 }
|
|
1904
|
+
};
|
|
1897
1905
|
const onTap = (event) => {
|
|
1898
1906
|
if (event.kind === "session_update") {
|
|
1899
1907
|
const variant = event.update.sessionUpdate ?? "unknown";
|
|
@@ -1915,6 +1923,25 @@ function wireAgentCapture(opts) {
|
|
|
1915
1923
|
};
|
|
1916
1924
|
return {
|
|
1917
1925
|
onTap,
|
|
1926
|
+
onLifecycle: (event) => {
|
|
1927
|
+
if (event.reason && event.outcome !== "unsupported") counters.closeAttempts++;
|
|
1928
|
+
if (event.reason && event.outcome === "closed") {
|
|
1929
|
+
counters.closeSuccesses++;
|
|
1930
|
+
counters.sessionsReclaimed++;
|
|
1931
|
+
}
|
|
1932
|
+
if (event.outcome === "recovered" && event.recoveryMethod) counters.recoveries[event.recoveryMethod]++;
|
|
1933
|
+
pending.push(sink.write({
|
|
1934
|
+
ts: now().toISOString(),
|
|
1935
|
+
agent: opts.agent,
|
|
1936
|
+
kind: "session_lifecycle",
|
|
1937
|
+
session_key: event.sessionKey,
|
|
1938
|
+
session_id: event.sessionId,
|
|
1939
|
+
reason: event.reason,
|
|
1940
|
+
outcome: event.outcome,
|
|
1941
|
+
recovery_method: event.recoveryMethod
|
|
1942
|
+
}));
|
|
1943
|
+
},
|
|
1944
|
+
readLifecycleCounters: () => ({ ...counters, recoveries: { ...counters.recoveries } }),
|
|
1918
1945
|
close: async () => {
|
|
1919
1946
|
await Promise.all(pending);
|
|
1920
1947
|
await sink.close();
|
|
@@ -2080,6 +2107,7 @@ async function runDev(flags) {
|
|
|
2080
2107
|
// the web client without needing an invite.
|
|
2081
2108
|
publicWorkforceSpace: true,
|
|
2082
2109
|
onTap: (agentName, event) => captures[agentName]?.onTap(event),
|
|
2110
|
+
onLifecycle: (agentName, event) => captures[agentName]?.onLifecycle(event),
|
|
2083
2111
|
prepullLog: (line) => {
|
|
2084
2112
|
t.output = line.replace(/^\[zooid\]\s+/, "").trim();
|
|
2085
2113
|
}
|
|
@@ -2116,6 +2144,8 @@ Pass an explicit path: --watch-web=/path/to/zooid-clients/packages/web`
|
|
|
2116
2144
|
const app = webStatic({
|
|
2117
2145
|
webRoot,
|
|
2118
2146
|
homeserverUrl: homeserver,
|
|
2147
|
+
// Same default as the daemon's space provisioning (start-daemon.ts).
|
|
2148
|
+
workforceSpace: matrix.transport.space ?? "dev",
|
|
2119
2149
|
...ctx.daemon?.vapidPublicKey ? {
|
|
2120
2150
|
// Tuwunel runs in a container; `localhost` here would
|
|
2121
2151
|
// resolve to the container, not the daemon. Same shorthand
|
|
@@ -2778,6 +2808,22 @@ async function dumpByTurn(dayDir, turnId, writer) {
|
|
|
2778
2808
|
// src/commands/start.ts
|
|
2779
2809
|
import { randomBytes as randomBytes2 } from "crypto";
|
|
2780
2810
|
import { resolve as resolve6 } from "path";
|
|
2811
|
+
|
|
2812
|
+
// src/observability/lifecycle-log.ts
|
|
2813
|
+
function formatLifecycleLine(agentName, event) {
|
|
2814
|
+
if (event.outcome === "unsupported") return null;
|
|
2815
|
+
if (event.recoveryMethod === "cached") return null;
|
|
2816
|
+
const what = event.outcome === "recovered" ? `recovered (${event.recoveryMethod ?? "unknown"})` : `${event.reason ?? "close"} \u2192 ${event.outcome}`;
|
|
2817
|
+
return `[lifecycle] ${agentName} key=${event.sessionKey} session=${event.sessionId} ${what}`;
|
|
2818
|
+
}
|
|
2819
|
+
function logLifecycle(agentName, event, out = console) {
|
|
2820
|
+
const line = formatLifecycleLine(agentName, event);
|
|
2821
|
+
if (!line) return;
|
|
2822
|
+
if (event.outcome === "failed") out.error(line);
|
|
2823
|
+
else out.log(line);
|
|
2824
|
+
}
|
|
2825
|
+
|
|
2826
|
+
// src/commands/start.ts
|
|
2781
2827
|
async function runStart(flags) {
|
|
2782
2828
|
if (flags.printToken) {
|
|
2783
2829
|
process.stdout.write(`${randomBytes2(32).toString("hex")}
|
|
@@ -2789,7 +2835,8 @@ async function runStart(flags) {
|
|
|
2789
2835
|
const handle = await startDaemon({
|
|
2790
2836
|
cliFlags: flags,
|
|
2791
2837
|
installSignalHandlers: true,
|
|
2792
|
-
agentsDir: layout.agentsDir
|
|
2838
|
+
agentsDir: layout.agentsDir,
|
|
2839
|
+
onLifecycle: (agentName, event) => logLifecycle(agentName, event)
|
|
2793
2840
|
});
|
|
2794
2841
|
console.log(`zooid listening on http://localhost:${handle.port}`);
|
|
2795
2842
|
for (const name of handle.agentNames) console.log(` agent: ${name}`);
|