@yadsh/dsh-kv-persist 0.1.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.
Files changed (98) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +110 -0
  3. package/compatibility.json +16 -0
  4. package/cordis.patch.yml +4 -0
  5. package/docs/dsh-kv-persist.md +3311 -0
  6. package/lib/backends/llama-cpp/backend.d.ts +20 -0
  7. package/lib/backends/llama-cpp/backend.d.ts.map +1 -0
  8. package/lib/backends/llama-cpp/backend.js +37 -0
  9. package/lib/backends/llama-cpp/backend.js.map +1 -0
  10. package/lib/backends/llama-cpp/client.d.ts +31 -0
  11. package/lib/backends/llama-cpp/client.d.ts.map +1 -0
  12. package/lib/backends/llama-cpp/client.js +120 -0
  13. package/lib/backends/llama-cpp/client.js.map +1 -0
  14. package/lib/backends/llama-cpp/discovery.d.ts +20 -0
  15. package/lib/backends/llama-cpp/discovery.d.ts.map +1 -0
  16. package/lib/backends/llama-cpp/discovery.js +33 -0
  17. package/lib/backends/llama-cpp/discovery.js.map +1 -0
  18. package/lib/backends/llama-cpp/types.d.ts +30 -0
  19. package/lib/backends/llama-cpp/types.d.ts.map +1 -0
  20. package/lib/backends/llama-cpp/types.js +9 -0
  21. package/lib/backends/llama-cpp/types.js.map +1 -0
  22. package/lib/backends/types.d.ts +52 -0
  23. package/lib/backends/types.d.ts.map +1 -0
  24. package/lib/backends/types.js +6 -0
  25. package/lib/backends/types.js.map +1 -0
  26. package/lib/config.d.ts +258 -0
  27. package/lib/config.d.ts.map +1 -0
  28. package/lib/config.js +169 -0
  29. package/lib/config.js.map +1 -0
  30. package/lib/coordinator/checkpoint-policy.d.ts +19 -0
  31. package/lib/coordinator/checkpoint-policy.d.ts.map +1 -0
  32. package/lib/coordinator/checkpoint-policy.js +40 -0
  33. package/lib/coordinator/checkpoint-policy.js.map +1 -0
  34. package/lib/coordinator/circuit-breaker.d.ts +29 -0
  35. package/lib/coordinator/circuit-breaker.d.ts.map +1 -0
  36. package/lib/coordinator/circuit-breaker.js +62 -0
  37. package/lib/coordinator/circuit-breaker.js.map +1 -0
  38. package/lib/coordinator/coordinator.d.ts +74 -0
  39. package/lib/coordinator/coordinator.d.ts.map +1 -0
  40. package/lib/coordinator/coordinator.js +542 -0
  41. package/lib/coordinator/coordinator.js.map +1 -0
  42. package/lib/coordinator/slot-lease.d.ts +22 -0
  43. package/lib/coordinator/slot-lease.d.ts.map +1 -0
  44. package/lib/coordinator/slot-lease.js +38 -0
  45. package/lib/coordinator/slot-lease.js.map +1 -0
  46. package/lib/coordinator/state-machine.d.ts +65 -0
  47. package/lib/coordinator/state-machine.d.ts.map +1 -0
  48. package/lib/coordinator/state-machine.js +40 -0
  49. package/lib/coordinator/state-machine.js.map +1 -0
  50. package/lib/errors.d.ts +82 -0
  51. package/lib/errors.d.ts.map +1 -0
  52. package/lib/errors.js +113 -0
  53. package/lib/errors.js.map +1 -0
  54. package/lib/index.d.ts +26 -0
  55. package/lib/index.d.ts.map +1 -0
  56. package/lib/index.js +17 -0
  57. package/lib/index.js.map +1 -0
  58. package/lib/logging/dsh-home.d.ts +13 -0
  59. package/lib/logging/dsh-home.d.ts.map +1 -0
  60. package/lib/logging/dsh-home.js +18 -0
  61. package/lib/logging/dsh-home.js.map +1 -0
  62. package/lib/logging/index.d.ts +10 -0
  63. package/lib/logging/index.d.ts.map +1 -0
  64. package/lib/logging/index.js +10 -0
  65. package/lib/logging/index.js.map +1 -0
  66. package/lib/logging/plugin-logger.d.ts +94 -0
  67. package/lib/logging/plugin-logger.d.ts.map +1 -0
  68. package/lib/logging/plugin-logger.js +397 -0
  69. package/lib/logging/plugin-logger.js.map +1 -0
  70. package/lib/observability/diagnostics.d.ts +37 -0
  71. package/lib/observability/diagnostics.d.ts.map +1 -0
  72. package/lib/observability/diagnostics.js +75 -0
  73. package/lib/observability/diagnostics.js.map +1 -0
  74. package/lib/observability/metrics.d.ts +38 -0
  75. package/lib/observability/metrics.d.ts.map +1 -0
  76. package/lib/observability/metrics.js +29 -0
  77. package/lib/observability/metrics.js.map +1 -0
  78. package/lib/service.d.ts +231 -0
  79. package/lib/service.d.ts.map +1 -0
  80. package/lib/service.js +232 -0
  81. package/lib/service.js.map +1 -0
  82. package/lib/snapshots/fingerprint.d.ts +53 -0
  83. package/lib/snapshots/fingerprint.d.ts.map +1 -0
  84. package/lib/snapshots/fingerprint.js +69 -0
  85. package/lib/snapshots/fingerprint.js.map +1 -0
  86. package/lib/snapshots/manifest.d.ts +51 -0
  87. package/lib/snapshots/manifest.d.ts.map +1 -0
  88. package/lib/snapshots/manifest.js +0 -0
  89. package/lib/snapshots/manifest.js.map +1 -0
  90. package/lib/snapshots/naming.d.ts +18 -0
  91. package/lib/snapshots/naming.d.ts.map +1 -0
  92. package/lib/snapshots/naming.js +33 -0
  93. package/lib/snapshots/naming.js.map +1 -0
  94. package/lib/snapshots/repository.d.ts +52 -0
  95. package/lib/snapshots/repository.d.ts.map +1 -0
  96. package/lib/snapshots/repository.js +270 -0
  97. package/lib/snapshots/repository.js.map +1 -0
  98. package/package.json +83 -0
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Snapshot metadata manifest (SPEC §14).
3
+ *
4
+ * The manifest is small, local, and independent from the potentially huge
5
+ * binary snapshot file owned by llama-server (SPEC §17). Validation is
6
+ * strict: a malformed manifest is reported (`KV_MANIFEST_INVALID`) instead
7
+ * of being silently repaired or dropped.
8
+ */
9
+ import type { SnapshotIdentity, SessionRoute } from "./fingerprint.js";
10
+ /** Lifecycle state of a snapshot (SPEC §18, §31). */
11
+ export type SnapshotState = "ready" | "invalid";
12
+ /** On-disk manifest for one snapshot. */
13
+ export interface SnapshotManifest {
14
+ readonly schemaVersion: 1;
15
+ readonly sessionId: string;
16
+ /** Latest known DSH session sequence at save time (SPEC §29, diagnostic). */
17
+ readonly sessionSeq: number | null;
18
+ readonly provider: string;
19
+ readonly model: string;
20
+ readonly backend: "llama.cpp";
21
+ readonly serverInstanceKey: string;
22
+ readonly compatibilityVersion: string;
23
+ readonly slotId: number;
24
+ readonly createdAt: string;
25
+ readonly updatedAt: string;
26
+ /** Server-reported token/byte counters when known. */
27
+ readonly tokens: number | null;
28
+ readonly bytes: number | null;
29
+ readonly snapshotFilename: string;
30
+ readonly state: SnapshotState;
31
+ readonly invalidReason: string | null;
32
+ }
33
+ /** Create a fresh manifest for an identity. */
34
+ export declare function createManifest(options: {
35
+ readonly identity: SnapshotIdentity;
36
+ readonly slotId: number;
37
+ readonly snapshotFilename: string;
38
+ readonly sessionSeq: number | null;
39
+ readonly now: string;
40
+ }): SnapshotManifest;
41
+ /**
42
+ * Validate an unknown parsed manifest document.
43
+ * Throws `KV_MANIFEST_INVALID` on any schema violation.
44
+ */
45
+ export declare function parseManifest(raw: unknown): SnapshotManifest;
46
+ /** True when the manifest can serve the requested route (SPEC Invariant 4). */
47
+ export declare function isManifestCompatible(manifest: SnapshotManifest, identity: SnapshotIdentity): boolean;
48
+ /** Route key under which a manifest is stored. */
49
+ export declare function manifestRouteKey(manifest: Pick<SnapshotManifest, "provider" | "model">): string;
50
+ export type { SessionRoute };
51
+ //# sourceMappingURL=manifest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../src/snapshots/manifest.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAEvE,qDAAqD;AACrD,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,SAAS,CAAC;AAEhD,yCAAyC;AACzC,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,aAAa,EAAE,CAAC,CAAC;IAE1B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,6EAA6E;IAC7E,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAEnC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAEvB,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC;IAC9B,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,oBAAoB,EAAE,MAAM,CAAC;IAEtC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAExB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAE3B,sDAAsD;IACtD,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAE9B,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAElC,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC;IAC9B,QAAQ,CAAC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;CACvC;AAED,+CAA+C;AAC/C,wBAAgB,cAAc,CAAC,OAAO,EAAE;IACtC,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,CAAC;IACpC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB,GAAG,gBAAgB,CAoBnB;AAcD;;;GAGG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,OAAO,GAAG,gBAAgB,CAyC5D;AAED,+EAA+E;AAC/E,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,gBAAgB,EAC1B,QAAQ,EAAE,gBAAgB,GACzB,OAAO,CAeT;AAED,kDAAkD;AAClD,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,IAAI,CAAC,gBAAgB,EAAE,UAAU,GAAG,OAAO,CAAC,GAAG,MAAM,CAE/F;AAED,YAAY,EAAE,YAAY,EAAE,CAAC"}
Binary file
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest.js","sourceRoot":"","sources":["../../src/snapshots/manifest.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAC;AACtD,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAoCxD,+CAA+C;AAC/C,MAAM,UAAU,cAAc,CAAC,OAM9B;IACC,MAAM,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC;IAC7B,OAAO;QACL,aAAa,EAAE,CAAC;QAChB,SAAS,EAAE,QAAQ,CAAC,SAAS;QAC7B,UAAU,EAAE,OAAO,CAAC,UAAU;QAC9B,QAAQ,EAAE,QAAQ,CAAC,QAAQ;QAC3B,KAAK,EAAE,QAAQ,CAAC,KAAK;QACrB,OAAO,EAAE,QAAQ,CAAC,OAAO;QACzB,iBAAiB,EAAE,QAAQ,CAAC,iBAAiB;QAC7C,oBAAoB,EAAE,QAAQ,CAAC,oBAAoB;QACnD,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,SAAS,EAAE,OAAO,CAAC,GAAG;QACtB,SAAS,EAAE,OAAO,CAAC,GAAG;QACtB,MAAM,EAAE,IAAI;QACZ,KAAK,EAAE,IAAI;QACX,gBAAgB,EAAE,OAAO,CAAC,gBAAgB;QAC1C,KAAK,EAAE,OAAO;QACd,aAAa,EAAE,IAAI;KACpB,CAAC;AACJ,CAAC;AAED,SAAS,QAAQ,CAAC,KAAc;IAC9B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,CAAC;AACrD,CAAC;AAED,SAAS,WAAW,CAAC,KAAc;IACjC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;AACvE,CAAC;AAED,SAAS,WAAW,CAAC,KAAc;IACjC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;AAC3F,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,GAAY;IACxC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,MAAM,IAAI,sBAAsB,CAAC,gCAAgC,CAAC,CAAC;IACvF,MAAM,IAAI,GAAG,CAAC,IAAY,EAAS,EAAE;QACnC,MAAM,IAAI,sBAAsB,CAAC,kBAAkB,IAAI,0BAA0B,CAAC,CAAC;IACrF,CAAC,CAAC;IACF,IAAI,GAAG,CAAC,aAAa,KAAK,CAAC;QAAE,IAAI,CAAC,eAAe,CAAC,CAAC;IACnD,KAAK,MAAM,GAAG,IAAI,CAAC,WAAW,EAAE,UAAU,EAAE,OAAO,CAAU,EAAE,CAAC;QAC9D,IAAI,OAAO,GAAG,CAAC,GAAG,CAAC,KAAK,QAAQ,IAAK,GAAG,CAAC,GAAG,CAAY,CAAC,MAAM,KAAK,CAAC;YAAE,IAAI,CAAC,GAAG,CAAC,CAAC;IACnF,CAAC;IACD,IAAI,GAAG,CAAC,OAAO,KAAK,WAAW;QAAE,IAAI,CAAC,SAAS,CAAC,CAAC;IACjD,IAAI,OAAO,GAAG,CAAC,iBAAiB,KAAK,QAAQ;QAAE,IAAI,CAAC,mBAAmB,CAAC,CAAC;IACzE,IAAI,OAAO,GAAG,CAAC,oBAAoB,KAAK,QAAQ;QAAE,IAAI,CAAC,sBAAsB,CAAC,CAAC;IAC/E,IAAI,OAAO,GAAG,CAAC,MAAM,KAAK,QAAQ;QAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;IACnD,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,SAAS,CAAC;QAAE,IAAI,CAAC,WAAW,CAAC,CAAC;IACnD,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,SAAS,CAAC;QAAE,IAAI,CAAC,WAAW,CAAC,CAAC;IACnD,IAAI,OAAO,GAAG,CAAC,gBAAgB,KAAK,QAAQ,IAAI,GAAG,CAAC,gBAAgB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAClF,IAAI,CAAC,kBAAkB,CAAC,CAAC;IAC3B,CAAC;IACD,IAAI,GAAG,CAAC,KAAK,KAAK,OAAO,IAAI,GAAG,CAAC,KAAK,KAAK,SAAS;QAAE,IAAI,CAAC,OAAO,CAAC,CAAC;IACpE,IAAI,GAAG,CAAC,aAAa,KAAK,IAAI,IAAI,OAAO,GAAG,CAAC,aAAa,KAAK,QAAQ;QAAE,IAAI,CAAC,eAAe,CAAC,CAAC;IAC/F,IAAI,GAAG,CAAC,UAAU,KAAK,IAAI,IAAI,OAAO,GAAG,CAAC,UAAU,KAAK,QAAQ;QAAE,IAAI,CAAC,YAAY,CAAC,CAAC;IACtF,IAAI,GAAG,CAAC,MAAM,KAAK,IAAI,IAAI,OAAO,GAAG,CAAC,MAAM,KAAK,QAAQ;QAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC1E,IAAI,GAAG,CAAC,KAAK,KAAK,IAAI,IAAI,OAAO,GAAG,CAAC,KAAK,KAAK,QAAQ;QAAE,IAAI,CAAC,OAAO,CAAC,CAAC;IACvE,OAAO;QACL,aAAa,EAAE,CAAC;QAChB,SAAS,EAAE,GAAG,CAAC,SAAmB;QAClC,UAAU,EAAE,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC;QACvC,QAAQ,EAAE,GAAG,CAAC,QAAkB;QAChC,KAAK,EAAE,GAAG,CAAC,KAAe;QAC1B,OAAO,EAAE,WAAW;QACpB,iBAAiB,EAAE,GAAG,CAAC,iBAA2B;QAClD,oBAAoB,EAAE,GAAG,CAAC,oBAA8B;QACxD,MAAM,EAAE,GAAG,CAAC,MAAgB;QAC5B,SAAS,EAAE,GAAG,CAAC,SAAmB;QAClC,SAAS,EAAE,GAAG,CAAC,SAAmB;QAClC,MAAM,EAAE,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC;QAC/B,KAAK,EAAE,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC;QAC7B,gBAAgB,EAAE,GAAG,CAAC,gBAA0B;QAChD,KAAK,EAAE,GAAG,CAAC,KAAsB;QACjC,aAAa,EAAE,GAAG,CAAC,aAA8B;KAClD,CAAC;AACJ,CAAC;AAED,+EAA+E;AAC/E,MAAM,UAAU,oBAAoB,CAClC,QAA0B,EAC1B,QAA0B;IAE1B,OAAO,CACL,QAAQ,CAAC,KAAK,KAAK,OAAO;QAC1B,oBAAoB,CAClB;YACE,SAAS,EAAE,QAAQ,CAAC,SAAS;YAC7B,QAAQ,EAAE,QAAQ,CAAC,QAAQ;YAC3B,KAAK,EAAE,QAAQ,CAAC,KAAK;YACrB,OAAO,EAAE,QAAQ,CAAC,OAAO;YACzB,iBAAiB,EAAE,QAAQ,CAAC,iBAAiB;YAC7C,oBAAoB,EAAE,QAAQ,CAAC,oBAAoB;SACpD,EACD,QAAQ,CACT,CACF,CAAC;AACJ,CAAC;AAED,kDAAkD;AAClD,MAAM,UAAU,gBAAgB,CAAC,QAAsD;IACrF,OAAO,GAAG,QAAQ,CAAC,QAAQ,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC;AAClD,CAAC"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Snapshot filename generation (SPEC §16, §41, Invariant 9).
3
+ *
4
+ * Filenames are plugin-generated opaque identifiers: sha256 over the
5
+ * identity tuple. Raw session ids, titles, or user input never become
6
+ * filenames, so there are no unsafe characters, no path traversal, and no
7
+ * leaked chat titles.
8
+ */
9
+ import type { SnapshotIdentity } from "./fingerprint.js";
10
+ /** One rolling snapshot per (session, route) pair by default (SPEC §41). */
11
+ export declare function snapshotFilename(identity: SnapshotIdentity): string;
12
+ /**
13
+ * Validate that a filename reaching the backend is plugin-shaped (SPEC §44):
14
+ * hex stem + `.bin`, no separators, no traversal. Defense in depth — the
15
+ * plugin never accepts external filenames, but the guard is cheap.
16
+ */
17
+ export declare function assertPluginGeneratedFilename(filename: string): void;
18
+ //# sourceMappingURL=naming.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"naming.d.ts","sourceRoot":"","sources":["../../src/snapshots/naming.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAGzD,4EAA4E;AAC5E,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,gBAAgB,GAAG,MAAM,CAYnE;AAED;;;;GAIG;AACH,wBAAgB,6BAA6B,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAMpE"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Snapshot filename generation (SPEC §16, §41, Invariant 9).
3
+ *
4
+ * Filenames are plugin-generated opaque identifiers: sha256 over the
5
+ * identity tuple. Raw session ids, titles, or user input never become
6
+ * filenames, so there are no unsafe characters, no path traversal, and no
7
+ * leaked chat titles.
8
+ */
9
+ import { sha256Hex } from "./fingerprint.js";
10
+ import { KvInvariantError } from "../errors.js";
11
+ /** One rolling snapshot per (session, route) pair by default (SPEC §41). */
12
+ export function snapshotFilename(identity) {
13
+ const digest = sha256Hex([
14
+ identity.serverInstanceKey,
15
+ identity.provider,
16
+ identity.model,
17
+ identity.sessionId,
18
+ ].join("\u0000"));
19
+ // Sharded flat name: fixed length, safe characters, no directories needed
20
+ // by the server-side save path.
21
+ return `${digest}.bin`;
22
+ }
23
+ /**
24
+ * Validate that a filename reaching the backend is plugin-shaped (SPEC §44):
25
+ * hex stem + `.bin`, no separators, no traversal. Defense in depth — the
26
+ * plugin never accepts external filenames, but the guard is cheap.
27
+ */
28
+ export function assertPluginGeneratedFilename(filename) {
29
+ if (!/^[0-9a-f]{64}\.bin$/.test(filename)) {
30
+ throw new KvInvariantError(`refusing non-plugin snapshot filename: ${JSON.stringify(filename.slice(0, 64))}`);
31
+ }
32
+ }
33
+ //# sourceMappingURL=naming.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"naming.js","sourceRoot":"","sources":["../../src/snapshots/naming.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAE7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAEhD,4EAA4E;AAC5E,MAAM,UAAU,gBAAgB,CAAC,QAA0B;IACzD,MAAM,MAAM,GAAG,SAAS,CACtB;QACE,QAAQ,CAAC,iBAAiB;QAC1B,QAAQ,CAAC,QAAQ;QACjB,QAAQ,CAAC,KAAK;QACd,QAAQ,CAAC,SAAS;KACnB,CAAC,IAAI,CAAC,QAAQ,CAAC,CACjB,CAAC;IACF,0EAA0E;IAC1E,gCAAgC;IAChC,OAAO,GAAG,MAAM,MAAM,CAAC;AACzB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,6BAA6B,CAAC,QAAgB;IAC5D,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC1C,MAAM,IAAI,gBAAgB,CACxB,0CAA0C,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAClF,CAAC;IACJ,CAAC;AACH,CAAC"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Local metadata repository (SPEC §39-§40).
3
+ *
4
+ * Layout below the metadata root (default `<$DSH_HOME>/cache/dsh-kv-persist`):
5
+ *
6
+ * instances/<serverInstanceKey>/sessions/<snapshotDigest>.json
7
+ *
8
+ * Binary KV files never live here — they are owned by llama-server's
9
+ * `--slot-save-path` (SPEC §17). All writes are atomic: temp file + rename
10
+ * (SPEC §40), so a crash cannot leave half-written metadata that parses.
11
+ */
12
+ import type { SnapshotInvalidationReason } from "../errors.js";
13
+ import type { SnapshotManifest } from "./manifest.js";
14
+ import type { SnapshotIdentity } from "./fingerprint.js";
15
+ export interface RepositoryPutInput {
16
+ readonly identity: SnapshotIdentity;
17
+ readonly slotId: number;
18
+ readonly sessionSeq: number | null;
19
+ readonly tokens: number | null;
20
+ readonly bytes: number | null;
21
+ readonly now: string;
22
+ }
23
+ /** Manifest storage for one metadata root. */
24
+ export declare class SnapshotRepository {
25
+ #private;
26
+ readonly root: string;
27
+ constructor(root: string);
28
+ /** Load the manifest for an identity; null when none exists. */
29
+ load(identity: SnapshotIdentity): Promise<SnapshotManifest | null>;
30
+ /** Create-or-update the manifest for an identity (atomic). */
31
+ put(input: RepositoryPutInput): Promise<SnapshotManifest>;
32
+ /** Flip a manifest to invalid without deleting anything (SPEC §31). */
33
+ markInvalid(identity: SnapshotIdentity, reason: SnapshotInvalidationReason, now: string): Promise<void>;
34
+ /** Remove a manifest (purge, SPEC §11); binary cleanup is backend-owned. */
35
+ remove(identity: SnapshotIdentity): Promise<boolean>;
36
+ /** Flip every manifest of a session to invalid (SPEC §31). */
37
+ invalidateSession(sessionId: string, reason: SnapshotInvalidationReason, now: string): Promise<number>;
38
+ /** Remove every manifest of a session across routes and instances. */
39
+ removeSession(sessionId: string): Promise<number>;
40
+ /**
41
+ * Find a ready, runtime-compatible manifest for the identity; incompatible
42
+ * manifests are marked invalid (SPEC §31) and ignored.
43
+ */
44
+ findCompatible(identity: SnapshotIdentity): Promise<SnapshotManifest | null>;
45
+ /** Aggregate manifest counts for the status API (SPEC §47). */
46
+ counts(): Promise<{
47
+ known: number;
48
+ valid: number;
49
+ invalid: number;
50
+ }>;
51
+ }
52
+ //# sourceMappingURL=repository.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repository.d.ts","sourceRoot":"","sources":["../../src/snapshots/repository.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAKH,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,cAAc,CAAC;AAE/D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEtD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEzD,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,CAAC;IACpC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB;AAQD,8CAA8C;AAC9C,qBAAa,kBAAkB;;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;gBAEV,IAAI,EAAE,MAAM;IAaxB,gEAAgE;IAC1D,IAAI,CAAC,QAAQ,EAAE,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC;IAgBxE,8DAA8D;IACxD,GAAG,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,gBAAgB,CAAC;IA0B/D,uEAAuE;IACjE,WAAW,CACf,QAAQ,EAAE,gBAAgB,EAC1B,MAAM,EAAE,0BAA0B,EAClC,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,IAAI,CAAC;IAWhB,4EAA4E;IACtE,MAAM,CAAC,QAAQ,EAAE,gBAAgB,GAAG,OAAO,CAAC,OAAO,CAAC;IAW1D,8DAA8D;IACxD,iBAAiB,CACrB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,0BAA0B,EAClC,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,MAAM,CAAC;IAelB,sEAAsE;IAChE,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAkDvD;;;OAGG;IACG,cAAc,CAAC,QAAQ,EAAE,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC;IAwBlF,+DAA+D;IACzD,MAAM,IAAI,OAAO,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;CAuD3E"}
@@ -0,0 +1,270 @@
1
+ /**
2
+ * Local metadata repository (SPEC §39-§40).
3
+ *
4
+ * Layout below the metadata root (default `<$DSH_HOME>/cache/dsh-kv-persist`):
5
+ *
6
+ * instances/<serverInstanceKey>/sessions/<snapshotDigest>.json
7
+ *
8
+ * Binary KV files never live here — they are owned by llama-server's
9
+ * `--slot-save-path` (SPEC §17). All writes are atomic: temp file + rename
10
+ * (SPEC §40), so a crash cannot leave half-written metadata that parses.
11
+ */
12
+ import { mkdir, readdir, readFile, rename, rm, writeFile } from "node:fs/promises";
13
+ import { dirname, join } from "node:path";
14
+ import { KvMetadataIoError } from "../errors.js";
15
+ import { parseManifest, createManifest } from "./manifest.js";
16
+ import { snapshotFilename } from "./naming.js";
17
+ function isNotFoundError(error) {
18
+ return (typeof error === "object" && error !== null && error.code === "ENOENT");
19
+ }
20
+ /** Manifest storage for one metadata root. */
21
+ export class SnapshotRepository {
22
+ root;
23
+ constructor(root) {
24
+ this.root = root;
25
+ }
26
+ #sessionsDir(instanceKey) {
27
+ return join(this.root, "instances", instanceKey, "sessions");
28
+ }
29
+ #manifestPath(identity) {
30
+ const digest = snapshotFilename(identity).replace(/\.bin$/, "");
31
+ return join(this.#sessionsDir(identity.serverInstanceKey), `${digest}.json`);
32
+ }
33
+ /** Load the manifest for an identity; null when none exists. */
34
+ async load(identity) {
35
+ const path = this.#manifestPath(identity);
36
+ let text;
37
+ try {
38
+ text = await readFile(path, "utf8");
39
+ }
40
+ catch (error) {
41
+ if (isNotFoundError(error))
42
+ return null;
43
+ throw new KvMetadataIoError(`cannot read manifest ${path}`, { cause: error });
44
+ }
45
+ try {
46
+ return parseManifest(JSON.parse(text));
47
+ }
48
+ catch (error) {
49
+ throw new KvMetadataIoError(`cannot parse manifest ${path}`, { cause: error });
50
+ }
51
+ }
52
+ /** Create-or-update the manifest for an identity (atomic). */
53
+ async put(input) {
54
+ const existing = await this.load(input.identity);
55
+ const manifest = existing
56
+ ? {
57
+ ...existing,
58
+ updatedAt: input.now,
59
+ slotId: input.slotId,
60
+ sessionSeq: input.sessionSeq,
61
+ tokens: input.tokens ?? existing.tokens,
62
+ bytes: input.bytes ?? existing.bytes,
63
+ }
64
+ : {
65
+ ...createManifest({
66
+ identity: input.identity,
67
+ slotId: input.slotId,
68
+ snapshotFilename: snapshotFilename(input.identity),
69
+ sessionSeq: input.sessionSeq,
70
+ now: input.now,
71
+ }),
72
+ tokens: input.tokens,
73
+ bytes: input.bytes,
74
+ };
75
+ await this.#write(manifest);
76
+ return manifest;
77
+ }
78
+ /** Flip a manifest to invalid without deleting anything (SPEC §31). */
79
+ async markInvalid(identity, reason, now) {
80
+ const existing = await this.load(identity);
81
+ if (!existing || existing.state === "invalid")
82
+ return;
83
+ await this.#write({
84
+ ...existing,
85
+ state: "invalid",
86
+ invalidReason: reason,
87
+ updatedAt: now,
88
+ });
89
+ }
90
+ /** Remove a manifest (purge, SPEC §11); binary cleanup is backend-owned. */
91
+ async remove(identity) {
92
+ const path = this.#manifestPath(identity);
93
+ try {
94
+ await rm(path, { force: false });
95
+ return true;
96
+ }
97
+ catch (error) {
98
+ if (isNotFoundError(error))
99
+ return false;
100
+ throw new KvMetadataIoError(`cannot remove manifest ${path}`, { cause: error });
101
+ }
102
+ }
103
+ /** Flip every manifest of a session to invalid (SPEC §31). */
104
+ async invalidateSession(sessionId, reason, now) {
105
+ let count = 0;
106
+ for (const manifest of await this.#listSessionManifests(sessionId)) {
107
+ if (manifest.state === "invalid")
108
+ continue;
109
+ await this.#write({
110
+ ...manifest,
111
+ state: "invalid",
112
+ invalidReason: reason,
113
+ updatedAt: now,
114
+ });
115
+ count += 1;
116
+ }
117
+ return count;
118
+ }
119
+ /** Remove every manifest of a session across routes and instances. */
120
+ async removeSession(sessionId) {
121
+ let count = 0;
122
+ for (const manifest of await this.#listSessionManifests(sessionId)) {
123
+ const identity = {
124
+ sessionId: manifest.sessionId,
125
+ provider: manifest.provider,
126
+ model: manifest.model,
127
+ backend: manifest.backend,
128
+ serverInstanceKey: manifest.serverInstanceKey,
129
+ compatibilityVersion: manifest.compatibilityVersion,
130
+ };
131
+ if (await this.remove(identity))
132
+ count += 1;
133
+ }
134
+ return count;
135
+ }
136
+ /** Every readable manifest of a session; unreadable entries are skipped. */
137
+ async #listSessionManifests(sessionId) {
138
+ const result = [];
139
+ const instancesDir = join(this.root, "instances");
140
+ let instanceKeys;
141
+ try {
142
+ instanceKeys = await readdir(instancesDir);
143
+ }
144
+ catch (error) {
145
+ if (isNotFoundError(error))
146
+ return result;
147
+ throw new KvMetadataIoError(`cannot list ${instancesDir}`, { cause: error });
148
+ }
149
+ for (const instanceKey of instanceKeys) {
150
+ const sessionsDir = join(instancesDir, instanceKey, "sessions");
151
+ let files;
152
+ try {
153
+ files = await readdir(sessionsDir);
154
+ }
155
+ catch (error) {
156
+ if (isNotFoundError(error))
157
+ continue;
158
+ throw new KvMetadataIoError(`cannot list ${sessionsDir}`, { cause: error });
159
+ }
160
+ for (const file of files) {
161
+ if (!file.endsWith(".json"))
162
+ continue;
163
+ const path = join(sessionsDir, file);
164
+ try {
165
+ const manifest = parseManifest(JSON.parse(await readFile(path, "utf8")));
166
+ if (manifest.sessionId === sessionId)
167
+ result.push(manifest);
168
+ }
169
+ catch {
170
+ // Unreadable manifests are not session state; ignore here.
171
+ }
172
+ }
173
+ }
174
+ return result;
175
+ }
176
+ /**
177
+ * Find a ready, runtime-compatible manifest for the identity; incompatible
178
+ * manifests are marked invalid (SPEC §31) and ignored.
179
+ */
180
+ async findCompatible(identity) {
181
+ const manifest = await this.load(identity);
182
+ if (!manifest)
183
+ return null;
184
+ const storedIdentity = {
185
+ sessionId: manifest.sessionId,
186
+ provider: manifest.provider,
187
+ model: manifest.model,
188
+ backend: manifest.backend,
189
+ serverInstanceKey: manifest.serverInstanceKey,
190
+ compatibilityVersion: manifest.compatibilityVersion,
191
+ };
192
+ const compatibleShape = storedIdentity.serverInstanceKey === identity.serverInstanceKey &&
193
+ storedIdentity.provider === identity.provider &&
194
+ storedIdentity.model === identity.model;
195
+ if (!compatibleShape)
196
+ return null;
197
+ if (manifest.state !== "ready")
198
+ return null;
199
+ if (storedIdentity.compatibilityVersion !== identity.compatibilityVersion) {
200
+ await this.markInvalid(identity, "MODEL_FINGERPRINT_CHANGED", new Date().toISOString());
201
+ return null;
202
+ }
203
+ return manifest;
204
+ }
205
+ /** Aggregate manifest counts for the status API (SPEC §47). */
206
+ async counts() {
207
+ const result = { known: 0, valid: 0, invalid: 0 };
208
+ const instancesDir = join(this.root, "instances");
209
+ let instanceKeys;
210
+ try {
211
+ instanceKeys = await readdir(instancesDir);
212
+ }
213
+ catch (error) {
214
+ if (isNotFoundError(error))
215
+ return result;
216
+ throw new KvMetadataIoError(`cannot list ${instancesDir}`, { cause: error });
217
+ }
218
+ for (const instanceKey of instanceKeys) {
219
+ const sessionsDir = join(instancesDir, instanceKey, "sessions");
220
+ let files;
221
+ try {
222
+ files = await readdir(sessionsDir);
223
+ }
224
+ catch (error) {
225
+ if (isNotFoundError(error))
226
+ continue;
227
+ throw new KvMetadataIoError(`cannot list ${sessionsDir}`, { cause: error });
228
+ }
229
+ for (const file of files) {
230
+ if (!file.endsWith(".json"))
231
+ continue;
232
+ result.known += 1;
233
+ try {
234
+ const text = await readFile(join(sessionsDir, file), "utf8");
235
+ const manifest = parseManifest(JSON.parse(text));
236
+ if (manifest.state === "ready")
237
+ result.valid += 1;
238
+ else
239
+ result.invalid += 1;
240
+ }
241
+ catch {
242
+ result.invalid += 1;
243
+ }
244
+ }
245
+ }
246
+ return result;
247
+ }
248
+ async #write(manifest) {
249
+ const identity = {
250
+ sessionId: manifest.sessionId,
251
+ provider: manifest.provider,
252
+ model: manifest.model,
253
+ backend: manifest.backend,
254
+ serverInstanceKey: manifest.serverInstanceKey,
255
+ compatibilityVersion: manifest.compatibilityVersion,
256
+ };
257
+ const path = this.#manifestPath(identity);
258
+ const tmpPath = `${path}.${process.pid}.${Date.now().toString(36)}.tmp`;
259
+ try {
260
+ await mkdir(dirname(path), { recursive: true });
261
+ await writeFile(tmpPath, `${JSON.stringify(manifest, null, 2)}\n`, "utf8");
262
+ await rename(tmpPath, path);
263
+ }
264
+ catch (error) {
265
+ await rm(tmpPath, { force: true }).catch(() => { });
266
+ throw new KvMetadataIoError(`cannot write manifest ${path}`, { cause: error });
267
+ }
268
+ }
269
+ }
270
+ //# sourceMappingURL=repository.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repository.js","sourceRoot":"","sources":["../../src/snapshots/repository.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,83 @@
1
+ {
2
+ "name": "@yadsh/dsh-kv-persist",
3
+ "version": "0.1.0",
4
+ "description": "Persistent KV-cache/session-state manager for DeepSeek Harness (llama.cpp slot snapshots)",
5
+ "keywords": [
6
+ "deepseek",
7
+ "deepseek-harness",
8
+ "dsh",
9
+ "dsh-plugin",
10
+ "kv-cache",
11
+ "llama-cpp",
12
+ "persistence"
13
+ ],
14
+ "homepage": "https://github.com/xarleyn/dsh-plugins/tree/main/plugins/dsh-kv-persist#readme",
15
+ "bugs": {
16
+ "url": "https://github.com/xarleyn/dsh-plugins/issues"
17
+ },
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "git+https://github.com/xarleyn/dsh-plugins.git",
21
+ "directory": "plugins/dsh-kv-persist"
22
+ },
23
+ "license": "MIT",
24
+ "author": "xarleyn",
25
+ "type": "module",
26
+ "main": "./lib/index.js",
27
+ "types": "./lib/index.d.ts",
28
+ "exports": {
29
+ ".": {
30
+ "types": "./lib/index.d.ts",
31
+ "default": "./lib/index.js"
32
+ },
33
+ "./package.json": "./package.json"
34
+ },
35
+ "files": [
36
+ "lib",
37
+ "cordis.patch.yml",
38
+ "compatibility.json",
39
+ "docs/dsh-kv-persist.md",
40
+ "README.md",
41
+ "LICENSE"
42
+ ],
43
+ "dsh": {
44
+ "bundle": {
45
+ "patch": "./cordis.patch.yml"
46
+ }
47
+ },
48
+ "scripts": {
49
+ "build": "tsc -p tsconfig.build.json",
50
+ "lint": "eslint src test",
51
+ "typecheck": "tsc -p tsconfig.json --noEmit",
52
+ "test": "vitest run",
53
+ "test:llama": "vitest run test/integration/llama-server.test.ts",
54
+ "verify:package": "node scripts/verify-package.mjs",
55
+ "verify": "npm run verify:package",
56
+ "check": "npm run typecheck && npm test && npm run build && npm run verify"
57
+ },
58
+ "publishConfig": {
59
+ "access": "public",
60
+ "registry": "https://registry.npmjs.org/"
61
+ },
62
+ "engines": {
63
+ "node": ">=22"
64
+ },
65
+ "peerDependencies": {
66
+ "@deepseek-ai/cordis": "catalog:dsh",
67
+ "@deepseek-ai/dsh-llm": "catalog:dsh",
68
+ "@deepseek-ai/schemastery": "catalog:dsh"
69
+ },
70
+ "devDependencies": {
71
+ "@deepseek-ai/cordis": "catalog:dsh-dev",
72
+ "@deepseek-ai/dsh-llm": "catalog:dsh-dev",
73
+ "@deepseek-ai/schemastery": "catalog:dsh-dev",
74
+ "@types/node": "catalog:tooling",
75
+ "@yadsh/dsh-config": "workspace:^",
76
+ "eslint": "catalog:tooling",
77
+ "typescript": "catalog:tooling",
78
+ "vitest": "catalog:tooling"
79
+ },
80
+ "dependencies": {
81
+ "pino": "^10.3.1"
82
+ }
83
+ }