antechamber 0.1.1 → 0.2.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/CHANGELOG.md +45 -0
- package/README.md +24 -14
- package/bin/opencode-antechamber +14 -1
- package/bin/opencode-pi +11 -1
- package/dist/approvals.d.ts +4 -1
- package/dist/approvals.js +51 -33
- package/dist/catalog.d.ts +1 -1
- package/dist/catalog.js +1 -1
- package/dist/commands/context.d.ts +0 -1
- package/dist/commands/context.js +1 -1
- package/dist/commands/doctor.d.ts +3 -2
- package/dist/commands/serve.d.ts +2 -1
- package/dist/commands/setup.d.ts +2 -3
- package/dist/commands/setup.js +16 -4
- package/dist/http.d.ts +8 -1
- package/dist/http.js +42 -19
- package/dist/pi-event-translation.d.ts +10 -6
- package/dist/pi-event-translation.js +237 -80
- package/dist/pi-rpc.d.ts +20 -2
- package/dist/pi-rpc.js +96 -29
- package/dist/prompt-parts.d.ts +40 -0
- package/dist/prompt-parts.js +157 -0
- package/dist/route-services.d.ts +45 -2
- package/dist/route-services.js +70 -3
- package/dist/routes-v1.js +113 -65
- package/dist/routes-v2.js +407 -95
- package/dist/server.d.ts +9 -1
- package/dist/server.js +109 -9
- package/dist/session-commands.d.ts +12 -15
- package/dist/session-commands.js +54 -13
- package/dist/session-diff.d.ts +1 -1
- package/dist/session-diff.js +10 -2
- package/dist/session-history.d.ts +1 -1
- package/dist/session-history.js +110 -44
- package/dist/session-hosts.js +2 -2
- package/dist/session-store.d.ts +8 -4
- package/dist/session-store.js +191 -38
- package/dist/session-tree.d.ts +10 -2
- package/dist/session-tree.js +55 -26
- package/dist/sessions.d.ts +32 -5
- package/dist/sessions.js +331 -120
- package/dist/sse.d.ts +16 -6
- package/dist/sse.js +77 -21
- package/dist/subagents.d.ts +5 -0
- package/dist/subagents.js +84 -71
- package/dist/tool-map.d.ts +3 -2
- package/dist/types.d.ts +152 -1
- package/dist/v2.d.ts +18 -4
- package/dist/v2.js +128 -44
- package/dist/vcs.d.ts +5 -0
- package/dist/vcs.js +199 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/extensions/omo-dag/README.md +2 -0
- package/extensions/omo-dag/docs/DESIGN.md +10 -1
- package/extensions/omo-dag/panel/index.html +1 -1
- package/extensions/omo-dag/panel/main.js +60 -60
- package/extensions/omo-dag/service/main.js +72 -8
- package/package.json +1 -1
package/dist/session-tree.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { RPC_COMMAND_TIMEOUT_MS } from "./pi-rpc.js";
|
|
2
2
|
import { readFileSync } from "node:fs";
|
|
3
|
+
import { contextMessageID, nativePromptInput } from "./prompt-parts.js";
|
|
3
4
|
export class SessionTreeError extends Error {
|
|
4
5
|
}
|
|
5
6
|
export function durableShellTree(tree) {
|
|
@@ -59,19 +60,19 @@ export function branchEntries(tree, leafId = tree.leafId) {
|
|
|
59
60
|
}
|
|
60
61
|
return branch.reverse();
|
|
61
62
|
}
|
|
62
|
-
|
|
63
|
-
export function bindMessageEntries(s, tree) {
|
|
63
|
+
function selectedLeafId(s, tree) {
|
|
64
64
|
let leafId = tree.leafId;
|
|
65
65
|
if (!s.tree.revert && s.tree.leafId !== undefined && s.tree.leafId !== null) {
|
|
66
66
|
const selected = branchEntries(tree, s.tree.leafId);
|
|
67
67
|
// A stale snapshot cannot discard a selection or its identity candidates.
|
|
68
68
|
if (selected.length === 0)
|
|
69
|
-
return;
|
|
69
|
+
return undefined;
|
|
70
70
|
if (tree.leafId === null || selected.some((entry) => entry.id === tree.leafId))
|
|
71
71
|
leafId = s.tree.leafId;
|
|
72
72
|
}
|
|
73
|
-
|
|
74
|
-
|
|
73
|
+
return leafId;
|
|
74
|
+
}
|
|
75
|
+
function pruneStaleShellTurns(s, positions) {
|
|
75
76
|
s.tree.localShellTurns = (s.tree.localShellTurns ?? []).filter((turn) => {
|
|
76
77
|
if (turn.afterEntryId === null || positions.has(turn.afterEntryId))
|
|
77
78
|
return true;
|
|
@@ -83,13 +84,58 @@ export function bindMessageEntries(s, tree) {
|
|
|
83
84
|
delete s.tree.shellDispatch[turn.messages[1].info.id];
|
|
84
85
|
return false;
|
|
85
86
|
});
|
|
87
|
+
}
|
|
88
|
+
function bindOrdinaryEntry(s, entry, messages, cursor) {
|
|
89
|
+
const content = entry.message?.content;
|
|
90
|
+
// pi allows plain-string message content (extensions, append_user_message).
|
|
91
|
+
const text = typeof content === "string"
|
|
92
|
+
? content
|
|
93
|
+
: content
|
|
94
|
+
?.filter((part) => part.type === "text")
|
|
95
|
+
.map((part) => part.text ?? "")
|
|
96
|
+
.join("");
|
|
97
|
+
const index = messages.findIndex((message, position) => position >= cursor &&
|
|
98
|
+
!s.localMessageIds?.has(message.info.id) &&
|
|
99
|
+
s.tree.messageEntries[message.info.id] === undefined &&
|
|
100
|
+
message.info.role === entry.message?.role &&
|
|
101
|
+
(message.info.role !== "user" ||
|
|
102
|
+
(s.tree.promptParts?.[message.info.id]
|
|
103
|
+
? nativePromptInput(message.parts
|
|
104
|
+
.filter((part) => part.type === "text")
|
|
105
|
+
.map((part) => part.text)
|
|
106
|
+
.join("\n"), s.tree.promptParts[message.info.id] ?? []).message
|
|
107
|
+
: message.parts
|
|
108
|
+
.filter((part) => part.type === "text")
|
|
109
|
+
.map((part) => part.text)
|
|
110
|
+
.join("")) === text));
|
|
111
|
+
const message = messages[index];
|
|
112
|
+
if (message === undefined)
|
|
113
|
+
return cursor;
|
|
114
|
+
s.tree.messageEntries[message.info.id] = entry.id;
|
|
115
|
+
return index + 1;
|
|
116
|
+
}
|
|
117
|
+
/** Live ids belong to the UI; restored ids belong to JSONL offsets. Save both. */
|
|
118
|
+
export function bindMessageEntries(s, tree) {
|
|
119
|
+
const leafId = selectedLeafId(s, tree);
|
|
120
|
+
if (leafId === undefined)
|
|
121
|
+
return;
|
|
122
|
+
const branch = branchEntries(tree, s.tree.revert ? s.tree.revert.previousLeafId : leafId);
|
|
123
|
+
const positions = new Map(branch.map((entry, index) => [entry.id, index]));
|
|
124
|
+
pruneStaleShellTurns(s, positions);
|
|
125
|
+
// Admitted context carries its OpenChamber id in the native custom message.
|
|
126
|
+
for (const entry of branch) {
|
|
127
|
+
const messageID = contextMessageID(entry);
|
|
128
|
+
if (messageID !== undefined && s.messages?.some((message) => message.info.id === messageID))
|
|
129
|
+
s.tree.messageEntries[messageID] = entry.id;
|
|
130
|
+
}
|
|
86
131
|
const entries = branch.filter((entry) => entry.type === "message" &&
|
|
87
132
|
(entry.message?.role === "user" ||
|
|
88
133
|
entry.message?.role === "assistant" ||
|
|
89
134
|
entry.message?.role === "bashExecution"));
|
|
135
|
+
const localShellTurns = s.tree.localShellTurns ?? [];
|
|
90
136
|
const visible = s.messages ?? [];
|
|
91
137
|
const visibleIds = new Set(visible.map((message) => message.info.id));
|
|
92
|
-
const candidates =
|
|
138
|
+
const candidates = localShellTurns
|
|
93
139
|
.flatMap((turn) => turn.messages)
|
|
94
140
|
.filter((message) => !visibleIds.has(message.info.id));
|
|
95
141
|
for (const message of candidates)
|
|
@@ -167,32 +213,15 @@ export function bindMessageEntries(s, tree) {
|
|
|
167
213
|
}
|
|
168
214
|
continue;
|
|
169
215
|
}
|
|
170
|
-
|
|
171
|
-
?.filter((part) => part.type === "text")
|
|
172
|
-
.map((part) => part.text ?? "")
|
|
173
|
-
.join("");
|
|
174
|
-
const index = messages.findIndex((message, i) => i >= cursor &&
|
|
175
|
-
!s.localMessageIds?.has(message.info.id) &&
|
|
176
|
-
s.tree.messageEntries[message.info.id] === undefined &&
|
|
177
|
-
message.info.role === entry.message?.role &&
|
|
178
|
-
(message.info.role !== "user" ||
|
|
179
|
-
message.parts
|
|
180
|
-
.filter((part) => part.type === "text")
|
|
181
|
-
.map((part) => part.text)
|
|
182
|
-
.join("") === text));
|
|
183
|
-
const message = messages[index];
|
|
184
|
-
if (message) {
|
|
185
|
-
s.tree.messageEntries[message.info.id] = entry.id;
|
|
186
|
-
cursor = index + 1;
|
|
187
|
-
}
|
|
216
|
+
cursor = bindOrdinaryEntry(s, entry, messages, cursor);
|
|
188
217
|
}
|
|
189
218
|
// Syncs/agent events preserve an active revert's navigation pin. Only
|
|
190
219
|
// revert/unrevert select it explicitly; prompt clears the pin before branching.
|
|
191
220
|
if (!s.tree.revert)
|
|
192
221
|
s.tree.leafId = leafId;
|
|
193
|
-
s.tree.localShellTurns =
|
|
222
|
+
s.tree.localShellTurns = localShellTurns.filter((turn) => s.tree.messageEntries[turn.messages[1].info.id] === undefined);
|
|
194
223
|
}
|
|
195
|
-
|
|
224
|
+
function entryForMessage(s, tree, messageID) {
|
|
196
225
|
const entryId = s.tree.messageEntries[messageID];
|
|
197
226
|
const entry = tree.entries.find((candidate) => candidate.id === entryId);
|
|
198
227
|
if (!entry || !s.messages?.some((message) => message.info.id === messageID)) {
|
package/dist/sessions.d.ts
CHANGED
|
@@ -10,7 +10,7 @@ import type { TodoBridge, Todo, TodoUpdated } from "./todo-bridge.js";
|
|
|
10
10
|
import { type SessionTreeState } from "./session-tree.js";
|
|
11
11
|
import { SubagentBridge } from "./subagents.js";
|
|
12
12
|
import { SessionStore, type TitleSource } from "./session-store.js";
|
|
13
|
-
import type { OCAssistantMessage, OCEvent, OCMessageWithParts, OCModelRef, OCPart, OCSession, OCSessionStatus, OCToolPart } from "./types.js";
|
|
13
|
+
import type { OCAssistantMessage, OCEvent, OCMessageWithParts, OCModelRef, OCPart, OCPromptPart, OCSession, OCSessionStatus, OCToolPart } from "./types.js";
|
|
14
14
|
export { ADAPTER_VERSION } from "./version.js";
|
|
15
15
|
interface StreamingState {
|
|
16
16
|
message: OCAssistantMessage;
|
|
@@ -18,6 +18,7 @@ interface StreamingState {
|
|
|
18
18
|
parts: Map<number, OCPart>;
|
|
19
19
|
}
|
|
20
20
|
export interface ManagedSession extends ThinkingState {
|
|
21
|
+
interruptRequested?: boolean;
|
|
21
22
|
titleSource?: TitleSource;
|
|
22
23
|
activeUserMessageID?: string;
|
|
23
24
|
inputs?: Map<string, {
|
|
@@ -42,6 +43,7 @@ export interface ManagedSession extends ThinkingState {
|
|
|
42
43
|
streaming: StreamingState | undefined;
|
|
43
44
|
/** A manual compaction started while idle; its end returns the session to idle. */
|
|
44
45
|
compactingFromIdle?: boolean;
|
|
46
|
+
compactionID?: string;
|
|
45
47
|
/** Cancels the adapter-owned user bash waiter and its OmO execution. */
|
|
46
48
|
cancelShell?: (interrupted?: boolean) => void;
|
|
47
49
|
/**
|
|
@@ -85,8 +87,14 @@ export declare class SessionManager {
|
|
|
85
87
|
/** freshness of the all-directories scan (see listAll). */
|
|
86
88
|
private scanAllCache;
|
|
87
89
|
constructor(emit: EventSink, store?: SessionStore, defaultDirectory?: string | undefined, lifecycleOptions?: LifecycleOptions);
|
|
88
|
-
create(directory: string, title?: string, parentID?: string
|
|
90
|
+
create(directory: string, title?: string, parentID?: string, options?: {
|
|
91
|
+
id?: string;
|
|
92
|
+
agent?: string;
|
|
93
|
+
model?: ModelSelection;
|
|
94
|
+
metadata?: Record<string, unknown>;
|
|
95
|
+
}): Promise<OCSession>;
|
|
89
96
|
private createLive;
|
|
97
|
+
private rollbackCreate;
|
|
90
98
|
private applyNativeTitle;
|
|
91
99
|
private refreshNativeTitles;
|
|
92
100
|
private wirePi;
|
|
@@ -111,11 +119,15 @@ export declare class SessionManager {
|
|
|
111
119
|
update(sessionId: string, patch: {
|
|
112
120
|
title?: string | undefined;
|
|
113
121
|
archived?: number | undefined;
|
|
114
|
-
|
|
122
|
+
metadata?: Record<string, unknown> | undefined;
|
|
123
|
+
agent?: string | undefined;
|
|
124
|
+
}): Promise<OCSession | undefined>;
|
|
115
125
|
messages(sessionId: string): OCMessageWithParts[] | undefined;
|
|
116
126
|
/** Append to canonical history, before the hidden redo branch while reverted. */
|
|
117
127
|
appendMessage(sessionId: string, message: OCMessageWithParts): void;
|
|
118
128
|
private operation;
|
|
129
|
+
/** Cancellation releases only the caller; the native action keeps its queue lease. */
|
|
130
|
+
private waitForOperation;
|
|
119
131
|
private syncTree;
|
|
120
132
|
private treeSession;
|
|
121
133
|
fork(sessionId: string, messageID?: string): Promise<OCSession>;
|
|
@@ -126,7 +138,13 @@ export declare class SessionManager {
|
|
|
126
138
|
private reloadMessagesLive;
|
|
127
139
|
statuses(): Record<string, OCSessionStatus>;
|
|
128
140
|
todos(sessionId: string): Todo[] | undefined;
|
|
129
|
-
|
|
141
|
+
commitRevert(sessionId: string): Promise<void>;
|
|
142
|
+
private commitRevertLive;
|
|
143
|
+
diff(sessionId: string, options?: {
|
|
144
|
+
from?: string | undefined;
|
|
145
|
+
to?: string | undefined;
|
|
146
|
+
context?: number | undefined;
|
|
147
|
+
}): Promise<import("./session-diff.js").SessionFileDiff[]>;
|
|
130
148
|
private emitDiff;
|
|
131
149
|
abort(sessionId: string): Promise<boolean>;
|
|
132
150
|
permissions(sessionId?: string): PendingPermission[];
|
|
@@ -149,8 +167,17 @@ export declare class SessionManager {
|
|
|
149
167
|
* the next cold start, and tell the UI. Returns whether anything changed.
|
|
150
168
|
*/
|
|
151
169
|
private applyPiModel;
|
|
152
|
-
prompt(sessionId: string, text: string, model?: ModelSelection, noReply?: boolean, messageID?: string, delivery?: "steer" | "queue"): Promise<void>;
|
|
170
|
+
prompt(sessionId: string, text: string, model?: ModelSelection, noReply?: boolean, messageID?: string, delivery?: "steer" | "queue", parts?: readonly OCPromptPart[], metadata?: Record<string, unknown>): Promise<void>;
|
|
171
|
+
private preparePrompt;
|
|
172
|
+
private publishPrompt;
|
|
153
173
|
private promptLive;
|
|
174
|
+
/**
|
|
175
|
+
* No-reply context (v2 synthetic, v1 noReply) joins the native conversation without a turn:
|
|
176
|
+
* OmO appends it now when idle, or after the running turn, so the next prompt carries it.
|
|
177
|
+
*/
|
|
178
|
+
private admitContext;
|
|
179
|
+
private dispatchPrompt;
|
|
180
|
+
private bindPromptState;
|
|
154
181
|
disposeAll(): Promise<void>;
|
|
155
182
|
/** Spawn pi against the session's JSONL file and adopt it as live. */
|
|
156
183
|
private revive;
|