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
130 lines (114 loc) · 5.65 KB
/
Copy pathindex.ts
File metadata and controls
130 lines (114 loc) · 5.65 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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/**
* Event-only filesystem observation policy; it registers no service. A weak owner/target map
* records every authoritative presence/absence observation, single-slot intent listeners derive
* guards from that state, and the provider performs the atomic freshness/no-clobber check. Without
* this plugin, tools retain the bare provider's unconditional mutation behavior. See the package
* README for composition rules.
* @module @deepseek-ai/dsh-fs-observation-policy
*/
import type { Context } from '@deepseek-ai/cordis'
import { FsError } from '@deepseek-ai/dsh-fs'
import type { FsObservation, FsTarget, FsVersion, FsWriteIntent } from '@deepseek-ai/dsh-fs'
import type { FsObservationActor } from './types.ts'
export type { FsObservationActor } from './types.ts'
/**
* Per-context observed-file state and the three `fs/*` decisions over it. One
* instance is created per `apply()` so disposal can drop all state for HMR.
*/
class ObservedStateGate {
/**
* Observed-file state, keyed first by the owner object (weakly held, so a
* collected session frees its state), then by {@link FsTarget.targetKey}. An
* entry's presence is the prior-observation record; its discriminant keeps
* confirmed absence distinct from an unseen target.
*/
private observed = new WeakMap<object, Map<string, FsObservation>>()
/**
* Derive the observed-state owner from the opaque event actor — normally the
* active agent session. `undefined` when no owner can be derived (e.g. a
* direct tool call with no agent); such calls read freely but cannot satisfy
* the write/edit prior-observation policy.
*/
private owner(actor: object | undefined): object | undefined {
// tsgolint treats object as assignable to weak FsObservationActor, while tsc still requires the structural cast for property access.
// See the analyzer-divergence consequence in .agents/notes/implemented/process/2026-07-29-oxlint-linter.md.
// oxlint-disable-next-line typescript/no-unnecessary-type-assertion -- The analyzers disagree on this weak type.
return (actor as FsObservationActor | undefined)?.agent?.session
}
private get(owner: object, targetKey: string): FsObservation | undefined {
return this.observed.get(owner)?.get(targetKey)
}
private set(owner: object, targetKey: string, observation: FsObservation): void {
let byTarget = this.observed.get(owner)
if (!byTarget) {
byTarget = new Map()
this.observed.set(owner, byTarget)
}
byTarget.set(targetKey, observation)
}
/** Drop all recorded state (HMR safety / disposal). */
clear(): void {
this.observed = new WeakMap()
}
/**
* Decide the write intent: unseen or confirmed absent ⇒ `createIfAbsent`;
* confirmed present ⇒ `replaceIfVersion` at the observed version.
*/
writeIntent(target: FsTarget, actor: object | undefined): FsWriteIntent {
const owner = this.owner(actor)
const prior = owner ? this.get(owner, target.targetKey) : undefined
return prior?.kind === 'present'
? { kind: 'replaceIfVersion', version: prior.version }
: { kind: 'createIfAbsent' }
}
/**
* Decide the edit version guard: unseen rejects with `FS_NOT_OBSERVED`,
* confirmed absence rejects with `FS_NOT_FOUND`, and presence supplies the
* observed version as the CAS basis.
*/
editIntent(target: FsTarget, actor: object | undefined): { version: FsVersion } {
const owner = this.owner(actor)
const prior = owner ? this.get(owner, target.targetKey) : undefined
if (!owner || prior === undefined) {
throw new FsError(`edit requires reading "${target.displayPath}" first`, 'FS_NOT_OBSERVED')
}
if (prior.kind === 'absent') {
throw new FsError(`cannot edit "${target.displayPath}": not found`, 'FS_NOT_FOUND')
}
return { version: prior.version }
}
/** Record an authoritative present or absent observation for this owner and target. */
observe(target: FsTarget, observation: FsObservation, actor: object | undefined): void {
const owner = this.owner(actor)
if (owner) this.set(owner, target.targetKey, observation)
}
}
/** Cordis plugin name used by loader diagnostics. */
export const name = 'fs-observation-policy'
/**
* Register the three `fs/*` listeners. No `inject` — this plugin reads no
* services; it operates only on its own `WeakMap`. The waterfalls are unbound
* (the tool dispatches them with no `this`), so the listeners take the raw
* `(target, actor, next)` arguments.
*/
export function apply(ctx: Context): void {
const gate = new ObservedStateGate()
ctx.effect(() => () => {
// Drop all recorded state on disposal so a reloaded plugin starts clean
// (HMR safety). The WeakMap itself would be GC'd, but replacing it makes the
// release observable and immediate for tests.
gate.clear()
}, 'fs-observation-policy observed-state teardown')
// fs/write-intent: occupy the single decision slot — do NOT call next().
// Deferred through Promise.resolve().then so the declared Promise return type
// holds (a throw rejects, never escapes synchronously through the waterfall).
ctx.on('fs/write-intent', (target, actor) => Promise.resolve().then(() => gate.writeIntent(target, actor)))
// fs/edit-intent: occupy the single decision slot — do not call next().
ctx.on('fs/edit-intent', (target, actor) => Promise.resolve().then(() => gate.editIntent(target, actor)))
// fs/observed must remain synchronous and non-throwing: emit does not await
// promises, and successful mutations have already committed. WeakMap.set
// satisfies that contract for both presence and absence.
ctx.on('fs/observed', (target, observation, actor) => {
gate.observe(target, observation, actor)
})
}