@geohar/unbien-durable 0.0.0-stage → 0.1.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/LICENSE +21 -0
- package/README.md +52 -2
- package/dist/agent_config.d.ts +56 -0
- package/dist/agent_config.js +92 -0
- package/dist/agent_config.js.map +1 -0
- package/dist/bridge.d.ts +175 -0
- package/dist/bridge.js +921 -0
- package/dist/bridge.js.map +1 -0
- package/dist/event_source.d.ts +53 -0
- package/dist/event_source.js +124 -0
- package/dist/event_source.js.map +1 -0
- package/dist/extension.d.ts +34 -0
- package/dist/extension.js +46 -0
- package/dist/extension.js.map +1 -0
- package/dist/host.d.ts +2 -0
- package/dist/host.js +261 -0
- package/dist/host.js.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.js +18 -0
- package/dist/index.js.map +1 -0
- package/dist/launch_wait_quit.d.ts +12 -0
- package/dist/launch_wait_quit.js +136 -0
- package/dist/launch_wait_quit.js.map +1 -0
- package/dist/mesh_delivery.d.ts +28 -0
- package/dist/mesh_delivery.js +31 -0
- package/dist/mesh_delivery.js.map +1 -0
- package/dist/mirror.d.ts +56 -0
- package/dist/mirror.js +136 -0
- package/dist/mirror.js.map +1 -0
- package/dist/ollama_cloud.d.ts +2 -0
- package/dist/ollama_cloud.js +98 -0
- package/dist/ollama_cloud.js.map +1 -0
- package/dist/pi_launch.d.ts +50 -0
- package/dist/pi_launch.js +84 -0
- package/dist/pi_launch.js.map +1 -0
- package/dist/port.d.ts +94 -0
- package/dist/port.js +121 -0
- package/dist/port.js.map +1 -0
- package/dist/registrar.d.ts +7 -0
- package/dist/registrar.js +31 -0
- package/dist/registrar.js.map +1 -0
- package/dist/thinking.d.ts +24 -0
- package/dist/thinking.js +36 -0
- package/dist/thinking.js.map +1 -0
- package/dist/view_translator.d.ts +83 -0
- package/dist/view_translator.js +317 -0
- package/dist/view_translator.js.map +1 -0
- package/package.json +63 -3
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Durable binding's HeadlessLaunchPort implementation: the launch-wait-quit
|
|
3
|
+
* primitive behind the `launch_pi_task` tool — the ONE place the two
|
|
4
|
+
* bindings meet at runtime.
|
|
5
|
+
*
|
|
6
|
+
* Launch path: the pi SDK's headless `createAgentSession` (the programmatic
|
|
7
|
+
* equivalent of `pi` without a TUI — NOT `pi -p`, whose print-mode exit the
|
|
8
|
+
* un-bien extension deliberately never auto-starts the relay in). The session
|
|
9
|
+
* loads its extensions through pi's own resource discovery from the target
|
|
10
|
+
* cwd (installed pi-packages, `<cwd>/.pi/extensions`, `<agentDir>`), so the
|
|
11
|
+
* un-bien pi extension must be discoverable there — when it is, its
|
|
12
|
+
* session_start auto-init joins the UDS mesh under the session's display
|
|
13
|
+
* name, which is the SCOPED name minted per invocation.
|
|
14
|
+
*
|
|
15
|
+
* Readiness: the local UDS broker is probed (observer probe — never
|
|
16
|
+
* registers, never perturbs the roster) until the scoped name appears as a
|
|
17
|
+
* peer address; that address is the agent_send routing key for the task.
|
|
18
|
+
*
|
|
19
|
+
* Teardown: `session.dispose()` — the un-bien extension's session_shutdown
|
|
20
|
+
* handler leaves the mesh and closes the relay, exactly as it does for a
|
|
21
|
+
* quitting interactive pi.
|
|
22
|
+
*/
|
|
23
|
+
import { createAgentSession, } from "@earendil-works/pi-coding-agent";
|
|
24
|
+
import { probeListPeers, } from "@geohar/un-bien";
|
|
25
|
+
import { LOCAL_SESSION_NAME, sessionSockPath, } from "@geohar/un-bien/durable";
|
|
26
|
+
/** Default readiness deadline: the launched session's auto-init does a cwd
|
|
27
|
+
* lock + config read + UDS broker join before the name is visible. */
|
|
28
|
+
const DEFAULT_READY_TIMEOUT_MS = 60_000;
|
|
29
|
+
const READY_POLL_INTERVAL_MS = 250;
|
|
30
|
+
export class HeadlessPiLaunch {
|
|
31
|
+
async launchHeadless(opts) {
|
|
32
|
+
const { session } = await createAgentSession({ cwd: opts.cwd });
|
|
33
|
+
return new HeadlessPiSession(session, opts.name);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
export class HeadlessPiSession {
|
|
37
|
+
session;
|
|
38
|
+
name;
|
|
39
|
+
constructor(session, name) {
|
|
40
|
+
this.session = session;
|
|
41
|
+
this.name = name;
|
|
42
|
+
}
|
|
43
|
+
/** join-mesh-under-name: bind the scoped name, then bring the un-bien
|
|
44
|
+
* extension up. `bindExtensions` fires session_start; the extension's
|
|
45
|
+
* auto-init resolves the mesh name from the session display name (set
|
|
46
|
+
* FIRST so the join sees it) and connects the broker. */
|
|
47
|
+
async joinMeshUnderName() {
|
|
48
|
+
this.session.setSessionName(this.name);
|
|
49
|
+
await this.session.bindExtensions({});
|
|
50
|
+
}
|
|
51
|
+
/** await-ready: poll the broker's observer probe until the scoped name is
|
|
52
|
+
* a registered peer. Resolves with the broker-assigned address (the name
|
|
53
|
+
* may carry a `#N` collision suffix the broker added). */
|
|
54
|
+
async awaitReady(opts) {
|
|
55
|
+
const timeoutMs = opts?.timeoutMs ?? DEFAULT_READY_TIMEOUT_MS;
|
|
56
|
+
const deadline = Date.now() + timeoutMs;
|
|
57
|
+
for (;;) {
|
|
58
|
+
const probe = await probeListPeers(sessionSockPath(LOCAL_SESSION_NAME), 2_000);
|
|
59
|
+
if (probe.status === "ok") {
|
|
60
|
+
const match = probe.detailed.find((entry) => entry.name === this.name ||
|
|
61
|
+
entry.name.startsWith(`${this.name}#`));
|
|
62
|
+
if (match)
|
|
63
|
+
return { address: match.address };
|
|
64
|
+
}
|
|
65
|
+
if (Date.now() >= deadline) {
|
|
66
|
+
throw new Error(`launched pi session "${this.name}" did not join the mesh within ` +
|
|
67
|
+
`${timeoutMs}ms — the un-bien extension must be discoverable by ` +
|
|
68
|
+
`pi from the target cwd (installed pi-package or .pi/extensions) ` +
|
|
69
|
+
`and that cwd needs a un-bien local config (auto_start_relay)`);
|
|
70
|
+
}
|
|
71
|
+
await new Promise((resolve) => setTimeout(resolve, READY_POLL_INTERVAL_MS));
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
/** tear-down: quit gracefully (extension disposal leaves the mesh). */
|
|
75
|
+
async tearDown() {
|
|
76
|
+
try {
|
|
77
|
+
this.session.dispose();
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
/* best-effort — dispose must not throw even mid-run */
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=pi_launch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pi_launch.js","sourceRoot":"","sources":["../src/pi_launch.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,OAAO,EACL,kBAAkB,GAEnB,MAAM,iCAAiC,CAAA;AAKxC,OAAO,EACL,cAAc,GACf,MAAM,iBAAiB,CAAA;AACxB,OAAO,EACL,kBAAkB,EAClB,eAAe,GAChB,MAAM,yBAAyB,CAAA;AAEhC;uEACuE;AACvE,MAAM,wBAAwB,GAAG,MAAM,CAAA;AACvC,MAAM,sBAAsB,GAAG,GAAG,CAAA;AAElC,MAAM,OAAO,gBAAgB;IAC3B,KAAK,CAAC,cAAc,CAAC,IAGpB;QACC,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,kBAAkB,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAA;QAC/D,OAAO,IAAI,iBAAiB,CAAC,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,CAAA;IAClD,CAAC;CACF;AAED,MAAM,OAAO,iBAAiB;IAET,OAAO;IACf,IAAI;IAFf,YACmB,OAAqB,EAC7B,IAAY;uBADJ,OAAO;oBACf,IAAI;IACZ,CAAC;IAEJ;;;8DAG0D;IAC1D,KAAK,CAAC,iBAAiB;QACrB,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QACtC,MAAM,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,EAAE,CAAC,CAAA;IACvC,CAAC;IAED;;+DAE2D;IAC3D,KAAK,CAAC,UAAU,CAAC,IAEhB;QACC,MAAM,SAAS,GAAG,IAAI,EAAE,SAAS,IAAI,wBAAwB,CAAA;QAC7D,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAA;QACvC,SAAS,CAAC;YACR,MAAM,KAAK,GAAG,MAAM,cAAc,CAChC,eAAe,CAAC,kBAAkB,CAAC,EACnC,KAAK,CACN,CAAA;YACD,IAAI,KAAK,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC;gBAC1B,MAAM,KAAK,GAAG,KAAK,CAAC,QAAQ,CAAC,IAAI,CAC/B,CAAC,KAAK,EAAE,EAAE,CACR,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI;oBACxB,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,IAAI,CAAC,IAAI,GAAG,CAAC,CACzC,CAAA;gBACD,IAAI,KAAK;oBAAE,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAA;YAC9C,CAAC;YACD,IAAI,IAAI,CAAC,GAAG,EAAE,IAAI,QAAQ,EAAE,CAAC;gBAC3B,MAAM,IAAI,KAAK,CACb,wBAAwB,IAAI,CAAC,IAAI,iCAAiC;oBAChE,GAAG,SAAS,qDAAqD;oBACjE,kEAAkE;oBAClE,8DAA8D,CACjE,CAAA;YACH,CAAC;YACD,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAC5B,UAAU,CAAC,OAAO,EAAE,sBAAsB,CAAC,CAC5C,CAAA;QACH,CAAC;IACH,CAAC;IAED,uEAAuE;IACvE,KAAK,CAAC,QAAQ;QACZ,IAAI,CAAC;YACH,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAA;QACxB,CAAC;QAAC,MAAM,CAAC;YACP,uDAAuD;QACzD,CAAC;IACH,CAAC;CACF"}
|
package/dist/port.d.ts
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Durable binding's AgentSessionPort + SessionControlPort implementations.
|
|
3
|
+
*
|
|
4
|
+
* A durable Conversation already has everything the port promises, with ONE
|
|
5
|
+
* structural difference from pi: its transcript and busy state are read
|
|
6
|
+
* asynchronously (Chord commits), while the port is synchronous (inbound rpc
|
|
7
|
+
* dispatch must not await the store). The bridge closes that gap with a
|
|
8
|
+
* TRANSCRIPT MIRROR (mirror.ts) kept in sync by the ConversationViewSource,
|
|
9
|
+
* which grows it with every entry the conversation view adds. Because
|
|
10
|
+
* durable conversation IDs are
|
|
11
|
+
* stable across restarts, there is NO session-replacement machinery here —
|
|
12
|
+
* no generations, no disposal re-arm, no stale-ctx juggling. A replacement
|
|
13
|
+
* is just a new conversation handle retargeted into a fresh port.
|
|
14
|
+
*
|
|
15
|
+
* ID mapping (documented v1 contract): durable ids are Seq-orderable
|
|
16
|
+
* branded numbers; the app's wire protocol (pi `SessionEntry` shape) keys
|
|
17
|
+
* entries by STRING ids and resumes paging with `since: <string leafId>`.
|
|
18
|
+
* The mirror stringifies every entry id (`String(id)`, `<id>.<n>` for an
|
|
19
|
+
* entry's later model messages) and the session-control verbs parse the
|
|
20
|
+
* app's string ids back with `entryIdOf`.
|
|
21
|
+
*/
|
|
22
|
+
import type { Context } from "@earendil-works/chord";
|
|
23
|
+
import type { Conversation } from "@earendil-works/pi-durable";
|
|
24
|
+
import type { AgentSessionPort, EntriesPage, EntryRange, NotifyLevel, SessionControlPort, SubmitContent, SubmitOptions, SubmitResult } from "@geohar/un-bien/core";
|
|
25
|
+
import { type DurableTranscriptMirror } from "./mirror.js";
|
|
26
|
+
export { DurableTranscriptMirror } from "./mirror.js";
|
|
27
|
+
export interface DurableSessionPortOptions {
|
|
28
|
+
/** The conversation this port serves (stable id across restarts). */
|
|
29
|
+
conversation: Conversation;
|
|
30
|
+
/** Chord context for the async handoffs (BACKGROUND_CONTEXT in the host). */
|
|
31
|
+
context: Context;
|
|
32
|
+
/** Transcript mirror fed by the host's ConversationViewSource. */
|
|
33
|
+
mirror: DurableTranscriptMirror;
|
|
34
|
+
/** The conversation's working directory (host-configured). */
|
|
35
|
+
cwd: string;
|
|
36
|
+
/** Live busy flag, maintained by the host from run_start/run_end events. */
|
|
37
|
+
busy(): boolean;
|
|
38
|
+
/** Append a custom entry via a committed app entry (best-effort). */
|
|
39
|
+
appendAppEntry(entry: {
|
|
40
|
+
customType: string;
|
|
41
|
+
content: string;
|
|
42
|
+
display?: boolean;
|
|
43
|
+
details?: unknown;
|
|
44
|
+
}): void;
|
|
45
|
+
/** Log surface for notify + asynchronous submission failures. */
|
|
46
|
+
log(message: string, level?: NotifyLevel): void;
|
|
47
|
+
/** Event-plane fanout hook (the host's ConversationViewSource); the port's
|
|
48
|
+
* subscribeEvents is additive on it. Absent = no events surface. */
|
|
49
|
+
subscribe?(handler: (event: string, payload: unknown) => void): () => void;
|
|
50
|
+
}
|
|
51
|
+
export declare class DurableSessionPort implements AgentSessionPort {
|
|
52
|
+
private readonly opts;
|
|
53
|
+
constructor(opts: DurableSessionPortOptions);
|
|
54
|
+
private get conversation();
|
|
55
|
+
get sessionId(): string | null;
|
|
56
|
+
get cwd(): string;
|
|
57
|
+
get streaming(): boolean;
|
|
58
|
+
submit(content: SubmitContent, submitOpts?: SubmitOptions): SubmitResult;
|
|
59
|
+
getEntries(range?: EntryRange): EntriesPage;
|
|
60
|
+
abort(): boolean;
|
|
61
|
+
compact(opts?: {
|
|
62
|
+
customInstructions?: string;
|
|
63
|
+
}): void;
|
|
64
|
+
notify(message: string, level?: NotifyLevel): void;
|
|
65
|
+
appendEntry(entry: {
|
|
66
|
+
customType: string;
|
|
67
|
+
content: string;
|
|
68
|
+
display?: boolean;
|
|
69
|
+
details?: unknown;
|
|
70
|
+
}): void;
|
|
71
|
+
subscribeEvents(handler: (event: string, payload: unknown) => void): () => void;
|
|
72
|
+
}
|
|
73
|
+
export interface DurableSessionControlOptions {
|
|
74
|
+
/** Create a conversation on the harness (the pi `new_session` analog). */
|
|
75
|
+
createConversation(context: Context): Promise<Conversation>;
|
|
76
|
+
/** Called with the NEW conversation so the host retargets bridge + port. */
|
|
77
|
+
retarget(conversation: Conversation): Promise<void>;
|
|
78
|
+
/** The CURRENT conversation (for fork). */
|
|
79
|
+
current(): Conversation;
|
|
80
|
+
context: Context;
|
|
81
|
+
/** Graceful host shutdown (close relay + harness; the process exits). */
|
|
82
|
+
shutdownHost(): Promise<void>;
|
|
83
|
+
}
|
|
84
|
+
export declare class DurableSessionControl implements SessionControlPort {
|
|
85
|
+
private readonly opts;
|
|
86
|
+
constructor(opts: DurableSessionControlOptions);
|
|
87
|
+
newSession(): Promise<void>;
|
|
88
|
+
fork(entryId: string, _opts?: {
|
|
89
|
+
position?: "at" | "before";
|
|
90
|
+
requestId?: string;
|
|
91
|
+
}): Promise<void>;
|
|
92
|
+
navigateTree(_entryId: string): Promise<void>;
|
|
93
|
+
shutdown(): Promise<void>;
|
|
94
|
+
}
|
package/dist/port.js
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { entryIdOf } from "./mirror.js";
|
|
2
|
+
export { DurableTranscriptMirror } from "./mirror.js";
|
|
3
|
+
export class DurableSessionPort {
|
|
4
|
+
opts;
|
|
5
|
+
constructor(opts) {
|
|
6
|
+
this.opts = opts;
|
|
7
|
+
}
|
|
8
|
+
get conversation() {
|
|
9
|
+
return this.opts.conversation;
|
|
10
|
+
}
|
|
11
|
+
get sessionId() {
|
|
12
|
+
return String(this.opts.conversation.id);
|
|
13
|
+
}
|
|
14
|
+
get cwd() {
|
|
15
|
+
return this.opts.cwd;
|
|
16
|
+
}
|
|
17
|
+
get streaming() {
|
|
18
|
+
return this.opts.busy();
|
|
19
|
+
}
|
|
20
|
+
submit(content, submitOpts) {
|
|
21
|
+
// Fire-and-forget, matching the port contract: a refused handoff must be
|
|
22
|
+
// a synchronous answer, but durable's submit is a commit — the wait
|
|
23
|
+
// happens on the harness side and the reply rides the event plane.
|
|
24
|
+
// `steer` maps to durable's whenBusy:"steer" (join the running work);
|
|
25
|
+
// everything else queues as a follow-up, pi's deliverAs:"followUp".
|
|
26
|
+
// The port's content blocks are structurally pi-ai's TextContent |
|
|
27
|
+
// ImageContent — the same blocks durable's user input accepts.
|
|
28
|
+
const draft = {
|
|
29
|
+
type: "input",
|
|
30
|
+
content,
|
|
31
|
+
whenBusy: submitOpts?.deliverAs === "steer" ? "steer" : undefined,
|
|
32
|
+
};
|
|
33
|
+
void this.conversation
|
|
34
|
+
.submit(draft, this.opts.context)
|
|
35
|
+
.then((submission) => submission.wait(this.opts.context))
|
|
36
|
+
.then((settled) => {
|
|
37
|
+
const record = settled;
|
|
38
|
+
if (record?.status === "unanswered") {
|
|
39
|
+
this.opts.log(`submission unanswered: ${String(record.reason ?? "unknown reason")}`, "warning");
|
|
40
|
+
}
|
|
41
|
+
})
|
|
42
|
+
.catch((err) => {
|
|
43
|
+
const detail = err instanceof Error ? err.message : String(err);
|
|
44
|
+
this.opts.log(`submission failed: ${detail}`, "error");
|
|
45
|
+
});
|
|
46
|
+
return { ok: true };
|
|
47
|
+
}
|
|
48
|
+
getEntries(range) {
|
|
49
|
+
return this.opts.mirror.page(range);
|
|
50
|
+
}
|
|
51
|
+
abort() {
|
|
52
|
+
// The port reports whether an abort was REQUESTED (the port surface is
|
|
53
|
+
// synchronous; durable's abort resolves once the conversation is idle).
|
|
54
|
+
if (!this.opts.busy())
|
|
55
|
+
return false;
|
|
56
|
+
// Fire-and-forget per the port contract — but not unguarded: a store
|
|
57
|
+
// failure must log, not surface as an unhandled rejection.
|
|
58
|
+
void this.conversation.abort(this.opts.context).catch((err) => {
|
|
59
|
+
const detail = err instanceof Error ? err.message : String(err);
|
|
60
|
+
this.opts.log(`abort failed: ${detail}`, "warning");
|
|
61
|
+
});
|
|
62
|
+
return true;
|
|
63
|
+
}
|
|
64
|
+
compact(opts) {
|
|
65
|
+
// Manual compaction always works on durable; it runs as a task and the
|
|
66
|
+
// bridge forwards its completion via the compaction events.
|
|
67
|
+
void this.conversation
|
|
68
|
+
.compact(opts?.customInstructions, this.opts.context)
|
|
69
|
+
.catch((err) => {
|
|
70
|
+
const detail = err instanceof Error ? err.message : String(err);
|
|
71
|
+
this.opts.log(`compact failed: ${detail}`, "warning");
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
notify(message, level = "info") {
|
|
75
|
+
this.opts.log(message, level);
|
|
76
|
+
}
|
|
77
|
+
appendEntry(entry) {
|
|
78
|
+
// Custom entries are data-only sidecars on the durable side (there is
|
|
79
|
+
// no TUI renderer here); committed best-effort through the host hook.
|
|
80
|
+
this.opts.appendAppEntry(entry);
|
|
81
|
+
}
|
|
82
|
+
subscribeEvents(handler) {
|
|
83
|
+
// The event plane is owned by the host's ConversationViewSource (one watch
|
|
84
|
+
// per conversation); the bridge fans translations to every subscriber.
|
|
85
|
+
// Registering through the port is additive on that fanout.
|
|
86
|
+
return this.opts.subscribe?.(handler) ?? (() => undefined);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
export class DurableSessionControl {
|
|
90
|
+
opts;
|
|
91
|
+
constructor(opts) {
|
|
92
|
+
this.opts = opts;
|
|
93
|
+
}
|
|
94
|
+
async newSession() {
|
|
95
|
+
const created = await this.opts.createConversation(this.opts.context);
|
|
96
|
+
await this.opts.retarget(created);
|
|
97
|
+
}
|
|
98
|
+
async fork(entryId, _opts) {
|
|
99
|
+
// Durable forks always branch AT the entry (there is no "before"
|
|
100
|
+
// placement); the requestId correlation is app-plane state the bridge
|
|
101
|
+
// tracks, not a conversation concern. The app's string id parses back
|
|
102
|
+
// to the durable Seq id (see the module header's ID-mapping note).
|
|
103
|
+
const at = entryIdOf(entryId);
|
|
104
|
+
if (at === undefined)
|
|
105
|
+
throw new Error(`Entry not found: ${entryId}`);
|
|
106
|
+
const forked = await this.opts.current().fork(at, {
|
|
107
|
+
ownership: { kind: "ownerless" },
|
|
108
|
+
}, this.opts.context);
|
|
109
|
+
await this.opts.retarget(forked);
|
|
110
|
+
}
|
|
111
|
+
async navigateTree(_entryId) {
|
|
112
|
+
// Durable transcripts are linear: branching happens by forking a NEW
|
|
113
|
+
// conversation (which keeps a stable id of its own). In-place leaf
|
|
114
|
+
// moves have no durable equivalent.
|
|
115
|
+
throw new Error("navigateTree is not implemented on the durable binding — fork instead");
|
|
116
|
+
}
|
|
117
|
+
async shutdown() {
|
|
118
|
+
await this.opts.shutdownHost();
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=port.js.map
|
package/dist/port.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"port.js","sourceRoot":"","sources":["../src/port.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type ToolRegistration } from "@earendil-works/pi-durable";
|
|
2
|
+
import type { MeshToolDef } from "@geohar/un-bien/core";
|
|
3
|
+
export declare class DurableToolRegistrar {
|
|
4
|
+
/** Registered so far — the host extension installs these in one bundle. */
|
|
5
|
+
readonly registrations: ToolRegistration[];
|
|
6
|
+
registerTool(def: MeshToolDef): void;
|
|
7
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { defineTool, } from "@earendil-works/pi-durable";
|
|
2
|
+
export class DurableToolRegistrar {
|
|
3
|
+
/** Registered so far — the host extension installs these in one bundle. */
|
|
4
|
+
registrations = [];
|
|
5
|
+
registerTool(def) {
|
|
6
|
+
this.registrations.push(defineTool({
|
|
7
|
+
name: def.name,
|
|
8
|
+
description: def.promptSnippet
|
|
9
|
+
? `${def.description}\n\nUsage: ${def.promptSnippet}`
|
|
10
|
+
: def.description,
|
|
11
|
+
parameters: def.parameters,
|
|
12
|
+
// SAFETY: the neutral defs build TypeBox schemas compatible with
|
|
13
|
+
// durable's validation; args arrive already validated, so the
|
|
14
|
+
// `never` parameter is only the generic inference's narrow view.
|
|
15
|
+
execute: async (args, _api, _context) => {
|
|
16
|
+
const outcome = await def.execute(args, undefined);
|
|
17
|
+
return {
|
|
18
|
+
output: outcome.content,
|
|
19
|
+
...(outcome.details !== undefined
|
|
20
|
+
? // SAFETY: the mesh tools' details payloads are all JSON
|
|
21
|
+
// trees (ACK results, MeshMessage records, rosters) — the
|
|
22
|
+
// neutral def types them `unknown` only to stay
|
|
23
|
+
// harness-neutral.
|
|
24
|
+
{ details: outcome.details }
|
|
25
|
+
: {}),
|
|
26
|
+
};
|
|
27
|
+
},
|
|
28
|
+
}));
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=registrar.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registrar.js","sourceRoot":"","sources":["../src/registrar.ts"],"names":[],"mappings":"AAcA,OAAO,EACL,UAAU,GAGX,MAAM,4BAA4B,CAAA;AAGnC,MAAM,OAAO,oBAAoB;IAC/B,2EAA2E;IAClE,aAAa,GAAuB,EAAE,CAAA;IAE/C,YAAY,CAAC,GAAgB;QAC3B,IAAI,CAAC,aAAa,CAAC,IAAI,CACrB,UAAU,CAAC;YACT,IAAI,EAAE,GAAG,CAAC,IAAI;YACd,WAAW,EAAE,GAAG,CAAC,aAAa;gBAC5B,CAAC,CAAC,GAAG,GAAG,CAAC,WAAW,cAAc,GAAG,CAAC,aAAa,EAAE;gBACrD,CAAC,CAAC,GAAG,CAAC,WAAW;YACnB,UAAU,EAAE,GAAG,CAAC,UAAU;YAC1B,iEAAiE;YACjE,8DAA8D;YAC9D,iEAAiE;YACjE,OAAO,EAAE,KAAK,EAAE,IAAW,EAAE,IAAI,EAAE,QAAQ,EAAgC,EAAE;gBAC3E,MAAM,OAAO,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,SAAS,CAAC,CAAA;gBAClD,OAAO;oBACL,MAAM,EAAE,OAAO,CAAC,OAAO;oBACvB,GAAG,CAAC,OAAO,CAAC,OAAO,KAAK,SAAS;wBAC/B,CAAC,CAAC,wDAAwD;4BACxD,0DAA0D;4BAC1D,gDAAgD;4BAChD,mBAAmB;4BACnB,EAAE,OAAO,EAAE,OAAO,CAAC,OAAoB,EAAE;wBAC3C,CAAC,CAAC,EAAE,CAAC;iBACR,CAAA;YACH,CAAC;SACF,CAAC,CACH,CAAA;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The default thinking level for durable conversations.
|
|
3
|
+
*
|
|
4
|
+
* pi-durable starts every conversation's agent at thinking level "off", so a
|
|
5
|
+
* reasoning model answers without reasoning blocks and its working
|
|
6
|
+
* narration arrives as plain text. pi starts sessions at the user's
|
|
7
|
+
* `defaultThinkingLevel` ("medium" unless configured). The bridge applies
|
|
8
|
+
* the same default to each conversation it attaches whose level is still
|
|
9
|
+
* "off", clamped to what the conversation's model supports (glm-5.3 has no
|
|
10
|
+
* "medium", so it gets "high"). A level other than "off" is left alone.
|
|
11
|
+
*/
|
|
12
|
+
import type { Context } from "@earendil-works/chord";
|
|
13
|
+
import type { ModelThinkingLevel } from "@earendil-works/pi-ai";
|
|
14
|
+
import { type Models } from "@earendil-works/pi-ai/models";
|
|
15
|
+
import type { Conversation } from "@earendil-works/pi-durable";
|
|
16
|
+
/** pi's default when settings name none. */
|
|
17
|
+
export declare const DEFAULT_THINKING_LEVEL: ModelThinkingLevel;
|
|
18
|
+
/** Parse a thinking level from a flag or env value; undefined when invalid. */
|
|
19
|
+
export declare function parseThinkingLevel(value: string | undefined): ModelThinkingLevel | undefined;
|
|
20
|
+
/**
|
|
21
|
+
* Raise `conversation` from "off" to `level` (clamped to its model).
|
|
22
|
+
* Returns the level set, or undefined when nothing changed.
|
|
23
|
+
*/
|
|
24
|
+
export declare function ensureThinkingLevel(conversation: Conversation, models: Models, level: ModelThinkingLevel, context: Context): Promise<ModelThinkingLevel | undefined>;
|
package/dist/thinking.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { clampThinkingLevel } from "@earendil-works/pi-ai/models";
|
|
2
|
+
/** pi's default when settings name none. */
|
|
3
|
+
export const DEFAULT_THINKING_LEVEL = "medium";
|
|
4
|
+
const LEVELS = [
|
|
5
|
+
"off",
|
|
6
|
+
"minimal",
|
|
7
|
+
"low",
|
|
8
|
+
"medium",
|
|
9
|
+
"high",
|
|
10
|
+
"xhigh",
|
|
11
|
+
"max",
|
|
12
|
+
];
|
|
13
|
+
/** Parse a thinking level from a flag or env value; undefined when invalid. */
|
|
14
|
+
export function parseThinkingLevel(value) {
|
|
15
|
+
return LEVELS.find((level) => level === value);
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Raise `conversation` from "off" to `level` (clamped to its model).
|
|
19
|
+
* Returns the level set, or undefined when nothing changed.
|
|
20
|
+
*/
|
|
21
|
+
export async function ensureThinkingLevel(conversation, models, level, context) {
|
|
22
|
+
if (level === "off")
|
|
23
|
+
return undefined;
|
|
24
|
+
const agent = await conversation.agent(context);
|
|
25
|
+
if (agent.thinkingLevel !== "off")
|
|
26
|
+
return undefined;
|
|
27
|
+
const model = agent.model !== undefined
|
|
28
|
+
? models.getModel(agent.model.provider, agent.model.modelId)
|
|
29
|
+
: undefined;
|
|
30
|
+
const target = model !== undefined ? clampThinkingLevel(model, level) : level;
|
|
31
|
+
if (target === "off")
|
|
32
|
+
return undefined;
|
|
33
|
+
await conversation.configure({ thinkingLevel: target }, context);
|
|
34
|
+
return target;
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=thinking.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"thinking.js","sourceRoot":"","sources":["../src/thinking.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,kBAAkB,EAAe,MAAM,8BAA8B,CAAA;AAG9E,4CAA4C;AAC5C,MAAM,CAAC,MAAM,sBAAsB,GAAuB,QAAQ,CAAA;AAElE,MAAM,MAAM,GAAkC;IAC5C,KAAK;IACL,SAAS;IACT,KAAK;IACL,QAAQ;IACR,MAAM;IACN,OAAO;IACP,KAAK;CACN,CAAA;AAED,+EAA+E;AAC/E,MAAM,UAAU,kBAAkB,CAChC,KAAyB;IAEzB,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,KAAK,CAAC,CAAA;AAChD,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,YAA0B,EAC1B,MAAc,EACd,KAAyB,EACzB,OAAgB;IAEhB,IAAI,KAAK,KAAK,KAAK;QAAE,OAAO,SAAS,CAAA;IACrC,MAAM,KAAK,GAAG,MAAM,YAAY,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;IAC/C,IAAI,KAAK,CAAC,aAAa,KAAK,KAAK;QAAE,OAAO,SAAS,CAAA;IACnD,MAAM,KAAK,GACT,KAAK,CAAC,KAAK,KAAK,SAAS;QACvB,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC;QAC5D,CAAC,CAAC,SAAS,CAAA;IACf,MAAM,MAAM,GAAG,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,kBAAkB,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAA;IAC7E,IAAI,MAAM,KAAK,KAAK;QAAE,OAAO,SAAS,CAAA;IACtC,MAAM,YAAY,CAAC,SAAS,CAAC,EAAE,aAAa,EAAE,MAAM,EAAE,EAAE,OAAO,CAAC,CAAA;IAChE,OAAO,MAAM,CAAA;AACf,CAAC"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Translate successive durable conversation-view states into pi's event
|
|
3
|
+
* plane: the event names and payloads `pi.on()` delivers, which the shared
|
|
4
|
+
* rpc-envelope producer turns into `pi --mode rpc` frames. The app therefore
|
|
5
|
+
* sees the same traffic from a durable conversation as from a pi session.
|
|
6
|
+
*
|
|
7
|
+
* pi-durable publishes state, not events: each view value holds the entries
|
|
8
|
+
* appended since the last one and the `pi.live` document (run control, the
|
|
9
|
+
* streaming answer, the tool round). `feed()` diffs that against what it has
|
|
10
|
+
* already emitted:
|
|
11
|
+
*
|
|
12
|
+
* pi.live.run appears / disappears → agent_start / agent_end + agent_settled
|
|
13
|
+
* first message of a turn → turn_start
|
|
14
|
+
* pi.user entry → message_start + message_end
|
|
15
|
+
* pi.live.generation.message → message_start, then message_update per
|
|
16
|
+
* block: text/thinking start, delta, end;
|
|
17
|
+
* toolcall_start, toolcall_end
|
|
18
|
+
* pi.assistant entry → remaining block deltas and ends, then
|
|
19
|
+
* message_end; with no tool calls, turn_end
|
|
20
|
+
* pi.live.tools slot running → tool_execution_start
|
|
21
|
+
* slot output/details change → tool_execution_update {content, details}
|
|
22
|
+
* pi.tool-result entry → tool_execution_end {content, details} with
|
|
23
|
+
* the message's isError, then message_start +
|
|
24
|
+
* message_end; the round's last → turn_end
|
|
25
|
+
* slot done without an entry (faulted) → tool_execution_end, isError
|
|
26
|
+
* pi.compaction entry → session_compact (the summary)
|
|
27
|
+
* un-bien.app entry, display → message_start + message_end, role custom
|
|
28
|
+
* pi.live.runFailure (new) → onRunFailure (the bridge records it as an
|
|
29
|
+
* app entry, which then arrives as above)
|
|
30
|
+
*
|
|
31
|
+
* No toolcall_delta: the view holds a call's parsed arguments, not pi's raw
|
|
32
|
+
* argument text, and the app builds tool cards from tool_execution_start.
|
|
33
|
+
*/
|
|
34
|
+
import type { EntryRecord, LiveState, RunFailure } from "@earendil-works/pi-durable";
|
|
35
|
+
type Emit = (name: string, payload: Record<string, unknown>) => void;
|
|
36
|
+
export interface ViewTranslatorOptions {
|
|
37
|
+
emit: Emit;
|
|
38
|
+
onBusyChange?(busy: boolean): void;
|
|
39
|
+
onRunFailure?(failure: RunFailure): void;
|
|
40
|
+
}
|
|
41
|
+
export declare class ViewTranslator {
|
|
42
|
+
private readonly opts;
|
|
43
|
+
private busy;
|
|
44
|
+
private inTurn;
|
|
45
|
+
/** Blocks of the streaming answer already emitted, and which are closed. */
|
|
46
|
+
private stream;
|
|
47
|
+
private lastAssistant;
|
|
48
|
+
private pendingCalls;
|
|
49
|
+
private turnResults;
|
|
50
|
+
private readonly toolsStarted;
|
|
51
|
+
private readonly toolsEnded;
|
|
52
|
+
private readonly toolProgress;
|
|
53
|
+
private runFailureTask;
|
|
54
|
+
constructor(opts: ViewTranslatorOptions);
|
|
55
|
+
/**
|
|
56
|
+
* Take the state at attachment without emitting: a run in flight sets the
|
|
57
|
+
* busy flag, and a run failure already recorded is not reported again.
|
|
58
|
+
*/
|
|
59
|
+
prime(live: LiveState | undefined): void;
|
|
60
|
+
/** Emit what changed: `added` are the entries new since the last call. */
|
|
61
|
+
feed(added: readonly EntryRecord[], live: LiveState | undefined): void;
|
|
62
|
+
private entry;
|
|
63
|
+
/** A message that arrives complete: start and end in one go. Only a run's
|
|
64
|
+
* messages open a turn; a notice written while idle (a run failure, a
|
|
65
|
+
* mesh notice) is just the message. */
|
|
66
|
+
private whole;
|
|
67
|
+
private assistant;
|
|
68
|
+
private toolResult;
|
|
69
|
+
private streaming;
|
|
70
|
+
/**
|
|
71
|
+
* Emit the block events that take the emitted blocks to `blocks`. A block
|
|
72
|
+
* ends when a later one starts, or, with `final`, at the message's end.
|
|
73
|
+
*/
|
|
74
|
+
private diffBlocks;
|
|
75
|
+
private endBlock;
|
|
76
|
+
private slot;
|
|
77
|
+
private startTool;
|
|
78
|
+
private argsOf;
|
|
79
|
+
private beginTurn;
|
|
80
|
+
private endTurn;
|
|
81
|
+
private endRun;
|
|
82
|
+
}
|
|
83
|
+
export {};
|