antechamber 0.2.20 → 0.2.21
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 +8 -0
- package/dist/pi-event-translation.d.ts +1 -1
- package/dist/pi-event-translation.js +12 -4
- package/dist/session-history.js +10 -4
- package/dist/sessions.js +2 -2
- package/dist/thinking-levels.d.ts +7 -1
- package/dist/thinking-levels.js +8 -0
- package/dist/types.d.ts +4 -1
- package/extensions/omo-dag/package.json +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,14 @@ and this project uses [Semantic Versioning](https://semver.org/).
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.2.21] - 2026-10-17
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- Keep a session's thinking level when it is reopened. User messages now carry the level as `model.variant`, both
|
|
15
|
+
live and in history rebuilt from OmO's session file. Without it OpenChamber fell back to the agent's default effort
|
|
16
|
+
and sent that with the next prompt, which reset the level and broke the prompt cache.
|
|
17
|
+
|
|
10
18
|
## [0.2.20] - 2026-10-17
|
|
11
19
|
|
|
12
20
|
### Fixed
|
|
@@ -35,7 +35,7 @@ export declare function syncSessionCost(s: ManagedSession): boolean;
|
|
|
35
35
|
* IDs derive from the native compaction entry, not its retained boundary:
|
|
36
36
|
* multiple compactions can retain the same entry.
|
|
37
37
|
*/
|
|
38
|
-
export declare function compactionMessages(s: ManagedSession, key: string, summary: string, created: number, model: OCModelRef | undefined): [OCMessageWithParts, OCMessageWithParts];
|
|
38
|
+
export declare function compactionMessages(s: ManagedSession, key: string, summary: string, created: number, model: OCModelRef | undefined, thinkingLevel: string | undefined): [OCMessageWithParts, OCMessageWithParts];
|
|
39
39
|
interface PiEventServices {
|
|
40
40
|
readonly emit: (directory: string, event: OCEvent | TodoUpdated) => void;
|
|
41
41
|
readonly subagents: SubagentBridge;
|
|
@@ -5,6 +5,7 @@ import { TodoBridge } from "./todo-bridge.js";
|
|
|
5
5
|
import { readSessionTree, recordTurn } from "./session-tree.js";
|
|
6
6
|
import { touchedFiles } from "./session-diff.js";
|
|
7
7
|
import { getAgentName } from "./agent-name.js";
|
|
8
|
+
import { userMessageModel } from "./thinking-levels.js";
|
|
8
9
|
import { debugLog } from "./misc-routes.js";
|
|
9
10
|
import { envSetting } from "./config.js";
|
|
10
11
|
export function id(prefix) {
|
|
@@ -100,14 +101,21 @@ export function syncSessionCost(s) {
|
|
|
100
101
|
* IDs derive from the native compaction entry, not its retained boundary:
|
|
101
102
|
* multiple compactions can retain the same entry.
|
|
102
103
|
*/
|
|
103
|
-
export function compactionMessages(s, key, summary, created, model) {
|
|
104
|
+
export function compactionMessages(s, key, summary, created, model, thinkingLevel) {
|
|
104
105
|
const sessionID = s.info.id;
|
|
105
106
|
const userID = `msg_compaction_${key}`;
|
|
106
107
|
const summaryID = `${userID}_summary`;
|
|
107
108
|
const served = model ?? { providerID: "unknown", modelID: "unknown" };
|
|
108
109
|
return [
|
|
109
110
|
{
|
|
110
|
-
info: {
|
|
111
|
+
info: {
|
|
112
|
+
id: userID,
|
|
113
|
+
sessionID,
|
|
114
|
+
role: "user",
|
|
115
|
+
time: { created },
|
|
116
|
+
agent: getAgentName(),
|
|
117
|
+
model: userMessageModel(served, thinkingLevel),
|
|
118
|
+
},
|
|
111
119
|
parts: [{ id: `prt_compaction_${key}`, sessionID, messageID: userID, type: "compaction", auto: false }],
|
|
112
120
|
},
|
|
113
121
|
{
|
|
@@ -222,7 +230,7 @@ export class PiEventTranslator {
|
|
|
222
230
|
role: "user",
|
|
223
231
|
time: { created: message.timestamp ?? Date.now() },
|
|
224
232
|
agent: getAgentName(),
|
|
225
|
-
model: s.model ?? { providerID: "unknown", modelID: "unknown" },
|
|
233
|
+
model: userMessageModel(s.model ?? { providerID: "unknown", modelID: "unknown" }, s.thinkingLevel),
|
|
226
234
|
},
|
|
227
235
|
parts: [{ id: id("prt"), sessionID: s.info.id, messageID, type: "text", text }],
|
|
228
236
|
};
|
|
@@ -554,7 +562,7 @@ export class PiEventTranslator {
|
|
|
554
562
|
key = entry.id;
|
|
555
563
|
}
|
|
556
564
|
}
|
|
557
|
-
for (const message of compactionMessages(s, key ?? id("compaction"), result.summary, Date.now(), s.model)) {
|
|
565
|
+
for (const message of compactionMessages(s, key ?? id("compaction"), result.summary, Date.now(), s.model, s.thinkingLevel)) {
|
|
558
566
|
if (messages.some((item) => item.info.id === message.info.id))
|
|
559
567
|
continue;
|
|
560
568
|
// Keep a hidden redo branch after the new turn, as appendMessage does.
|
package/dist/session-history.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { readFileSync } from "node:fs";
|
|
3
3
|
import { applyProviderToolResults, finishProviderToolParts, mapTool, providerToolParts, resultMetadata, resultText, } from "./tool-map.js";
|
|
4
4
|
import { TodoBridge } from "./todo-bridge.js";
|
|
5
|
+
import { userMessageModel } from "./thinking-levels.js";
|
|
5
6
|
import { contextMessageID } from "./prompt-parts.js";
|
|
6
7
|
import { bindMessageEntries } from "./session-tree.js";
|
|
7
8
|
import { taskParts, updateTaskParts, taskCompletions } from "./subagents.js";
|
|
@@ -127,6 +128,7 @@ export function parsePiSessionText(s, agentName, raw) {
|
|
|
127
128
|
const out = [];
|
|
128
129
|
const toolParts = new Map();
|
|
129
130
|
let currentModel = { providerID: "unknown", modelID: "unknown" };
|
|
131
|
+
let currentThinkingLevel;
|
|
130
132
|
let lastUserId = "";
|
|
131
133
|
// Like live agent_end, a new user turn closes the previous run: its own
|
|
132
134
|
// unresolved provider cards end with that run's stop reason.
|
|
@@ -142,9 +144,13 @@ export function parsePiSessionText(s, agentName, raw) {
|
|
|
142
144
|
currentModel = { providerID: e.provider, modelID: e.modelId };
|
|
143
145
|
continue;
|
|
144
146
|
}
|
|
147
|
+
if (e.type === "thinking_level_change" && typeof e.thinkingLevel === "string") {
|
|
148
|
+
currentThinkingLevel = e.thinkingLevel;
|
|
149
|
+
continue;
|
|
150
|
+
}
|
|
145
151
|
if (e.type === "compaction" && typeof e.summary === "string" && typeof e.firstKeptEntryId === "string") {
|
|
146
152
|
// Not a run boundary: an automatic compaction can sit between steps of one turn.
|
|
147
|
-
out.push(...compactionMessages(s, e.id ?? `r${indexOf.get(e) ?? 0}`, e.summary, entryTime(e), currentModel));
|
|
153
|
+
out.push(...compactionMessages(s, e.id ?? `r${indexOf.get(e) ?? 0}`, e.summary, entryTime(e), currentModel, currentThinkingLevel));
|
|
148
154
|
continue;
|
|
149
155
|
}
|
|
150
156
|
const contextID = contextMessageID(e);
|
|
@@ -165,7 +171,7 @@ export function parsePiSessionText(s, agentName, raw) {
|
|
|
165
171
|
role: "user",
|
|
166
172
|
time: { created: time },
|
|
167
173
|
agent: agentName,
|
|
168
|
-
model: currentModel,
|
|
174
|
+
model: userMessageModel(currentModel, currentThinkingLevel),
|
|
169
175
|
synthetic: true,
|
|
170
176
|
},
|
|
171
177
|
parts: [
|
|
@@ -205,7 +211,7 @@ export function parsePiSessionText(s, agentName, raw) {
|
|
|
205
211
|
role: "user",
|
|
206
212
|
time: { created },
|
|
207
213
|
agent: agentName,
|
|
208
|
-
model: currentModel,
|
|
214
|
+
model: userMessageModel(currentModel, currentThinkingLevel),
|
|
209
215
|
};
|
|
210
216
|
const parts = [
|
|
211
217
|
{
|
|
@@ -457,7 +463,7 @@ export function parsePiSessionText(s, agentName, raw) {
|
|
|
457
463
|
role: "user",
|
|
458
464
|
time: { created: entryTime(entry) },
|
|
459
465
|
agent: agentName,
|
|
460
|
-
model: currentModel,
|
|
466
|
+
model: userMessageModel(currentModel, currentThinkingLevel),
|
|
461
467
|
},
|
|
462
468
|
parts: [{ id: `prt_${messageID}_pending`, sessionID, messageID, type: "text", text }],
|
|
463
469
|
});
|
package/dist/sessions.js
CHANGED
|
@@ -9,7 +9,7 @@ import { existsSync, readdirSync, statSync, unlinkSync } from "node:fs";
|
|
|
9
9
|
import { join } from "node:path";
|
|
10
10
|
import { COMPACT_RPC_TIMEOUT_MS, PiRpcClient, RPC_COMMAND_TIMEOUT_MS, } from "./pi-rpc.js";
|
|
11
11
|
import { stopSessionHosts } from "./session-hosts.js";
|
|
12
|
-
import { setThinkingLevel } from "./thinking-levels.js";
|
|
12
|
+
import { setThinkingLevel, userMessageModel } from "./thinking-levels.js";
|
|
13
13
|
import { SessionLifecycle } from "./lifecycle.js";
|
|
14
14
|
import { ApprovalBridge, extensionUiRequestFrom } from "./approvals.js";
|
|
15
15
|
import { getAgentName, getExposedAgentNames } from "./agent-name.js";
|
|
@@ -908,7 +908,7 @@ export class SessionManager {
|
|
|
908
908
|
role: "user",
|
|
909
909
|
time: { created: Date.now() },
|
|
910
910
|
agent: getAgentName(),
|
|
911
|
-
model: s.model ?? model ?? { providerID: "unknown", modelID: "unknown" },
|
|
911
|
+
model: userMessageModel(s.model ?? model ?? { providerID: "unknown", modelID: "unknown" }, s.thinkingLevel),
|
|
912
912
|
...(context ? { synthetic: true } : {}),
|
|
913
913
|
...(metadata !== undefined ? { metadata } : {}),
|
|
914
914
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { PiRpcClient } from "./pi-rpc.js";
|
|
2
|
-
import type { OCModelRef } from "./types.js";
|
|
2
|
+
import type { OCModelRef, OCUserMessage } from "./types.js";
|
|
3
3
|
export interface ModelSelection extends OCModelRef {
|
|
4
4
|
readonly variant?: string;
|
|
5
5
|
}
|
|
@@ -10,6 +10,12 @@ export interface ThinkingModel {
|
|
|
10
10
|
}
|
|
11
11
|
/** OmO's RPC list is authoritative; null map entries explicitly disable a level. */
|
|
12
12
|
export declare function thinkingVariants(model: ThinkingModel): Record<string, Record<string, unknown>> | undefined;
|
|
13
|
+
/**
|
|
14
|
+
* A user message's model as OpenCode >= 1.4 stores it: the thinking level travels as
|
|
15
|
+
* `model.variant`. Without it OpenChamber restores the agent's default effort on every
|
|
16
|
+
* reopen and sends that with the next prompt, which resets the level and breaks the cache.
|
|
17
|
+
*/
|
|
18
|
+
export declare function userMessageModel(model: OCModelRef, variant: string | undefined): OCUserMessage["model"];
|
|
13
19
|
export interface ThinkingState {
|
|
14
20
|
thinkingLevel?: string;
|
|
15
21
|
}
|
package/dist/thinking-levels.js
CHANGED
|
@@ -8,6 +8,14 @@ export function thinkingVariants(model) {
|
|
|
8
8
|
.map(([level]) => level);
|
|
9
9
|
return levels.length === 0 ? undefined : Object.fromEntries(levels.map((level) => [level, {}]));
|
|
10
10
|
}
|
|
11
|
+
/**
|
|
12
|
+
* A user message's model as OpenCode >= 1.4 stores it: the thinking level travels as
|
|
13
|
+
* `model.variant`. Without it OpenChamber restores the agent's default effort on every
|
|
14
|
+
* reopen and sends that with the next prompt, which resets the level and breaks the cache.
|
|
15
|
+
*/
|
|
16
|
+
export function userMessageModel(model, variant) {
|
|
17
|
+
return { providerID: model.providerID, modelID: model.modelID, ...(variant !== undefined ? { variant } : {}) };
|
|
18
|
+
}
|
|
11
19
|
/** Cache only the level OmO actually applied, including when it clamps a request. */
|
|
12
20
|
export async function setThinkingLevel(state, pi, level) {
|
|
13
21
|
if (level === undefined || state.thinkingLevel === level)
|
package/dist/types.d.ts
CHANGED
|
@@ -61,7 +61,10 @@ export interface OCUserMessage {
|
|
|
61
61
|
created: number;
|
|
62
62
|
};
|
|
63
63
|
agent: string;
|
|
64
|
-
|
|
64
|
+
/** `variant` is the thinking level; OpenChamber restores the effort picker from the latest user message. */
|
|
65
|
+
model: OCModelRef & {
|
|
66
|
+
variant?: string;
|
|
67
|
+
};
|
|
65
68
|
/** No-reply context admitted without a turn (v2 lists it as `type: "synthetic"`). */
|
|
66
69
|
synthetic?: boolean;
|
|
67
70
|
/** Client metadata sent with the prompt (OpenChamber 2.x). */
|