dsh-plugin-coding-delegate 0.0.0-stage → 0.2.2
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/LICENSE +21 -0
- package/README.md +920 -2
- package/cordis.patch.example.yml +48 -0
- package/cordis.patch.yml +13 -0
- package/dist/attestation.d.ts +25 -0
- package/dist/attestation.js +44 -0
- package/dist/containment.d.ts +33 -0
- package/dist/containment.js +63 -0
- package/dist/context-quality.d.ts +79 -0
- package/dist/context-quality.js +181 -0
- package/dist/context.d.ts +39 -0
- package/dist/context.js +136 -0
- package/dist/contracts.d.ts +174 -0
- package/dist/contracts.js +415 -0
- package/dist/declaration-egress-hook.d.ts +45 -0
- package/dist/declaration-egress-hook.js +125 -0
- package/dist/declaration-egress.d.ts +37 -0
- package/dist/declaration-egress.js +169 -0
- package/dist/delegation.d.ts +339 -0
- package/dist/delegation.js +933 -0
- package/dist/emission.d.ts +70 -0
- package/dist/emission.js +310 -0
- package/dist/guard.d.ts +162 -0
- package/dist/guard.js +873 -0
- package/dist/host-events.d.ts +15 -0
- package/dist/host-events.js +27 -0
- package/dist/index.d.ts +560 -0
- package/dist/index.js +1398 -0
- package/dist/local-classifier.d.ts +52 -0
- package/dist/local-classifier.js +159 -0
- package/dist/logging.d.ts +21 -0
- package/dist/logging.js +90 -0
- package/dist/paths.d.ts +10 -0
- package/dist/paths.js +83 -0
- package/dist/profiles.d.ts +35 -0
- package/dist/profiles.js +95 -0
- package/dist/retry-context.d.ts +52 -0
- package/dist/retry-context.js +97 -0
- package/dist/roles.d.ts +129 -0
- package/dist/roles.js +363 -0
- package/dist/routing.d.ts +35 -0
- package/dist/routing.js +88 -0
- package/dist/savings-tracker.d.ts +128 -0
- package/dist/savings-tracker.js +340 -0
- package/dist/session-events.d.ts +17 -0
- package/dist/session-events.js +31 -0
- package/dist/verification.d.ts +104 -0
- package/dist/verification.js +560 -0
- package/package.json +66 -4
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Events } from '@deepseek-ai/cordis';
|
|
2
|
+
/**
|
|
3
|
+
* Subscribe to a host event, with the event NAME and the handler's SHAPE both taken from the host.
|
|
4
|
+
*
|
|
5
|
+
* `OmitThisParameter` is load-bearing rather than cosmetic. Several host events declare `this:
|
|
6
|
+
* Scoped<Agent>` or `this: Scoped<Session>`, and Cordis binds that itself; a plain arrow function has
|
|
7
|
+
* `this: void` and would be rejected for a `this` it never uses. Stripping the parameter keeps the real
|
|
8
|
+
* arguments and the return type, which are the parts a handler can get wrong.
|
|
9
|
+
*
|
|
10
|
+
* Declaring the handler this way is what makes the payloads checked: a handler written as
|
|
11
|
+
* `(payload, next) => …` with no annotations now has both parameters inferred from the host's own
|
|
12
|
+
* signature, so reading a field the host does not send is a compile error. Handlers that still annotate
|
|
13
|
+
* `any` compile as before -- the check is available, not enforced by force.
|
|
14
|
+
*/
|
|
15
|
+
export declare function onHost<K extends keyof Events>(ctx: any, event: K, handler: OmitThisParameter<Events[K]>, options?: any): void;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.onHost = onHost;
|
|
4
|
+
/**
|
|
5
|
+
* Subscribe to a host event, with the event NAME and the handler's SHAPE both taken from the host.
|
|
6
|
+
*
|
|
7
|
+
* `OmitThisParameter` is load-bearing rather than cosmetic. Several host events declare `this:
|
|
8
|
+
* Scoped<Agent>` or `this: Scoped<Session>`, and Cordis binds that itself; a plain arrow function has
|
|
9
|
+
* `this: void` and would be rejected for a `this` it never uses. Stripping the parameter keeps the real
|
|
10
|
+
* arguments and the return type, which are the parts a handler can get wrong.
|
|
11
|
+
*
|
|
12
|
+
* Declaring the handler this way is what makes the payloads checked: a handler written as
|
|
13
|
+
* `(payload, next) => …` with no annotations now has both parameters inferred from the host's own
|
|
14
|
+
* signature, so reading a field the host does not send is a compile error. Handlers that still annotate
|
|
15
|
+
* `any` compile as before -- the check is available, not enforced by force.
|
|
16
|
+
*/
|
|
17
|
+
function onHost(ctx, event, handler, options) {
|
|
18
|
+
if (typeof ctx?.on !== 'function')
|
|
19
|
+
return;
|
|
20
|
+
// The optional third argument is Cordis's own listener options (`{ prepend: true }` is used by the DLP
|
|
21
|
+
// and routing hooks, which must see a request before anything else does). Passed through rather than
|
|
22
|
+
// dropped: a wrapper that silently changes dispatch order is a worse bug than the one it is preventing.
|
|
23
|
+
if (options === undefined)
|
|
24
|
+
ctx.on(event, handler);
|
|
25
|
+
else
|
|
26
|
+
ctx.on(event, handler, options);
|
|
27
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,560 @@
|
|
|
1
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
2
|
+
import { SavingsTracker, RouteType, StepUsage } from './savings-tracker';
|
|
3
|
+
import { PROFILES, ProfileConfig } from './profiles';
|
|
4
|
+
import { extractAndEmitFiles } from './emission';
|
|
5
|
+
import { VerificationPolicy, parseTestOutput, runSandboxVerification } from './verification';
|
|
6
|
+
import { resolveContextFiles } from './context';
|
|
7
|
+
import { DelegateReadPolicy, GuardVerdict, evaluateDelegatedReadPolicy } from './guard';
|
|
8
|
+
import { SourceEgressPolicy, applyAgentRole, applyArchitectConfig, describeSourceRead, detectSourceEgress, evaluateSourceEgress, rememberAgentRole, resetAgentRoles, resolveAgentRole, resolveLeadProviders, roleForAgent } from './roles';
|
|
9
|
+
import { applySearchReplaceBlocks, delegateWorker, parseSearchReplaceBlocks, resolveDelegateStatus, resolveVerificationRepeats } from './delegation';
|
|
10
|
+
import { contractFileHashes, contractViolations, loadDelegatedRegistry, mergeDelegatedRecords, parseDelegatedRegistry, pruneDelegatedRecords, rememberDelegated, resolveContractFiles, resolveDelegatedRegistryPath, saveDelegatedRegistry, sha256File } from './contracts';
|
|
11
|
+
export { PROFILES, ProfileConfig, SavingsTracker, RouteType, StepUsage };
|
|
12
|
+
export { resolveDataDir, trace } from './logging';
|
|
13
|
+
export { isPathWithin } from './paths';
|
|
14
|
+
export { evaluateEmissionPath, evaluateUnitScope, extractAndEmitFiles } from './emission';
|
|
15
|
+
export { DELETE_PRIMITIVES, evaluateCodeWriteGuard, evaluateDelegatedReadPolicy, hasCommandDeleteSignal, hasCommandWriteSignal, } from './guard';
|
|
16
|
+
export { AGENT_ROLE_LIMIT, DEFAULT_SOURCE_EGRESS_MIN_LINES, agentLineageRole, applyAgentRole, applyArchitectConfig, describeSourceRead, detectSourceEgress, evaluateSourceEgress, rememberAgentRole, resetAgentRoles, resolveAgentRole, resolveLeadProviders, roleForAgent, roleFromLineage, } from './roles';
|
|
17
|
+
export { ContextInjection, ContextRequest, ContextResolution, DEFAULT_CONTEXT_MAX_BYTES, resolveContextFiles, } from './context';
|
|
18
|
+
export { contractFileHashes, contractViolations, loadDelegatedRegistry, mergeDelegatedRecords, parseDelegatedRegistry, pruneDelegatedRecords, rememberDelegated, recordOperatorAttestation, resolveContractFiles, resolveDelegatedRegistryPath, saveDelegatedRegistry, sha256File, } from './contracts';
|
|
19
|
+
export { DEFAULT_VERIFICATION_POLICY, DEFAULT_VERIFICATION_TIMEOUT_MS, commandProgram, describeFailures, evaluateVerificationPolicy, parseTestOutput, redactVerificationOutput, resolveVerificationTimeoutMs, runInProcessFallback, runSandboxVerification, } from './verification';
|
|
20
|
+
export { ContextQuality, EMPTY_CONTEXT_QUALITY, describeContextQuality, foldContextQuality, } from './context-quality';
|
|
21
|
+
export { DELEGATE_WORKER_OPENAI_SCHEMA, DELEGATE_WORKER_SCHEMA, DELEGATE_WORKER_SCHEMA_COVERS_EVERY_PARAMETER, DEFAULT_LOCAL_ENDPOINT, MIN_SEARCH_CHARS, applySearchReplaceBlocks, delegateWorker, estimateTokenCount, extractPromptText, parseSearchReplaceBlocks, resolveChatCompletionsUrl, resolveDelegateStatus, resolveVerificationRepeats, } from './delegation';
|
|
22
|
+
export { FailureLocation, RETRY_CONTEXT_WINDOW_LINES, parseFailureLocations, retryContextRequests, } from './retry-context';
|
|
23
|
+
export declare const inject: string[];
|
|
24
|
+
export declare const using: readonly ["tools"];
|
|
25
|
+
export interface PluginConfig {
|
|
26
|
+
localProvider?: string;
|
|
27
|
+
cloudProvider?: string;
|
|
28
|
+
localModel?: string;
|
|
29
|
+
cloudModel?: string;
|
|
30
|
+
contextTokenThreshold?: number;
|
|
31
|
+
contextThreshold?: number;
|
|
32
|
+
timeoutMs?: number;
|
|
33
|
+
enforceDLP?: boolean;
|
|
34
|
+
/**
|
|
35
|
+
* What a tripped DLP firewall does with an outbound request: `'block'`
|
|
36
|
+
* (default) refuses to transmit it, `'local'` reroutes it to the local worker.
|
|
37
|
+
* Either way the credential never reaches the cloud.
|
|
38
|
+
*/
|
|
39
|
+
dlpAction?: 'block' | 'local';
|
|
40
|
+
/** Enable the high-entropy backstop (default true). */
|
|
41
|
+
entropyCheck?: boolean;
|
|
42
|
+
/** Bits per character above which a token counts as suspiciously random (default 4.5). */
|
|
43
|
+
entropyMinBitsPerChar?: number;
|
|
44
|
+
/** Minimum token length before entropy is scored (default 20). */
|
|
45
|
+
entropyMinLength?: number;
|
|
46
|
+
/** Refuse cloud-authored writes to source files (default: true). */
|
|
47
|
+
/**
|
|
48
|
+
* What a read of source code returns to the architect.
|
|
49
|
+
*
|
|
50
|
+
* `'source'` (the default) is the historical behaviour: the file's contents are served unchanged.
|
|
51
|
+
*
|
|
52
|
+
* `'declarations'` serves the compiled TYPE SKELETON instead -- declarations, signatures and doc
|
|
53
|
+
* comments, with every function body stripped -- computed by the same `tsc` build that produces `dist/`.
|
|
54
|
+
* This is the mechanical form of "inverted ingestion": what crosses to the model is whatever the
|
|
55
|
+
* declaration emitter produced, so implementation bodies cannot leave the machine because of the shape of
|
|
56
|
+
* the egress rather than because the model chose not to ask for them. Measured on this repository, the
|
|
57
|
+
* skeleton is 3.3x smaller than the source with doc comments and 7.8x smaller without.
|
|
58
|
+
*
|
|
59
|
+
* A source file with no corresponding declaration is REFUSED rather than served as source. Failing closed
|
|
60
|
+
* is the point: an unimplemented mapping must not silently become the hole it was built to close.
|
|
61
|
+
* Requires `declarationRoot`.
|
|
62
|
+
*
|
|
63
|
+
* The limit worth knowing before turning this on: doc comments and signatures are preserved, not
|
|
64
|
+
* summarised, so an implementation whose behaviour lives in its body is still invisible. This removes
|
|
65
|
+
* bodies, not the need to read them when a defect has no structural signature.
|
|
66
|
+
*
|
|
67
|
+
* NOT the same option as `sourceEgress`, which is rule 8 and governs source inside a prompt payload.
|
|
68
|
+
* This one governs file reads by a tool call. They are different leaks and they fail differently, so
|
|
69
|
+
* they are named differently on purpose.
|
|
70
|
+
*/
|
|
71
|
+
sourceReadEgress?: 'source' | 'declarations';
|
|
72
|
+
/**
|
|
73
|
+
* Directory holding emitted `.d.ts` files, used when `sourceReadEgress` is `'declarations'`. A source
|
|
74
|
+
* path's tree below `src/` is preserved, so `src/guard.ts` resolves under this root as `guard.d.ts`.
|
|
75
|
+
*/
|
|
76
|
+
declarationRoot?: string;
|
|
77
|
+
/**
|
|
78
|
+
* Who to name as the operator when an attestation is recorded through `delegate_worker`.
|
|
79
|
+
*
|
|
80
|
+
* An attestation is a HUMAN claim about content, so it needs a human to name. There is deliberately no
|
|
81
|
+
* fallback to the calling agent's id: an autonomous session identifier cannot stand in for a person, and
|
|
82
|
+
* stamping one into the registry would produce a record LESS attributable than a typed name while looking
|
|
83
|
+
* like more. A delegation that asks for an attestation with no identity available is refused, with the
|
|
84
|
+
* unit's own verdict left intact -- the delegation succeeded, and only the attestation did not.
|
|
85
|
+
*
|
|
86
|
+
* Set once per environment or developer seat. A call may override it with `attestOperator`, which is the
|
|
87
|
+
* explicit-over-ambient precedence.
|
|
88
|
+
*/
|
|
89
|
+
operatorIdentity?: string;
|
|
90
|
+
localCodeGuard?: boolean;
|
|
91
|
+
/** Force every guard hit to an approval prompt instead of a hard deny. */
|
|
92
|
+
guardMode?: 'deny' | 'ask';
|
|
93
|
+
/** Path fragments that downgrade a deny to an approval prompt. */
|
|
94
|
+
guardAskPaths?: string[];
|
|
95
|
+
/**
|
|
96
|
+
* What happens to `delegate_worker`'s model-supplied `runVerification` command.
|
|
97
|
+
* `'ask'` (default) routes it through the approval seam before anything executes;
|
|
98
|
+
* `'allow'` restores the pre-hardening unattended behaviour; `'deny'` never runs it.
|
|
99
|
+
*/
|
|
100
|
+
verificationApproval?: 'ask' | 'allow' | 'deny';
|
|
101
|
+
/**
|
|
102
|
+
* Verification programs (the command's first token) that skip the prompt under
|
|
103
|
+
* `verificationApproval: 'ask'`. Weak by construction: it constrains the program,
|
|
104
|
+
* not its arguments, so listing `node` also permits `node -e "<anything>"`.
|
|
105
|
+
*/
|
|
106
|
+
verificationAllowlist?: string[];
|
|
107
|
+
/**
|
|
108
|
+
* How long `delegate_worker`'s verification command may run before it is killed, in milliseconds.
|
|
109
|
+
* Defaults to 30,000 — the value this used to be hardcoded to — so configuring nothing changes
|
|
110
|
+
* nothing. Raise it for a contract whose command legitimately needs longer: a full suite, a build,
|
|
111
|
+
* an install.
|
|
112
|
+
*
|
|
113
|
+
* A value that is not a positive finite number falls back to the default rather than removing the
|
|
114
|
+
* bound. An unbounded command that is model-selected and runs with the DSH process's authority is a
|
|
115
|
+
* hang, not a permission.
|
|
116
|
+
*/
|
|
117
|
+
verificationTimeoutMs?: number;
|
|
118
|
+
/**
|
|
119
|
+
* The project's own check — a build, a full suite — run after each unit's contract, with the power to
|
|
120
|
+
* void an otherwise passing unit. This is what catches two units disagreeing: a unit can pass the tests
|
|
121
|
+
* written for it and still break every caller of what it changed.
|
|
122
|
+
*
|
|
123
|
+
* Operator configuration, not model input, which is why it is absent from the tool schema and not
|
|
124
|
+
* approval-gated — the operator wrote this string here, exactly as they would in CI. It runs as an
|
|
125
|
+
* ordinary subprocess under `verificationTimeoutMs`, and a denied spawn is a failure rather than a
|
|
126
|
+
* pass. It is skipped when the unit wrote no files, since a delegation that changed nothing cannot
|
|
127
|
+
* have broken coherence.
|
|
128
|
+
*
|
|
129
|
+
* A failure is reported as `INCOHERENT` rather than `VERIFICATION_FAILED`: the unit is fine and the
|
|
130
|
+
* project is not, which is a different instruction to the architect.
|
|
131
|
+
*/
|
|
132
|
+
coherenceVerification?: string;
|
|
133
|
+
/**
|
|
134
|
+
* Whether a unit's declared `targetFiles` is a boundary. `'enforce'` (the default) refuses a write to
|
|
135
|
+
* any path the unit did not declare; `'off'` restores the behaviour before the boundary existed.
|
|
136
|
+
*
|
|
137
|
+
* This is what makes the coherence check above attributable. A unit that sprawls can break the tree in
|
|
138
|
+
* a way no record can assign to a unit, so `coherenceVerification` can say *that* something broke but
|
|
139
|
+
* not *what*. Declared targets, enforced, are the other half of that pair.
|
|
140
|
+
*/
|
|
141
|
+
unitScope?: 'enforce' | 'off';
|
|
142
|
+
/**
|
|
143
|
+
* Whether a unit that failed has its failure locations read back and offered to the next attempt in
|
|
144
|
+
* the same workspace as context. `'auto'` (the default) does this once per failure; `'off'` disables it.
|
|
145
|
+
*
|
|
146
|
+
* This is the loop closing on itself. The ordinary cause of a unit that failed "for no visible reason"
|
|
147
|
+
* is that the worker was never shown the code it had to change, and the failure already names the file.
|
|
148
|
+
* The plugin reads that file into the WORKER's prompt while the architect is handed metadata only, so a
|
|
149
|
+
* retry can widen the worker's view without widening the architect's window. It is best-effort by
|
|
150
|
+
* construction: it is dropped rather than allowed to turn a runnable delegation into a refusal.
|
|
151
|
+
*/
|
|
152
|
+
retryContext?: 'auto' | 'off';
|
|
153
|
+
/**
|
|
154
|
+
* Extra directories a delegated worker may write into besides the resolved session
|
|
155
|
+
* workspace. Absolute worker paths and `..` escapes outside every allowed root are
|
|
156
|
+
* refused and reported rather than written.
|
|
157
|
+
*/
|
|
158
|
+
emitAllowlist?: string[];
|
|
159
|
+
/**
|
|
160
|
+
* Run the verification module inside the DSH server process when the sandbox denies
|
|
161
|
+
* a piped spawn (default false). That fallback executes model-influenced code with
|
|
162
|
+
* full host authority and can kill the server, so it is opt-in only.
|
|
163
|
+
*/
|
|
164
|
+
allowInProcessFallback?: boolean;
|
|
165
|
+
/**
|
|
166
|
+
* Base URL of the local OpenAI-compatible server that `delegate_worker` posts to — for
|
|
167
|
+
* example `http://127.0.0.1:11434/v1` for Ollama, or a vLLM/llama.cpp port. A full
|
|
168
|
+
* `/chat/completions` URL is also accepted. Defaults to `http://127.0.0.1:1234/v1`.
|
|
169
|
+
*
|
|
170
|
+
* This is operator configuration, deliberately separate from the tool's arguments: a
|
|
171
|
+
* caller-supplied `endpoint` is ignored, because honouring it would let the model redirect
|
|
172
|
+
* a task — and the file contents it carries — to any address.
|
|
173
|
+
*/
|
|
174
|
+
localEndpoint?: string;
|
|
175
|
+
/**
|
|
176
|
+
* Provider ids whose requests are NOT the architect — the lead tier. A request the host has already
|
|
177
|
+
* resolved to one of these is left exactly as configured: not repinned to the cloud, not given the
|
|
178
|
+
* architect's instruction, and not offered `delegate_worker`. The DLP gate still runs.
|
|
179
|
+
*
|
|
180
|
+
* Empty by default, which means every request is the architect — the behaviour before this option
|
|
181
|
+
* existed. An allowlist rather than an inference on purpose: guessing the role from "the provider is
|
|
182
|
+
* not the architect's" would stop pinning the architect as soon as a profile named its provider
|
|
183
|
+
* something else, and the failure would be silent and in the direction of the cloud.
|
|
184
|
+
*/
|
|
185
|
+
leadProviders?: string[];
|
|
186
|
+
/**
|
|
187
|
+
* Convenience switch for the lead tier: derives `leadProviders` from the LEAD profile, so the
|
|
188
|
+
* provider id is declared in exactly one place. An explicit `leadProviders` list wins over it.
|
|
189
|
+
*
|
|
190
|
+
* Do not point this at the provider your architect session uses — the hook would stop pinning it,
|
|
191
|
+
* which is the one failure direction that costs you source leaving the machine.
|
|
192
|
+
*/
|
|
193
|
+
leadTier?: boolean;
|
|
194
|
+
/**
|
|
195
|
+
* What happens when an agent reads a file a delegated worker wrote. `ask` (default) prompts,
|
|
196
|
+
* `deny` refuses, and `allow` permits it.
|
|
197
|
+
*
|
|
198
|
+
* `allow` exists for a lead tier that must read the code it writes contracts about, and it is an
|
|
199
|
+
* honest weakening of rule 3 rather than a fix — the fix is the host exposing agent lineage. The
|
|
200
|
+
* guard cannot yet tell the architect from a lead, so `allow` relaxes the rule for every agent.
|
|
201
|
+
*/
|
|
202
|
+
delegateReadPolicy?: DelegateReadPolicy;
|
|
203
|
+
/**
|
|
204
|
+
* Paths whose source the architect may author, because a contract test is the specification rather
|
|
205
|
+
* than the implementation. Rule 2 forbids the architect writing source and rule 7 needs the architect
|
|
206
|
+
* to own the tests, which conflict for exactly this case, so this is the declared exception.
|
|
207
|
+
* Defaults to `['tests/']`; an empty list disables the carve-out.
|
|
208
|
+
*/
|
|
209
|
+
contractPaths?: string[];
|
|
210
|
+
/**
|
|
211
|
+
* What a write to a contract path does: `ask` (default), `allow`, or `deny`. Deliberately separate
|
|
212
|
+
* from `guardAskPaths`, which decides what may be written at all; this decides what the architect is
|
|
213
|
+
* allowed to specify. Setting `allow` is the opt-in that makes contract authoring frictionless.
|
|
214
|
+
*/
|
|
215
|
+
contractWriteMode?: 'allow' | 'ask' | 'deny';
|
|
216
|
+
/**
|
|
217
|
+
* Rule 8: what happens when a cloud-bound request carries source code in its own payload.
|
|
218
|
+
*
|
|
219
|
+
* `deny` (default) refuses the request, `ask` puts it to the operator, `allow` transmits it. A
|
|
220
|
+
* request bound for the local worker is not egress and is never affected.
|
|
221
|
+
*
|
|
222
|
+
* This is the one rule here that can refuse a request the operator typed themselves, so it is worth
|
|
223
|
+
* knowing the detector: fenced blocks with a source language tag, at least
|
|
224
|
+
* `sourceEgressMinLines` lines long. Prose about code does not trip it, and neither does an
|
|
225
|
+
* untagged block — a real false negative, documented rather than hidden.
|
|
226
|
+
*/
|
|
227
|
+
sourceEgress?: SourceEgressPolicy;
|
|
228
|
+
/** Lines a fenced source block needs before it counts (default 3). Lower is more false positives. */
|
|
229
|
+
sourceEgressMinLines?: number;
|
|
230
|
+
}
|
|
231
|
+
export interface RouterMetadata {
|
|
232
|
+
provider: string;
|
|
233
|
+
model?: string;
|
|
234
|
+
route: RouteType;
|
|
235
|
+
gate: string;
|
|
236
|
+
rationale: string;
|
|
237
|
+
tier: string;
|
|
238
|
+
estimatedTokens: number;
|
|
239
|
+
dlpViolations?: string[];
|
|
240
|
+
scores?: {
|
|
241
|
+
is_private: number;
|
|
242
|
+
complexity: number;
|
|
243
|
+
target: string;
|
|
244
|
+
};
|
|
245
|
+
latencyMs?: number;
|
|
246
|
+
failover?: boolean;
|
|
247
|
+
previousProvider?: string;
|
|
248
|
+
}
|
|
249
|
+
export interface LLMSession {
|
|
250
|
+
provider?: string;
|
|
251
|
+
model?: string;
|
|
252
|
+
prompt?: string;
|
|
253
|
+
input?: string;
|
|
254
|
+
apiKey?: string;
|
|
255
|
+
reasoningEffort?: string;
|
|
256
|
+
messages?: Array<{
|
|
257
|
+
role: string;
|
|
258
|
+
content: any;
|
|
259
|
+
}>;
|
|
260
|
+
options?: {
|
|
261
|
+
provider?: string;
|
|
262
|
+
model?: string;
|
|
263
|
+
apiKey?: string;
|
|
264
|
+
reasoningEffort?: string;
|
|
265
|
+
[key: string]: any;
|
|
266
|
+
};
|
|
267
|
+
metadata?: {
|
|
268
|
+
router?: RouterMetadata;
|
|
269
|
+
[key: string]: any;
|
|
270
|
+
};
|
|
271
|
+
redispatch?: () => Promise<any>;
|
|
272
|
+
retry?: () => Promise<any>;
|
|
273
|
+
[key: string]: any;
|
|
274
|
+
}
|
|
275
|
+
export declare const name = "dsh-plugin-coding-delegate";
|
|
276
|
+
export declare function scanDLP(text: string, options?: {
|
|
277
|
+
entropyCheck?: boolean;
|
|
278
|
+
entropyMinBitsPerChar?: number;
|
|
279
|
+
entropyMinLength?: number;
|
|
280
|
+
}): {
|
|
281
|
+
hasSensitiveData: boolean;
|
|
282
|
+
violations: string[];
|
|
283
|
+
highConfidence: boolean;
|
|
284
|
+
};
|
|
285
|
+
interface EffectiveConfig {
|
|
286
|
+
localProvider: string;
|
|
287
|
+
cloudProvider: string;
|
|
288
|
+
localModel: string;
|
|
289
|
+
cloudModel: string;
|
|
290
|
+
contextThreshold: number;
|
|
291
|
+
timeoutMs: number;
|
|
292
|
+
enforceDLP: boolean;
|
|
293
|
+
}
|
|
294
|
+
export declare class LocalRouter {
|
|
295
|
+
private config;
|
|
296
|
+
constructor(config?: PluginConfig);
|
|
297
|
+
getConfig(): EffectiveConfig;
|
|
298
|
+
predictRoute(promptText: string): Promise<{
|
|
299
|
+
provider: string;
|
|
300
|
+
model: string;
|
|
301
|
+
route: RouteType;
|
|
302
|
+
gate: string;
|
|
303
|
+
rationale: string;
|
|
304
|
+
scores: any;
|
|
305
|
+
latencyMs: number;
|
|
306
|
+
dlpViolations?: string[];
|
|
307
|
+
}>;
|
|
308
|
+
handleBeforeRequest(session: LLMSession): Promise<LLMSession>;
|
|
309
|
+
handleError(session: LLMSession, error: any): Promise<LLMSession>;
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* Commands that READ a file named on the command line rather than executing it.
|
|
313
|
+
*
|
|
314
|
+
* Without this list, `Select-String -Path some.js` was treated as an invocation of
|
|
315
|
+
* `some.js`: the guard read the whole file and, since any sizeable program contains a write
|
|
316
|
+
* primitive, asked for approval to *read* it. Reading a file is not running it.
|
|
317
|
+
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
|
|
321
|
+
|
|
322
|
+
|
|
323
|
+
|
|
324
|
+
/** Closed approval vocabulary; only 'allowed-once' is a grant. */
|
|
325
|
+
export type ApprovalOutcome = 'allowed-once' | 'rejected' | 'cancelled' | 'unavailable';
|
|
326
|
+
/**
|
|
327
|
+
* Route an `ask` guard decision through the real approval seam.
|
|
328
|
+
*
|
|
329
|
+
* Returning `{ kind: 'ask' }` from a tools/pre-execute listener prompts nobody: the
|
|
330
|
+
* pipeline understands only `deny`, so every other kind is an allow. The seam that
|
|
331
|
+
* actually asks is `dsh-user-approval` (ctx.approval), and it fails closed — a
|
|
332
|
+
* missing service, a missing agent, an idle turn or a throwing answerer all resolve
|
|
333
|
+
* to 'unavailable', which this treats as a refusal.
|
|
334
|
+
*/
|
|
335
|
+
export declare function requestApprovalForWrite(ctx: any, exec: any, verdict: GuardVerdict): Promise<ApprovalOutcome>;
|
|
336
|
+
export declare function resolveVerificationPolicy(options?: PluginConfig): VerificationPolicy;
|
|
337
|
+
/**
|
|
338
|
+
* Ask the operator to approve one model-selected verification command. Unlike the write
|
|
339
|
+
* guard this is not a `tools/pre-execute` decision, because the command runs after the
|
|
340
|
+
* worker responds; it is asked before dispatch so the operator sees it up front.
|
|
341
|
+
* Fails closed on every error path.
|
|
342
|
+
*/
|
|
343
|
+
export declare function requestApprovalForVerification(ctx: any, exec: any, command: string): Promise<boolean>;
|
|
344
|
+
/**
|
|
345
|
+
* Ask the operator before a delegation writes into a directory that is neither the session workspace
|
|
346
|
+
* nor an allowlisted root. Same seam as the verification prompt above, and the same fail-closed rule:
|
|
347
|
+
* no approval service, no agent, or a thrown request all resolve to refusal rather than to consent.
|
|
348
|
+
*/
|
|
349
|
+
export declare function requestApprovalForWorkspace(ctx: any, exec: any, dir: string, reason: string): Promise<boolean>;
|
|
350
|
+
export declare function apply(ctx: Context, options?: PluginConfig): void;
|
|
351
|
+
declare const pluginExport: {
|
|
352
|
+
name: string;
|
|
353
|
+
inject: string[];
|
|
354
|
+
using: readonly ["tools"];
|
|
355
|
+
apply: typeof apply;
|
|
356
|
+
LocalRouter: typeof LocalRouter;
|
|
357
|
+
SavingsTracker: typeof SavingsTracker;
|
|
358
|
+
scanDLP: typeof scanDLP;
|
|
359
|
+
delegateWorker: typeof delegateWorker;
|
|
360
|
+
extractAndEmitFiles: typeof extractAndEmitFiles;
|
|
361
|
+
runSandboxVerification: typeof runSandboxVerification;
|
|
362
|
+
parseTestOutput: typeof parseTestOutput;
|
|
363
|
+
sha256File: typeof sha256File;
|
|
364
|
+
resolveContextFiles: typeof resolveContextFiles;
|
|
365
|
+
parseSearchReplaceBlocks: typeof parseSearchReplaceBlocks;
|
|
366
|
+
applySearchReplaceBlocks: typeof applySearchReplaceBlocks;
|
|
367
|
+
MIN_SEARCH_CHARS: number;
|
|
368
|
+
DEFAULT_CONTEXT_MAX_BYTES: number;
|
|
369
|
+
resolveContractFiles: typeof resolveContractFiles;
|
|
370
|
+
contractFileHashes: typeof contractFileHashes;
|
|
371
|
+
contractViolations: typeof contractViolations;
|
|
372
|
+
resolveDelegateStatus: typeof resolveDelegateStatus;
|
|
373
|
+
resolveVerificationRepeats: typeof resolveVerificationRepeats;
|
|
374
|
+
MAX_VERIFICATION_REPEATS: number;
|
|
375
|
+
resolveLeadProviders: typeof resolveLeadProviders;
|
|
376
|
+
evaluateDelegatedReadPolicy: typeof evaluateDelegatedReadPolicy;
|
|
377
|
+
rememberAgentRole: typeof rememberAgentRole;
|
|
378
|
+
roleForAgent: typeof roleForAgent;
|
|
379
|
+
resetAgentRoles: typeof resetAgentRoles;
|
|
380
|
+
describeSourceRead: typeof describeSourceRead;
|
|
381
|
+
AGENT_ROLE_LIMIT: number;
|
|
382
|
+
detectSourceEgress: typeof detectSourceEgress;
|
|
383
|
+
evaluateSourceEgress: typeof evaluateSourceEgress;
|
|
384
|
+
DEFAULT_SOURCE_EGRESS_MIN_LINES: number;
|
|
385
|
+
resolveDelegatedRegistryPath: typeof resolveDelegatedRegistryPath;
|
|
386
|
+
parseDelegatedRegistry: typeof parseDelegatedRegistry;
|
|
387
|
+
mergeDelegatedRecords: typeof mergeDelegatedRecords;
|
|
388
|
+
pruneDelegatedRecords: typeof pruneDelegatedRecords;
|
|
389
|
+
saveDelegatedRegistry: typeof saveDelegatedRegistry;
|
|
390
|
+
loadDelegatedRegistry: typeof loadDelegatedRegistry;
|
|
391
|
+
rememberDelegated: typeof rememberDelegated;
|
|
392
|
+
resolveAgentRole: typeof resolveAgentRole;
|
|
393
|
+
applyArchitectConfig: typeof applyArchitectConfig;
|
|
394
|
+
applyAgentRole: typeof applyAgentRole;
|
|
395
|
+
DELEGATE_WORKER_SCHEMA: {
|
|
396
|
+
type: string;
|
|
397
|
+
function: {
|
|
398
|
+
name: string;
|
|
399
|
+
description: string;
|
|
400
|
+
parameters: {
|
|
401
|
+
type: string;
|
|
402
|
+
properties: {
|
|
403
|
+
taskName: {
|
|
404
|
+
type: string;
|
|
405
|
+
description: string;
|
|
406
|
+
};
|
|
407
|
+
instruction: {
|
|
408
|
+
type: string;
|
|
409
|
+
description: string;
|
|
410
|
+
};
|
|
411
|
+
targetFiles: {
|
|
412
|
+
type: string;
|
|
413
|
+
items: {
|
|
414
|
+
type: string;
|
|
415
|
+
};
|
|
416
|
+
description: string;
|
|
417
|
+
};
|
|
418
|
+
runVerification: {
|
|
419
|
+
type: string;
|
|
420
|
+
description: string;
|
|
421
|
+
};
|
|
422
|
+
verificationRepeats: {
|
|
423
|
+
type: string;
|
|
424
|
+
description: string;
|
|
425
|
+
};
|
|
426
|
+
attestTargets: {
|
|
427
|
+
type: string;
|
|
428
|
+
items: {
|
|
429
|
+
type: string;
|
|
430
|
+
};
|
|
431
|
+
description: string;
|
|
432
|
+
};
|
|
433
|
+
attestEvidence: {
|
|
434
|
+
type: string;
|
|
435
|
+
description: string;
|
|
436
|
+
};
|
|
437
|
+
attestOperator: {
|
|
438
|
+
type: string;
|
|
439
|
+
description: string;
|
|
440
|
+
};
|
|
441
|
+
contractFiles: {
|
|
442
|
+
type: string;
|
|
443
|
+
items: {
|
|
444
|
+
type: string;
|
|
445
|
+
};
|
|
446
|
+
description: string;
|
|
447
|
+
};
|
|
448
|
+
contextFiles: {
|
|
449
|
+
type: string;
|
|
450
|
+
description: string;
|
|
451
|
+
items: {
|
|
452
|
+
type: string;
|
|
453
|
+
properties: {
|
|
454
|
+
path: {
|
|
455
|
+
type: string;
|
|
456
|
+
};
|
|
457
|
+
startLine: {
|
|
458
|
+
type: string;
|
|
459
|
+
};
|
|
460
|
+
endLine: {
|
|
461
|
+
type: string;
|
|
462
|
+
};
|
|
463
|
+
};
|
|
464
|
+
required: string[];
|
|
465
|
+
};
|
|
466
|
+
};
|
|
467
|
+
workspaceDir: {
|
|
468
|
+
type: string;
|
|
469
|
+
description: string;
|
|
470
|
+
};
|
|
471
|
+
};
|
|
472
|
+
required: string[];
|
|
473
|
+
};
|
|
474
|
+
};
|
|
475
|
+
};
|
|
476
|
+
DELEGATE_WORKER_OPENAI_SCHEMA: {
|
|
477
|
+
type: string;
|
|
478
|
+
function: {
|
|
479
|
+
name: string;
|
|
480
|
+
description: string;
|
|
481
|
+
parameters: {
|
|
482
|
+
type: string;
|
|
483
|
+
properties: {
|
|
484
|
+
taskName: {
|
|
485
|
+
type: string;
|
|
486
|
+
description: string;
|
|
487
|
+
};
|
|
488
|
+
instruction: {
|
|
489
|
+
type: string;
|
|
490
|
+
description: string;
|
|
491
|
+
};
|
|
492
|
+
targetFiles: {
|
|
493
|
+
type: string;
|
|
494
|
+
items: {
|
|
495
|
+
type: string;
|
|
496
|
+
};
|
|
497
|
+
description: string;
|
|
498
|
+
};
|
|
499
|
+
runVerification: {
|
|
500
|
+
type: string;
|
|
501
|
+
description: string;
|
|
502
|
+
};
|
|
503
|
+
verificationRepeats: {
|
|
504
|
+
type: string;
|
|
505
|
+
description: string;
|
|
506
|
+
};
|
|
507
|
+
attestTargets: {
|
|
508
|
+
type: string;
|
|
509
|
+
items: {
|
|
510
|
+
type: string;
|
|
511
|
+
};
|
|
512
|
+
description: string;
|
|
513
|
+
};
|
|
514
|
+
attestEvidence: {
|
|
515
|
+
type: string;
|
|
516
|
+
description: string;
|
|
517
|
+
};
|
|
518
|
+
attestOperator: {
|
|
519
|
+
type: string;
|
|
520
|
+
description: string;
|
|
521
|
+
};
|
|
522
|
+
contractFiles: {
|
|
523
|
+
type: string;
|
|
524
|
+
items: {
|
|
525
|
+
type: string;
|
|
526
|
+
};
|
|
527
|
+
description: string;
|
|
528
|
+
};
|
|
529
|
+
contextFiles: {
|
|
530
|
+
type: string;
|
|
531
|
+
description: string;
|
|
532
|
+
items: {
|
|
533
|
+
type: string;
|
|
534
|
+
properties: {
|
|
535
|
+
path: {
|
|
536
|
+
type: string;
|
|
537
|
+
};
|
|
538
|
+
startLine: {
|
|
539
|
+
type: string;
|
|
540
|
+
};
|
|
541
|
+
endLine: {
|
|
542
|
+
type: string;
|
|
543
|
+
};
|
|
544
|
+
};
|
|
545
|
+
required: string[];
|
|
546
|
+
};
|
|
547
|
+
};
|
|
548
|
+
workspaceDir: {
|
|
549
|
+
type: string;
|
|
550
|
+
description: string;
|
|
551
|
+
};
|
|
552
|
+
};
|
|
553
|
+
required: string[];
|
|
554
|
+
};
|
|
555
|
+
};
|
|
556
|
+
};
|
|
557
|
+
PROFILES: import("./profiles").Profiles;
|
|
558
|
+
default: typeof apply;
|
|
559
|
+
};
|
|
560
|
+
export default pluginExport;
|