@nylorun/harness 0.5.0-beta.1

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.
Files changed (87) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/LICENSE +192 -0
  3. package/README.md +124 -0
  4. package/dist/build/adapters.d.ts +11 -0
  5. package/dist/build/adapters.js +91 -0
  6. package/dist/build/agent.d.ts +19 -0
  7. package/dist/build/agent.js +28 -0
  8. package/dist/build/assemble.d.ts +9 -0
  9. package/dist/build/assemble.js +76 -0
  10. package/dist/build/bind-tool.d.ts +4 -0
  11. package/dist/build/bind-tool.js +15 -0
  12. package/dist/build/builder.d.ts +31 -0
  13. package/dist/build/builder.js +74 -0
  14. package/dist/build/helpers.d.ts +7 -0
  15. package/dist/build/helpers.js +5 -0
  16. package/dist/build/manifest.d.ts +9 -0
  17. package/dist/build/manifest.js +15 -0
  18. package/dist/build/schema.d.ts +19 -0
  19. package/dist/build/schema.js +86 -0
  20. package/dist/errors.d.ts +17 -0
  21. package/dist/errors.js +17 -0
  22. package/dist/index.d.ts +11 -0
  23. package/dist/index.js +4 -0
  24. package/dist/model-normalize.d.ts +6 -0
  25. package/dist/model-normalize.js +211 -0
  26. package/dist/session/event-log.d.ts +11 -0
  27. package/dist/session/event-log.js +63 -0
  28. package/dist/session/input-queue.d.ts +29 -0
  29. package/dist/session/input-queue.js +78 -0
  30. package/dist/session/scheduler.d.ts +48 -0
  31. package/dist/session/scheduler.js +352 -0
  32. package/dist/session/session.d.ts +14 -0
  33. package/dist/session/session.js +55 -0
  34. package/dist/session/state.d.ts +10 -0
  35. package/dist/session/state.js +36 -0
  36. package/dist/session/submission-stream.d.ts +13 -0
  37. package/dist/session/submission-stream.js +36 -0
  38. package/dist/step/canonicalize.d.ts +21 -0
  39. package/dist/step/canonicalize.js +62 -0
  40. package/dist/step/compose.d.ts +4 -0
  41. package/dist/step/compose.js +106 -0
  42. package/dist/step/context-draft.d.ts +10 -0
  43. package/dist/step/context-draft.js +71 -0
  44. package/dist/step/model-configuration.d.ts +15 -0
  45. package/dist/step/model-configuration.js +153 -0
  46. package/dist/step/project.d.ts +2 -0
  47. package/dist/step/project.js +103 -0
  48. package/dist/step/resolve.d.ts +9 -0
  49. package/dist/step/resolve.js +16 -0
  50. package/dist/step/run.d.ts +27 -0
  51. package/dist/step/run.js +127 -0
  52. package/dist/step/seal.d.ts +31 -0
  53. package/dist/step/seal.js +108 -0
  54. package/dist/step/slot-assembly.d.ts +39 -0
  55. package/dist/step/slot-assembly.js +52 -0
  56. package/dist/step/step-context.d.ts +36 -0
  57. package/dist/step/step-context.js +255 -0
  58. package/dist/turn/plan-runner.d.ts +55 -0
  59. package/dist/turn/plan-runner.js +370 -0
  60. package/dist/turn/runner.d.ts +53 -0
  61. package/dist/turn/runner.js +128 -0
  62. package/dist/types/manifest.d.ts +22 -0
  63. package/dist/types/manifest.js +1 -0
  64. package/dist/types/middleware.d.ts +65 -0
  65. package/dist/types/middleware.js +1 -0
  66. package/dist/types/model.d.ts +166 -0
  67. package/dist/types/model.js +1 -0
  68. package/dist/types/session.d.ts +122 -0
  69. package/dist/types/session.js +1 -0
  70. package/dist/types/shared.d.ts +180 -0
  71. package/dist/types/shared.js +1 -0
  72. package/dist/types/tool.d.ts +101 -0
  73. package/dist/types/tool.js +1 -0
  74. package/dist/utils/digest.d.ts +1 -0
  75. package/dist/utils/digest.js +14 -0
  76. package/dist/utils/ids.d.ts +1 -0
  77. package/dist/utils/ids.js +3 -0
  78. package/dist/utils/immutable.d.ts +5 -0
  79. package/dist/utils/immutable.js +54 -0
  80. package/dist/utils/maps.d.ts +1 -0
  81. package/dist/utils/maps.js +37 -0
  82. package/dist/utils/observe.d.ts +8 -0
  83. package/dist/utils/observe.js +29 -0
  84. package/docs/loop.md +47 -0
  85. package/docs/model-call-projection.md +112 -0
  86. package/docs/reference.md +122 -0
  87. package/package.json +70 -0
