forked from deepseek-ai/deepseek-harness
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.ts
More file actions
65 lines (57 loc) · 2.3 KB
/
Copy pathindex.ts
File metadata and controls
65 lines (57 loc) · 2.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
/**
* `LocalSpillStore`: the host-filesystem implementation of the
* `@deepseek-ai/dsh-spill` storage seam. Persists a tool's oversized text to a
* private, session-scoped file (see `./store.ts` for the traversal-safe naming
* and exclusive owner-only write) and returns a path locator plus local
* read/grep retrieval guidance.
*
* @module @deepseek-ai/dsh-spill-local
*/
import { Context } from '@deepseek-ai/cordis'
import { resolve } from 'node:path'
import z from '@deepseek-ai/schemastery'
import { SpillLocator, SpillStore } from '@deepseek-ai/dsh-spill'
import type { SaveTextSpill, SpillRef } from '@deepseek-ai/dsh-spill'
import { privateRoot, saveTextFile } from './store.ts'
export { encodeSegment, privateRoot, saveTextFile, sessionDir } from './store.ts'
export type { SavedText, SaveTextOptions } from './store.ts'
/** Plugin config (all optional — `static Config` supplies the defaults). */
export interface Config {
/**
* Root directory for spill files. Omitted uses a lazily-created private
* (0700) per-process directory under the OS temp dir — the safe default for
* a local deployment. Set it to keep spill files under a known location.
*/
root?: string
}
/**
* Local-filesystem spill backend. Files land under `<root>/session-<hash>/…`
* with unpredictable names, an exclusive owner-only (0600) write, and a private
* (0700) root — a spilled tool result must not be readable by other local users
* or redirectable via a planted symlink.
*/
export class LocalSpillStore extends SpillStore {
static Config: z<Config> = z.object({
root: z.string(),
})
/** Resolved absolute spill root (config `root`, else the private default), fixed at construction. */
readonly root: string
constructor(ctx: Context, config: Config) {
super(ctx)
this.root = config.root !== undefined ? resolve(config.root) : privateRoot()
}
async saveText(input: SaveTextSpill): Promise<SpillRef> {
const saved = await saveTextFile({
root: this.root,
sessionId: input.owner.sessionId,
suggestedName: input.suggestedName,
content: input.content,
})
return {
locator: SpillLocator(saved.path),
bytes: saved.bytes,
retrievalHint: 'Use read with offset/limit, or grep this path to search within it.',
}
}
}
export default LocalSpillStore