@robiteame/dsh-pi-agent-session-tree 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.
- package/README.i18n.yaml +6 -0
- package/README.md +98 -0
- package/README.zh.md +72 -0
- package/lib/index.js +1190 -0
- package/lib/invariant.js +12 -0
- package/lib/typert.host.d.ts +1 -0
- package/lib/typert.host.js +762 -0
- package/lib/typert.remote-client.d.ts +2 -0
- package/lib/typert.remote-client.js +247 -0
- package/lib/types/client.d.ts +8 -0
- package/lib/types/index.d.ts +130 -0
- package/lib/types/invariant.d.ts +15 -0
- package/lib/types/session-event-adapter.d.ts +28 -0
- package/lib/types/session-tree-marker.d.ts +13 -0
- package/lib/types/session-tree-sidecar.d.ts +29 -0
- package/lib/types/session-tree.d.ts +182 -0
- package/lib/types/types.d.ts +185 -0
- package/package.json +77 -0
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure JSON-safe payload vocabulary of the session-tree domain. This module
|
|
3
|
+
* imports nothing host-side: `./client` re-exports it for the browser half,
|
|
4
|
+
* the Typert generator reflects it into wire schemas, and `./types` serves
|
|
5
|
+
* host consumers. Everything here is lossless-JSON serializable (acceptance:
|
|
6
|
+
* tool and Remote results are plain JSON with a stable error envelope).
|
|
7
|
+
*
|
|
8
|
+
* @module @robiteame/dsh-pi-agent-session-tree/types
|
|
9
|
+
*/
|
|
10
|
+
import type { SessionId } from '@deepseek-ai/dsh-session/types';
|
|
11
|
+
/** Roles accepted in one stored conversation message. */
|
|
12
|
+
export type LlmRole = 'system' | 'user' | 'assistant' | 'tool';
|
|
13
|
+
/** PI-Agent-style entry kinds; every session entry is still one tree node. */
|
|
14
|
+
export type TreeEntryType = 'message' | 'tool_call' | 'tool_result' | 'model_change' | 'compaction' | 'branch_summary' | 'custom';
|
|
15
|
+
/** Structured Pi-style content part carried by an entry. */
|
|
16
|
+
export type ContentPart = {
|
|
17
|
+
readonly type: 'text';
|
|
18
|
+
readonly text: string;
|
|
19
|
+
} | {
|
|
20
|
+
readonly type: 'tool_call';
|
|
21
|
+
readonly id: string;
|
|
22
|
+
readonly name: string;
|
|
23
|
+
readonly arguments: JsonValue;
|
|
24
|
+
} | {
|
|
25
|
+
readonly type: 'tool_result';
|
|
26
|
+
readonly toolCallId: string;
|
|
27
|
+
readonly content: string;
|
|
28
|
+
readonly isError?: boolean;
|
|
29
|
+
} | {
|
|
30
|
+
readonly type: 'reasoning';
|
|
31
|
+
readonly text: string;
|
|
32
|
+
};
|
|
33
|
+
/** One standard LLM message carried by a tree node (the `messages` payload). */
|
|
34
|
+
export interface LlmMessage {
|
|
35
|
+
readonly role: LlmRole;
|
|
36
|
+
readonly content: string;
|
|
37
|
+
readonly name?: string;
|
|
38
|
+
readonly toolCallId?: string;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* One immutable history node. Nodes are append-only: once created, no field
|
|
42
|
+
* changes and no node is ever removed. Branching moves the cursor to an
|
|
43
|
+
* existing node; the next append becomes that node's child.
|
|
44
|
+
*/
|
|
45
|
+
export interface TreeNode {
|
|
46
|
+
/** Stable identity; unique within one session tree. */
|
|
47
|
+
readonly nodeId: string;
|
|
48
|
+
/** Parent node id, or null for a root. */
|
|
49
|
+
readonly parentId: string | null;
|
|
50
|
+
/** Number of direct forks created from this entry (derived, never mutated). */
|
|
51
|
+
readonly forkCount?: number;
|
|
52
|
+
/** PI-Agent-style entry discriminator; defaults to `message` for legacy nodes. */
|
|
53
|
+
readonly type?: TreeEntryType;
|
|
54
|
+
/** Branch label this node belongs to (defaults to the active branch). */
|
|
55
|
+
readonly branch: string;
|
|
56
|
+
/** Human-readable preview shown in tree views. */
|
|
57
|
+
readonly summary: string;
|
|
58
|
+
/** ISO-8601 creation time. */
|
|
59
|
+
readonly createdAt: string;
|
|
60
|
+
/**
|
|
61
|
+
* Detached compatibility DTO for display/context responses; this is not the
|
|
62
|
+
* Harness `Message` union and must not be passed to model APIs as-is.
|
|
63
|
+
*/
|
|
64
|
+
readonly message?: LlmMessage;
|
|
65
|
+
/** Pi-style structured content; message is retained as the derived compatibility DTO. */
|
|
66
|
+
readonly content?: readonly ContentPart[];
|
|
67
|
+
/** Optional model/provider metadata. */
|
|
68
|
+
readonly model?: string;
|
|
69
|
+
/** Optional usage/cost/error metadata from the model turn. */
|
|
70
|
+
readonly usage?: Record<string, JsonValue>;
|
|
71
|
+
readonly cost?: number;
|
|
72
|
+
readonly error?: string;
|
|
73
|
+
/** Optional lossless-JSON extras. */
|
|
74
|
+
readonly metadata?: Record<string, JsonValue>;
|
|
75
|
+
}
|
|
76
|
+
/** Lossless JSON value used across the payload vocabulary. */
|
|
77
|
+
export type JsonValue = null | boolean | number | string | JsonValue[] | {
|
|
78
|
+
[key: string]: JsonValue;
|
|
79
|
+
};
|
|
80
|
+
/** One branch's aggregated view: its nodes in creation order. */
|
|
81
|
+
export interface BranchView {
|
|
82
|
+
readonly name: string;
|
|
83
|
+
/** Id of the branch's newest node. */
|
|
84
|
+
readonly headId: string;
|
|
85
|
+
readonly nodeIds: readonly string[];
|
|
86
|
+
}
|
|
87
|
+
/** One append-only JSONL record for incremental tree persistence. */
|
|
88
|
+
export interface SessionTreeLogEntry {
|
|
89
|
+
readonly seq: number;
|
|
90
|
+
readonly node: TreeNode;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Versioned durable snapshot accepted by `snapshot.load` and produced by
|
|
94
|
+
* `snapshot.save`. `version` guards the on-disk format; unknown versions are
|
|
95
|
+
* rejected as `INVALID_SNAPSHOT`.
|
|
96
|
+
*/
|
|
97
|
+
export interface SessionTreeSnapshot {
|
|
98
|
+
readonly version: 1;
|
|
99
|
+
readonly sessionId: string;
|
|
100
|
+
readonly cursor: string | null;
|
|
101
|
+
readonly activeBranch: string;
|
|
102
|
+
/** Highest native Session event seq represented by this snapshot, when known. */
|
|
103
|
+
readonly nativeEventSeq?: number;
|
|
104
|
+
/** Session-level branch heads, matching Pi's named branch pointers. */
|
|
105
|
+
readonly branchHeads?: Record<string, string>;
|
|
106
|
+
/** Explicit UI-selected node used as the context for /fork and /clone. */
|
|
107
|
+
readonly selectedNodeId?: string | null;
|
|
108
|
+
readonly nodes: readonly TreeNode[];
|
|
109
|
+
}
|
|
110
|
+
/** Summary of the active tree/session for the `/session` surface. */
|
|
111
|
+
export interface SessionTreeSessionInfo {
|
|
112
|
+
/** Session-level branch heads, matching Pi's named branch pointers. */
|
|
113
|
+
readonly branchHeads?: Record<string, string>;
|
|
114
|
+
readonly sessionId: SessionId;
|
|
115
|
+
readonly nodeCount: number;
|
|
116
|
+
/** Number of message-carrying entries across the whole tree. */
|
|
117
|
+
readonly messageCount: number;
|
|
118
|
+
readonly branchCount: number;
|
|
119
|
+
readonly cursor: string | null;
|
|
120
|
+
readonly activeBranch: string;
|
|
121
|
+
readonly selectedNodeId?: string | null;
|
|
122
|
+
readonly currentPathLength: number;
|
|
123
|
+
/** Aggregated model usage from entries that recorded it. */
|
|
124
|
+
readonly usage?: Record<string, number>;
|
|
125
|
+
/** Sum of all numeric usage fields whose key ends in `Tokens`. */
|
|
126
|
+
readonly tokenCount?: number;
|
|
127
|
+
/** Aggregated model cost from entries that recorded it. */
|
|
128
|
+
readonly cost?: number;
|
|
129
|
+
readonly snapshotVersion: 1;
|
|
130
|
+
}
|
|
131
|
+
/** Read view served to the browser panel and `list` operations. */
|
|
132
|
+
export interface SessionTreeView {
|
|
133
|
+
readonly sessionId: SessionId;
|
|
134
|
+
readonly cursor: string | null;
|
|
135
|
+
readonly activeBranch: string;
|
|
136
|
+
/** Explicit UI-selected node; unlike cursor, it is only set by node selection. */
|
|
137
|
+
readonly selectedNodeId?: string | null;
|
|
138
|
+
/** Session-level branch heads, matching Pi's named branch pointers. */
|
|
139
|
+
readonly branchHeads?: Record<string, string>;
|
|
140
|
+
readonly nodes: readonly TreeNode[];
|
|
141
|
+
readonly branches: readonly BranchView[];
|
|
142
|
+
}
|
|
143
|
+
/** Result of tree cursor navigation: the new cursor plus the projected path. */
|
|
144
|
+
export interface JumpView {
|
|
145
|
+
readonly cursor: string | null;
|
|
146
|
+
readonly messages: readonly LlmMessage[];
|
|
147
|
+
}
|
|
148
|
+
/** Stable error codes for every failure path. */
|
|
149
|
+
export type TreeErrorCode = 'INVALID_ARGUMENT' | 'SESSION_NOT_FOUND' | 'SESSION_ALREADY_EXISTS' | 'NODE_NOT_FOUND' | 'INVALID_SNAPSHOT' | 'NOT_FOUND';
|
|
150
|
+
/** Standard success/error envelope returned by every tree operation. */
|
|
151
|
+
export type TreeResult<T> = {
|
|
152
|
+
readonly ok: true;
|
|
153
|
+
readonly value: T;
|
|
154
|
+
} | {
|
|
155
|
+
readonly ok: false;
|
|
156
|
+
readonly error: {
|
|
157
|
+
readonly code: TreeErrorCode;
|
|
158
|
+
readonly message: string;
|
|
159
|
+
};
|
|
160
|
+
};
|
|
161
|
+
declare module '@deepseek-ai/dsh-session/types' {
|
|
162
|
+
interface SessionEventMap {
|
|
163
|
+
/** Durable append-only SessionTree node written through Harness Session.append(). */
|
|
164
|
+
'session-tree/node': {
|
|
165
|
+
node: TreeNode;
|
|
166
|
+
};
|
|
167
|
+
/** Durable cursor movement; history nodes remain untouched. */
|
|
168
|
+
'session-tree/cursor': {
|
|
169
|
+
nodeId: string | null;
|
|
170
|
+
};
|
|
171
|
+
/** Durable named branch pointer and active-branch selection. */
|
|
172
|
+
'session-tree/branch': {
|
|
173
|
+
nodeId: string;
|
|
174
|
+
branch: string;
|
|
175
|
+
};
|
|
176
|
+
/** Durable explicit browser selection used by context-aware commands. */
|
|
177
|
+
'session-tree/selection': {
|
|
178
|
+
nodeId: string;
|
|
179
|
+
};
|
|
180
|
+
/** Durable full-tree replacement marker for explicit snapshot restore. */
|
|
181
|
+
'session-tree/snapshot': {
|
|
182
|
+
snapshot: SessionTreeSnapshot;
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@robiteame/dsh-pi-agent-session-tree",
|
|
3
|
+
"description": "Append-only multi-branch session trees: the SessionTree/SessionTreeStore domain model, JSON snapshots, and the sessionTree Remote service",
|
|
4
|
+
"version": "0.1.0",
|
|
5
|
+
"publishConfig": {
|
|
6
|
+
"access": "public"
|
|
7
|
+
},
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/robiteame/dsh-session-tree-extension.git",
|
|
11
|
+
"directory": "packages/extensions/pi-agent-session-tree"
|
|
12
|
+
},
|
|
13
|
+
"bugs": {
|
|
14
|
+
"url": "https://github.com/robiteame/dsh-session-tree-extension/issues"
|
|
15
|
+
},
|
|
16
|
+
"type": "module",
|
|
17
|
+
"main": "lib/index.js",
|
|
18
|
+
"types": "lib/types/index.d.ts",
|
|
19
|
+
"exports": {
|
|
20
|
+
".": {
|
|
21
|
+
"types": "./lib/types/index.d.ts",
|
|
22
|
+
"default": "./lib/index.js"
|
|
23
|
+
},
|
|
24
|
+
"./invariant": {
|
|
25
|
+
"types": "./lib/types/invariant.d.ts",
|
|
26
|
+
"default": "./lib/invariant.js"
|
|
27
|
+
},
|
|
28
|
+
"./types": {
|
|
29
|
+
"types": "./lib/types/types.d.ts",
|
|
30
|
+
"default": "./lib/index.js"
|
|
31
|
+
},
|
|
32
|
+
"./client": {
|
|
33
|
+
"types": "./lib/types/client.d.ts",
|
|
34
|
+
"default": "./lib/index.js"
|
|
35
|
+
},
|
|
36
|
+
"./typert": {
|
|
37
|
+
"types": "./lib/typert.host.d.ts",
|
|
38
|
+
"default": "./lib/typert.host.js"
|
|
39
|
+
},
|
|
40
|
+
"./remote": {
|
|
41
|
+
"types": "./lib/typert.remote-client.d.ts",
|
|
42
|
+
"default": "./lib/typert.remote-client.js"
|
|
43
|
+
},
|
|
44
|
+
"./package.json": "./package.json"
|
|
45
|
+
},
|
|
46
|
+
"files": [
|
|
47
|
+
"lib/index.js",
|
|
48
|
+
"lib/invariant.js",
|
|
49
|
+
"lib/types/**/*.d.ts",
|
|
50
|
+
"lib/typert.host.js",
|
|
51
|
+
"lib/typert.host.d.ts",
|
|
52
|
+
"lib/typert.remote-client.js",
|
|
53
|
+
"lib/typert.remote-client.d.ts",
|
|
54
|
+
"README.md"
|
|
55
|
+
],
|
|
56
|
+
"scripts": {
|
|
57
|
+
"build": "node ../../../scripts/build.mjs pi",
|
|
58
|
+
"watch": "node ../../../scripts/build.mjs pi"
|
|
59
|
+
},
|
|
60
|
+
"license": "MIT",
|
|
61
|
+
"peerDependencies": {
|
|
62
|
+
"@deepseek-ai/cordis": "^4.0.2",
|
|
63
|
+
"@deepseek-ai/dsh-agent": "^0.1.2-alpha.3",
|
|
64
|
+
"@deepseek-ai/dsh-commands": "^0.1.2-alpha.3",
|
|
65
|
+
"@deepseek-ai/dsh-invariants": "^0.1.2-alpha.3",
|
|
66
|
+
"@deepseek-ai/dsh-session": "^0.1.2-alpha.3",
|
|
67
|
+
"@deepseek-ai/dsh-system-prompt": "^0.1.2-alpha.3",
|
|
68
|
+
"@deepseek-ai/dsh-tools": "^0.1.2-alpha.3",
|
|
69
|
+
"@deepseek-ai/dsh-typert-protocol": "^0.1.2-alpha.3"
|
|
70
|
+
},
|
|
71
|
+
"dependencies": {
|
|
72
|
+
"zod": "^4.4.3"
|
|
73
|
+
},
|
|
74
|
+
"engines": {
|
|
75
|
+
"node": ">=22"
|
|
76
|
+
}
|
|
77
|
+
}
|