@code-yeongyu/senpi-agent-core 2026.10.21-2 → 2026.10.21-3
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.
|
@@ -79,6 +79,9 @@ export const DEFAULT_COMPACTION_SETTINGS = {
|
|
|
79
79
|
};
|
|
80
80
|
/** Calculate total context tokens from provider usage. */
|
|
81
81
|
export function calculateContextTokens(usage) {
|
|
82
|
+
if (usage.contextUsage !== undefined) {
|
|
83
|
+
return usage.contextUsage === null ? 0 : usage.contextUsage.input + usage.contextUsage.output;
|
|
84
|
+
}
|
|
82
85
|
return usage.totalTokens || usage.input + usage.output + usage.cacheRead + usage.cacheWrite;
|
|
83
86
|
}
|
|
84
87
|
function getAssistantUsage(msg) {
|
|
@@ -96,7 +96,11 @@ export declare class Harness<Ks extends readonly AnyKind[] = []> {
|
|
|
96
96
|
private reconcileOrphans;
|
|
97
97
|
quiescent(): boolean;
|
|
98
98
|
hold(): () => void;
|
|
99
|
-
/**
|
|
99
|
+
/**
|
|
100
|
+
* Cancel and join in-process invocations, clear transient waits, then close without terminalizing tasks.
|
|
101
|
+
* The views and the session are closed even when joining or the waiting-state commit fails (a storage
|
|
102
|
+
* that refuses writes), so a failed suspend never leaks the session files; the first error is rethrown.
|
|
103
|
+
*/
|
|
100
104
|
suspend(ctx: Context): Promise<void>;
|
|
101
105
|
registerTaskKind<K extends AnyKind>(kind: K): () => void;
|
|
102
106
|
namespace<T extends JsonObject>(id: string, defaults: NamespaceDefaults<T>, opts?: {
|
|
@@ -266,26 +266,43 @@ export class Harness {
|
|
|
266
266
|
throw new Error("cannot hold a non-quiescent harness; suspend it instead");
|
|
267
267
|
return this.scheduler.hold();
|
|
268
268
|
}
|
|
269
|
-
/**
|
|
269
|
+
/**
|
|
270
|
+
* Cancel and join in-process invocations, clear transient waits, then close without terminalizing tasks.
|
|
271
|
+
* The views and the session are closed even when joining or the waiting-state commit fails (a storage
|
|
272
|
+
* that refuses writes), so a failed suspend never leaks the session files; the first error is rethrown.
|
|
273
|
+
*/
|
|
270
274
|
async suspend(ctx) {
|
|
271
275
|
if (this.suspended)
|
|
272
276
|
return;
|
|
273
277
|
this.suspended = true;
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
const
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
const
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
278
|
+
let failure;
|
|
279
|
+
try {
|
|
280
|
+
await this.scheduler.joinAll();
|
|
281
|
+
const tools = [...this.session.liveTasks.values()].filter((task) => task.kind === "pi.tool");
|
|
282
|
+
if (tools.length > 0) {
|
|
283
|
+
const docs = [...new Set(tools.map((task) => task.conversationId))].map((conversationId) => ({ doc: "sticky", conversationId }));
|
|
284
|
+
await this.session.commit(KERNEL, (tx) => {
|
|
285
|
+
for (const task of tools) {
|
|
286
|
+
const index = task.input.index;
|
|
287
|
+
const slot = tx.sticky(task.conversationId).turn.tools[index];
|
|
288
|
+
if (slot?.waitingOn !== undefined)
|
|
289
|
+
delete slot.waitingOn;
|
|
290
|
+
}
|
|
291
|
+
}, ctx, { docs });
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
catch (error) {
|
|
295
|
+
failure = { error };
|
|
286
296
|
}
|
|
287
297
|
this.views.close();
|
|
288
|
-
|
|
298
|
+
try {
|
|
299
|
+
await this.session.close(ctx);
|
|
300
|
+
}
|
|
301
|
+
catch (error) {
|
|
302
|
+
failure ??= { error };
|
|
303
|
+
}
|
|
304
|
+
if (failure !== undefined)
|
|
305
|
+
throw failure.error;
|
|
289
306
|
}
|
|
290
307
|
// --- registries --------------------------------------------------------------
|
|
291
308
|
registerTaskKind(kind) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@code-yeongyu/senpi-agent-core",
|
|
3
|
-
"version": "2026.10.21-
|
|
3
|
+
"version": "2026.10.21-3",
|
|
4
4
|
"description": "General-purpose agent with transport abstraction, state management, and attachment support",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -62,8 +62,8 @@
|
|
|
62
62
|
},
|
|
63
63
|
"dependencies": {
|
|
64
64
|
"@earendil-works/chord": "0.99.1",
|
|
65
|
-
"@earendil-works/pi-ai": "npm:@code-yeongyu/senpi-ai@2026.10.21-
|
|
66
|
-
"@earendil-works/pi-telemetry": "npm:@code-yeongyu/senpi-telemetry@2026.10.21-
|
|
65
|
+
"@earendil-works/pi-ai": "npm:@code-yeongyu/senpi-ai@2026.10.21-3",
|
|
66
|
+
"@earendil-works/pi-telemetry": "npm:@code-yeongyu/senpi-telemetry@2026.10.21-3",
|
|
67
67
|
"diff": "9.0.0",
|
|
68
68
|
"ignore": "7.0.9",
|
|
69
69
|
"typebox": "1.3.34",
|