dsh-context 0.29.0 → 0.30.1
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 +1 -0
- package/cordis.patch.yml +3 -7
- package/lib/client.js +173 -204
- package/lib/index.d.ts +21 -54
- package/lib/index.js +17 -34
- package/package.json +1 -1
package/lib/index.d.ts
CHANGED
|
@@ -2,29 +2,24 @@ import { ZodType, z } from "zod";
|
|
|
2
2
|
import { Session, SessionEvent } from "@deepseek-ai/dsh-session";
|
|
3
3
|
import { Context, Service } from "@deepseek-ai/cordis";
|
|
4
4
|
//#region src/host/config.d.ts
|
|
5
|
-
/** dsh-context host config. All fields optional; defaults below. */
|
|
6
5
|
interface Config {
|
|
7
6
|
/** Cap on kept per-step request records (the hard step backstop). */
|
|
8
7
|
maxRequestSteps?: number;
|
|
9
8
|
/** Newest whole-turn window kept; trimming crosses whole turns, never mid-turn. */
|
|
10
9
|
maxKeptTurns?: number;
|
|
11
|
-
/** Newest context-event records kept. */
|
|
12
10
|
maxEvents?: number;
|
|
13
11
|
/**
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* surface far below it in healthy sessions, so the browser effectively
|
|
18
|
-
* lists EVERY live node; the bound stays as a backstop for pathological
|
|
19
|
-
* sessions (every projection push ships the whole value, ~150B per node).
|
|
12
|
+
* Served surface nodes (newest carry the signal; live inject nodes are pinned — they land first and are few). Deliberately generous:
|
|
13
|
+
* auto-compaction keeps healthy surfaces far below it, so the browser effectively lists every live node; the bound is a
|
|
14
|
+
* pathological-session backstop (each push ships the whole value, ~150B/node).
|
|
20
15
|
*/
|
|
21
16
|
maxNodes?: number;
|
|
22
17
|
/** Removed (shadowed) surface nodes kept for per-step reconstruction. */
|
|
23
18
|
maxArchiveNodes?: number;
|
|
24
19
|
}
|
|
25
20
|
/**
|
|
26
|
-
* The cordis `Config` validator: strict on keys, defaults on the schema fields
|
|
27
|
-
*
|
|
21
|
+
* The cordis `Config` validator: strict on keys, defaults on the schema fields; tolerates `undefined` (a patch row without a `config:`
|
|
22
|
+
* block — defaults win).
|
|
28
23
|
*/
|
|
29
24
|
declare const Config: z.ZodPreprocess<z.ZodObject<{
|
|
30
25
|
maxRequestSteps: z.ZodDefault<z.ZodNumber>;
|
|
@@ -36,19 +31,10 @@ declare const Config: z.ZodPreprocess<z.ZodObject<{
|
|
|
36
31
|
//#endregion
|
|
37
32
|
//#region src/shared/types.d.ts
|
|
38
33
|
/**
|
|
39
|
-
* Shared wire contract — the snapshot model exchanged between the Host and
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
* `view()` payload of the `contextTimeline` session projection, registered on
|
|
44
|
-
* the harness's `ctx.sessionProjections` registry. The registry drives
|
|
45
|
-
* `apply(state, event)` over every committed session event, persists the state
|
|
46
|
-
* through `ctx.sessionProjectionCache`, and pushes the finished value to the
|
|
47
|
-
* browser as a `session/projection` frame (with a tail-page baseline), where
|
|
48
|
-
* the Client reads it through the framework-standard `useProjection` seat.
|
|
49
|
-
*
|
|
50
|
-
* TYPE-ONLY host-side module: both halves import these as `import type`, so
|
|
51
|
-
* nothing from here ever reaches the runtime bundles.
|
|
34
|
+
* Shared wire contract — the snapshot model exchanged between the Host and Client halves. Delivered as the `view()` payload of the
|
|
35
|
+
* `contextTimeline`/`contextHeaders` session projections (registered on `ctx.sessionProjections`; the registry pushes finished views as
|
|
36
|
+
* `session/projection` frames — see host/timeline.ts). TYPE-ONLY host-side module: both halves import these as `import type`, so nothing
|
|
37
|
+
* from here ever reaches the runtime bundles.
|
|
52
38
|
*/
|
|
53
39
|
declare module '@deepseek-ai/dsh-session-projection/types' {
|
|
54
40
|
interface SessionProjectionMap {
|
|
@@ -70,7 +56,6 @@ declare module '@deepseek-ai/dsh-session-projection/types' {
|
|
|
70
56
|
contextHeaders: ContextHeaders;
|
|
71
57
|
}
|
|
72
58
|
}
|
|
73
|
-
/** The five priced context categories (plus system/tools handled separately). */
|
|
74
59
|
type Category = 'user' | 'inject' | 'assistant' | 'tool';
|
|
75
60
|
interface Snapshot {
|
|
76
61
|
ok: boolean;
|
|
@@ -93,15 +78,10 @@ interface Snapshot {
|
|
|
93
78
|
* instead. Kept optional for wire compatibility with older clients.
|
|
94
79
|
*/
|
|
95
80
|
occupancy?: {
|
|
96
|
-
/** Provider-reported prompt size of the most recent request (input + cache). */
|
|
97
81
|
pressureTokens?: number;
|
|
98
|
-
/** Heuristic total over the current model-visible surface. */
|
|
99
82
|
surfaceTokens: number;
|
|
100
|
-
/** `surfaceTokens` at the newest usage sample. */
|
|
101
83
|
sampledSurfaceTokens?: number;
|
|
102
|
-
/** pressureTokens + surface movement since the sample (clamped ≥ 0). */
|
|
103
84
|
projectedTokens?: number;
|
|
104
|
-
/** Newest recorded route capacity (last-wins). */
|
|
105
85
|
contextWindow?: number;
|
|
106
86
|
};
|
|
107
87
|
toolList: {
|
|
@@ -131,10 +111,9 @@ interface Snapshot {
|
|
|
131
111
|
*/
|
|
132
112
|
cost?: SessionCostUsage;
|
|
133
113
|
/**
|
|
134
|
-
* The served live surface: the newest `maxNodes` tail PLUS every live
|
|
135
|
-
*
|
|
136
|
-
* they are pinned
|
|
137
|
-
* browser could list none). Seq-ordered, oldest first.
|
|
114
|
+
* The served live surface: the newest `maxNodes` tail PLUS every live inject node older than the tail (injections land first and are
|
|
115
|
+
* few,
|
|
116
|
+
* so they are pinned). Seq-ordered, oldest first.
|
|
138
117
|
*/
|
|
139
118
|
nodes: SurfaceNode[];
|
|
140
119
|
/** Live nodes not served (the overflow beyond `maxNodes`, minus pinned injects — see `nodes`). */
|
|
@@ -159,11 +138,8 @@ interface Snapshot {
|
|
|
159
138
|
archiveFloor?: number;
|
|
160
139
|
}
|
|
161
140
|
/**
|
|
162
|
-
* The `contextTimeline` projection's whole value — the same snapshot the
|
|
163
|
-
*
|
|
164
|
-
* pipeline. `ok` is always `true` here (a delivered projection is by
|
|
165
|
-
* definition available); it is kept for wire compatibility with the
|
|
166
|
-
* snapshot shape.
|
|
141
|
+
* The `contextTimeline` projection's whole value — the same snapshot the Client has always rendered. `ok` is always `true` here (a
|
|
142
|
+
* delivered projection is by definition available); kept for wire compatibility with the snapshot shape.
|
|
167
143
|
*/
|
|
168
144
|
type ContextTimeline = Snapshot;
|
|
169
145
|
/**
|
|
@@ -172,20 +148,14 @@ type ContextTimeline = Snapshot;
|
|
|
172
148
|
* session log, immune to the request/event retention bounds).
|
|
173
149
|
*/
|
|
174
150
|
interface CostBucketTotals {
|
|
175
|
-
/** Billed prompt tokens that missed the provider cache. */
|
|
176
151
|
uncached: number;
|
|
177
|
-
/** Billed prompt tokens served from the provider cache. */
|
|
178
152
|
cacheRead: number;
|
|
179
|
-
/** Billed prompt tokens written into the provider cache. */
|
|
180
153
|
cacheWrite: number;
|
|
181
|
-
/** Billed output tokens (reasoning included). */
|
|
182
154
|
output: number;
|
|
183
155
|
}
|
|
184
156
|
/** One model family's totals split by DeepSeek's pricing period (Beijing Time). */
|
|
185
157
|
interface CostFamilyUsage {
|
|
186
|
-
/** Peak windows: 09:00-12:00 and 14:00-18:00 Beijing Time, weekdays only. */
|
|
187
158
|
peak?: CostBucketTotals;
|
|
188
|
-
/** All other hours plus all of Saturday/Sunday (half the peak rate). */
|
|
189
159
|
off?: CostBucketTotals;
|
|
190
160
|
}
|
|
191
161
|
/**
|
|
@@ -202,7 +172,6 @@ interface SessionCostUsage {
|
|
|
202
172
|
/** One model-visible message on the surface, with its heuristic token price. */
|
|
203
173
|
interface SurfaceNode {
|
|
204
174
|
seq: number;
|
|
205
|
-
/** Event timestamp (ms epoch); the Client shows it when present. */
|
|
206
175
|
time?: number;
|
|
207
176
|
cat: Category;
|
|
208
177
|
tokens: number;
|
|
@@ -236,6 +205,12 @@ interface RequestRecord {
|
|
|
236
205
|
tool: number;
|
|
237
206
|
total: number;
|
|
238
207
|
prompt?: number;
|
|
208
|
+
/**
|
|
209
|
+
* Billed cache-read (served) prompt tokens of this request — the
|
|
210
|
+
* hit-rate numerator against `prompt` (input + cacheRead + cacheWrite).
|
|
211
|
+
* Absent on older hosts / usage-less requests; zero is a real value.
|
|
212
|
+
*/
|
|
213
|
+
cacheRead?: number;
|
|
239
214
|
output?: number;
|
|
240
215
|
/**
|
|
241
216
|
* Turn-mode aggregate marker, set by the Client's aggregateByTurn (one bar
|
|
@@ -280,10 +255,7 @@ interface HeaderTool {
|
|
|
280
255
|
schema?: unknown;
|
|
281
256
|
}
|
|
282
257
|
/**
|
|
283
|
-
* One request-header epoch: the full system prompt and tool schemas in force
|
|
284
|
-
* from this event's seq until the next epoch. Headers change rarely (the loop
|
|
285
|
-
* only logs `request/header` on change), so this unit's pushes are rare and
|
|
286
|
-
* carrying full content is cheap.
|
|
258
|
+
* One request-header epoch: the full system prompt and tool schemas in force from this event's seq until the next epoch.
|
|
287
259
|
*/
|
|
288
260
|
interface HeaderRecord {
|
|
289
261
|
seq: number;
|
|
@@ -307,11 +279,9 @@ interface ContextHeaders {
|
|
|
307
279
|
* (not only when the raw step bound is), so the bounded state stays at the
|
|
308
280
|
* newest ~`maxKeptTurns` turns deterministically as a live log grows.
|
|
309
281
|
*/
|
|
310
|
-
/** The projection unit's persisted state (plain JSON, bounded see above). */
|
|
311
282
|
interface TimelineState {
|
|
312
283
|
/** Model-visible surface, newest last. */
|
|
313
284
|
surface: SurfaceNode[];
|
|
314
|
-
/** Live per-category token sums over the surface. */
|
|
315
285
|
sums: Record<Category, number>;
|
|
316
286
|
systemTokens: number;
|
|
317
287
|
toolsTokens: number;
|
|
@@ -351,7 +321,6 @@ interface TimelineState {
|
|
|
351
321
|
* Absent until a v4-flash / v4-pro request reports usage.
|
|
352
322
|
*/
|
|
353
323
|
cost?: SessionCostUsage;
|
|
354
|
-
/** Newest `gone` among archive entries dropped by the retention bounds. */
|
|
355
324
|
archiveFloor?: number;
|
|
356
325
|
/**
|
|
357
326
|
* Tool callId → name, armed by `tool/call` and DELETED when its
|
|
@@ -608,14 +577,12 @@ declare class SessionProjectionRegistry extends Service {
|
|
|
608
577
|
}
|
|
609
578
|
//#endregion
|
|
610
579
|
//#region src/host/headers.d.ts
|
|
611
|
-
/** The unit's persisted state (plain JSON, bounded). */
|
|
612
580
|
interface HeadersState {
|
|
613
581
|
headers: HeaderRecord[];
|
|
614
582
|
}
|
|
615
583
|
//#endregion
|
|
616
584
|
//#region src/host/index.d.ts
|
|
617
585
|
declare const name = "dsh-context";
|
|
618
|
-
/** Required services: the session-projection registry that drives the unit. */
|
|
619
586
|
declare const inject: string[];
|
|
620
587
|
declare function apply(ctx: Context, config: Config): void;
|
|
621
588
|
//#endregion
|
package/lib/index.js
CHANGED
|
@@ -17,7 +17,6 @@ import { deriveEventMessage } from "@deepseek-ai/dsh-session";
|
|
|
17
17
|
* only tune the fold's retention / presentation slice, so changing them never
|
|
18
18
|
* requires a projection `stateVersion` bump.
|
|
19
19
|
*/
|
|
20
|
-
/** Defaults — the exact bounds the fold used before they became configurable. */
|
|
21
20
|
const DEFAULT_BOUNDS = {
|
|
22
21
|
maxRequestSteps: 1500,
|
|
23
22
|
maxKeptTurns: 300,
|
|
@@ -26,8 +25,8 @@ const DEFAULT_BOUNDS = {
|
|
|
26
25
|
maxArchiveNodes: 400
|
|
27
26
|
};
|
|
28
27
|
/**
|
|
29
|
-
* The cordis `Config` validator: strict on keys, defaults on the schema fields
|
|
30
|
-
*
|
|
28
|
+
* The cordis `Config` validator: strict on keys, defaults on the schema fields; tolerates `undefined` (a patch row without a `config:`
|
|
29
|
+
* block — defaults win).
|
|
31
30
|
*/
|
|
32
31
|
const Config = z.preprocess((v) => v ?? {}, z.object({
|
|
33
32
|
maxRequestSteps: z.number().int().min(1).default(DEFAULT_BOUNDS.maxRequestSteps),
|
|
@@ -36,7 +35,6 @@ const Config = z.preprocess((v) => v ?? {}, z.object({
|
|
|
36
35
|
maxNodes: z.number().int().min(1).default(DEFAULT_BOUNDS.maxNodes),
|
|
37
36
|
maxArchiveNodes: z.number().int().min(1).default(DEFAULT_BOUNDS.maxArchiveNodes)
|
|
38
37
|
}).strict());
|
|
39
|
-
/** Validate (and default) the entry config into concrete fold bounds. */
|
|
40
38
|
function resolveBounds(config) {
|
|
41
39
|
return Config.parse(config ?? {});
|
|
42
40
|
}
|
|
@@ -69,7 +67,6 @@ const MAX_WH_RATIO = 8;
|
|
|
69
67
|
const MIN_PIXELS = 147456;
|
|
70
68
|
const floorDiv = (a, b) => Math.floor(a / b);
|
|
71
69
|
const ceilDiv = (a, b) => Math.floor((a + b - 1) / b);
|
|
72
|
-
/** Token count of one patch grid (rows×cols) under the v4 layout rule. */
|
|
73
70
|
function gridTokens(rows, cols) {
|
|
74
71
|
let n = rows * (cols + 1) + 2;
|
|
75
72
|
if (rows % 2 === 1) n += cols + 1;
|
|
@@ -151,10 +148,8 @@ function calcResizeInner(width, height) {
|
|
|
151
148
|
return safeResize(h, w, paddedHeight, paddedWidth);
|
|
152
149
|
}
|
|
153
150
|
/**
|
|
154
|
-
* Estimate the tokens one image consumes in a DeepSeek vision request
|
|
155
|
-
*
|
|
156
|
-
* or when the official iteration fails to converge — callers fall back to
|
|
157
|
-
* the generic structural price.
|
|
151
|
+
* Estimate the tokens one image consumes in a DeepSeek vision request from its pixel dimensions. Returns null for non-positive/non-finite
|
|
152
|
+
* dimensions or when the official iteration fails to converge — callers fall back to the generic structural price.
|
|
158
153
|
*/
|
|
159
154
|
function estimateImageTokens(width, height) {
|
|
160
155
|
if (!Number.isFinite(width) || !Number.isFinite(height) || width <= 0 || height <= 0) return null;
|
|
@@ -188,7 +183,6 @@ function estimateImageTokens(width, height) {
|
|
|
188
183
|
const CHARS_PER_TOKEN = 4;
|
|
189
184
|
const BLOCK_OVERHEAD = 4;
|
|
190
185
|
const ROLE_OVERHEAD = 4;
|
|
191
|
-
/** Whole-array tool-schema price (the header's tools total). */
|
|
192
186
|
function estimateToolsTotal(tools) {
|
|
193
187
|
return tools.length > 0 ? Math.ceil(JSON.stringify(tools).length / CHARS_PER_TOKEN) + BLOCK_OVERHEAD : 0;
|
|
194
188
|
}
|
|
@@ -234,9 +228,8 @@ function estimateToolSchema(tool) {
|
|
|
234
228
|
return Math.ceil(JSON.stringify(tool).length / CHARS_PER_TOKEN) + BLOCK_OVERHEAD;
|
|
235
229
|
}
|
|
236
230
|
/**
|
|
237
|
-
* Count image blocks in a message payload, recursing into nested content
|
|
238
|
-
*
|
|
239
|
-
* whole-session image-file cell.
|
|
231
|
+
* Count image blocks in a message payload, recursing into nested content (tool-result blocks carry their inner blocks) — seeds each node's
|
|
232
|
+
* `imgs`, which the stats board's image cell sums over the LIVE surface (compacted/pruned messages stop counting).
|
|
240
233
|
*/
|
|
241
234
|
function imageCountOf(blocks) {
|
|
242
235
|
let count = 0;
|
|
@@ -312,12 +305,10 @@ const contextHeadersSchema = z.object({ headers: z.array(z.object({
|
|
|
312
305
|
tools: z.array(headerToolSchema)
|
|
313
306
|
}).strict()) }).strict();
|
|
314
307
|
/**
|
|
315
|
-
*
|
|
316
|
-
*
|
|
317
|
-
* dsh 0.1.1-rc.1+ `stateSchema`/`wire` contract.
|
|
308
|
+
* State and wire are the same shape (the view only shallow-copies each record), so one schema validates both under the dsh 0.1.1-rc.1+
|
|
309
|
+
* `stateSchema`/`wire` contract.
|
|
318
310
|
*/
|
|
319
311
|
const contextHeadersStateSchema = contextHeadersSchema;
|
|
320
|
-
/** Fold one `request/header` payload into an epoch record (display-priced). */
|
|
321
312
|
function recordOf(event) {
|
|
322
313
|
if (event.type !== "request/header") return null;
|
|
323
314
|
const rawHeader = event.data.header;
|
|
@@ -342,14 +333,9 @@ function recordOf(event) {
|
|
|
342
333
|
return record;
|
|
343
334
|
}
|
|
344
335
|
/**
|
|
345
|
-
* The context-headers projection unit
|
|
346
|
-
*
|
|
347
|
-
*
|
|
348
|
-
*
|
|
349
|
-
* Dual-contract definition (see compat.ts): `schema`/`view` for
|
|
350
|
-
* dsh <= 0.1.0-rc.8, `stateSchema`/`wire` for dsh >= 0.1.1-rc.1. Without
|
|
351
|
-
* `wire`, the 0.1.1-rc.1+ registry treats the unit as host-only and the
|
|
352
|
-
* Context browser's system/tools sections would degrade.
|
|
336
|
+
* The context-headers projection unit; registered alongside the timeline unit (host/index.ts); clients read it through
|
|
337
|
+
* `useProjection('contextHeaders')` and degrade to tokens-only header sections when the key is absent. Dual-contract definition (see
|
|
338
|
+
* compat.ts).
|
|
353
339
|
*/
|
|
354
340
|
function createContextHeadersDefinition() {
|
|
355
341
|
const view = (state) => ({ headers: state.headers.map((h) => ({
|
|
@@ -394,7 +380,6 @@ function installSettings(ctx) {
|
|
|
394
380
|
}
|
|
395
381
|
//#endregion
|
|
396
382
|
//#region src/host/fold.ts
|
|
397
|
-
/** Keep only the trailing `maxTurns` turn-runs of a request timeline. */
|
|
398
383
|
function trimToLastTurns(requests, maxTurns) {
|
|
399
384
|
let runs = 0;
|
|
400
385
|
let start = requests.length;
|
|
@@ -410,7 +395,6 @@ function trimToLastTurns(requests, maxTurns) {
|
|
|
410
395
|
}
|
|
411
396
|
return requests.slice(start);
|
|
412
397
|
}
|
|
413
|
-
/** Distinct turn runs in a request timeline (consecutive equal-turn runs). */
|
|
414
398
|
function countTurnRuns(requests) {
|
|
415
399
|
let runs = 0;
|
|
416
400
|
let prevTurn;
|
|
@@ -420,7 +404,6 @@ function countTurnRuns(requests) {
|
|
|
420
404
|
}
|
|
421
405
|
return runs;
|
|
422
406
|
}
|
|
423
|
-
/** Retain the newest tail of the two unbounded lists (bounded persisted state). */
|
|
424
407
|
function trimState(st, bounds) {
|
|
425
408
|
if (countTurnRuns(st.requests) > bounds.maxKeptTurns) st.requests = trimToLastTurns(st.requests, bounds.maxKeptTurns);
|
|
426
409
|
if (st.requests.length > bounds.maxRequestSteps) st.requests = st.requests.slice(-bounds.maxRequestSteps);
|
|
@@ -767,6 +750,7 @@ function applyTimeline(state, event, bounds) {
|
|
|
767
750
|
if (data && typeof data.step === "number") record.step = data.step;
|
|
768
751
|
if (usage && typeof usage.inputTokens === "number") {
|
|
769
752
|
record.prompt = usage.inputTokens + (usage.cacheReadTokens || 0) + (usage.cacheWriteTokens || 0);
|
|
753
|
+
if (typeof usage.cacheReadTokens === "number") record.cacheRead = usage.cacheReadTokens;
|
|
770
754
|
if (typeof usage.outputTokens === "number") record.output = usage.outputTokens;
|
|
771
755
|
accumulateCost(s, event.time, usage);
|
|
772
756
|
}
|
|
@@ -808,10 +792,9 @@ function applyTimeline(state, event, bounds) {
|
|
|
808
792
|
return state;
|
|
809
793
|
}
|
|
810
794
|
/**
|
|
811
|
-
*
|
|
812
|
-
*
|
|
813
|
-
*
|
|
814
|
-
* objects are never mutated).
|
|
795
|
+
* Serve the projection's wire view: bound the surface nodes to the newest tail and attach each event to the request around it; stamp
|
|
796
|
+
* COPIES
|
|
797
|
+
* — the persisted state objects are never mutated.
|
|
815
798
|
*/
|
|
816
799
|
function buildTimelineView(state, bounds) {
|
|
817
800
|
const surfaceTotal = state.sums.user + state.sums.inject + state.sums.assistant + state.sums.tool;
|
|
@@ -936,6 +919,7 @@ const requestRecordSchema = z.object({
|
|
|
936
919
|
tool: z.number().int().nonnegative(),
|
|
937
920
|
total: z.number().int().nonnegative(),
|
|
938
921
|
prompt: z.number().int().nonnegative().optional(),
|
|
922
|
+
cacheRead: z.number().int().nonnegative().optional(),
|
|
939
923
|
output: z.number().int().nonnegative().optional(),
|
|
940
924
|
stepCount: z.number().int().positive().optional()
|
|
941
925
|
}).strict();
|
|
@@ -1072,13 +1056,12 @@ function createContextTimelineDefinition(config) {
|
|
|
1072
1056
|
},
|
|
1073
1057
|
init: () => createTimelineState(),
|
|
1074
1058
|
apply: (state, event) => applyTimeline(state, event, bounds),
|
|
1075
|
-
stateVersion:
|
|
1059
|
+
stateVersion: 9
|
|
1076
1060
|
};
|
|
1077
1061
|
}
|
|
1078
1062
|
//#endregion
|
|
1079
1063
|
//#region src/host/index.ts
|
|
1080
1064
|
const name = "dsh-context";
|
|
1081
|
-
/** Required services: the session-projection registry that drives the unit. */
|
|
1082
1065
|
const inject = ["sessionProjections"];
|
|
1083
1066
|
function apply(ctx, config) {
|
|
1084
1067
|
ctx.sessionProjections.register(createContextTimelineDefinition(config));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-context",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.30.1",
|
|
4
4
|
"description": "A DeepSeek Harness plugin for context insight and management, with context dashboard and context command, for understanding how the context is made of, and how it evolves.",
|
|
5
5
|
"author": "bowenliang123",
|
|
6
6
|
"repository": {
|