teapot-coding-agent 0.17.7 → 0.17.9
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/dist/agent/agent.js +29 -2
- package/dist/master.js +8 -2
- package/dist/model-meta.js +3 -1
- package/dist/server/api.js +4 -1
- package/package.json +1 -1
- package/public/assets/{index-BYsAwMLd.js → index---2ewwxO.js} +22 -22
- package/public/assets/index---2ewwxO.js.map +1 -0
- package/public/assets/{index-Bx8y52-N.css → index-Dk6pnmQd.css} +1 -1
- package/public/assets/{shiki--p20uN1M.js → shiki-yEid1sXe.js} +2 -2
- package/public/assets/{shiki--p20uN1M.js.map → shiki-yEid1sXe.js.map} +1 -1
- package/public/index.html +2 -2
- package/public/assets/index-BYsAwMLd.js.map +0 -1
package/dist/agent/agent.js
CHANGED
|
@@ -100,6 +100,8 @@ export class Agent {
|
|
|
100
100
|
runChain = Promise.resolve();
|
|
101
101
|
/** whether contextTokenBudget came from config (manual) or was derived */
|
|
102
102
|
manualCompactBudget = false;
|
|
103
|
+
/** workspace dir absent at boot — session runs "as ghost" until created */
|
|
104
|
+
workspaceMissing = false;
|
|
103
105
|
lastProgressAt = Date.now();
|
|
104
106
|
/** the provider's own prompt_tokens from the last completed turn */
|
|
105
107
|
lastUsage;
|
|
@@ -192,6 +194,18 @@ export class Agent {
|
|
|
192
194
|
get workspace() {
|
|
193
195
|
return this.opts.workspace;
|
|
194
196
|
}
|
|
197
|
+
/** true while the workspace directory does not exist on disk yet */
|
|
198
|
+
get isGhost() {
|
|
199
|
+
return this.workspaceMissing;
|
|
200
|
+
}
|
|
201
|
+
/** Create the workspace on demand — before any tool touches the fs. */
|
|
202
|
+
async ensureWorkspace() {
|
|
203
|
+
if (!this.workspaceMissing)
|
|
204
|
+
return;
|
|
205
|
+
await fs.mkdir(this.opts.workspace, { recursive: true });
|
|
206
|
+
this.workspaceMissing = false;
|
|
207
|
+
bus.emit("update", { kind: "agent-update", agentId: this.opts.id });
|
|
208
|
+
}
|
|
195
209
|
/** true when the operator pinned contextTokenBudget in the config */
|
|
196
210
|
get compactBudgetIsManual() {
|
|
197
211
|
return this.manualCompactBudget;
|
|
@@ -232,7 +246,15 @@ export class Agent {
|
|
|
232
246
|
}
|
|
233
247
|
async init() {
|
|
234
248
|
await this.log.load();
|
|
235
|
-
|
|
249
|
+
// NOTE: the workspace is NOT created here. Boot-time mkdir resurrected
|
|
250
|
+
// deleted project directories on every restart, which operators hated.
|
|
251
|
+
// It is created lazily in ensureWorkspace() when the agent first needs
|
|
252
|
+
// to touch the filesystem. Until then a missing workspace marks the
|
|
253
|
+
// session as "ghost" (visible-but-flagged in the UI).
|
|
254
|
+
this.workspaceMissing = !(await fs
|
|
255
|
+
.stat(this.workspace)
|
|
256
|
+
.then(() => true)
|
|
257
|
+
.catch(() => false));
|
|
236
258
|
// goal lives next to the session log (dataDir), NOT in the workspace —
|
|
237
259
|
// migrate a legacy workspace GOAL.md once, then never touch the workspace
|
|
238
260
|
await this.migrateGoalFromWorkspace();
|
|
@@ -402,7 +424,9 @@ export class Agent {
|
|
|
402
424
|
this.stats.compactions++;
|
|
403
425
|
}
|
|
404
426
|
}
|
|
405
|
-
//
|
|
427
|
+
// newest usage event seeds the context gauge right after reload —
|
|
428
|
+
// inputTokens from the LAST turn is the live context size, and cached
|
|
429
|
+
// must ride along or the "⚡ N% cached" pill disappears after a restart
|
|
406
430
|
for (let i = own.length - 1; i >= 0; i--) {
|
|
407
431
|
if (own[i].type === "usage") {
|
|
408
432
|
const u = own[i].data;
|
|
@@ -629,6 +653,7 @@ export class Agent {
|
|
|
629
653
|
status: this.status,
|
|
630
654
|
statusReason: this.statusReason,
|
|
631
655
|
workspace: this.workspace,
|
|
656
|
+
workspaceMissing: this.workspaceMissing,
|
|
632
657
|
session: this.currentSession,
|
|
633
658
|
branch: this.currentBranch,
|
|
634
659
|
goal: {
|
|
@@ -1199,6 +1224,8 @@ export class Agent {
|
|
|
1199
1224
|
argsRaw: call.function.arguments, // byte-exact for cache-safe restore
|
|
1200
1225
|
});
|
|
1201
1226
|
const t0 = Date.now();
|
|
1227
|
+
// first filesystem touch creates a missing workspace (never at boot)
|
|
1228
|
+
await this.ensureWorkspace();
|
|
1202
1229
|
const result = await executeTool(call.function.name, call.function.arguments, this.toolCtx);
|
|
1203
1230
|
this.stats.toolCalls++;
|
|
1204
1231
|
await this.log.append("tool_result", this.currentSession, this.currentBranch, {
|
package/dist/master.js
CHANGED
|
@@ -357,8 +357,14 @@ export class Master {
|
|
|
357
357
|
// endpoint, cached) unless the config already pins one explicitly
|
|
358
358
|
let inferredWindow;
|
|
359
359
|
if (!ac.contextWindowTokens && !this.config.contextWindowTokens) {
|
|
360
|
-
|
|
361
|
-
|
|
360
|
+
// don't block the event loop on provider metadata: fire the lookup but
|
|
361
|
+
// keep boot moving. The agent's gauge fills in when it resolves.
|
|
362
|
+
const listPromise = fetchModelList(llm.baseUrl, llm.apiKey);
|
|
363
|
+
inferredWindow = await Promise.race([
|
|
364
|
+
listPromise.then((l) => contextLengthFor(l, llm.model)),
|
|
365
|
+
new Promise((r) => setTimeout(() => r(undefined), 1_500)),
|
|
366
|
+
]);
|
|
367
|
+
void listPromise.catch(() => []);
|
|
362
368
|
}
|
|
363
369
|
const sessionDir = this.resolveSessionDir(ac.id, opts.fresh === true);
|
|
364
370
|
await mkdirSync(sessionDir, { recursive: true });
|
package/dist/model-meta.js
CHANGED
|
@@ -19,7 +19,9 @@ export async function fetchModelList(baseUrl, apiKey) {
|
|
|
19
19
|
...(apiKey ? { authorization: `Bearer ${apiKey}` } : {}),
|
|
20
20
|
...providerHeaders(baseUrl), // OpenRouter app attribution
|
|
21
21
|
},
|
|
22
|
-
|
|
22
|
+
// boot-time calls happen per agent; a slow/unroutable endpoint used to
|
|
23
|
+
// stall startup for up to 15s PER AGENT before this was tightened
|
|
24
|
+
signal: AbortSignal.timeout(3_000),
|
|
23
25
|
});
|
|
24
26
|
if (!res.ok)
|
|
25
27
|
throw new Error(`HTTP ${res.status}`);
|
package/dist/server/api.js
CHANGED
|
@@ -387,6 +387,8 @@ export function buildApp(master) {
|
|
|
387
387
|
for (const d of dirents) {
|
|
388
388
|
if (d.name.startsWith(".") && !(showHidden && d.name !== "." && d.name !== ".."))
|
|
389
389
|
continue; // hidden files stay out unless the caller opted in
|
|
390
|
+
// .git behaves like an ignored entry (dimmed/hidden with the rest)
|
|
391
|
+
const forceIgnored = !d.isDirectory() ? false : d.name === ".git";
|
|
390
392
|
const isDir = d.isDirectory();
|
|
391
393
|
let size;
|
|
392
394
|
if (!isDir) {
|
|
@@ -397,11 +399,12 @@ export function buildApp(master) {
|
|
|
397
399
|
/* vanished mid-scan — fine */
|
|
398
400
|
}
|
|
399
401
|
}
|
|
402
|
+
const gitIg = ignoredNames.has(d.name);
|
|
400
403
|
entries.push({
|
|
401
404
|
name: d.name,
|
|
402
405
|
dir: isDir,
|
|
403
406
|
...(size !== undefined ? { size } : {}),
|
|
404
|
-
...(
|
|
407
|
+
...(gitIg || forceIgnored ? { ignored: true } : {}),
|
|
405
408
|
});
|
|
406
409
|
}
|
|
407
410
|
entries.sort((x, y) => (x.dir !== y.dir ? (x.dir ? -1 : 1) : x.name.localeCompare(y.name)));
|