@botiverse/oar 0.0.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/LICENSE +202 -0
- package/README.md +13 -0
- package/dist/contracts/account-usage.d.ts +33 -0
- package/dist/contracts/account-usage.d.ts.map +1 -0
- package/dist/contracts/account-usage.js +2 -0
- package/dist/contracts/account-usage.js.map +1 -0
- package/dist/contracts/installation.d.ts +27 -0
- package/dist/contracts/installation.d.ts.map +1 -0
- package/dist/contracts/installation.js +2 -0
- package/dist/contracts/installation.js.map +1 -0
- package/dist/contracts/runtime.d.ts +12 -0
- package/dist/contracts/runtime.d.ts.map +1 -0
- package/dist/contracts/runtime.js +4 -0
- package/dist/contracts/runtime.js.map +1 -0
- package/dist/contracts/session.d.ts +188 -0
- package/dist/contracts/session.d.ts.map +1 -0
- package/dist/contracts/session.js +2 -0
- package/dist/contracts/session.js.map +1 -0
- package/dist/index.d.ts +28 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +23 -0
- package/dist/index.js.map +1 -0
- package/dist/installation.d.ts +15 -0
- package/dist/installation.d.ts.map +1 -0
- package/dist/installation.js +60 -0
- package/dist/installation.js.map +1 -0
- package/dist/observe/agent-status.d.ts +39 -0
- package/dist/observe/agent-status.d.ts.map +1 -0
- package/dist/observe/agent-status.js +31 -0
- package/dist/observe/agent-status.js.map +1 -0
- package/dist/observe/aggregate-events.d.ts +15 -0
- package/dist/observe/aggregate-events.d.ts.map +1 -0
- package/dist/observe/aggregate-events.js +70 -0
- package/dist/observe/aggregate-events.js.map +1 -0
- package/dist/observe/index.d.ts +17 -0
- package/dist/observe/index.d.ts.map +1 -0
- package/dist/observe/index.js +13 -0
- package/dist/observe/index.js.map +1 -0
- package/dist/observe/observe-agent.d.ts +38 -0
- package/dist/observe/observe-agent.d.ts.map +1 -0
- package/dist/observe/observe-agent.js +61 -0
- package/dist/observe/observe-agent.js.map +1 -0
- package/dist/observe/stall-observer.d.ts +19 -0
- package/dist/observe/stall-observer.d.ts.map +1 -0
- package/dist/observe/stall-observer.js +36 -0
- package/dist/observe/stall-observer.js.map +1 -0
- package/dist/observe/tool-activity.d.ts +21 -0
- package/dist/observe/tool-activity.d.ts.map +1 -0
- package/dist/observe/tool-activity.js +87 -0
- package/dist/observe/tool-activity.js.map +1 -0
- package/dist/registry.d.ts +10 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +30 -0
- package/dist/registry.js.map +1 -0
- package/dist/runtimes/claude/account-usage.d.ts +29 -0
- package/dist/runtimes/claude/account-usage.d.ts.map +1 -0
- package/dist/runtimes/claude/account-usage.js +179 -0
- package/dist/runtimes/claude/account-usage.js.map +1 -0
- package/dist/runtimes/claude/context-usage.d.ts +10 -0
- package/dist/runtimes/claude/context-usage.d.ts.map +1 -0
- package/dist/runtimes/claude/context-usage.js +23 -0
- package/dist/runtimes/claude/context-usage.js.map +1 -0
- package/dist/runtimes/claude/index.d.ts +9 -0
- package/dist/runtimes/claude/index.d.ts.map +1 -0
- package/dist/runtimes/claude/index.js +13 -0
- package/dist/runtimes/claude/index.js.map +1 -0
- package/dist/runtimes/claude/installation.d.ts +2 -0
- package/dist/runtimes/claude/installation.d.ts.map +1 -0
- package/dist/runtimes/claude/installation.js +3 -0
- package/dist/runtimes/claude/installation.js.map +1 -0
- package/dist/runtimes/claude/projection.d.ts +46 -0
- package/dist/runtimes/claude/projection.d.ts.map +1 -0
- package/dist/runtimes/claude/projection.js +110 -0
- package/dist/runtimes/claude/projection.js.map +1 -0
- package/dist/runtimes/claude/session.d.ts +3 -0
- package/dist/runtimes/claude/session.d.ts.map +1 -0
- package/dist/runtimes/claude/session.js +166 -0
- package/dist/runtimes/claude/session.js.map +1 -0
- package/dist/runtimes/codex/account-usage.d.ts +40 -0
- package/dist/runtimes/codex/account-usage.d.ts.map +1 -0
- package/dist/runtimes/codex/account-usage.js +185 -0
- package/dist/runtimes/codex/account-usage.js.map +1 -0
- package/dist/runtimes/codex/app-server-client.d.ts +17 -0
- package/dist/runtimes/codex/app-server-client.d.ts.map +1 -0
- package/dist/runtimes/codex/app-server-client.js +68 -0
- package/dist/runtimes/codex/app-server-client.js.map +1 -0
- package/dist/runtimes/codex/context-usage.d.ts +10 -0
- package/dist/runtimes/codex/context-usage.d.ts.map +1 -0
- package/dist/runtimes/codex/context-usage.js +16 -0
- package/dist/runtimes/codex/context-usage.js.map +1 -0
- package/dist/runtimes/codex/index.d.ts +9 -0
- package/dist/runtimes/codex/index.d.ts.map +1 -0
- package/dist/runtimes/codex/index.js +13 -0
- package/dist/runtimes/codex/index.js.map +1 -0
- package/dist/runtimes/codex/installation.d.ts +2 -0
- package/dist/runtimes/codex/installation.d.ts.map +1 -0
- package/dist/runtimes/codex/installation.js +17 -0
- package/dist/runtimes/codex/installation.js.map +1 -0
- package/dist/runtimes/codex/item-detail.d.ts +4 -0
- package/dist/runtimes/codex/item-detail.d.ts.map +1 -0
- package/dist/runtimes/codex/item-detail.js +47 -0
- package/dist/runtimes/codex/item-detail.js.map +1 -0
- package/dist/runtimes/codex/projection.d.ts +28 -0
- package/dist/runtimes/codex/projection.d.ts.map +1 -0
- package/dist/runtimes/codex/projection.js +98 -0
- package/dist/runtimes/codex/projection.js.map +1 -0
- package/dist/runtimes/codex/reasoning.d.ts +4 -0
- package/dist/runtimes/codex/reasoning.d.ts.map +1 -0
- package/dist/runtimes/codex/reasoning.js +23 -0
- package/dist/runtimes/codex/reasoning.js.map +1 -0
- package/dist/runtimes/codex/session.d.ts +3 -0
- package/dist/runtimes/codex/session.d.ts.map +1 -0
- package/dist/runtimes/codex/session.js +199 -0
- package/dist/runtimes/codex/session.js.map +1 -0
- package/dist/runtimes/pi/index.d.ts +12 -0
- package/dist/runtimes/pi/index.d.ts.map +1 -0
- package/dist/runtimes/pi/index.js +15 -0
- package/dist/runtimes/pi/index.js.map +1 -0
- package/dist/runtimes/pi/installation.d.ts +10 -0
- package/dist/runtimes/pi/installation.d.ts.map +1 -0
- package/dist/runtimes/pi/installation.js +33 -0
- package/dist/runtimes/pi/installation.js.map +1 -0
- package/dist/runtimes/pi/projection.d.ts +39 -0
- package/dist/runtimes/pi/projection.d.ts.map +1 -0
- package/dist/runtimes/pi/projection.js +112 -0
- package/dist/runtimes/pi/projection.js.map +1 -0
- package/dist/runtimes/pi/session.d.ts +11 -0
- package/dist/runtimes/pi/session.d.ts.map +1 -0
- package/dist/runtimes/pi/session.js +201 -0
- package/dist/runtimes/pi/session.js.map +1 -0
- package/dist/runtimes/pi/tool-detail.d.ts +4 -0
- package/dist/runtimes/pi/tool-detail.d.ts.map +1 -0
- package/dist/runtimes/pi/tool-detail.js +14 -0
- package/dist/runtimes/pi/tool-detail.js.map +1 -0
- package/dist/shared/diagnostic-text.d.ts +2 -0
- package/dist/shared/diagnostic-text.d.ts.map +1 -0
- package/dist/shared/diagnostic-text.js +15 -0
- package/dist/shared/diagnostic-text.js.map +1 -0
- package/dist/shared/executable/index.d.ts +8 -0
- package/dist/shared/executable/index.d.ts.map +1 -0
- package/dist/shared/executable/index.js +5 -0
- package/dist/shared/executable/index.js.map +1 -0
- package/dist/shared/executable/process.d.ts +27 -0
- package/dist/shared/executable/process.d.ts.map +1 -0
- package/dist/shared/executable/process.js +77 -0
- package/dist/shared/executable/process.js.map +1 -0
- package/dist/shared/executable/resolve.d.ts +16 -0
- package/dist/shared/executable/resolve.d.ts.map +1 -0
- package/dist/shared/executable/resolve.js +63 -0
- package/dist/shared/executable/resolve.js.map +1 -0
- package/dist/shared/executable/run.d.ts +13 -0
- package/dist/shared/executable/run.d.ts.map +1 -0
- package/dist/shared/executable/run.js +26 -0
- package/dist/shared/executable/run.js.map +1 -0
- package/dist/shared/executable/version.d.ts +6 -0
- package/dist/shared/executable/version.d.ts.map +1 -0
- package/dist/shared/executable/version.js +17 -0
- package/dist/shared/executable/version.js.map +1 -0
- package/dist/shared/failure-class.d.ts +8 -0
- package/dist/shared/failure-class.d.ts.map +1 -0
- package/dist/shared/failure-class.js +24 -0
- package/dist/shared/failure-class.js.map +1 -0
- package/dist/shared/installation.d.ts +9 -0
- package/dist/shared/installation.d.ts.map +1 -0
- package/dist/shared/installation.js +53 -0
- package/dist/shared/installation.js.map +1 -0
- package/dist/shared/instant.d.ts +4 -0
- package/dist/shared/instant.d.ts.map +1 -0
- package/dist/shared/instant.js +4 -0
- package/dist/shared/instant.js.map +1 -0
- package/dist/shared/json.d.ts +10 -0
- package/dist/shared/json.d.ts.map +1 -0
- package/dist/shared/json.js +29 -0
- package/dist/shared/json.js.map +1 -0
- package/dist/shared/seal-session.d.ts +8 -0
- package/dist/shared/seal-session.d.ts.map +1 -0
- package/dist/shared/seal-session.js +24 -0
- package/dist/shared/seal-session.js.map +1 -0
- package/dist/shared/session-kernel.d.ts +25 -0
- package/dist/shared/session-kernel.d.ts.map +1 -0
- package/dist/shared/session-kernel.js +64 -0
- package/dist/shared/session-kernel.js.map +1 -0
- package/package.json +47 -0
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { existsSync } from "node:fs";
|
|
3
|
+
import { resolveExecutable, runExecutable } from "./shared/executable/index.js";
|
|
4
|
+
function candidates(definition) {
|
|
5
|
+
const explicit = definition.explicit?.trim();
|
|
6
|
+
if (explicit !== undefined && explicit.length > 0) {
|
|
7
|
+
const command = path.isAbsolute(explicit) ? explicit : resolveExecutable(explicit);
|
|
8
|
+
return command !== null && existsSync(command) ? [command] : [];
|
|
9
|
+
}
|
|
10
|
+
const found = [];
|
|
11
|
+
const onPath = resolveExecutable(definition.command);
|
|
12
|
+
if (onPath !== null) {
|
|
13
|
+
found.push(onPath);
|
|
14
|
+
}
|
|
15
|
+
for (const command of definition.fallbacks ?? []) {
|
|
16
|
+
if (existsSync(command) && !found.includes(command)) {
|
|
17
|
+
found.push(command);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
return found;
|
|
21
|
+
}
|
|
22
|
+
function version(stdout) {
|
|
23
|
+
const value = stdout.trim().split(/\r?\n/u)[0];
|
|
24
|
+
return value === undefined || value.length === 0 ? undefined : value;
|
|
25
|
+
}
|
|
26
|
+
export function createExecutableInstallation(definition) {
|
|
27
|
+
return {
|
|
28
|
+
async probe() {
|
|
29
|
+
const available = candidates(definition);
|
|
30
|
+
if (available.length === 0) {
|
|
31
|
+
return { kind: "not_found" };
|
|
32
|
+
}
|
|
33
|
+
for (const command of available) {
|
|
34
|
+
if (definition.readiness !== undefined) {
|
|
35
|
+
const readiness = await runExecutable(command, definition.readiness.args);
|
|
36
|
+
if (!readiness.ok && readiness.exitCode === null) {
|
|
37
|
+
throw new Error(`Failed to probe the ${definition.label} readiness surface`);
|
|
38
|
+
}
|
|
39
|
+
if (!readiness.ok) {
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
const result = await runExecutable(command, ["--version"]);
|
|
44
|
+
if (!result.ok && result.exitCode === null) {
|
|
45
|
+
throw new Error(`Failed to probe the ${definition.label} installation version`);
|
|
46
|
+
}
|
|
47
|
+
const value = result.ok ? version(result.stdout) : undefined;
|
|
48
|
+
return {
|
|
49
|
+
kind: "available",
|
|
50
|
+
...(value === undefined ? {} : { version: value }),
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
return {
|
|
54
|
+
kind: "unsupported",
|
|
55
|
+
reason: definition.readiness?.unsupportedReason ?? "readiness_check_failed",
|
|
56
|
+
};
|
|
57
|
+
},
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=installation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"installation.js","sourceRoot":"","sources":["../src/installation.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { SessionEvent, TurnOutcome } from "../contracts/session.js";
|
|
2
|
+
/**
|
|
3
|
+
* status = fold(events). The reducer is pure — no clock, no IO — so status is
|
|
4
|
+
* replayable from any event log and snapshot-testable. Time-qualified
|
|
5
|
+
* judgments (stalled) are deliberately OUTSIDE the ontology: they are
|
|
6
|
+
* fold(events) × clock, provided by `stallOf` next to it.
|
|
7
|
+
*
|
|
8
|
+
* Transition table (from the minimal v1 event union):
|
|
9
|
+
* turn_started → running/waiting_model
|
|
10
|
+
* reasoning → running/thinking
|
|
11
|
+
* text_delta → running/responding
|
|
12
|
+
* tool_call_started → running/{tool, callId}
|
|
13
|
+
* tool_call_ended → running/waiting_model (the model consumes the result next)
|
|
14
|
+
* turn_ended → idle{lastTurnOutcome}
|
|
15
|
+
* The fold is total: any mid-turn event while idle adopts that turn (a
|
|
16
|
+
* consumer may subscribe mid-turn, and claude can start a turn on its own).
|
|
17
|
+
*/
|
|
18
|
+
export type RunningPhase = "waiting_model" | "thinking" | "responding" | {
|
|
19
|
+
readonly tool: string;
|
|
20
|
+
readonly callId: string;
|
|
21
|
+
};
|
|
22
|
+
export type AgentStatus = {
|
|
23
|
+
readonly kind: "idle";
|
|
24
|
+
readonly lastTurnOutcome?: TurnOutcome;
|
|
25
|
+
} | {
|
|
26
|
+
readonly kind: "running";
|
|
27
|
+
readonly turnId: string;
|
|
28
|
+
readonly phase: RunningPhase;
|
|
29
|
+
/** Envelope receivedAt (unix epoch ms) of the latest folded event. */
|
|
30
|
+
readonly lastEventAt: number;
|
|
31
|
+
};
|
|
32
|
+
export declare const initialStatus: AgentStatus;
|
|
33
|
+
export declare function reduceStatus(previous: AgentStatus, event: SessionEvent): AgentStatus;
|
|
34
|
+
/** fold(events) × clock: how long a running status has been silent, if beyond the threshold. */
|
|
35
|
+
export declare function stallOf(status: AgentStatus, nowMs: number, thresholdMs: number): {
|
|
36
|
+
readonly turnId: string;
|
|
37
|
+
readonly silentForMs: number;
|
|
38
|
+
} | null;
|
|
39
|
+
//# sourceMappingURL=agent-status.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-status.d.ts","sourceRoot":"","sources":["../../src/observe/agent-status.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAEzE;;;;;;;;;;;;;;;GAeG;AAEH,MAAM,MAAM,YAAY,GACpB,eAAe,GACf,UAAU,GACV,YAAY,GACZ;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEvD,MAAM,MAAM,WAAW,GACnB;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,eAAe,CAAC,EAAE,WAAW,CAAA;CAAE,GACjE;IACE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAC;IAC7B,sEAAsE;IACtE,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B,CAAC;AAEN,eAAO,MAAM,aAAa,EAAE,WAA8B,CAAC;AAM3D,wBAAgB,YAAY,CAAC,QAAQ,EAAE,WAAW,EAAE,KAAK,EAAE,YAAY,GAAG,WAAW,CAiBpF;AAED,gGAAgG;AAChG,wBAAgB,OAAO,CACrB,MAAM,EAAE,WAAW,EACnB,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,MAAM,GAClB;IAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAMlE"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export const initialStatus = { kind: "idle" };
|
|
2
|
+
function running(event, phase) {
|
|
3
|
+
return { kind: "running", turnId: event.turnId, phase, lastEventAt: event.receivedAt };
|
|
4
|
+
}
|
|
5
|
+
export function reduceStatus(previous, event) {
|
|
6
|
+
switch (event.kind) {
|
|
7
|
+
case "turn_started":
|
|
8
|
+
return running(event, "waiting_model");
|
|
9
|
+
case "reasoning":
|
|
10
|
+
return running(event, "thinking");
|
|
11
|
+
case "text_delta":
|
|
12
|
+
return running(event, "responding");
|
|
13
|
+
case "tool_call_started":
|
|
14
|
+
return running(event, { tool: event.tool, callId: event.callId });
|
|
15
|
+
case "tool_call_ended":
|
|
16
|
+
return running(event, "waiting_model");
|
|
17
|
+
case "turn_ended":
|
|
18
|
+
return { kind: "idle", lastTurnOutcome: event.outcome };
|
|
19
|
+
default:
|
|
20
|
+
return previous;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
/** fold(events) × clock: how long a running status has been silent, if beyond the threshold. */
|
|
24
|
+
export function stallOf(status, nowMs, thresholdMs) {
|
|
25
|
+
if (status.kind !== "running") {
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
const silentForMs = nowMs - status.lastEventAt;
|
|
29
|
+
return silentForMs >= thresholdMs ? { turnId: status.turnId, silentForMs } : null;
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=agent-status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-status.js","sourceRoot":"","sources":["../../src/observe/agent-status.ts"],"names":[],"mappings":"AAmCA,MAAM,CAAC,MAAM,aAAa,GAAgB,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;AAE3D,SAAS,OAAO,CAAC,KAAmB,EAAE,KAAmB;IACvD,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,CAAC,UAAU,EAAE,CAAC;AACzF,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,QAAqB,EAAE,KAAmB;IACrE,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;QACnB,KAAK,cAAc;YACjB,OAAO,OAAO,CAAC,KAAK,EAAE,eAAe,CAAC,CAAC;QACzC,KAAK,WAAW;YACd,OAAO,OAAO,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;QACpC,KAAK,YAAY;YACf,OAAO,OAAO,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC;QACtC,KAAK,mBAAmB;YACtB,OAAO,OAAO,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;QACpE,KAAK,iBAAiB;YACpB,OAAO,OAAO,CAAC,KAAK,EAAE,eAAe,CAAC,CAAC;QACzC,KAAK,YAAY;YACf,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,eAAe,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC;QAC1D;YACE,OAAO,QAAQ,CAAC;IACpB,CAAC;AACH,CAAC;AAED,gGAAgG;AAChG,MAAM,UAAU,OAAO,CACrB,MAAmB,EACnB,KAAa,EACb,WAAmB;IAEnB,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC9B,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,WAAW,GAAG,KAAK,GAAG,MAAM,CAAC,WAAW,CAAC;IAC/C,OAAO,WAAW,IAAI,WAAW,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AACpF,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { SessionObserver } from "../contracts/session.js";
|
|
2
|
+
/**
|
|
3
|
+
* Optional consumer-side aggregation: wrap an observer so consecutive
|
|
4
|
+
* text/reasoning chunks arrive as one merged event instead of a token stream.
|
|
5
|
+
* A merged event flushes when the delta kind changes, a non-delta event
|
|
6
|
+
* arrives, the turn ends, or — when `maxHoldMs` is set — the stream goes
|
|
7
|
+
* quiet for that long (a stalled model pause must not hold text hostage;
|
|
8
|
+
* order is safe because only consecutive same-kind deltas are ever held).
|
|
9
|
+
* It carries the LAST delta's envelope with the concatenated text. Purely a
|
|
10
|
+
* decorator over the side-tap — adapters and the kernel are unaware.
|
|
11
|
+
*/
|
|
12
|
+
export declare function aggregateDeltas(observer: SessionObserver, options?: {
|
|
13
|
+
readonly maxHoldMs?: number;
|
|
14
|
+
}): SessionObserver;
|
|
15
|
+
//# sourceMappingURL=aggregate-events.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aggregate-events.d.ts","sourceRoot":"","sources":["../../src/observe/aggregate-events.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAgB,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAqB7E;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,eAAe,EACzB,OAAO,GAAE;IAAE,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAO,GAC5C,eAAe,CA4CjB"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
function textOf(event) {
|
|
2
|
+
if (event.kind === "text_delta") {
|
|
3
|
+
return event.text;
|
|
4
|
+
}
|
|
5
|
+
return event.kind === "reasoning" && event.content.kind === "text"
|
|
6
|
+
? event.content.text
|
|
7
|
+
: null;
|
|
8
|
+
}
|
|
9
|
+
function withText(event, text) {
|
|
10
|
+
if (event.kind === "reasoning") {
|
|
11
|
+
return { ...event, content: { kind: "text", text } };
|
|
12
|
+
}
|
|
13
|
+
if (event.kind === "text_delta") {
|
|
14
|
+
return { ...event, text };
|
|
15
|
+
}
|
|
16
|
+
return event;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Optional consumer-side aggregation: wrap an observer so consecutive
|
|
20
|
+
* text/reasoning chunks arrive as one merged event instead of a token stream.
|
|
21
|
+
* A merged event flushes when the delta kind changes, a non-delta event
|
|
22
|
+
* arrives, the turn ends, or — when `maxHoldMs` is set — the stream goes
|
|
23
|
+
* quiet for that long (a stalled model pause must not hold text hostage;
|
|
24
|
+
* order is safe because only consecutive same-kind deltas are ever held).
|
|
25
|
+
* It carries the LAST delta's envelope with the concatenated text. Purely a
|
|
26
|
+
* decorator over the side-tap — adapters and the kernel are unaware.
|
|
27
|
+
*/
|
|
28
|
+
export function aggregateDeltas(observer, options = {}) {
|
|
29
|
+
let held = null;
|
|
30
|
+
let holdTimer = null;
|
|
31
|
+
const flush = () => {
|
|
32
|
+
if (holdTimer !== null) {
|
|
33
|
+
clearTimeout(holdTimer);
|
|
34
|
+
holdTimer = null;
|
|
35
|
+
}
|
|
36
|
+
if (held !== null) {
|
|
37
|
+
const event = held;
|
|
38
|
+
held = null;
|
|
39
|
+
observer(event);
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
const armHoldTimer = () => {
|
|
43
|
+
if (options.maxHoldMs === undefined) {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
if (holdTimer !== null) {
|
|
47
|
+
clearTimeout(holdTimer);
|
|
48
|
+
}
|
|
49
|
+
holdTimer = setTimeout(flush, options.maxHoldMs);
|
|
50
|
+
};
|
|
51
|
+
return (event) => {
|
|
52
|
+
const text = textOf(event);
|
|
53
|
+
if (text !== null) {
|
|
54
|
+
const previousText = held === null ? null : textOf(held);
|
|
55
|
+
if (held !== null && previousText !== null
|
|
56
|
+
&& held.kind === event.kind && held.turnId === event.turnId) {
|
|
57
|
+
held = withText(event, `${previousText}${text}`);
|
|
58
|
+
armHoldTimer();
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
flush();
|
|
62
|
+
held = event;
|
|
63
|
+
armHoldTimer();
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
flush();
|
|
67
|
+
observer(event);
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=aggregate-events.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aggregate-events.js","sourceRoot":"","sources":["../../src/observe/aggregate-events.ts"],"names":[],"mappings":"AAEA,SAAS,MAAM,CAAC,KAAmB;IACjC,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;QAChC,OAAO,KAAK,CAAC,IAAI,CAAC;IACpB,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,KAAK,WAAW,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,KAAK,MAAM;QAChE,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI;QACpB,CAAC,CAAC,IAAI,CAAC;AACX,CAAC;AAED,SAAS,QAAQ,CAAC,KAAmB,EAAE,IAAY;IACjD,IAAI,KAAK,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;QAC/B,OAAO,EAAE,GAAG,KAAK,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC;IACvD,CAAC;IACD,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;QAChC,OAAO,EAAE,GAAG,KAAK,EAAE,IAAI,EAAE,CAAC;IAC5B,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,eAAe,CAC7B,QAAyB,EACzB,UAA2C,EAAE;IAE7C,IAAI,IAAI,GAAwB,IAAI,CAAC;IACrC,IAAI,SAAS,GAA0B,IAAI,CAAC;IAE5C,MAAM,KAAK,GAAG,GAAS,EAAE;QACvB,IAAI,SAAS,KAAK,IAAI,EAAE,CAAC;YACvB,YAAY,CAAC,SAAS,CAAC,CAAC;YACxB,SAAS,GAAG,IAAI,CAAC;QACnB,CAAC;QACD,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;YAClB,MAAM,KAAK,GAAG,IAAI,CAAC;YACnB,IAAI,GAAG,IAAI,CAAC;YACZ,QAAQ,CAAC,KAAK,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,YAAY,GAAG,GAAS,EAAE;QAC9B,IAAI,OAAO,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;YACpC,OAAO;QACT,CAAC;QACD,IAAI,SAAS,KAAK,IAAI,EAAE,CAAC;YACvB,YAAY,CAAC,SAAS,CAAC,CAAC;QAC1B,CAAC;QACD,SAAS,GAAG,UAAU,CAAC,KAAK,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;IACnD,CAAC,CAAC;IAEF,OAAO,CAAC,KAAK,EAAE,EAAE;QACf,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;QAC3B,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;YAClB,MAAM,YAAY,GAAG,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YACzD,IAAI,IAAI,KAAK,IAAI,IAAI,YAAY,KAAK,IAAI;mBACrC,IAAI,CAAC,IAAI,KAAK,KAAK,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM,EAAE,CAAC;gBAC9D,IAAI,GAAG,QAAQ,CAAC,KAAK,EAAE,GAAG,YAAY,GAAG,IAAI,EAAE,CAAC,CAAC;gBACjD,YAAY,EAAE,CAAC;gBACf,OAAO;YACT,CAAC;YACD,KAAK,EAAE,CAAC;YACR,IAAI,GAAG,KAAK,CAAC;YACb,YAAY,EAAE,CAAC;YACf,OAAO;QACT,CAAC;QACD,KAAK,EAAE,CAAC;QACR,QAAQ,CAAC,KAAK,CAAC,CAAC;IAClB,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Browser-safe observe subpath: the pure derivation utilities over
|
|
3
|
+
* SessionEvents, with ZERO Node and ZERO adapter imports. A renderer can
|
|
4
|
+
* value-import `@botiverse/oar/observe` directly without dragging the runtime
|
|
5
|
+
* adapters (node:child_process, the pi SDK, …) into a browser bundle. The
|
|
6
|
+
* root `@botiverse/oar` re-exports these too, for Node consumers.
|
|
7
|
+
*/
|
|
8
|
+
export { aggregateDeltas } from "./aggregate-events.js";
|
|
9
|
+
export { initialStatus, reduceStatus, stallOf } from "./agent-status.js";
|
|
10
|
+
export type { AgentStatus, RunningPhase } from "./agent-status.js";
|
|
11
|
+
export { observeStalls } from "./stall-observer.js";
|
|
12
|
+
export type { StallInfo } from "./stall-observer.js";
|
|
13
|
+
export { observeAgent, simpleStateOf } from "./observe-agent.js";
|
|
14
|
+
export type { AgentObserver, AgentView, ObserveAgentOptions } from "./observe-agent.js";
|
|
15
|
+
export { classifyTool, toolActionLabel } from "./tool-activity.js";
|
|
16
|
+
export type { ToolAction, ToolActionKind } from "./tool-activity.js";
|
|
17
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/observe/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AACzE,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACnE,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,YAAY,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACjE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACxF,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACnE,YAAY,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Browser-safe observe subpath: the pure derivation utilities over
|
|
3
|
+
* SessionEvents, with ZERO Node and ZERO adapter imports. A renderer can
|
|
4
|
+
* value-import `@botiverse/oar/observe` directly without dragging the runtime
|
|
5
|
+
* adapters (node:child_process, the pi SDK, …) into a browser bundle. The
|
|
6
|
+
* root `@botiverse/oar` re-exports these too, for Node consumers.
|
|
7
|
+
*/
|
|
8
|
+
export { aggregateDeltas } from "./aggregate-events.js";
|
|
9
|
+
export { initialStatus, reduceStatus, stallOf } from "./agent-status.js";
|
|
10
|
+
export { observeStalls } from "./stall-observer.js";
|
|
11
|
+
export { observeAgent, simpleStateOf } from "./observe-agent.js";
|
|
12
|
+
export { classifyTool, toolActionLabel } from "./tool-activity.js";
|
|
13
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/observe/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAEzE,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEjE,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { Session } from "../contracts/session.js";
|
|
2
|
+
import { type AgentStatus } from "./agent-status.js";
|
|
3
|
+
/**
|
|
4
|
+
* The composed observer: one subscription yields a unified derived view of
|
|
5
|
+
* the agent — fold state plus the clock overlay. This is the wiring every
|
|
6
|
+
* host was about to hand-roll (subscribe + fold + a ticker): pushed on every
|
|
7
|
+
* event (the fold advances) and on the silence edge (the clock crosses the
|
|
8
|
+
* threshold). The primitives (reduceStatus/stallOf) stay exported for
|
|
9
|
+
* consumers with their own composition needs.
|
|
10
|
+
*/
|
|
11
|
+
export interface AgentView {
|
|
12
|
+
readonly status: AgentStatus;
|
|
13
|
+
readonly stall: {
|
|
14
|
+
readonly turnId: string;
|
|
15
|
+
readonly silentForMs: number;
|
|
16
|
+
} | null;
|
|
17
|
+
}
|
|
18
|
+
export interface ObserveAgentOptions {
|
|
19
|
+
readonly stallAfterMs: number;
|
|
20
|
+
/** Clock injection for tests; defaults to Date.now. */
|
|
21
|
+
readonly now?: () => number;
|
|
22
|
+
/** Stall-edge poll interval; defaults to 1s. */
|
|
23
|
+
readonly tickMs?: number;
|
|
24
|
+
}
|
|
25
|
+
export interface AgentObserver {
|
|
26
|
+
/** Push the current view immediately, then on every change; returns unsubscribe. */
|
|
27
|
+
subscribe(listener: (view: AgentView) => void): () => void;
|
|
28
|
+
dispose(): void;
|
|
29
|
+
}
|
|
30
|
+
export declare function observeAgent(session: Session, options: ObserveAgentOptions): AgentObserver;
|
|
31
|
+
/**
|
|
32
|
+
* The four-word collapse for consumers who want exactly idle/busy/stuck/error.
|
|
33
|
+
* Precedence: stuck beats busy (a silent turn is a problem before it is
|
|
34
|
+
* progress); error means "idle after a failed last turn" — a report about
|
|
35
|
+
* history, never a running state (see the status-bar design notes).
|
|
36
|
+
*/
|
|
37
|
+
export declare function simpleStateOf(view: AgentView): "idle" | "busy" | "stuck" | "error";
|
|
38
|
+
//# sourceMappingURL=observe-agent.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"observe-agent.d.ts","sourceRoot":"","sources":["../../src/observe/observe-agent.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAwC,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAE3F;;;;;;;GAOG;AAEH,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE;QAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;CAClF;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,uDAAuD;IACvD,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IAC5B,gDAAgD;IAChD,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,aAAa;IAC5B,oFAAoF;IACpF,SAAS,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;IAC3D,OAAO,IAAI,IAAI,CAAC;CACjB;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,mBAAmB,GAAG,aAAa,CA6C1F;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,CAQlF"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { initialStatus, reduceStatus, stallOf } from "./agent-status.js";
|
|
2
|
+
export function observeAgent(session, options) {
|
|
3
|
+
const now = options.now ?? (() => Date.now());
|
|
4
|
+
const listeners = new Set();
|
|
5
|
+
let status = initialStatus;
|
|
6
|
+
let lastStalled = false;
|
|
7
|
+
const view = () => ({ status, stall: stallOf(status, now(), options.stallAfterMs) });
|
|
8
|
+
const push = () => {
|
|
9
|
+
const current = view();
|
|
10
|
+
lastStalled = current.stall !== null;
|
|
11
|
+
for (const listener of listeners) {
|
|
12
|
+
try {
|
|
13
|
+
listener(current);
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
// observer isolation: one throwing listener never starves the rest
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
const unsubscribe = session.subscribe((event) => {
|
|
21
|
+
status = reduceStatus(status, event);
|
|
22
|
+
push();
|
|
23
|
+
});
|
|
24
|
+
const ticker = setInterval(() => {
|
|
25
|
+
// push only on the silence EDGES, not every tick
|
|
26
|
+
const stalledNow = stallOf(status, now(), options.stallAfterMs) !== null;
|
|
27
|
+
if (stalledNow !== lastStalled) {
|
|
28
|
+
push();
|
|
29
|
+
}
|
|
30
|
+
}, options.tickMs ?? 1000);
|
|
31
|
+
return {
|
|
32
|
+
subscribe(listener) {
|
|
33
|
+
listeners.add(listener);
|
|
34
|
+
listener(view());
|
|
35
|
+
return () => {
|
|
36
|
+
listeners.delete(listener);
|
|
37
|
+
};
|
|
38
|
+
},
|
|
39
|
+
dispose() {
|
|
40
|
+
clearInterval(ticker);
|
|
41
|
+
unsubscribe();
|
|
42
|
+
listeners.clear();
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* The four-word collapse for consumers who want exactly idle/busy/stuck/error.
|
|
48
|
+
* Precedence: stuck beats busy (a silent turn is a problem before it is
|
|
49
|
+
* progress); error means "idle after a failed last turn" — a report about
|
|
50
|
+
* history, never a running state (see the status-bar design notes).
|
|
51
|
+
*/
|
|
52
|
+
export function simpleStateOf(view) {
|
|
53
|
+
if (view.stall !== null) {
|
|
54
|
+
return "stuck";
|
|
55
|
+
}
|
|
56
|
+
if (view.status.kind === "running") {
|
|
57
|
+
return "busy";
|
|
58
|
+
}
|
|
59
|
+
return view.status.lastTurnOutcome?.kind === "failed" ? "error" : "idle";
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=observe-agent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"observe-agent.js","sourceRoot":"","sources":["../../src/observe/observe-agent.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,OAAO,EAAoB,MAAM,mBAAmB,CAAC;AA8B3F,MAAM,UAAU,YAAY,CAAC,OAAgB,EAAE,OAA4B;IACzE,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,CAAC,GAAW,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;IACtD,MAAM,SAAS,GAAG,IAAI,GAAG,EAA6B,CAAC;IACvD,IAAI,MAAM,GAAgB,aAAa,CAAC;IACxC,IAAI,WAAW,GAAG,KAAK,CAAC;IAExB,MAAM,IAAI,GAAG,GAAc,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE,OAAO,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;IAChG,MAAM,IAAI,GAAG,GAAS,EAAE;QACtB,MAAM,OAAO,GAAG,IAAI,EAAE,CAAC;QACvB,WAAW,GAAG,OAAO,CAAC,KAAK,KAAK,IAAI,CAAC;QACrC,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;YACjC,IAAI,CAAC;gBACH,QAAQ,CAAC,OAAO,CAAC,CAAC;YACpB,CAAC;YAAC,MAAM,CAAC;gBACP,mEAAmE;YACrE,CAAC;QACH,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,WAAW,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,KAAK,EAAE,EAAE;QAC9C,MAAM,GAAG,YAAY,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QACrC,IAAI,EAAE,CAAC;IACT,CAAC,CAAC,CAAC;IACH,MAAM,MAAM,GAAG,WAAW,CAAC,GAAG,EAAE;QAC9B,iDAAiD;QACjD,MAAM,UAAU,GAAG,OAAO,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE,OAAO,CAAC,YAAY,CAAC,KAAK,IAAI,CAAC;QACzE,IAAI,UAAU,KAAK,WAAW,EAAE,CAAC;YAC/B,IAAI,EAAE,CAAC;QACT,CAAC;IACH,CAAC,EAAE,OAAO,CAAC,MAAM,IAAI,IAAI,CAAC,CAAC;IAE3B,OAAO;QACL,SAAS,CAAC,QAAQ;YAChB,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;YACxB,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;YACjB,OAAO,GAAG,EAAE;gBACV,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YAC7B,CAAC,CAAC;QACJ,CAAC;QACD,OAAO;YACL,aAAa,CAAC,MAAM,CAAC,CAAC;YACtB,WAAW,EAAE,CAAC;YACd,SAAS,CAAC,KAAK,EAAE,CAAC;QACpB,CAAC;KACF,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,aAAa,CAAC,IAAe;IAC3C,IAAI,IAAI,CAAC,KAAK,KAAK,IAAI,EAAE,CAAC;QACxB,OAAO,OAAO,CAAC;IACjB,CAAC;IACD,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QACnC,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,OAAO,IAAI,CAAC,MAAM,CAAC,eAAe,EAAE,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC;AAC3E,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { Session, Unsubscribe } from "../contracts/session.js";
|
|
2
|
+
/**
|
|
3
|
+
* Convenience layer over the public status reducer: fold the session's events
|
|
4
|
+
* with reduceStatus, ask stallOf with the wall clock, and report when an
|
|
5
|
+
* active turn has been silent for `stallAfterMs`. There is deliberately no
|
|
6
|
+
* second state machine here — the reducer is the single source of truth.
|
|
7
|
+
* Fires once per silence episode; the next event re-arms it. The embedder
|
|
8
|
+
* decides what a stall means (surface, notify, or abort via its turn handle).
|
|
9
|
+
*/
|
|
10
|
+
export interface StallInfo {
|
|
11
|
+
readonly turnId: string;
|
|
12
|
+
readonly silentForMs: number;
|
|
13
|
+
readonly lastEventKind: string;
|
|
14
|
+
}
|
|
15
|
+
export declare function observeStalls(session: Session, options: {
|
|
16
|
+
readonly stallAfterMs: number;
|
|
17
|
+
readonly onStall: (info: StallInfo) => void;
|
|
18
|
+
}): Unsubscribe;
|
|
19
|
+
//# sourceMappingURL=stall-observer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stall-observer.d.ts","sourceRoot":"","sources":["../../src/observe/stall-observer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAGpE;;;;;;;GAOG;AACH,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;CAChC;AAED,wBAAgB,aAAa,CAC3B,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE;IAAE,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAA;CAAE,GACtF,WAAW,CAmCb"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { initialStatus, reduceStatus, stallOf } from "./agent-status.js";
|
|
2
|
+
export function observeStalls(session, options) {
|
|
3
|
+
let status = initialStatus;
|
|
4
|
+
let lastEventKind = "";
|
|
5
|
+
let timer = null;
|
|
6
|
+
const disarm = () => {
|
|
7
|
+
if (timer !== null) {
|
|
8
|
+
clearTimeout(timer);
|
|
9
|
+
timer = null;
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
const arm = () => {
|
|
13
|
+
disarm();
|
|
14
|
+
timer = setTimeout(() => {
|
|
15
|
+
const stall = stallOf(status, Date.now(), options.stallAfterMs);
|
|
16
|
+
if (stall !== null) {
|
|
17
|
+
options.onStall({ ...stall, lastEventKind });
|
|
18
|
+
}
|
|
19
|
+
}, options.stallAfterMs);
|
|
20
|
+
};
|
|
21
|
+
const unsubscribe = session.subscribe((event) => {
|
|
22
|
+
status = reduceStatus(status, event);
|
|
23
|
+
lastEventKind = event.kind;
|
|
24
|
+
if (status.kind === "running") {
|
|
25
|
+
arm();
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
disarm();
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
return () => {
|
|
32
|
+
disarm();
|
|
33
|
+
unsubscribe();
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=stall-observer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stall-observer.js","sourceRoot":"","sources":["../../src/observe/stall-observer.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,OAAO,EAAoB,MAAM,mBAAmB,CAAC;AAgB3F,MAAM,UAAU,aAAa,CAC3B,OAAgB,EAChB,OAAuF;IAEvF,IAAI,MAAM,GAAgB,aAAa,CAAC;IACxC,IAAI,aAAa,GAAG,EAAE,CAAC;IACvB,IAAI,KAAK,GAA0B,IAAI,CAAC;IAExC,MAAM,MAAM,GAAG,GAAS,EAAE;QACxB,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;YACnB,YAAY,CAAC,KAAK,CAAC,CAAC;YACpB,KAAK,GAAG,IAAI,CAAC;QACf,CAAC;IACH,CAAC,CAAC;IACF,MAAM,GAAG,GAAG,GAAS,EAAE;QACrB,MAAM,EAAE,CAAC;QACT,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;YACtB,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;YAChE,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;gBACnB,OAAO,CAAC,OAAO,CAAC,EAAE,GAAG,KAAK,EAAE,aAAa,EAAE,CAAC,CAAC;YAC/C,CAAC;QACH,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;IAC3B,CAAC,CAAC;IAEF,MAAM,WAAW,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,KAAK,EAAE,EAAE;QAC9C,MAAM,GAAG,YAAY,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QACrC,aAAa,GAAG,KAAK,CAAC,IAAI,CAAC;QAC3B,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YAC9B,GAAG,EAAE,CAAC;QACR,CAAC;aAAM,CAAC;YACN,MAAM,EAAE,CAAC;QACX,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,GAAG,EAAE;QACV,MAAM,EAAE,CAAC;QACT,WAAW,EAAE,CAAC;IAChB,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cross-runtime tool classification — the friendly-Activity utility. Each
|
|
3
|
+
* runtime names the same action differently (claude "Bash", codex
|
|
4
|
+
* "commandExecution", pi "bash"); only OAR knows the mapping, so it lives
|
|
5
|
+
* here. Pure: raw tool_call events stay the source of truth; a friendly view
|
|
6
|
+
* derives labels via this (same pattern as reduceStatus / aggregateDeltas).
|
|
7
|
+
*
|
|
8
|
+
* The tool set is OPEN (custom + MCP tools have arbitrary names), so unknown
|
|
9
|
+
* tools fall back to "other" rather than being force-fit.
|
|
10
|
+
*/
|
|
11
|
+
export type ToolActionKind = "run_command" | "read_file" | "edit_file" | "search" | "web" | "mcp" | "other";
|
|
12
|
+
export interface ToolAction {
|
|
13
|
+
readonly kind: ToolActionKind;
|
|
14
|
+
/** A short target extracted from the tool input: the command text, a file path, a query. */
|
|
15
|
+
readonly detail?: string;
|
|
16
|
+
}
|
|
17
|
+
/** Classify one tool call into a cross-runtime semantic action plus an extracted detail. */
|
|
18
|
+
export declare function classifyTool(runtimeId: string, tool: string, inputJson?: string): ToolAction;
|
|
19
|
+
/** The human label for an action in a given lifecycle state — tense centralized here so views stay consistent. */
|
|
20
|
+
export declare function toolActionLabel(kind: ToolActionKind, state: "running" | "done" | "failed"): string;
|
|
21
|
+
//# sourceMappingURL=tool-activity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-activity.d.ts","sourceRoot":"","sources":["../../src/observe/tool-activity.ts"],"names":[],"mappings":"AAEA;;;;;;;;;GASG;AAEH,MAAM,MAAM,cAAc,GACtB,aAAa,GACb,WAAW,GACX,WAAW,GACX,QAAQ,GACR,KAAK,GACL,KAAK,GACL,OAAO,CAAC;AAEZ,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC;IAC9B,4FAA4F;IAC5F,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAwED,4FAA4F;AAC5F,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,UAAU,CAI5F;AAYD,kHAAkH;AAClH,wBAAgB,eAAe,CAAC,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,SAAS,GAAG,MAAM,GAAG,QAAQ,GAAG,MAAM,CAElG"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { asRecord, parseJson } from "../shared/json.js";
|
|
2
|
+
// Per-runtime tool name → kind. Names are what the tool_call_started event
|
|
3
|
+
// carries (codex uses its item type; claude/pi use the tool name).
|
|
4
|
+
const BY_RUNTIME = {
|
|
5
|
+
claude: {
|
|
6
|
+
Bash: "run_command",
|
|
7
|
+
Read: "read_file",
|
|
8
|
+
Edit: "edit_file",
|
|
9
|
+
Write: "edit_file",
|
|
10
|
+
NotebookEdit: "edit_file",
|
|
11
|
+
Grep: "search",
|
|
12
|
+
Glob: "search",
|
|
13
|
+
WebFetch: "web",
|
|
14
|
+
WebSearch: "web",
|
|
15
|
+
},
|
|
16
|
+
codex: {
|
|
17
|
+
commandExecution: "run_command",
|
|
18
|
+
fileChange: "edit_file",
|
|
19
|
+
webSearch: "web",
|
|
20
|
+
mcpToolCall: "mcp",
|
|
21
|
+
},
|
|
22
|
+
pi: {
|
|
23
|
+
bash: "run_command",
|
|
24
|
+
read: "read_file",
|
|
25
|
+
ls: "read_file",
|
|
26
|
+
edit: "edit_file",
|
|
27
|
+
write: "edit_file",
|
|
28
|
+
grep: "search",
|
|
29
|
+
find: "search",
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
function kindOf(runtimeId, tool) {
|
|
33
|
+
const runtime = runtimeId.replace(/-aimock$/u, "");
|
|
34
|
+
const direct = BY_RUNTIME[runtime]?.[tool];
|
|
35
|
+
if (direct !== undefined) {
|
|
36
|
+
return direct;
|
|
37
|
+
}
|
|
38
|
+
// MCP tools are conventionally prefixed on claude (mcp__server__tool).
|
|
39
|
+
if (tool.startsWith("mcp__")) {
|
|
40
|
+
return "mcp";
|
|
41
|
+
}
|
|
42
|
+
return "other";
|
|
43
|
+
}
|
|
44
|
+
const FIRST_STRING_KEYS = ["command", "cmd", "path", "file_path", "filePath", "file", "pattern", "query", "url"];
|
|
45
|
+
function detailOf(inputJson) {
|
|
46
|
+
if (inputJson === undefined) {
|
|
47
|
+
return undefined;
|
|
48
|
+
}
|
|
49
|
+
const input = asRecord(parseJson(inputJson));
|
|
50
|
+
if (input === null) {
|
|
51
|
+
return undefined;
|
|
52
|
+
}
|
|
53
|
+
for (const key of FIRST_STRING_KEYS) {
|
|
54
|
+
const value = input[key];
|
|
55
|
+
if (typeof value === "string" && value.length > 0) {
|
|
56
|
+
return value;
|
|
57
|
+
}
|
|
58
|
+
// codex nests the shell command as ["bash","-lc", "<cmd>"] sometimes.
|
|
59
|
+
if (Array.isArray(value)) {
|
|
60
|
+
const last = value.at(-1);
|
|
61
|
+
if (typeof last === "string" && last.length > 0) {
|
|
62
|
+
return last;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return undefined;
|
|
67
|
+
}
|
|
68
|
+
/** Classify one tool call into a cross-runtime semantic action plus an extracted detail. */
|
|
69
|
+
export function classifyTool(runtimeId, tool, inputJson) {
|
|
70
|
+
const kind = kindOf(runtimeId, tool);
|
|
71
|
+
const detail = detailOf(inputJson) ?? (kind === "other" ? tool : undefined);
|
|
72
|
+
return detail === undefined ? { kind } : { kind, detail };
|
|
73
|
+
}
|
|
74
|
+
const LABELS = {
|
|
75
|
+
run_command: { running: "Running command", done: "Ran command", failed: "Command failed" },
|
|
76
|
+
read_file: { running: "Reading file", done: "Read file", failed: "Read failed" },
|
|
77
|
+
edit_file: { running: "Editing file", done: "Edited file", failed: "Edit failed" },
|
|
78
|
+
search: { running: "Searching", done: "Searched", failed: "Search failed" },
|
|
79
|
+
web: { running: "Searching the web", done: "Searched the web", failed: "Web request failed" },
|
|
80
|
+
mcp: { running: "Using a tool", done: "Used a tool", failed: "Tool failed" },
|
|
81
|
+
other: { running: "Working", done: "Done", failed: "Failed" },
|
|
82
|
+
};
|
|
83
|
+
/** The human label for an action in a given lifecycle state — tense centralized here so views stay consistent. */
|
|
84
|
+
export function toolActionLabel(kind, state) {
|
|
85
|
+
return LABELS[kind][state];
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=tool-activity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-activity.js","sourceRoot":"","sources":["../../src/observe/tool-activity.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Runtime } from "./contracts/runtime.js";
|
|
2
|
+
export declare class RuntimeRegistry {
|
|
3
|
+
#private;
|
|
4
|
+
constructor(runtimes: Iterable<Runtime>);
|
|
5
|
+
get(id: string): Runtime | undefined;
|
|
6
|
+
require(id: string): Runtime;
|
|
7
|
+
list(): readonly Runtime[];
|
|
8
|
+
}
|
|
9
|
+
export declare function createRuntimeRegistry(runtimes: Iterable<Runtime>): RuntimeRegistry;
|
|
10
|
+
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAEtD,qBAAa,eAAe;;gBAGd,QAAQ,EAAE,QAAQ,CAAC,OAAO,CAAC;IAWvC,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS;IAIpC,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAQ5B,IAAI,IAAI,SAAS,OAAO,EAAE;CAG3B;AAED,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,eAAe,CAElF"}
|
package/dist/registry.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export class RuntimeRegistry {
|
|
2
|
+
#runtimes;
|
|
3
|
+
constructor(runtimes) {
|
|
4
|
+
const indexed = new Map();
|
|
5
|
+
for (const runtime of runtimes) {
|
|
6
|
+
if (indexed.has(runtime.id)) {
|
|
7
|
+
throw new Error(`duplicate runtime id: ${runtime.id}`);
|
|
8
|
+
}
|
|
9
|
+
indexed.set(runtime.id, runtime);
|
|
10
|
+
}
|
|
11
|
+
this.#runtimes = indexed;
|
|
12
|
+
}
|
|
13
|
+
get(id) {
|
|
14
|
+
return this.#runtimes.get(id);
|
|
15
|
+
}
|
|
16
|
+
require(id) {
|
|
17
|
+
const runtime = this.get(id);
|
|
18
|
+
if (runtime === undefined) {
|
|
19
|
+
throw new Error(`unknown runtime: ${id}`);
|
|
20
|
+
}
|
|
21
|
+
return runtime;
|
|
22
|
+
}
|
|
23
|
+
list() {
|
|
24
|
+
return [...this.#runtimes.values()];
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
export function createRuntimeRegistry(runtimes) {
|
|
28
|
+
return new RuntimeRegistry(runtimes);
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,eAAe;IACjB,SAAS,CAA+B;IAEjD,YAAY,QAA2B;QACrC,MAAM,OAAO,GAAG,IAAI,GAAG,EAAmB,CAAC;QAC3C,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;YAC/B,IAAI,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC;gBAC5B,MAAM,IAAI,KAAK,CAAC,yBAAyB,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC;YACzD,CAAC;YACD,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;QACnC,CAAC;QACD,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC;IAC3B,CAAC;IAED,GAAG,CAAC,EAAU;QACZ,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChC,CAAC;IAED,OAAO,CAAC,EAAU;QAChB,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC7B,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC1B,MAAM,IAAI,KAAK,CAAC,oBAAoB,EAAE,EAAE,CAAC,CAAC;QAC5C,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,IAAI;QACF,OAAO,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC;IACtC,CAAC;CACF;AAED,MAAM,UAAU,qBAAqB,CAAC,QAA2B;IAC/D,OAAO,IAAI,eAAe,CAAC,QAAQ,CAAC,CAAC;AACvC,CAAC"}
|