@oh-my-pi/pi-coding-agent 16.1.10 → 16.1.12
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/dist/cli.js +2480 -2481
- package/dist/types/export/html/index.d.ts +31 -2
- package/dist/types/export/html/web-palette.d.ts +117 -0
- package/dist/types/export/share.d.ts +10 -5
- package/dist/types/hindsight/content.d.ts +7 -0
- package/dist/types/hindsight/transcript.d.ts +1 -1
- package/dist/types/modes/components/hook-editor.d.ts +2 -1
- package/dist/types/modes/interactive-mode.d.ts +5 -0
- package/dist/types/modes/types.d.ts +17 -0
- package/dist/types/modes/utils/keybinding-matchers.d.ts +13 -0
- package/dist/types/secrets/index.d.ts +1 -1
- package/dist/types/secrets/obfuscator.d.ts +43 -9
- package/dist/types/session/agent-session.d.ts +4 -0
- package/dist/types/session/session-context.d.ts +2 -0
- package/dist/types/session/session-entries.d.ts +6 -0
- package/dist/types/session/session-manager.d.ts +2 -1
- package/dist/types/tools/acp-bridge.d.ts +29 -0
- package/dist/types/tools/browser/cmux/cmux-tab.d.ts +7 -0
- package/dist/types/tools/browser/tab-worker.d.ts +20 -0
- package/dist/types/utils/jj.d.ts +25 -0
- package/dist/types/utils/title-generator.d.ts +0 -2
- package/package.json +12 -12
- package/scripts/generate-share-viewer.ts +4 -2
- package/src/autoresearch/git.ts +12 -0
- package/src/discovery/opencode.ts +47 -4
- package/src/edit/hashline/filesystem.ts +8 -0
- package/src/edit/modes/patch.ts +18 -2
- package/src/edit/modes/replace.ts +13 -10
- package/src/export/html/index.ts +50 -8
- package/src/export/html/web-palette.ts +142 -0
- package/src/export/share.ts +198 -8
- package/src/hindsight/backend.ts +4 -4
- package/src/hindsight/content.ts +17 -1
- package/src/hindsight/transcript.ts +2 -2
- package/src/internal-urls/docs-index.generated.txt +1 -1
- package/src/main.ts +8 -0
- package/src/modes/components/agent-dashboard.ts +8 -8
- package/src/modes/components/hook-editor.ts +13 -10
- package/src/modes/components/session-selector.ts +3 -0
- package/src/modes/controllers/event-controller.ts +9 -5
- package/src/modes/controllers/extension-ui-controller.ts +6 -2
- package/src/modes/interactive-mode.ts +69 -29
- package/src/modes/theme/dark.json +1 -1
- package/src/modes/types.ts +18 -0
- package/src/modes/utils/keybinding-matchers.ts +36 -1
- package/src/modes/utils/ui-helpers.ts +1 -0
- package/src/prompts/tools/browser.md +3 -2
- package/src/sdk.ts +14 -2
- package/src/secrets/index.ts +1 -1
- package/src/secrets/obfuscator.ts +220 -71
- package/src/session/agent-session.ts +57 -43
- package/src/session/session-context.ts +5 -0
- package/src/session/session-entries.ts +6 -0
- package/src/session/session-manager.ts +3 -1
- package/src/task/worktree.ts +12 -4
- package/src/thinking.ts +1 -1
- package/src/tools/acp-bridge.ts +66 -0
- package/src/tools/browser/cmux/cmux-tab.ts +37 -0
- package/src/tools/browser/tab-worker.ts +160 -37
- package/src/tools/write.ts +2 -25
- package/src/utils/jj.ts +47 -0
- package/src/utils/title-generator.ts +31 -99
|
@@ -12,7 +12,7 @@ import type { Settings } from "../config/settings";
|
|
|
12
12
|
import titleMarkerInstruction from "../prompts/system/title-marker-instruction.md" with { type: "text" };
|
|
13
13
|
import titleSystemPrompt from "../prompts/system/title-system.md" with { type: "text" };
|
|
14
14
|
import titleMarkerSystemPrompt from "../prompts/system/title-system-marker.md" with { type: "text" };
|
|
15
|
-
import { ONLINE_TINY_TITLE_MODEL_KEY } from "../tiny/models";
|
|
15
|
+
import { isTinyTitleLocalModelKey, ONLINE_TINY_TITLE_MODEL_KEY } from "../tiny/models";
|
|
16
16
|
import { formatTitleUserMessage, isLowSignalTitleInput, normalizeGeneratedTitle } from "../tiny/text";
|
|
17
17
|
import { tinyTitleClient } from "../tiny/title-client";
|
|
18
18
|
|
|
@@ -23,7 +23,6 @@ const TITLE_MARKER_INSTRUCTION = prompt.render(titleMarkerInstruction);
|
|
|
23
23
|
const DEFAULT_TERMINAL_TITLE = "π";
|
|
24
24
|
const TERMINAL_TITLE_CONTROL_CHARS = /[\u0000-\u001f\u007f-\u009f]/g;
|
|
25
25
|
|
|
26
|
-
export const TITLE_LOCAL_FALLBACK_DELAY_MS = 10_000;
|
|
27
26
|
const TITLE_MAX_TOKENS = 30;
|
|
28
27
|
const REASONING_SAFE_MAX_TOKENS = 1024;
|
|
29
28
|
const SET_TITLE_TOOL_NAME = "set_title";
|
|
@@ -81,78 +80,6 @@ function getTitleModel(registry: ModelRegistry, settings: Settings, currentModel
|
|
|
81
80
|
return undefined;
|
|
82
81
|
}
|
|
83
82
|
|
|
84
|
-
export async function raceFirstNonNull<T>(
|
|
85
|
-
primary: Promise<T | null>,
|
|
86
|
-
startFallback: () => Promise<T | null>,
|
|
87
|
-
delayMs: number = TITLE_LOCAL_FALLBACK_DELAY_MS,
|
|
88
|
-
onPrimaryWinAfterFallback?: () => void,
|
|
89
|
-
): Promise<T | null> {
|
|
90
|
-
const { promise, resolve } = Promise.withResolvers<T | null>();
|
|
91
|
-
let resolved = false;
|
|
92
|
-
let primarySettled = false;
|
|
93
|
-
let fallbackStarted = false;
|
|
94
|
-
let fallbackSettled = false;
|
|
95
|
-
|
|
96
|
-
const resolveOnce = (value: T | null): void => {
|
|
97
|
-
if (resolved) return;
|
|
98
|
-
resolved = true;
|
|
99
|
-
resolve(value);
|
|
100
|
-
};
|
|
101
|
-
const maybeResolveNull = (): void => {
|
|
102
|
-
if (primarySettled && fallbackStarted && fallbackSettled) resolveOnce(null);
|
|
103
|
-
};
|
|
104
|
-
const startFallbackOnce = (): void => {
|
|
105
|
-
if (fallbackStarted || resolved) return;
|
|
106
|
-
fallbackStarted = true;
|
|
107
|
-
let fallback: Promise<T | null>;
|
|
108
|
-
try {
|
|
109
|
-
fallback = startFallback();
|
|
110
|
-
} catch {
|
|
111
|
-
fallbackSettled = true;
|
|
112
|
-
maybeResolveNull();
|
|
113
|
-
return;
|
|
114
|
-
}
|
|
115
|
-
void fallback.then(
|
|
116
|
-
value => {
|
|
117
|
-
fallbackSettled = true;
|
|
118
|
-
if (value !== null) resolveOnce(value);
|
|
119
|
-
else maybeResolveNull();
|
|
120
|
-
},
|
|
121
|
-
() => {
|
|
122
|
-
fallbackSettled = true;
|
|
123
|
-
maybeResolveNull();
|
|
124
|
-
},
|
|
125
|
-
);
|
|
126
|
-
};
|
|
127
|
-
|
|
128
|
-
const timer = setTimeout(startFallbackOnce, delayMs);
|
|
129
|
-
void primary.then(
|
|
130
|
-
value => {
|
|
131
|
-
primarySettled = true;
|
|
132
|
-
clearTimeout(timer);
|
|
133
|
-
if (value !== null) {
|
|
134
|
-
if (fallbackStarted) onPrimaryWinAfterFallback?.();
|
|
135
|
-
resolveOnce(value);
|
|
136
|
-
return;
|
|
137
|
-
}
|
|
138
|
-
startFallbackOnce();
|
|
139
|
-
maybeResolveNull();
|
|
140
|
-
},
|
|
141
|
-
() => {
|
|
142
|
-
primarySettled = true;
|
|
143
|
-
clearTimeout(timer);
|
|
144
|
-
startFallbackOnce();
|
|
145
|
-
maybeResolveNull();
|
|
146
|
-
},
|
|
147
|
-
);
|
|
148
|
-
|
|
149
|
-
try {
|
|
150
|
-
return await promise;
|
|
151
|
-
} finally {
|
|
152
|
-
clearTimeout(timer);
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
|
|
156
83
|
/**
|
|
157
84
|
* Generate a title for a session based on the first user message.
|
|
158
85
|
*
|
|
@@ -200,36 +127,41 @@ export async function generateSessionTitle(
|
|
|
200
127
|
);
|
|
201
128
|
}
|
|
202
129
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
130
|
+
// User explicitly picked a local tiny model. NEVER fall back to the online
|
|
131
|
+
// smol path (issue #3187): the smol role resolves through priority.json and
|
|
132
|
+
// silently bills whatever provider holds the resolved API key — OpenRouter
|
|
133
|
+
// in the reporter's case, leaking real credits without consent. If the
|
|
134
|
+
// local worker fails (unknown key, download missing, transformers.js
|
|
135
|
+
// crash, abort), leave the session untitled; the next user turn retries.
|
|
136
|
+
if (!isTinyTitleLocalModelKey(tinyModel)) {
|
|
137
|
+
logger.warn("title-generator: unknown local tiny model; skipping title (will not fall back to online)", {
|
|
138
|
+
sessionId,
|
|
139
|
+
model: tinyModel,
|
|
140
|
+
reason: "unknown-local-model",
|
|
141
|
+
});
|
|
142
|
+
return null;
|
|
143
|
+
}
|
|
144
|
+
try {
|
|
145
|
+
const localTitle = titleSystemPrompt
|
|
146
|
+
? await tinyTitleClient.generate(tinyModel, firstMessage, { systemPrompt: titleSystemPrompt })
|
|
147
|
+
: await tinyTitleClient.generate(tinyModel, firstMessage);
|
|
148
|
+
if (!localTitle) {
|
|
149
|
+
logger.warn("title-generator: local tiny model produced no title; skipping (no online fallback)", {
|
|
211
150
|
sessionId,
|
|
212
151
|
model: tinyModel,
|
|
213
|
-
|
|
152
|
+
reason: "local-no-output",
|
|
214
153
|
});
|
|
215
154
|
return null;
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
firstMessage,
|
|
221
|
-
registry,
|
|
222
|
-
settings,
|
|
155
|
+
}
|
|
156
|
+
return localTitle;
|
|
157
|
+
} catch (err) {
|
|
158
|
+
logger.warn("title-generator: local tiny model errored; skipping (no online fallback)", {
|
|
223
159
|
sessionId,
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
return raceFirstNonNull(localTitle, startOnline, TITLE_LOCAL_FALLBACK_DELAY_MS, () => {
|
|
231
|
-
onlineAbortController.abort();
|
|
232
|
-
});
|
|
160
|
+
model: tinyModel,
|
|
161
|
+
error: err instanceof Error ? err.message : String(err),
|
|
162
|
+
});
|
|
163
|
+
return null;
|
|
164
|
+
}
|
|
233
165
|
}
|
|
234
166
|
|
|
235
167
|
export async function generateTitleOnline(
|