@responsibleai/agent-hooks 0.1.0-alpha.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/README.md ADDED
@@ -0,0 +1,47 @@
1
+ # agent-hooks (TypeScript SDK)
2
+
3
+ TypeScript implementation of
4
+ [AGENT-HOOKS-0.1](https://github.com/responsibleai/agent-hooks/blob/main/spec/AGENT-HOOKS-0.1.md)
5
+ over the canonical Rust core (napi-rs native module): interception
6
+ points, `AgentContextBuilder`, `Verdict` types, host-side
7
+ `InterceptionEmitter` with the four composition profiles, the
8
+ identity-provider seam, and the CTK runner.
9
+
10
+ > **Trust model.** agent-hooks is a *cooperative contract*, not a security
11
+ > boundary: the host framework is fully trusted, interceptors run in-process
12
+ > with full data access, and no complete-mediation claim is made. Read
13
+ > [SECURITY.md](https://github.com/responsibleai/agent-hooks/blob/main/SECURITY.md)
14
+ > and [spec §1.4](https://github.com/responsibleai/agent-hooks/blob/main/spec/AGENT-HOOKS-0.1.md#14-trust-model-and-non-goals)
15
+ > before relying on it.
16
+
17
+ ```bash
18
+ # Not yet published to npm — install from source:
19
+ git clone https://github.com/responsibleai/agent-hooks && cd agent-hooks/sdk/typescript
20
+ npm install && npm run build # builds the native module (needs a Rust toolchain)
21
+ ```
22
+
23
+ ## Usage
24
+
25
+ ```ts
26
+ import { AgentContextBuilder, InterceptionEmitter, Verdict } from "@responsibleai/agent-hooks";
27
+
28
+ const emitter = new InterceptionEmitter();
29
+ emitter.register({
30
+ intercept(ctx) {
31
+ if (ctx.interception_point === "pre_tool_call" && ctx.tool_call.name === "rm") {
32
+ return { decision: "deny", reason: "dangerous" };
33
+ }
34
+ return { decision: "allow" };
35
+ },
36
+ });
37
+
38
+ const builder = new AgentContextBuilder({ agentId: "my-agent", framework: "my-fw", sessionId: "s-1" });
39
+ const ctx = builder.preToolCall("tc-1", "http_get", { url });
40
+ await emitter.emit(ctx); // throws InterceptionBlocked on a combined deny
41
+ ```
42
+
43
+ **JavaScript value-domain caveat (spec §4.4):** `JSON.parse` rounds
44
+ integers beyond 2^53 before any guard can run, so this SDK cannot claim
45
+ the `int64_json`/`bigint_json` CTK capabilities — string-encode
46
+ 64-bit identifiers at the adapter boundary. Non-finite numbers are
47
+ rejected fail-closed by a pre-serialization scan.
Binary file
package/binding.d.ts ADDED
@@ -0,0 +1,18 @@
1
+ /* tslint:disable */
2
+ /* eslint-disable */
3
+
4
+ /* auto-generated by NAPI-RS */
5
+
6
+ export declare function specVersion(): string
7
+ export declare function canonicalJson(valueJson: string): string
8
+ export declare function contextIdentity(ctxJson: string): string
9
+ export declare function validateVerdict(verdictJson: string): string
10
+ export declare function applyTransform(targetJson: string, path: string, valueJson: string): string
11
+ export declare function applyTransformCtx(ctxJson: string, path: string, valueJson: string): string
12
+ export declare function validateTransformCtx(ctxJson: string, path: string, valueJson: string): string
13
+ export declare function finalize(ctxJson: string, verdictJson: string, mode: string, optionsJson: string): string
14
+ export declare function composeAggregate(compositionJson: string, verdictsJson: string): string
15
+ export declare function ctkScriptedIntercept(rulesJson: string, ctxJson: string): string
16
+ export declare function ctkScriptedResolve(rulesJson: string, ctxJson: string, identity: string): string
17
+ export declare function ctkShouldSkip(vectorJson: string, harnessCapsJson: string): string
18
+ export declare function ctkAssert(vectorJson: string, recordedJson: string, runRecordJson: string): string
package/binding.js ADDED
@@ -0,0 +1,327 @@
1
+ /* tslint:disable */
2
+ /* eslint-disable */
3
+ /* prettier-ignore */
4
+
5
+ /* auto-generated by NAPI-RS */
6
+
7
+ const { existsSync, readFileSync } = require('fs')
8
+ const { join } = require('path')
9
+
10
+ const { platform, arch } = process
11
+
12
+ let nativeBinding = null
13
+ let localFileExisted = false
14
+ let loadError = null
15
+
16
+ function isMusl() {
17
+ // For Node 10
18
+ if (!process.report || typeof process.report.getReport !== 'function') {
19
+ try {
20
+ const lddPath = require('child_process').execSync('which ldd').toString().trim()
21
+ return readFileSync(lddPath, 'utf8').includes('musl')
22
+ } catch (e) {
23
+ return true
24
+ }
25
+ } else {
26
+ const { glibcVersionRuntime } = process.report.getReport().header
27
+ return !glibcVersionRuntime
28
+ }
29
+ }
30
+
31
+ switch (platform) {
32
+ case 'android':
33
+ switch (arch) {
34
+ case 'arm64':
35
+ localFileExisted = existsSync(join(__dirname, 'agent-hooks.android-arm64.node'))
36
+ try {
37
+ if (localFileExisted) {
38
+ nativeBinding = require('./agent-hooks.android-arm64.node')
39
+ } else {
40
+ nativeBinding = require('@responsibleai/agent-hooks-android-arm64')
41
+ }
42
+ } catch (e) {
43
+ loadError = e
44
+ }
45
+ break
46
+ case 'arm':
47
+ localFileExisted = existsSync(join(__dirname, 'agent-hooks.android-arm-eabi.node'))
48
+ try {
49
+ if (localFileExisted) {
50
+ nativeBinding = require('./agent-hooks.android-arm-eabi.node')
51
+ } else {
52
+ nativeBinding = require('@responsibleai/agent-hooks-android-arm-eabi')
53
+ }
54
+ } catch (e) {
55
+ loadError = e
56
+ }
57
+ break
58
+ default:
59
+ throw new Error(`Unsupported architecture on Android ${arch}`)
60
+ }
61
+ break
62
+ case 'win32':
63
+ switch (arch) {
64
+ case 'x64':
65
+ localFileExisted = existsSync(
66
+ join(__dirname, 'agent-hooks.win32-x64-msvc.node')
67
+ )
68
+ try {
69
+ if (localFileExisted) {
70
+ nativeBinding = require('./agent-hooks.win32-x64-msvc.node')
71
+ } else {
72
+ nativeBinding = require('@responsibleai/agent-hooks-win32-x64-msvc')
73
+ }
74
+ } catch (e) {
75
+ loadError = e
76
+ }
77
+ break
78
+ case 'ia32':
79
+ localFileExisted = existsSync(
80
+ join(__dirname, 'agent-hooks.win32-ia32-msvc.node')
81
+ )
82
+ try {
83
+ if (localFileExisted) {
84
+ nativeBinding = require('./agent-hooks.win32-ia32-msvc.node')
85
+ } else {
86
+ nativeBinding = require('@responsibleai/agent-hooks-win32-ia32-msvc')
87
+ }
88
+ } catch (e) {
89
+ loadError = e
90
+ }
91
+ break
92
+ case 'arm64':
93
+ localFileExisted = existsSync(
94
+ join(__dirname, 'agent-hooks.win32-arm64-msvc.node')
95
+ )
96
+ try {
97
+ if (localFileExisted) {
98
+ nativeBinding = require('./agent-hooks.win32-arm64-msvc.node')
99
+ } else {
100
+ nativeBinding = require('@responsibleai/agent-hooks-win32-arm64-msvc')
101
+ }
102
+ } catch (e) {
103
+ loadError = e
104
+ }
105
+ break
106
+ default:
107
+ throw new Error(`Unsupported architecture on Windows: ${arch}`)
108
+ }
109
+ break
110
+ case 'darwin':
111
+ localFileExisted = existsSync(join(__dirname, 'agent-hooks.darwin-universal.node'))
112
+ try {
113
+ if (localFileExisted) {
114
+ nativeBinding = require('./agent-hooks.darwin-universal.node')
115
+ } else {
116
+ nativeBinding = require('@responsibleai/agent-hooks-darwin-universal')
117
+ }
118
+ break
119
+ } catch {}
120
+ switch (arch) {
121
+ case 'x64':
122
+ localFileExisted = existsSync(join(__dirname, 'agent-hooks.darwin-x64.node'))
123
+ try {
124
+ if (localFileExisted) {
125
+ nativeBinding = require('./agent-hooks.darwin-x64.node')
126
+ } else {
127
+ nativeBinding = require('@responsibleai/agent-hooks-darwin-x64')
128
+ }
129
+ } catch (e) {
130
+ loadError = e
131
+ }
132
+ break
133
+ case 'arm64':
134
+ localFileExisted = existsSync(
135
+ join(__dirname, 'agent-hooks.darwin-arm64.node')
136
+ )
137
+ try {
138
+ if (localFileExisted) {
139
+ nativeBinding = require('./agent-hooks.darwin-arm64.node')
140
+ } else {
141
+ nativeBinding = require('@responsibleai/agent-hooks-darwin-arm64')
142
+ }
143
+ } catch (e) {
144
+ loadError = e
145
+ }
146
+ break
147
+ default:
148
+ throw new Error(`Unsupported architecture on macOS: ${arch}`)
149
+ }
150
+ break
151
+ case 'freebsd':
152
+ if (arch !== 'x64') {
153
+ throw new Error(`Unsupported architecture on FreeBSD: ${arch}`)
154
+ }
155
+ localFileExisted = existsSync(join(__dirname, 'agent-hooks.freebsd-x64.node'))
156
+ try {
157
+ if (localFileExisted) {
158
+ nativeBinding = require('./agent-hooks.freebsd-x64.node')
159
+ } else {
160
+ nativeBinding = require('@responsibleai/agent-hooks-freebsd-x64')
161
+ }
162
+ } catch (e) {
163
+ loadError = e
164
+ }
165
+ break
166
+ case 'linux':
167
+ switch (arch) {
168
+ case 'x64':
169
+ if (isMusl()) {
170
+ localFileExisted = existsSync(
171
+ join(__dirname, 'agent-hooks.linux-x64-musl.node')
172
+ )
173
+ try {
174
+ if (localFileExisted) {
175
+ nativeBinding = require('./agent-hooks.linux-x64-musl.node')
176
+ } else {
177
+ nativeBinding = require('@responsibleai/agent-hooks-linux-x64-musl')
178
+ }
179
+ } catch (e) {
180
+ loadError = e
181
+ }
182
+ } else {
183
+ localFileExisted = existsSync(
184
+ join(__dirname, 'agent-hooks.linux-x64-gnu.node')
185
+ )
186
+ try {
187
+ if (localFileExisted) {
188
+ nativeBinding = require('./agent-hooks.linux-x64-gnu.node')
189
+ } else {
190
+ nativeBinding = require('@responsibleai/agent-hooks-linux-x64-gnu')
191
+ }
192
+ } catch (e) {
193
+ loadError = e
194
+ }
195
+ }
196
+ break
197
+ case 'arm64':
198
+ if (isMusl()) {
199
+ localFileExisted = existsSync(
200
+ join(__dirname, 'agent-hooks.linux-arm64-musl.node')
201
+ )
202
+ try {
203
+ if (localFileExisted) {
204
+ nativeBinding = require('./agent-hooks.linux-arm64-musl.node')
205
+ } else {
206
+ nativeBinding = require('@responsibleai/agent-hooks-linux-arm64-musl')
207
+ }
208
+ } catch (e) {
209
+ loadError = e
210
+ }
211
+ } else {
212
+ localFileExisted = existsSync(
213
+ join(__dirname, 'agent-hooks.linux-arm64-gnu.node')
214
+ )
215
+ try {
216
+ if (localFileExisted) {
217
+ nativeBinding = require('./agent-hooks.linux-arm64-gnu.node')
218
+ } else {
219
+ nativeBinding = require('@responsibleai/agent-hooks-linux-arm64-gnu')
220
+ }
221
+ } catch (e) {
222
+ loadError = e
223
+ }
224
+ }
225
+ break
226
+ case 'arm':
227
+ if (isMusl()) {
228
+ localFileExisted = existsSync(
229
+ join(__dirname, 'agent-hooks.linux-arm-musleabihf.node')
230
+ )
231
+ try {
232
+ if (localFileExisted) {
233
+ nativeBinding = require('./agent-hooks.linux-arm-musleabihf.node')
234
+ } else {
235
+ nativeBinding = require('@responsibleai/agent-hooks-linux-arm-musleabihf')
236
+ }
237
+ } catch (e) {
238
+ loadError = e
239
+ }
240
+ } else {
241
+ localFileExisted = existsSync(
242
+ join(__dirname, 'agent-hooks.linux-arm-gnueabihf.node')
243
+ )
244
+ try {
245
+ if (localFileExisted) {
246
+ nativeBinding = require('./agent-hooks.linux-arm-gnueabihf.node')
247
+ } else {
248
+ nativeBinding = require('@responsibleai/agent-hooks-linux-arm-gnueabihf')
249
+ }
250
+ } catch (e) {
251
+ loadError = e
252
+ }
253
+ }
254
+ break
255
+ case 'riscv64':
256
+ if (isMusl()) {
257
+ localFileExisted = existsSync(
258
+ join(__dirname, 'agent-hooks.linux-riscv64-musl.node')
259
+ )
260
+ try {
261
+ if (localFileExisted) {
262
+ nativeBinding = require('./agent-hooks.linux-riscv64-musl.node')
263
+ } else {
264
+ nativeBinding = require('@responsibleai/agent-hooks-linux-riscv64-musl')
265
+ }
266
+ } catch (e) {
267
+ loadError = e
268
+ }
269
+ } else {
270
+ localFileExisted = existsSync(
271
+ join(__dirname, 'agent-hooks.linux-riscv64-gnu.node')
272
+ )
273
+ try {
274
+ if (localFileExisted) {
275
+ nativeBinding = require('./agent-hooks.linux-riscv64-gnu.node')
276
+ } else {
277
+ nativeBinding = require('@responsibleai/agent-hooks-linux-riscv64-gnu')
278
+ }
279
+ } catch (e) {
280
+ loadError = e
281
+ }
282
+ }
283
+ break
284
+ case 's390x':
285
+ localFileExisted = existsSync(
286
+ join(__dirname, 'agent-hooks.linux-s390x-gnu.node')
287
+ )
288
+ try {
289
+ if (localFileExisted) {
290
+ nativeBinding = require('./agent-hooks.linux-s390x-gnu.node')
291
+ } else {
292
+ nativeBinding = require('@responsibleai/agent-hooks-linux-s390x-gnu')
293
+ }
294
+ } catch (e) {
295
+ loadError = e
296
+ }
297
+ break
298
+ default:
299
+ throw new Error(`Unsupported architecture on Linux: ${arch}`)
300
+ }
301
+ break
302
+ default:
303
+ throw new Error(`Unsupported OS: ${platform}, architecture: ${arch}`)
304
+ }
305
+
306
+ if (!nativeBinding) {
307
+ if (loadError) {
308
+ throw loadError
309
+ }
310
+ throw new Error(`Failed to load native binding`)
311
+ }
312
+
313
+ const { specVersion, canonicalJson, contextIdentity, validateVerdict, applyTransform, applyTransformCtx, validateTransformCtx, finalize, composeAggregate, ctkScriptedIntercept, ctkScriptedResolve, ctkShouldSkip, ctkAssert } = nativeBinding
314
+
315
+ module.exports.specVersion = specVersion
316
+ module.exports.canonicalJson = canonicalJson
317
+ module.exports.contextIdentity = contextIdentity
318
+ module.exports.validateVerdict = validateVerdict
319
+ module.exports.applyTransform = applyTransform
320
+ module.exports.applyTransformCtx = applyTransformCtx
321
+ module.exports.validateTransformCtx = validateTransformCtx
322
+ module.exports.finalize = finalize
323
+ module.exports.composeAggregate = composeAggregate
324
+ module.exports.ctkScriptedIntercept = ctkScriptedIntercept
325
+ module.exports.ctkScriptedResolve = ctkScriptedResolve
326
+ module.exports.ctkShouldSkip = ctkShouldSkip
327
+ module.exports.ctkAssert = ctkAssert
@@ -0,0 +1,37 @@
1
+ /**
2
+ * `AgentContext` construction (§4).
3
+ *
4
+ * Stateful per-session builder that owns the L0 envelope
5
+ * (agent/session/sequence) and exposes one method per interception
6
+ * point that fills L1 and sets `target`.
7
+ */
8
+ import { AgentContext, JsonValue } from "./index";
9
+ export declare class AgentContextBuilder {
10
+ private seq;
11
+ private readonly agent;
12
+ private readonly session;
13
+ constructor(opts: {
14
+ agentId: string;
15
+ framework: string;
16
+ sessionId: string;
17
+ agentName?: string;
18
+ agentVersion?: string;
19
+ sessionStartedAt?: string;
20
+ });
21
+ private envelope;
22
+ agentStartup(toolsRegistered: string[]): AgentContext;
23
+ input(content: JsonValue, role?: "user" | "system" | "external"): AgentContext;
24
+ preModelCall(modelId: string, messages: Array<{
25
+ role: string;
26
+ content: JsonValue;
27
+ }>): AgentContext;
28
+ postModelCall(modelId: string, content: JsonValue, toolCalls: Array<{
29
+ id: string;
30
+ name: string;
31
+ args: Record<string, JsonValue>;
32
+ }>, finishReason: string): AgentContext;
33
+ preToolCall(callId: string, name: string, args: Record<string, JsonValue>): AgentContext;
34
+ postToolCall(callId: string, name: string, args: Record<string, JsonValue>, value: JsonValue, isError?: boolean): AgentContext;
35
+ output(content: JsonValue): AgentContext;
36
+ agentShutdown(reason: "completed" | "error" | "cancelled"): AgentContext;
37
+ }
@@ -0,0 +1,94 @@
1
+ "use strict";
2
+ // Copyright (c) Microsoft Corporation.
3
+ // Licensed under the MIT License.
4
+ /**
5
+ * `AgentContext` construction (§4).
6
+ *
7
+ * Stateful per-session builder that owns the L0 envelope
8
+ * (agent/session/sequence) and exposes one method per interception
9
+ * point that fills L1 and sets `target`.
10
+ */
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.AgentContextBuilder = void 0;
13
+ const index_1 = require("./index");
14
+ function now() {
15
+ return new Date().toISOString();
16
+ }
17
+ class AgentContextBuilder {
18
+ seq = 0;
19
+ agent;
20
+ session;
21
+ constructor(opts) {
22
+ this.agent = { id: opts.agentId, framework: opts.framework };
23
+ if (opts.agentName)
24
+ this.agent.name = opts.agentName;
25
+ if (opts.agentVersion)
26
+ this.agent.version = opts.agentVersion;
27
+ this.session = { id: opts.sessionId };
28
+ if (opts.sessionStartedAt)
29
+ this.session.started_at = opts.sessionStartedAt;
30
+ }
31
+ envelope(ip, target) {
32
+ const ctx = {
33
+ spec: index_1.SPEC_VERSION,
34
+ interception_point: ip,
35
+ timestamp: now(),
36
+ sequence: this.seq++,
37
+ agent: { ...this.agent },
38
+ session: { ...this.session },
39
+ target,
40
+ };
41
+ return ctx;
42
+ }
43
+ agentStartup(toolsRegistered) {
44
+ const agentInit = { tools_registered: [...toolsRegistered] };
45
+ const ctx = this.envelope(index_1.InterceptionPoint.AgentStartup, agentInit);
46
+ ctx.agent_init = agentInit;
47
+ return ctx;
48
+ }
49
+ input(content, role = "user") {
50
+ const inp = { content, role };
51
+ const ctx = this.envelope(index_1.InterceptionPoint.Input, inp);
52
+ ctx.input = inp;
53
+ return ctx;
54
+ }
55
+ preModelCall(modelId, messages) {
56
+ const ctx = this.envelope(index_1.InterceptionPoint.PreModelCall, messages);
57
+ ctx.model = { id: modelId };
58
+ ctx.messages = messages;
59
+ return ctx;
60
+ }
61
+ postModelCall(modelId, content, toolCalls, finishReason) {
62
+ const response = { content, tool_calls: toolCalls, finish_reason: finishReason };
63
+ const ctx = this.envelope(index_1.InterceptionPoint.PostModelCall, response);
64
+ ctx.model = { id: modelId };
65
+ ctx.response = response;
66
+ return ctx;
67
+ }
68
+ preToolCall(callId, name, args) {
69
+ const tc = { id: callId, name, args };
70
+ const ctx = this.envelope(index_1.InterceptionPoint.PreToolCall, args);
71
+ ctx.tool_call = tc;
72
+ return ctx;
73
+ }
74
+ postToolCall(callId, name, args, value, isError = false) {
75
+ const tr = { value, is_error: isError };
76
+ const ctx = this.envelope(index_1.InterceptionPoint.PostToolCall, value);
77
+ ctx.tool_call = { id: callId, name, args };
78
+ ctx.tool_result = tr;
79
+ return ctx;
80
+ }
81
+ output(content) {
82
+ const out = { content };
83
+ const ctx = this.envelope(index_1.InterceptionPoint.Output, out);
84
+ ctx.output = out;
85
+ return ctx;
86
+ }
87
+ agentShutdown(reason) {
88
+ const summary = { reason };
89
+ const ctx = this.envelope(index_1.InterceptionPoint.AgentShutdown, summary);
90
+ ctx.summary = summary;
91
+ return ctx;
92
+ }
93
+ }
94
+ exports.AgentContextBuilder = AgentContextBuilder;
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Conformance Test Kit (§13.2).
3
+ *
4
+ * The assertion engine and scripted interceptor/resolver live in the
5
+ * Rust core; this module defines the `Harness` interface framework
6
+ * adapters implement, plus the runner and reference harness that use it.
7
+ */
8
+ import type { ApprovalResolver, CompositionConfig, EnforcementMode, Interceptor, JsonValue } from "../index";
9
+ export { loadVectors, runVector, runVectors, VectorResult } from "./runner";
10
+ export { ReferenceHarness } from "./reference";
11
+ /** Host-declared capability subset (§3.2). */
12
+ export type Capability = "model_calls" | "tool_calls" | "parallel_tool_calls" | "streaming" | "multi_turn";
13
+ export type RunOutcome = "completed" | "blocked" | "suspended" | "error";
14
+ /** Hermetic scripted run loaded from a CTK vector (wire-shaped). */
15
+ export interface Scenario {
16
+ input: {
17
+ content: JsonValue;
18
+ role: "user" | "system" | "external";
19
+ };
20
+ tools?: Array<{
21
+ name: string;
22
+ schema?: Record<string, JsonValue>;
23
+ behavior: Array<{
24
+ when_args?: Record<string, JsonValue>;
25
+ return: JsonValue;
26
+ is_error?: boolean;
27
+ }>;
28
+ }>;
29
+ model_script?: Array<{
30
+ respond: {
31
+ content: JsonValue;
32
+ tool_calls: Array<{
33
+ id: string;
34
+ name: string;
35
+ args: Record<string, JsonValue>;
36
+ }>;
37
+ finish_reason: string;
38
+ };
39
+ }>;
40
+ }
41
+ /** What `Harness.run` returns to the CTK runner. */
42
+ export interface RunRecord {
43
+ outcome: RunOutcome;
44
+ final_output: JsonValue | null;
45
+ tool_invocations: Array<{
46
+ name: string;
47
+ args: Record<string, JsonValue>;
48
+ }>;
49
+ error?: string;
50
+ /** `(input_identity, enforced_identity)` per interception, in order,
51
+ * from the harness's emitter (`null` under a `null` identity
52
+ * provider, §10.1). Enables `expect.identities_equal`. */
53
+ identities: Array<[string | null, string | null]>;
54
+ /** Wire-shaped `InterceptionRecord`s (§10.3), one per emission, in
55
+ * order. Enables `expect.records` assertions. */
56
+ records: JsonValue[];
57
+ }
58
+ /** The single interface a framework adapter implements for the CTK. */
59
+ export interface Harness {
60
+ readonly name: string;
61
+ readonly capabilities: ReadonlySet<Capability>;
62
+ /** Wire the scenario's mock model + tools into the framework,
63
+ * register the interceptors and resolver, set the enforcement mode,
64
+ * the vector's composition profile (§7.1), and its identity provider
65
+ * (§10.1; vectors declare `"jcs-sha256"` or `null` — custom providers
66
+ * are functions and not vector-expressible). */
67
+ setup(scenario: Scenario, interceptors: Interceptor[], resolver: ApprovalResolver | null, mode: EnforcementMode, composition: CompositionConfig, identityProvider: 'jcs-sha256' | null): void;
68
+ run(): Promise<RunRecord>;
69
+ teardown(): void;
70
+ }
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ // Copyright (c) Microsoft Corporation.
3
+ // Licensed under the MIT License.
4
+ /**
5
+ * Conformance Test Kit (§13.2).
6
+ *
7
+ * The assertion engine and scripted interceptor/resolver live in the
8
+ * Rust core; this module defines the `Harness` interface framework
9
+ * adapters implement, plus the runner and reference harness that use it.
10
+ */
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.ReferenceHarness = exports.runVectors = exports.runVector = exports.loadVectors = void 0;
13
+ var runner_1 = require("./runner");
14
+ Object.defineProperty(exports, "loadVectors", { enumerable: true, get: function () { return runner_1.loadVectors; } });
15
+ Object.defineProperty(exports, "runVector", { enumerable: true, get: function () { return runner_1.runVector; } });
16
+ Object.defineProperty(exports, "runVectors", { enumerable: true, get: function () { return runner_1.runVectors; } });
17
+ var reference_1 = require("./reference");
18
+ Object.defineProperty(exports, "ReferenceHarness", { enumerable: true, get: function () { return reference_1.ReferenceHarness; } });
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Reference in-memory agent + harness.
3
+ *
4
+ * The simplest possible conformant agent loop; exists so the
5
+ * CTK can self-test without a real framework. Port of
6
+ * `sdk/python/python/agent_hooks/ctk/reference.py`.
7
+ */
8
+ import { ApprovalResolver, CompositionConfig, EnforcementMode, Interceptor } from "../index";
9
+ import type { Capability, Harness, RunRecord, Scenario } from "./index";
10
+ export declare class ReferenceHarness implements Harness {
11
+ readonly name = "reference-agent";
12
+ readonly capabilities: ReadonlySet<Capability>;
13
+ private scenario;
14
+ private emitter;
15
+ private builder;
16
+ private toolLog;
17
+ setup(scenario: Scenario, interceptors: Interceptor[], resolver: ApprovalResolver | null, mode: EnforcementMode, composition: CompositionConfig, identityProvider: 'jcs-sha256' | null): void;
18
+ run(): Promise<RunRecord>;
19
+ teardown(): void;
20
+ }