@@ -0,0 +1,65 @@
1
+ import type { ContextMutationOptions, ModelCandidate, ModelDirective, ModelToolCall, ModelConfigurationMutationOptions } from "./model.js";
2
+ import type { InputEvent, TranscriptEntry } from "./session.js";
3
+ import type { ContextItem, JsonObject, Tripwire } from "./shared.js";
4
+ import type { Interaction, ToolDefinition, ToolResult } from "./tool.js";
5
+ export interface StepInput {
6
+ readonly sessionId: string;
7
+ readonly turnId: string;
8
+ readonly stepId: string;
9
+ /** One-based position of this turn within the Session. */
10
+ readonly turnNumber: number;
11
+ /** One-based position of this Model Step within the Turn. */
12
+ readonly stepNumber: number;
13
+ readonly session: Readonly<{
14
+ readonly userId?: string;
15
+ readonly context?: JsonObject;
16
+ }>;
17
+ readonly arrivals: readonly InputEvent[];
18
+ readonly toolResults: readonly ToolResult[];
19
+ readonly transcript: readonly TranscriptEntry[];
20
+ }
21
+ export interface StepRequest {
22
+ /** Opaque identity of the Session that owns this Step. */
23
+ readonly sessionId: string;
24
+ /** Opaque identity of the Turn that owns this Step. */
25
+ readonly turnId: string;
26
+ /** Opaque identity of this Model Step. */
27
+ readonly stepId: string;
28
+ readonly session: StepInput["session"];
29
+ readonly turnNumber: number;
30
+ readonly stepNumber: number;
31
+ readonly arrivals: readonly InputEvent[];
32
+ readonly toolResults: readonly ToolResult[];
33
+ readonly transcript: readonly TranscriptEntry[];
34
+ readonly context: {
35
+ set(slot: string, items: readonly ContextItem[], options?: ContextMutationOptions): void;
36
+ };
37
+ readonly configuration: {
38
+ readonly instructions: {
39
+ set(slot: string, items: readonly string[], options?: ModelConfigurationMutationOptions): void;
40
+ };
41
+ readonly tools: {
42
+ set(slot: string, tools: readonly ToolDefinition[], options?: ModelConfigurationMutationOptions): void;
43
+ };
44
+ readonly model: {
45
+ select(directive: ModelDirective, options?: Omit<ModelConfigurationMutationOptions, "order">): void;
46
+ replace(directive: ModelDirective, options?: Omit<ModelConfigurationMutationOptions, "order">): void;
47
+ clear(options?: Omit<ModelConfigurationMutationOptions, "order">): void;
48
+ };
49
+ };
50
+ tripwire(error: Tripwire): StepResponse;
51
+ }
52
+ export interface StepResponse {
53
+ candidate(): Readonly<ModelCandidate> | undefined;
54
+ toolCalls(): readonly ModelToolCall[];
55
+ replace(candidate: ModelCandidate): void;
56
+ deny(callId: string, reason: string): void;
57
+ requireInteraction(callId: string, interaction: Interaction): void;
58
+ requirePreflight(callId: string, kind: "sandbox" | "validation"): void;
59
+ tripwire(error: Tripwire): StepResponse;
60
+ }
61
+ export type StepMiddleware = (request: StepRequest, next: () => Promise<StepResponse>) => Promise<StepResponse>;
62
+ export interface BoundMiddleware {
63
+ readonly id: string;
64
+ readonly handle: StepMiddleware;
65
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,166 @@
1
+ import type { ContextItem, JsonObject } from "./shared.js";
2
+ import type { InputEvent, TranscriptEntry } from "./session.js";
3
+ import type { BoundToolDefinition, ToolResult } from "./tool.js";
4
+ export interface ModelToolCall {
5
+ readonly id: string;
6
+ readonly name: string;
7
+ readonly args: JsonObject;
8
+ }
9
+ export type ModelOutputBlock = {
10
+ readonly type: "text";
11
+ readonly text: string;
12
+ } | {
13
+ readonly type: "reasoning";
14
+ readonly text: string;
15
+ } | {
16
+ readonly type: "tool-call";
17
+ readonly id: string;
18
+ readonly name: string;
19
+ readonly args: JsonObject;
20
+ readonly raw?: string;
21
+ };
22
+ export interface ModelUsage {
23
+ readonly inputTokens?: number;
24
+ readonly outputTokens?: number;
25
+ readonly totalTokens?: number;
26
+ readonly cachedTokens?: number;
27
+ readonly reasoningTokens?: number;
28
+ readonly costUsd?: number;
29
+ }
30
+ export type ModelFinishReason = "stop" | "length" | "tool-calls" | "content-filter" | "other";
31
+ export interface ModelEvidence {
32
+ readonly requestId?: string;
33
+ readonly resolvedModel?: string;
34
+ readonly warnings?: readonly string[];
35
+ readonly extras?: JsonObject;
36
+ }
37
+ export interface ModelCandidate {
38
+ readonly output: readonly ModelOutputBlock[];
39
+ readonly finishReason?: ModelFinishReason;
40
+ readonly usage?: ModelUsage;
41
+ readonly evidence?: ModelEvidence;
42
+ }
43
+ export interface ModelControls {
44
+ readonly temperature?: number;
45
+ readonly maxOutputTokens?: number;
46
+ }
47
+ export interface ModelDirective {
48
+ readonly id?: string;
49
+ readonly controls?: ModelControls;
50
+ readonly config?: JsonObject;
51
+ }
52
+ /** A middleware-owned declaration for the model-visible configuration. */
53
+ export interface ModelConfigurationMutationOptions {
54
+ readonly order?: number;
55
+ readonly reason?: string;
56
+ }
57
+ export interface ModelConfigurationContributor {
58
+ readonly middlewareId: string;
59
+ readonly slot: string;
60
+ readonly order: number;
61
+ readonly digest: string;
62
+ readonly reason?: string;
63
+ }
64
+ export interface ModelConfigurationTool {
65
+ readonly name: string;
66
+ readonly description?: string;
67
+ readonly inputSchema: JsonObject;
68
+ readonly digest: string;
69
+ readonly contributor: ModelConfigurationContributor;
70
+ }
71
+ export interface ModelConfigurationInstruction {
72
+ readonly text: string;
73
+ readonly digest: string;
74
+ readonly contributor: ModelConfigurationContributor;
75
+ }
76
+ export interface ModelConfigurationSnapshot {
77
+ readonly version: 1;
78
+ readonly model?: ModelDirective;
79
+ readonly instructions: readonly ModelConfigurationInstruction[];
80
+ /** Bound tools are retained for execution; their digest covers only their provider-visible contract. */
81
+ readonly tools: readonly BoundToolDefinition[];
82
+ readonly toolContracts: readonly ModelConfigurationTool[];
83
+ readonly contributors: readonly ModelConfigurationContributor[];
84
+ readonly digests: Readonly<{
85
+ readonly logical: string;
86
+ readonly model: string;
87
+ readonly request: string;
88
+ }>;
89
+ }
90
+ /** A middleware-owned declaration for this model call's runtime context. */
91
+ export interface ContextMutationOptions {
92
+ readonly order?: number;
93
+ readonly reason?: string;
94
+ }
95
+ export interface ContextContributor {
96
+ readonly middlewareId: string;
97
+ readonly slot: string;
98
+ readonly order: number;
99
+ readonly digest: string;
100
+ readonly reason?: string;
101
+ }
102
+ /** Canonical runtime context for one model call. Not part of the configuration digest. */
103
+ export interface ContextSnapshot {
104
+ readonly items: readonly ContextItem[];
105
+ readonly contributors: readonly ContextContributor[];
106
+ readonly digest: string;
107
+ }
108
+ export interface ModelRequest {
109
+ readonly sessionId: string;
110
+ readonly turnId: string;
111
+ readonly stepId: string;
112
+ readonly model?: ModelDirective;
113
+ /** Canonical, immutable Harness-owned model configuration for this call. */
114
+ readonly configuration: ModelConfigurationSnapshot;
115
+ readonly instructions: readonly string[];
116
+ readonly context: ContextSnapshot;
117
+ readonly transcript: readonly TranscriptEntry[];
118
+ readonly arrivals: readonly InputEvent[];
119
+ readonly toolResults: readonly ToolResult[];
120
+ /** Tools are normalized and immutable by the time a Model sees them. */
121
+ readonly tools: readonly BoundToolDefinition[];
122
+ }
123
+ export type PromptContentPart = {
124
+ readonly type: "text";
125
+ readonly text: string;
126
+ } | {
127
+ readonly type: "tool-call";
128
+ readonly id: string;
129
+ readonly name: string;
130
+ readonly args: JsonObject;
131
+ };
132
+ export type PromptItem = {
133
+ readonly kind: "instructions";
134
+ readonly role: "system";
135
+ readonly content: readonly PromptContentPart[];
136
+ } | {
137
+ readonly kind: "message";
138
+ readonly role: "user" | "assistant";
139
+ readonly content: readonly PromptContentPart[];
140
+ } | {
141
+ readonly kind: "tool-result";
142
+ readonly toolCallId: string;
143
+ readonly toolName: string;
144
+ readonly status: "completed" | "denied" | "failed";
145
+ readonly content: readonly PromptContentPart[];
146
+ } | {
147
+ readonly kind: "context";
148
+ readonly role: "user";
149
+ readonly content: readonly PromptContentPart[];
150
+ };
151
+ export interface ModelCallTool {
152
+ readonly name: string;
153
+ readonly description?: string;
154
+ readonly inputSchema: JsonObject;
155
+ }
156
+ export interface ModelCall {
157
+ readonly model?: ModelDirective;
158
+ readonly prompt: readonly PromptItem[];
159
+ readonly tools: readonly ModelCallTool[];
160
+ readonly sessionId: string;
161
+ }
162
+ export interface ModelAdapterContext {
163
+ readonly request: ModelRequest;
164
+ readonly signal: AbortSignal;
165
+ }
166
+ export type ModelAdapter = (call: ModelCall, context: ModelAdapterContext) => Promise<ModelCandidate | string>;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,122 @@
1
+ import type { ModelCandidate } from "./model.js";
2
+ import type { JsonObject, JsonValue, Observer, Tripwire } from "./shared.js";
3
+ import type { RequiredInteraction, ToolResult } from "./tool.js";
4
+ export type InputEvent = {
5
+ readonly kind: "user-message";
6
+ readonly text: string;
7
+ readonly metadata?: JsonObject;
8
+ } | {
9
+ readonly kind: "interrupt";
10
+ readonly text: string;
11
+ readonly metadata?: JsonObject;
12
+ } | {
13
+ readonly kind: "approve";
14
+ readonly interactionId: string;
15
+ readonly approved: boolean;
16
+ } | {
17
+ readonly kind: "respond";
18
+ readonly interactionId: string;
19
+ readonly value: JsonValue;
20
+ };
21
+ export type SessionEvent = {
22
+ readonly type: "input";
23
+ readonly event: InputEvent;
24
+ readonly turnId: string;
25
+ } | {
26
+ readonly type: "candidate";
27
+ readonly turnId: string;
28
+ readonly stepId: string;
29
+ readonly candidate: ModelCandidate;
30
+ } | {
31
+ readonly type: "final";
32
+ readonly output: string;
33
+ readonly turnId: string;
34
+ } | {
35
+ readonly type: "interaction.required";
36
+ readonly interaction: RequiredInteraction;
37
+ readonly turnId: string;
38
+ } | {
39
+ readonly type: "tripwire";
40
+ readonly tripwire: Tripwire;
41
+ readonly turnId: string;
42
+ } | {
43
+ readonly type: "input.queued";
44
+ readonly inputId: string;
45
+ } | {
46
+ readonly type: "input.rejected";
47
+ readonly inputId: string;
48
+ readonly reason: string;
49
+ } | {
50
+ readonly type: "input.cancelled";
51
+ readonly inputId: string;
52
+ readonly reason: string;
53
+ } | {
54
+ readonly type: "session.stopped";
55
+ readonly sessionId: string;
56
+ };
57
+ export interface InputCompletion {
58
+ readonly inputId: string;
59
+ readonly status: "completed" | "waiting" | "rejected" | "cancelled" | "stopped";
60
+ readonly events: readonly SessionEvent[];
61
+ }
62
+ export interface InputHandle {
63
+ readonly inputId: string;
64
+ readonly completed: Promise<InputCompletion>;
65
+ }
66
+ export interface SessionOptions {
67
+ readonly id?: string;
68
+ readonly userId?: string;
69
+ readonly context?: JsonObject;
70
+ }
71
+ export interface InputOptions {
72
+ readonly signal?: AbortSignal;
73
+ }
74
+ export type MessageInput = string | {
75
+ readonly text: string;
76
+ readonly metadata?: JsonObject;
77
+ };
78
+ export type InteractionReply = Extract<InputEvent, {
79
+ kind: "approve" | "respond";
80
+ }>;
81
+ /** Ordinary user text or an interaction reply. Use `Session.interrupt()` for barge-in text. */
82
+ export type SessionInput = MessageInput | InteractionReply;
83
+ export interface TranscriptInputEntry {
84
+ readonly kind: "input";
85
+ readonly turnId: string;
86
+ readonly event: InputEvent;
87
+ }
88
+ export interface TranscriptCandidateEntry {
89
+ readonly kind: "candidate";
90
+ readonly turnId: string;
91
+ readonly stepId: string;
92
+ readonly candidate: ModelCandidate;
93
+ }
94
+ export interface TranscriptToolsEntry {
95
+ readonly kind: "tool-results";
96
+ readonly turnId: string;
97
+ readonly stepId: string;
98
+ readonly results: readonly ToolResult[];
99
+ }
100
+ export interface TranscriptFinalEntry {
101
+ readonly kind: "final";
102
+ readonly turnId: string;
103
+ readonly stepId: string;
104
+ readonly output: string;
105
+ }
106
+ export type TranscriptEntry = TranscriptInputEntry | TranscriptCandidateEntry | TranscriptToolsEntry | TranscriptFinalEntry;
107
+ export interface SessionSnapshot {
108
+ readonly id: string;
109
+ readonly status: "idle" | "running" | "waiting" | "stopped";
110
+ readonly turnCount: number;
111
+ readonly transcript: readonly TranscriptEntry[];
112
+ readonly pendingInteraction?: RequiredInteraction;
113
+ }
114
+ export interface Session {
115
+ readonly id: string;
116
+ readonly state: SessionSnapshot;
117
+ input(event: SessionInput, options?: InputOptions): InputHandle;
118
+ interrupt(event: MessageInput, options?: InputOptions): InputHandle;
119
+ stream(): AsyncIterable<SessionEvent>;
120
+ observe(listener: Observer): () => void;
121
+ stop(reason?: string): Promise<void>;
122
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,180 @@
1
+ import type { ContextSnapshot, ModelCandidate, ModelCall, ModelConfigurationSnapshot } from "./model.js";
2
+ import type { InputEvent, TranscriptEntry } from "./session.js";
3
+ import type { RequiredInteraction, ToolResult } from "./tool.js";
4
+ export type JsonPrimitive = string | number | boolean | null;
5
+ export type JsonValue = JsonPrimitive | JsonObject | readonly JsonValue[];
6
+ export type JsonObject = {
7
+ readonly [key: string]: JsonValue;
8
+ };
9
+ export interface BuildDiagnostic {
10
+ readonly code: string;
11
+ readonly message: string;
12
+ readonly toolName?: string;
13
+ readonly details?: Readonly<Record<string, string | number | boolean>>;
14
+ readonly cause?: unknown;
15
+ }
16
+ export interface ContextItem {
17
+ readonly type?: string;
18
+ readonly value: JsonValue;
19
+ }
20
+ export interface Tripwire {
21
+ readonly code: string;
22
+ readonly message: string;
23
+ readonly scope?: "step" | "session";
24
+ }
25
+ export interface ObserveToolSnapshot {
26
+ readonly name: string;
27
+ readonly description?: string;
28
+ readonly executeWith: string;
29
+ readonly parameters: {
30
+ readonly jsonSchema: JsonObject;
31
+ };
32
+ }
33
+ /** JSON-only model-configuration view suitable for an observation stream. */
34
+ export interface ObserveModelConfigurationSnapshot extends Omit<ModelConfigurationSnapshot, "tools"> {
35
+ readonly tools: readonly ObserveToolSnapshot[];
36
+ }
37
+ export interface ObserveSealedCall {
38
+ readonly callId: string;
39
+ readonly toolName: string;
40
+ readonly args: JsonValue;
41
+ readonly executeWith: string;
42
+ readonly invocationId: string;
43
+ readonly preflight?: "sandbox" | "validation";
44
+ readonly interaction?: RequiredInteraction;
45
+ }
46
+ export interface ObserveModelRequested {
47
+ /** The exact immutable logical input supplied to the ModelAdapter. */
48
+ readonly call: ModelCall;
49
+ /** Canonical configuration facts and attribution; hashes have no policy semantics. */
50
+ readonly configuration: ObserveModelConfigurationSnapshot;
51
+ /** Current-step runtime context and attribution. */
52
+ readonly context: ContextSnapshot;
53
+ }
54
+ export type ObserveEvent = {
55
+ readonly type: "session.stopped";
56
+ readonly reason: string;
57
+ } | {
58
+ readonly type: "input.received";
59
+ readonly inputId: string;
60
+ readonly kind: string;
61
+ } | {
62
+ readonly type: "input.queued";
63
+ readonly inputId: string;
64
+ } | {
65
+ readonly type: "input.rejected";
66
+ readonly inputId: string;
67
+ readonly reason: string;
68
+ } | {
69
+ readonly type: "input.cancelled";
70
+ readonly inputId: string;
71
+ readonly reason: string;
72
+ } | {
73
+ readonly type: "model.requested";
74
+ readonly turnId: string;
75
+ readonly stepId: string;
76
+ readonly inputId?: string;
77
+ readonly requestedModelId?: string;
78
+ readonly attributes: ObserveModelRequested;
79
+ } | {
80
+ readonly type: "model.completed";
81
+ readonly turnId: string;
82
+ readonly stepId: string;
83
+ readonly inputId?: string;
84
+ readonly requestedModelId?: string;
85
+ readonly attributes: ModelCandidate;
86
+ } | {
87
+ readonly type: "step.started";
88
+ readonly turnId: string;
89
+ readonly stepId: string;
90
+ readonly inputId?: string;
91
+ readonly turnNumber: number;
92
+ readonly stepNumber: number;
93
+ readonly attributes: {
94
+ readonly session?: {
95
+ readonly userId?: string;
96
+ readonly context?: JsonObject;
97
+ };
98
+ readonly arrivals: readonly InputEvent[];
99
+ readonly toolResults: readonly ToolResult[];
100
+ readonly transcript: readonly TranscriptEntry[];
101
+ };
102
+ } | {
103
+ readonly type: "middleware.entered" | "middleware.completed";
104
+ readonly turnId: string;
105
+ readonly stepId: string;
106
+ readonly inputId?: string;
107
+ readonly middlewareId: string;
108
+ } | {
109
+ readonly type: "middleware.lease-violation";
110
+ readonly turnId: string;
111
+ readonly stepId: string;
112
+ readonly inputId?: string;
113
+ readonly middlewareId: string;
114
+ readonly reason: string;
115
+ } | {
116
+ readonly type: "tool.sealed";
117
+ readonly turnId: string;
118
+ readonly stepId: string;
119
+ readonly inputId?: string;
120
+ readonly attributes: {
121
+ readonly executable: readonly ObserveSealedCall[];
122
+ readonly immediate: readonly ToolResult[];
123
+ };
124
+ } | {
125
+ readonly type: "adapter.preflight.started" | "adapter.started";
126
+ readonly turnId: string;
127
+ readonly stepId: string;
128
+ readonly inputId?: string;
129
+ readonly adapterId: string;
130
+ readonly toolName: string;
131
+ readonly callId: string;
132
+ readonly invocationId?: string;
133
+ readonly attributes: {
134
+ readonly args: JsonValue;
135
+ };
136
+ } | {
137
+ readonly type: "adapter.preflight.completed" | "adapter.completed";
138
+ readonly turnId: string;
139
+ readonly stepId: string;
140
+ readonly inputId?: string;
141
+ readonly adapterId: string;
142
+ readonly toolName: string;
143
+ readonly callId: string;
144
+ readonly outcome: string;
145
+ readonly code?: string;
146
+ readonly attributes?: ToolResult;
147
+ } | {
148
+ readonly type: "turn.completed";
149
+ readonly turnId: string;
150
+ readonly stepId: string;
151
+ readonly inputId?: string;
152
+ readonly attributes: {
153
+ readonly output: string;
154
+ };
155
+ } | {
156
+ readonly type: "interaction.required";
157
+ readonly turnId: string;
158
+ readonly stepId: string;
159
+ readonly inputId?: string;
160
+ readonly interactionId: string;
161
+ readonly kind: string;
162
+ readonly callId?: string;
163
+ readonly toolName?: string;
164
+ readonly phase?: "interaction" | "preflight" | "execute";
165
+ readonly attributes: {
166
+ readonly prompt: string;
167
+ readonly metadata?: JsonObject;
168
+ };
169
+ } | {
170
+ readonly type: "tripwire";
171
+ readonly turnId: string;
172
+ readonly stepId?: string;
173
+ readonly inputId?: string;
174
+ readonly code: string;
175
+ readonly scope: string;
176
+ readonly attributes: {
177
+ readonly message: string;
178
+ };
179
+ };
180
+ export type Observer = (event: ObserveEvent) => void | Promise<void>;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,101 @@
1
+ import type { ZodObject, output } from "zod";
2
+ import type { JsonObject, JsonValue } from "./shared.js";
3
+ type SchemaValidationSuccess<T> = {
4
+ readonly ok: true;
5
+ readonly value: T;
6
+ };
7
+ type SchemaValidationFailure = {
8
+ readonly ok: false;
9
+ readonly issues: readonly string[];
10
+ };
11
+ type SchemaValidation<T> = SchemaValidationSuccess<T> | SchemaValidationFailure;
12
+ /** Harness tool parameters are synchronous Zod object schemas. */
13
+ export type ToolObjectSchema = ZodObject;
14
+ export interface BoundToolSchema<T> {
15
+ readonly jsonSchema: JsonObject;
16
+ validate(value: unknown): SchemaValidation<T>;
17
+ }
18
+ export interface ToolDefinition<Parameters extends ToolObjectSchema = ToolObjectSchema> {
19
+ readonly name: string;
20
+ readonly description?: string;
21
+ readonly parameters: Parameters;
22
+ readonly executeWith: string;
23
+ }
24
+ export interface BoundToolDefinition<Parameters extends ToolObjectSchema = ToolObjectSchema> extends Omit<ToolDefinition<Parameters>, "parameters"> {
25
+ readonly parameters: BoundToolSchema<output<Parameters>>;
26
+ }
27
+ export interface Interaction {
28
+ readonly id?: string;
29
+ readonly kind: "approval" | "response";
30
+ readonly prompt: string;
31
+ readonly metadata?: JsonObject;
32
+ }
33
+ export interface RequiredInteraction extends Interaction {
34
+ readonly id: string;
35
+ }
36
+ export interface ToolExecutionResume {
37
+ readonly interactionId: string;
38
+ readonly kind: "approval" | "response";
39
+ readonly approved?: boolean;
40
+ readonly value?: JsonValue;
41
+ readonly token?: JsonValue;
42
+ }
43
+ export interface SealedToolCall {
44
+ readonly callId: string;
45
+ readonly toolName: string;
46
+ readonly args: JsonValue;
47
+ readonly executeWith: string;
48
+ }
49
+ export type ToolContent = JsonValue;
50
+ export type ToolOutcome = {
51
+ readonly kind: "completed";
52
+ readonly output: ToolContent;
53
+ } | {
54
+ readonly kind: "denied";
55
+ readonly reason: string;
56
+ } | {
57
+ readonly kind: "failed";
58
+ readonly code: string;
59
+ readonly message: string;
60
+ } | {
61
+ readonly kind: "interaction-required";
62
+ readonly interaction: Interaction;
63
+ readonly token?: JsonValue;
64
+ };
65
+ export type PreflightOutcome = {
66
+ readonly kind: "completed";
67
+ } | Exclude<ToolOutcome, {
68
+ readonly kind: "completed";
69
+ }>;
70
+ export interface ToolAdapter {
71
+ readonly id: string;
72
+ preflight?(call: SealedToolCall, context: {
73
+ readonly kind: "sandbox" | "validation";
74
+ readonly invocationId: string;
75
+ readonly signal: AbortSignal;
76
+ readonly resume?: ToolExecutionResume;
77
+ }): Promise<PreflightOutcome>;
78
+ execute(call: SealedToolCall, context: {
79
+ readonly invocationId: string;
80
+ readonly signal: AbortSignal;
81
+ readonly resume?: ToolExecutionResume;
82
+ }): Promise<ToolOutcome>;
83
+ }
84
+ /** Scheduling policy for one adapter registration on an Agent. */
85
+ export interface AdapterExecutionOptions {
86
+ /**
87
+ * Maximum concurrent execute() calls across all Sessions from the built Agent.
88
+ * Omit for unbounded parallel execution.
89
+ */
90
+ readonly maxConcurrentCalls?: number;
91
+ }
92
+ export interface ToolResult {
93
+ readonly callId: string;
94
+ readonly toolName: string;
95
+ readonly kind: "completed" | "denied" | "failed";
96
+ readonly output?: ToolContent;
97
+ readonly reason?: string;
98
+ readonly code?: string;
99
+ readonly message?: string;
100
+ }
101
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export declare const digest: (value: unknown) => string;
@@ -0,0 +1,14 @@
1
+ import { sha256 } from "@noble/hashes/sha2.js";
2
+ import { bytesToHex, utf8ToBytes } from "@noble/hashes/utils.js";
3
+ function canonical(value) {
4
+ if (Array.isArray(value))
5
+ return `[${value.map(canonical).join(",")}]`;
6
+ if (value && typeof value === "object") {
7
+ return `{${Object.entries(value)
8
+ .sort(([a], [b]) => a.localeCompare(b))
9
+ .map(([key, item]) => `${JSON.stringify(key)}:${canonical(item)}`)
10
+ .join(",")}}`;
11
+ }
12
+ return JSON.stringify(value);
13
+ }
14
+ export const digest = (value) => bytesToHex(sha256(utf8ToBytes(canonical(value))));
@@ -0,0 +1 @@
1
+ export declare function createId(prefix: string): string;
@@ -0,0 +1,3 @@
1
+ export function createId(prefix) {
2
+ return `${prefix}_${globalThis.crypto.randomUUID()}`;
3
+ }
@@ -0,0 +1,5 @@
1
+ import type { JsonObject, JsonValue } from "../types/shared.js";
2
+ export declare function assertJson(value: unknown, path?: string): asserts value is JsonValue;
3
+ export declare function copyJson<T>(value: T): T;
4
+ export declare function copyJsonObject(value: unknown, path: string): JsonObject;
5
+ export declare function deepFreeze<T>(value: T): T;