@takboo/dsh-session-bin 0.1.0 → 0.2.0
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/README.md +10 -10
- package/dist/client-model.js +61 -2
- package/dist/client.js +223 -137
- package/dist/client.js.map +1 -1
- package/dist/host/native-retirement-metadata.d.ts +7 -0
- package/dist/index.js +92 -5
- package/dist/index.js.map +2 -2
- package/dist/types/client/locales.d.ts +11 -4
- package/dist/types/client/model.d.ts +15 -1
- package/docs/client-interface.md +4 -4
- package/docs/host-lifecycle.md +2 -0
- package/package.json +1 -1
|
@@ -64,6 +64,9 @@ export declare class NativeMetadataAdapter {
|
|
|
64
64
|
private readonly targets;
|
|
65
65
|
private readonly retained;
|
|
66
66
|
private readonly followers;
|
|
67
|
+
private readonly followerStops;
|
|
68
|
+
private readonly activationTarget;
|
|
69
|
+
private readonly apiHandles;
|
|
67
70
|
private readonly operations;
|
|
68
71
|
private readonly queueTarget;
|
|
69
72
|
private readonly receivers;
|
|
@@ -78,6 +81,7 @@ export declare class NativeMetadataAdapter {
|
|
|
78
81
|
private readonly queryProvider;
|
|
79
82
|
private readonly cacheTable;
|
|
80
83
|
private readonly cacheDirectory;
|
|
84
|
+
private readonly agents;
|
|
81
85
|
private moveCacheDocument;
|
|
82
86
|
private clearCacheStage;
|
|
83
87
|
private removeCacheStage;
|
|
@@ -90,6 +94,9 @@ export declare class NativeMetadataAdapter {
|
|
|
90
94
|
private refuse;
|
|
91
95
|
private assertInstances;
|
|
92
96
|
private assertCold;
|
|
97
|
+
/** Explicit deletion preparation may unload an idle API-owned lifecycle.
|
|
98
|
+
* No bare registry Agent, foreign handle, or unknown reader is disposed. */
|
|
99
|
+
releaseIdle(id: string): Promise<void>;
|
|
93
100
|
private cacheView;
|
|
94
101
|
private openCacheDocument;
|
|
95
102
|
private pathAbsent;
|
package/dist/index.js
CHANGED
|
@@ -1834,6 +1834,20 @@ async function nativeRetirementSdkFingerprint() {
|
|
|
1834
1834
|
if (createHash3("sha256").update(await readFile(join2(dirname(path), file))).digest("hex") !== digest2) return null;
|
|
1835
1835
|
}
|
|
1836
1836
|
}
|
|
1837
|
+
const runtime = createRequire(base.resolve("@deepseek-ai/dsh-base/package.json"));
|
|
1838
|
+
for (const [name2, expected] of Object.entries({
|
|
1839
|
+
"dsh-agent": "7b9aa39474de83115cf890dd7f8904cf0d59df0811cb335ab85565a04f1aac93",
|
|
1840
|
+
"dsh-agent-loop": "00c4814d63f3d1e2754eb09144832d19b30499d6ea444730473f740b587948c2"
|
|
1841
|
+
})) {
|
|
1842
|
+
let path;
|
|
1843
|
+
try {
|
|
1844
|
+
path = runtime.resolve(`@deepseek-ai/${name2}/package.json`);
|
|
1845
|
+
} catch (error) {
|
|
1846
|
+
if (error.code === "MODULE_NOT_FOUND") return null;
|
|
1847
|
+
throw error;
|
|
1848
|
+
}
|
|
1849
|
+
if (JSON.parse(await readFile(path, "utf8")).version !== "0.2.0-rc.2" || createHash3("sha256").update(await readFile(join2(dirname(path), "lib/index.js"))).digest("hex") !== expected) return null;
|
|
1850
|
+
}
|
|
1837
1851
|
return createHash3("sha256").update(JSON.stringify(nativeRetirementSdkSources)).digest("hex");
|
|
1838
1852
|
}
|
|
1839
1853
|
|
|
@@ -2448,10 +2462,14 @@ var NativeMetadataAdapter = class _NativeMetadataAdapter {
|
|
|
2448
2462
|
this.queryProvider = !query ? "none" : query.config.openAt === "never" ? "sqlite-memory-disabled-0.2.0-rc.2" : "sqlite-0.2.0-rc.2";
|
|
2449
2463
|
this.cacheTable = cache?.requireTable();
|
|
2450
2464
|
this.cacheDirectory = this.cacheTable?.host.unit.dir;
|
|
2465
|
+
this.agents = controller ? _NativeMetadataAdapter.get(ctx, "agents") : void 0;
|
|
2451
2466
|
}
|
|
2452
2467
|
targets = /* @__PURE__ */ new Set();
|
|
2453
2468
|
retained = /* @__PURE__ */ new Map();
|
|
2454
2469
|
followers = /* @__PURE__ */ new Map();
|
|
2470
|
+
followerStops = /* @__PURE__ */ new Map();
|
|
2471
|
+
activationTarget = new AsyncLocalStorage();
|
|
2472
|
+
apiHandles = /* @__PURE__ */ new Map();
|
|
2455
2473
|
operations = /* @__PURE__ */ new Map();
|
|
2456
2474
|
queueTarget = new AsyncLocalStorage();
|
|
2457
2475
|
receivers = new AsyncLocalStorage();
|
|
@@ -2466,6 +2484,7 @@ var NativeMetadataAdapter = class _NativeMetadataAdapter {
|
|
|
2466
2484
|
queryProvider;
|
|
2467
2485
|
cacheTable;
|
|
2468
2486
|
cacheDirectory;
|
|
2487
|
+
agents;
|
|
2469
2488
|
moveCacheDocument = renameWindowsWriteThrough;
|
|
2470
2489
|
clearCacheStage = async (handle) => {
|
|
2471
2490
|
await handle.truncate(0);
|
|
@@ -2494,7 +2513,7 @@ var NativeMetadataAdapter = class _NativeMetadataAdapter {
|
|
|
2494
2513
|
const disabledMemory = query.config?.openAt === "never" && query.config.path === ":memory:" && query._db === void 0 && query._ready === void 0;
|
|
2495
2514
|
if (query.constructor.name !== "SqliteSessionQueryEngine" || !enabled && !disabledMemory || typeof query.config?.path !== "string" || !methods(query, ["searchSessions", "listSessions", "observeSession", "_serialized"]) || !(query._observations?.cache instanceof Map) || !methods(query._observations, ["read", "store"])) return void 0;
|
|
2496
2515
|
}
|
|
2497
|
-
if (controller && (controller.constructor.name !== "SessionController" || !(controller.history?.closeFollowers instanceof Set) || !methods(controller.history, ["page", "follow", "sourceFor"]))) return void 0;
|
|
2516
|
+
if (controller && (controller.constructor.name !== "SessionController" || !(controller.history?.closeFollowers instanceof Set) || !methods(controller.history, ["page", "follow", "sourceFor"]) || controller.agents?.constructor.name !== "ApiSessionAgentController" || !methods(controller.agents, ["resumeObserved", "createOrAdopt"]) || !methods(controller.listState ?? {}, ["summarizeCold"]) || !methods(this.get(ctx, "agents") ?? {}, ["create", "resume", "get"]))) return void 0;
|
|
2498
2517
|
return new _NativeMetadataAdapter(ctx, admission, workspace, sessions, cache, query, controller);
|
|
2499
2518
|
}
|
|
2500
2519
|
assert(id) {
|
|
@@ -2533,7 +2552,7 @@ var NativeMetadataAdapter = class _NativeMetadataAdapter {
|
|
|
2533
2552
|
if (this.guardedMethods.some(({ port, name: name2, replacement }) => port[name2] !== replacement)) {
|
|
2534
2553
|
this.refuse("native/guard-replaced", "A native metadata admission guard was replaced.");
|
|
2535
2554
|
}
|
|
2536
|
-
if (_NativeMetadataAdapter.get(this.ctx, "workspaceRegistry") !== this.workspace || _NativeMetadataAdapter.get(this.ctx, "sessions") !== this.sessions || _NativeMetadataAdapter.get(this.ctx, "sessionProjectionCache") !== this.cache || _NativeMetadataAdapter.get(this.ctx, "sessionQuery") !== this.query || _NativeMetadataAdapter.get(this.ctx, "sessionController") !== this.controller || this.cache && (this.cache.requireTable() !== this.cacheTable || this.cacheTable.host.unit.dir !== this.cacheDirectory) || this.query && (this.query.config.path !== this.queryConfiguration.path || this.query.config.openAt !== this.queryConfiguration.openAt) || this.queryProvider === "sqlite-memory-disabled-0.2.0-rc.2" && (this.query._db !== void 0 || this.query._ready !== void 0)) {
|
|
2555
|
+
if (_NativeMetadataAdapter.get(this.ctx, "workspaceRegistry") !== this.workspace || _NativeMetadataAdapter.get(this.ctx, "sessions") !== this.sessions || _NativeMetadataAdapter.get(this.ctx, "sessionProjectionCache") !== this.cache || _NativeMetadataAdapter.get(this.ctx, "sessionQuery") !== this.query || _NativeMetadataAdapter.get(this.ctx, "sessionController") !== this.controller || this.controller && _NativeMetadataAdapter.get(this.ctx, "agents") !== this.agents || this.cache && (this.cache.requireTable() !== this.cacheTable || this.cacheTable.host.unit.dir !== this.cacheDirectory) || this.query && (this.query.config.path !== this.queryConfiguration.path || this.query.config.openAt !== this.queryConfiguration.openAt) || this.queryProvider === "sqlite-memory-disabled-0.2.0-rc.2" && (this.query._db !== void 0 || this.query._ready !== void 0)) {
|
|
2537
2556
|
this.refuse("native/composition-changed", "Native metadata service composition changed.");
|
|
2538
2557
|
}
|
|
2539
2558
|
}
|
|
@@ -2548,6 +2567,34 @@ var NativeMetadataAdapter = class _NativeMetadataAdapter {
|
|
|
2548
2567
|
if ((this.controller?.history.closeFollowers.size ?? 0) > knownFollowers) this.refuse("native/unknown-follow", "A history follower predates native admission tracking.");
|
|
2549
2568
|
if (this.cache && [...this.cache.dirty.keys()].some((session) => session.id === id)) this.refuse("native/cache-dirty", "Target cache write-behind is not quiescent.");
|
|
2550
2569
|
}
|
|
2570
|
+
/** Explicit deletion preparation may unload an idle API-owned lifecycle.
|
|
2571
|
+
* No bare registry Agent, foreign handle, or unknown reader is disposed. */
|
|
2572
|
+
async releaseIdle(id) {
|
|
2573
|
+
this.assertInstances();
|
|
2574
|
+
const handle = this.apiHandles.get(id);
|
|
2575
|
+
if (!handle) return;
|
|
2576
|
+
const agent = handle.agent;
|
|
2577
|
+
const registry = this.agents;
|
|
2578
|
+
if (registry.get(id) !== agent || this.sessions.get(id) !== agent.session) return;
|
|
2579
|
+
const activity = await this.admission.withoutBypass(() => this.ctx.waterfall(
|
|
2580
|
+
"workspace/session-activity",
|
|
2581
|
+
{ sessionId: id },
|
|
2582
|
+
async () => []
|
|
2583
|
+
));
|
|
2584
|
+
if (activity.length || agent.constructor.name !== "ReactLoopAgent" || agent.phase?.kind !== "idle" || agent.status !== "idle" || !Array.isArray(agent.inbox?.nextTurn) || !Array.isArray(agent.inbox?.nextStep) || agent.inbox.nextTurn.length || agent.inbox.nextStep.length) {
|
|
2585
|
+
this.refuse("native/session-active", "Native deletion refuses active or queued work.");
|
|
2586
|
+
}
|
|
2587
|
+
if (!this.workspace.archivedSessionIds.includes(id)) this.refuse("native/not-archived", "Only an archived target may be unloaded.");
|
|
2588
|
+
if (registry.get(id) !== agent || this.sessions.get(id) !== agent.session) this.refuse("native/session-live", "The API lifecycle changed.");
|
|
2589
|
+
await this.admission.bypass(id, async () => {
|
|
2590
|
+
await handle.dispose();
|
|
2591
|
+
for (const stop of [...this.followerStops.get(id) ?? []]) await stop();
|
|
2592
|
+
if (this.cache) await this.cache.requireTable().host.enqueue(async () => void 0);
|
|
2593
|
+
const summary = this.controller.listState.summarizeCold(agent.session.header);
|
|
2594
|
+
this.admission.withoutBypass(() => this.ctx.emit("api-session/added", summary));
|
|
2595
|
+
});
|
|
2596
|
+
this.apiHandles.delete(id);
|
|
2597
|
+
}
|
|
2551
2598
|
async cacheView(table, id, acceptedStage) {
|
|
2552
2599
|
table.host.assertReadable();
|
|
2553
2600
|
if (!/^[a-zA-Z0-9_-]+$/.test(id)) this.refuse("native/cache-key-unsupported", "The pinned cache backend cannot own this record key.");
|
|
@@ -2912,19 +2959,54 @@ var NativeMetadataAdapter = class _NativeMetadataAdapter {
|
|
|
2912
2959
|
}
|
|
2913
2960
|
if (this.controller) {
|
|
2914
2961
|
const adapter = this;
|
|
2962
|
+
for (const name2 of ["resumeObserved", "createOrAdopt"]) {
|
|
2963
|
+
this.wrap(this.controller.agents, name2, (original) => (id, ...args) => this.tracked(id, () => this.activationTarget.run(id, async () => original(id, ...args))));
|
|
2964
|
+
}
|
|
2965
|
+
const agents = this.agents;
|
|
2966
|
+
for (const name2 of ["create", "resume"]) {
|
|
2967
|
+
this.wrap(agents, name2, (original) => (options, ...args) => {
|
|
2968
|
+
const id = String(name2 === "create" ? options.sessionId : options.resumeSessionId);
|
|
2969
|
+
return this.tracked(id, async () => {
|
|
2970
|
+
const handle = await original(options, ...args);
|
|
2971
|
+
if (this.activationTarget.getStore() === id && options.parentAgent === void 0 && handle.agent.id === id && handle.agent.session.header.origin !== "subagent" && typeof handle.dispose === "function") this.apiHandles.set(id, handle);
|
|
2972
|
+
return handle;
|
|
2973
|
+
});
|
|
2974
|
+
});
|
|
2975
|
+
}
|
|
2976
|
+
this.restores.push(this.ctx.on("agent/disposed", ({ agent }) => {
|
|
2977
|
+
if (this.apiHandles.get(agent.id)?.agent === agent) this.apiHandles.delete(agent.id);
|
|
2978
|
+
}, { global: true }));
|
|
2915
2979
|
this.wrap(this.controller.history, "follow", (original) => function(request, signal) {
|
|
2916
2980
|
const id = String(request.address.sessionId);
|
|
2917
2981
|
adapter.assert(id);
|
|
2918
2982
|
return (async function* () {
|
|
2919
2983
|
adapter.assert(id);
|
|
2920
2984
|
adapter.increment(adapter.followers, id, 1);
|
|
2985
|
+
const cancellation = new AbortController();
|
|
2986
|
+
const iterator = original(request, AbortSignal.any([signal, cancellation.signal]));
|
|
2987
|
+
const stops = adapter.followerStops.get(id) ?? /* @__PURE__ */ new Set();
|
|
2988
|
+
adapter.followerStops.set(id, stops);
|
|
2989
|
+
let finished = false;
|
|
2990
|
+
const finish = () => {
|
|
2991
|
+
if (finished) return;
|
|
2992
|
+
finished = true;
|
|
2993
|
+
adapter.increment(adapter.followers, id, -1);
|
|
2994
|
+
stops.delete(stop);
|
|
2995
|
+
if (!stops.size) adapter.followerStops.delete(id);
|
|
2996
|
+
};
|
|
2997
|
+
const stop = async () => {
|
|
2998
|
+
cancellation.abort();
|
|
2999
|
+
await iterator.return();
|
|
3000
|
+
finish();
|
|
3001
|
+
};
|
|
3002
|
+
stops.add(stop);
|
|
2921
3003
|
try {
|
|
2922
|
-
for await (const frame of
|
|
3004
|
+
for await (const frame of iterator) {
|
|
2923
3005
|
adapter.assert(id);
|
|
2924
3006
|
yield frame;
|
|
2925
3007
|
}
|
|
2926
3008
|
} finally {
|
|
2927
|
-
|
|
3009
|
+
finish();
|
|
2928
3010
|
}
|
|
2929
3011
|
})();
|
|
2930
3012
|
});
|
|
@@ -2939,6 +3021,7 @@ var NativeMetadataAdapter = class _NativeMetadataAdapter {
|
|
|
2939
3021
|
return () => closing ??= (async () => {
|
|
2940
3022
|
this.fallbackRetired = new Set([...this.targets].filter((id) => this.admission.isRetired(id)));
|
|
2941
3023
|
this.disposed = true;
|
|
3024
|
+
this.apiHandles.clear();
|
|
2942
3025
|
if (this.fallbackRetired.size === 0) {
|
|
2943
3026
|
for (const restore of [...this.restores].reverse()) restore();
|
|
2944
3027
|
this.restores.length = 0;
|
|
@@ -2957,6 +3040,7 @@ var NativeMetadataAdapter = class _NativeMetadataAdapter {
|
|
|
2957
3040
|
this.restores.length = 0;
|
|
2958
3041
|
this.guardedMethods.length = 0;
|
|
2959
3042
|
this.fallbackRetired.clear();
|
|
3043
|
+
this.apiHandles.clear();
|
|
2960
3044
|
}
|
|
2961
3045
|
async converge(input, expected, request) {
|
|
2962
3046
|
const snapshot = nativeMetadataSnapshotSchema.parse(input);
|
|
@@ -4088,16 +4172,19 @@ var NativeRetirementOwner = class _NativeRetirementOwner {
|
|
|
4088
4172
|
async eligibilityInner(id) {
|
|
4089
4173
|
if (nativeServiceInstance(this.ctx.sessionPersistence) !== this.originalProvider) return "native/composition-changed";
|
|
4090
4174
|
if (this.admission.isRetired(id)) return "native/session-retired";
|
|
4091
|
-
if (this.provider.busy(id)) return "native/persistence-retained";
|
|
4092
4175
|
try {
|
|
4093
4176
|
const scope = this.scopes.get(id);
|
|
4094
4177
|
if (scope) {
|
|
4178
|
+
if (this.provider.busy(id)) return "native/persistence-retained";
|
|
4095
4179
|
if (scope.blocked) return scope.blocked;
|
|
4096
4180
|
await this.metadata.capture(id);
|
|
4097
4181
|
return null;
|
|
4098
4182
|
}
|
|
4099
4183
|
const release = await this.admission.acquire(id);
|
|
4100
4184
|
try {
|
|
4185
|
+
await this.metadata.releaseIdle(id);
|
|
4186
|
+
await this.admission.drain(id);
|
|
4187
|
+
if (this.provider.busy(id)) return "native/persistence-retained";
|
|
4101
4188
|
await this.metadata.capture(id);
|
|
4102
4189
|
const snapshot = await this.provider.stat(id);
|
|
4103
4190
|
if (!snapshot) return "session-not-found";
|