@agentium/harness 4.1.0 → 4.5.0

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.
@@ -0,0 +1,39 @@
1
+ import type { RunContext } from "@agentium/core";
2
+ import type { AbilityBinding } from "./runtime/index.cjs";
3
+ import { type AbilityFactory, createHarnessDefinition, describeHarnessDefinition, exportHarnessManifest, extendHarnessDefinition, hashHarnessManifest, type JsonObject, type LocalAbilityUse, loadHarnessManifest } from "./runtime/index.cjs";
4
+ export interface AbilityDescription {
5
+ toolNames: readonly string[];
6
+ requirements: readonly string[];
7
+ runtimeDependent?: boolean;
8
+ }
9
+ export interface AbilityDefinition<Options> {
10
+ type: string;
11
+ version?: number;
12
+ /** Pure validation/snapshotting. Preserve caller-owned service references; never freeze clients. */
13
+ validate: (options: Options) => Options;
14
+ describe: (options: Options) => AbilityDescription;
15
+ bind: (options: Options, ctx: RunContext) => AbilityBinding | Promise<AbilityBinding>;
16
+ /** Explicit trusted mapping. Omit for local callbacks/services that cannot be serialized. */
17
+ portable?: {
18
+ validateOptions: (options: JsonObject) => JsonObject;
19
+ toOptions: (options: JsonObject) => Options;
20
+ toJSON: (options: Options) => JsonObject;
21
+ };
22
+ }
23
+ export interface Ability<Options> {
24
+ (options: Options, config?: {
25
+ instanceId?: string;
26
+ }): LocalAbilityUse;
27
+ readonly type: string;
28
+ readonly version: number;
29
+ readonly factory?: AbilityFactory;
30
+ }
31
+ /** Capture typed local options; erase only the wrapper so heterogeneous abilities compose without casts. */
32
+ export declare function defineAbility<Options>(definition: AbilityDefinition<Options>): Ability<Options>;
33
+ export declare const defineHarness: typeof createHarnessDefinition;
34
+ export declare const extendHarness: typeof extendHarnessDefinition;
35
+ export declare const describeHarness: typeof describeHarnessDefinition;
36
+ export declare const exportManifest: typeof exportHarnessManifest;
37
+ export declare const loadManifest: typeof loadHarnessManifest;
38
+ export declare const hashManifest: typeof hashHarnessManifest;
39
+ //# sourceMappingURL=definition.d.ts.map
@@ -0,0 +1,14 @@
1
+ import { Agent, type AgentConfig, type Team, type Workflow } from "@agentium/core";
2
+ import type { ExecutionDriver, HarnessRunRequest } from "./runtime/index.cjs";
3
+ /** Passing an Agent borrows it. Passing configuration creates/disposes a run-owned
4
+ * Agent and applies the definition's explicit defaults here, outside core. */
5
+ export declare function agentDriver(agent: Agent | AgentConfig, config?: {
6
+ stream?: boolean;
7
+ }): ExecutionDriver;
8
+ /** Input defaults to a JSON object patch over the Workflow constructor's initial state. */
9
+ export declare function workflowDriver<T extends Record<string, unknown>>(workflow: Workflow<T>, config?: {
10
+ input?: (input: HarnessRunRequest["input"]) => Partial<T>;
11
+ }): ExecutionDriver;
12
+ /** Remote Team members fail explicitly because their effects cannot be intercepted locally. */
13
+ export declare function teamDriver(team: Team): ExecutionDriver;
14
+ //# sourceMappingURL=drivers.d.ts.map
@@ -0,0 +1,16 @@
1
+ export type { Ability, AbilityDefinition, AbilityDescription } from "./definition.cjs";
2
+ export { defineAbility, defineHarness, describeHarness, exportManifest, extendHarness, hashManifest, loadManifest, } from "./definition.cjs";
3
+ export { agentDriver, teamDriver, workflowDriver } from "./drivers.cjs";
4
+ export type { MCPResourceClient, MCPResourceGrant, MCPResourcesOptions } from "./mcp-resources.cjs";
5
+ export { mcpResources } from "./mcp-resources.cjs";
6
+ export type { ReflectionPolicyOptions, SummaryContextPolicyOptions } from "./policies.cjs";
7
+ export { reflectionPolicy, summaryContextPolicy } from "./policies.cjs";
8
+ export type { BaseOptions, FileContextOptions, ResearchOptions, SuppliedToolsOptions, TextContextOptions, } from "./presets.cjs";
9
+ export { base, fileContext, research, suppliedTools, textContext } from "./presets.cjs";
10
+ export type { AbilityBinding, AbilityFactory, AbilitySelection, BoundHarness, CompletionDecision, CompletionPolicy, ContextPolicy, ContextProjection, ExecutionDriver, HarnessBudgets, HarnessContextBudget, HarnessContextEntry, HarnessContextSource, HarnessDefaults, HarnessDefinition, HarnessDescription, HarnessDiagnostic, HarnessDriverOutput, HarnessEvent, HarnessEventPayload, HarnessExecutionServices, HarnessExtension, HarnessGrants, HarnessIdentity, HarnessManifest, HarnessMiddleware, HarnessReason, HarnessRegistryEntry, HarnessRegistryReference, HarnessResult, HarnessRunRequest, HarnessRuntimeBindings, HarnessRuntimeConfig, HarnessRuntimeReferences, HarnessRuntimeRegistry, HarnessSendMode, HarnessSessionLease, HarnessSessionSnapshot, HarnessSessionStore, HarnessStartOptions, HarnessStatus, JsonObject, JsonValue, LocalAbilityUse, ModelRoleBinding, PromptFragment, ResolvedHarness, RunHandle, ScopedResource, SessionResourceLease, StepController, StepOverrides, } from "./runtime/index.cjs";
11
+ export { HarnessBudgetError, HarnessEventGapError, HarnessResourcePool, HarnessRuntime, HarnessSessionConflict, HarnessUnsupportedError, InMemoryHarnessEventStore, InMemoryHarnessSessionStore, resolveHarnessRuntime, } from "./runtime/index.cjs";
12
+ export { defineWatch, describeWatch } from "./watch/definition.cjs";
13
+ export { type GmailWatchClient, type GmailWatchOptions, gmailWatchSource } from "./watch/gmail.cjs";
14
+ export { DurableWatch } from "./watch/runtime.cjs";
15
+ export type * from "./watch/types.cjs";
16
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,42 @@
1
+ import { RunContext } from "@agentium/core";
2
+ /** Structural port: both MCP SDK generations can supply a connected Client. */
3
+ export interface MCPResourceClient {
4
+ readResource(params: {
5
+ uri: string;
6
+ }, options?: {
7
+ signal?: AbortSignal;
8
+ timeout?: number;
9
+ cacheMode?: "bypass";
10
+ }): Promise<{
11
+ contents: readonly {
12
+ uri: string;
13
+ mimeType?: string;
14
+ text?: string;
15
+ blob?: string;
16
+ }[];
17
+ }>;
18
+ }
19
+ export interface MCPResourceGrant {
20
+ /** Exact server URI, never a local path or a URL fetched by the harness. */
21
+ uri: string;
22
+ /** Explicit text formats. A missing MIME is accepted only when listed as "". */
23
+ mimeTypes: readonly string[];
24
+ }
25
+ export interface MCPResourcesOptions {
26
+ id: string;
27
+ /** Creates a principal-scoped connection for this binding. Authentication belongs to the host. */
28
+ connect: (ctx: RunContext) => Promise<{
29
+ client: MCPResourceClient;
30
+ dispose?: () => Promise<void>;
31
+ }>;
32
+ /** Bounds setup even when the host connection factory ignores cancellation. Default 5000. */
33
+ connectTimeoutMs?: number;
34
+ resources: readonly MCPResourceGrant[];
35
+ /** Rechecked before reading and before returning content, including on every subsequent fetch. */
36
+ authorize: (grant: MCPResourceGrant, ctx: RunContext) => boolean | Promise<boolean>;
37
+ /** Optional host selector, constrained to the declared grants. No server-wide discovery. */
38
+ select?: (query: string, ctx: RunContext) => readonly string[] | Promise<readonly string[]>;
39
+ }
40
+ /** Approved text resources become untrusted, provenance-labelled context, never tools or prompts. */
41
+ export declare const mcpResources: import("./definition.cjs").Ability<MCPResourcesOptions>;
42
+ //# sourceMappingURL=mcp-resources.d.ts.map
@@ -0,0 +1,29 @@
1
+ import type { CompletionPolicy, ContextPolicy } from "./runtime/index.cjs";
2
+ interface ControlOptions {
3
+ /** Explicit role in HarnessRuntime.models and grants.modelRoles. */
4
+ modelRole: string;
5
+ /** Maximum serialized source bytes sent to the policy model. Default: 65536. */
6
+ maxInputBytes?: number;
7
+ }
8
+ export interface ReflectionPolicyOptions extends ControlOptions {
9
+ id?: string;
10
+ /** Host-authored acceptance criteria, not retrieved instructions. */
11
+ criteria: string;
12
+ /** Maximum critic output tokens; the host binding must allow maxTokens. Default: 1024. */
13
+ maxTokens?: number;
14
+ }
15
+ export interface SummaryContextPolicyOptions extends ControlOptions {
16
+ id?: string;
17
+ /** Request token estimate including instructions, retained turns and summary. */
18
+ maxContextTokens: number;
19
+ /** Latest complete turn groups kept unchanged, including the live turn. Default: 1. */
20
+ keepRecentTurns?: number;
21
+ /** Maximum summary output tokens; the host binding must allow maxTokens. Default: 1024. */
22
+ summaryMaxTokens?: number;
23
+ }
24
+ /** A budgeted critic. Revisions and effect permissions remain owned by HarnessRuntime. */
25
+ export declare function reflectionPolicy(options: ReflectionPolicyOptions): CompletionPolicy;
26
+ /** Summarize removable historical turns, preserving host instructions and the latest whole turns. */
27
+ export declare function summaryContextPolicy(options: SummaryContextPolicyOptions): ContextPolicy;
28
+ export {};
29
+ //# sourceMappingURL=policies.d.ts.map
@@ -0,0 +1,41 @@
1
+ import type { ToolDef } from "@agentium/core";
2
+ import type { HarnessDefaults, HarnessDefinition, LocalAbilityUse } from "./runtime/index.cjs";
3
+ export interface TextContextOptions {
4
+ id: string;
5
+ entries: readonly {
6
+ id: string;
7
+ text: string;
8
+ uri?: string;
9
+ }[];
10
+ }
11
+ /** Static source data. These entries are always marked source, never host instructions. */
12
+ export declare const textContext: import("./definition.cjs").Ability<TextContextOptions>;
13
+ export interface FileContextOptions {
14
+ id: string;
15
+ /** Explicit host grant. Must be absolute; filesystem access begins only during fetch. */
16
+ root: string;
17
+ files: readonly string[];
18
+ }
19
+ /** Read only explicitly selected UTF-8 files within a canonical workspace. Local-only host capability. */
20
+ export declare const fileContext: import("./definition.cjs").Ability<FileContextOptions>;
21
+ export interface SuppliedToolsOptions {
22
+ tools: readonly ToolDef[];
23
+ requirements?: readonly string[];
24
+ }
25
+ /** Application-owned search/document/service tools retain their existing ToolDef enforcement. */
26
+ export declare const suppliedTools: import("./definition.cjs").Ability<SuppliedToolsOptions>;
27
+ export interface BaseOptions {
28
+ id?: string;
29
+ abilities?: readonly LocalAbilityUse[];
30
+ defaults?: HarnessDefaults;
31
+ }
32
+ /** Minimal local composition, no background jobs, learning, tools or provider selected implicitly. */
33
+ export declare function base(options?: BaseOptions): HarnessDefinition;
34
+ export interface ResearchOptions extends BaseOptions {
35
+ text?: TextContextOptions;
36
+ files?: FileContextOptions;
37
+ tools?: readonly ToolDef[];
38
+ }
39
+ /** Real context sources plus application-supplied research tools; no connector credentials or implicit web calls. */
40
+ export declare function research(options?: ResearchOptions): HarnessDefinition;
41
+ //# sourceMappingURL=presets.d.ts.map
@@ -0,0 +1,20 @@
1
+ import type { ChatMessage, RunContext } from "@agentium/core";
2
+ import type { HarnessContextEntry } from "./types.cjs";
3
+ export interface ContextProjection {
4
+ messages: ChatMessage[];
5
+ provenance: readonly {
6
+ sourceId: string;
7
+ included: boolean;
8
+ reason?: string;
9
+ }[];
10
+ }
11
+ export interface ContextPolicy {
12
+ id: string;
13
+ project: (input: {
14
+ history: readonly ChatMessage[];
15
+ entries: readonly HarnessContextEntry[];
16
+ }, ctx: RunContext) => Promise<ContextProjection>;
17
+ }
18
+ /** Request projections never mutate the canonical history. */
19
+ export declare function projectHarnessContext(policy: ContextPolicy | undefined, history: readonly ChatMessage[], ctx: RunContext, entries?: readonly HarnessContextEntry[]): Promise<ContextProjection>;
20
+ //# sourceMappingURL=context-policy.d.ts.map
@@ -0,0 +1,15 @@
1
+ import type { ChatMessage } from "@agentium/core";
2
+ import { RunContext } from "@agentium/core";
3
+ import type { HarnessContextBudget, HarnessContextSource } from "./types.cjs";
4
+ export interface HarnessContextDiagnostic {
5
+ sourceId: string;
6
+ entryId?: string;
7
+ code: "expired" | "invalid" | "truncated" | "budget" | "deadline" | "failed" | "trust_downgraded";
8
+ message: string;
9
+ }
10
+ /** All limits apply across every source. Tokens are centrally estimated, never accepted from the source. */
11
+ export declare function fetchHarnessContext(sources: readonly HarnessContextSource[], query: string, ctx: RunContext, configured?: Partial<HarnessContextBudget>): Promise<{
12
+ messages: ChatMessage[];
13
+ diagnostics: HarnessContextDiagnostic[];
14
+ }>;
15
+ //# sourceMappingURL=context.d.ts.map
@@ -0,0 +1,51 @@
1
+ import type { ModelConfig, ModelResponse, RunContext, ToolDefinition } from "@agentium/core";
2
+ import type { ContextPolicy } from "./context-policy.cjs";
3
+ export interface StepOverrides {
4
+ activeToolIds?: readonly string[];
5
+ modelRole?: string;
6
+ options?: ModelConfig;
7
+ contextPolicy?: ContextPolicy;
8
+ stop?: {
9
+ reason: string;
10
+ };
11
+ }
12
+ export interface StepController {
13
+ id: string;
14
+ prepareRun?: (ctx: RunContext) => Promise<StepOverrides | undefined>;
15
+ prepareStep?: (step: {
16
+ index: number;
17
+ tools: readonly ToolDefinition[];
18
+ }, ctx: RunContext) => Promise<StepOverrides | undefined>;
19
+ }
20
+ export type CompletionDecision = {
21
+ action: "accept";
22
+ reason: string;
23
+ evidence?: readonly string[];
24
+ } | {
25
+ action: "revise";
26
+ reason: string;
27
+ instruction: string;
28
+ evidence?: readonly string[];
29
+ } | {
30
+ action: "await_input" | "stop";
31
+ reason: string;
32
+ evidence?: readonly string[];
33
+ };
34
+ export interface CompletionPolicy {
35
+ id: string;
36
+ evaluate: (response: {
37
+ text: string;
38
+ structured?: unknown;
39
+ revision: number;
40
+ }, ctx: RunContext) => Promise<CompletionDecision>;
41
+ }
42
+ export interface ModelRoleBinding {
43
+ provider: import("@agentium/core").ModelProvider;
44
+ /** Explicit allowlist of ModelConfig keys supported by this binding. */
45
+ options?: readonly (keyof ModelConfig)[];
46
+ }
47
+ export interface ModelInvocation {
48
+ response: ModelResponse;
49
+ modelRole: string;
50
+ }
51
+ //# sourceMappingURL=controller.d.ts.map
@@ -0,0 +1,146 @@
1
+ import type { ApprovalManager, ChatMessage, ExecutionPolicy, ExecutionServices, MessageContent, ModelConfig, ModelResponse, RunMode, TokenUsage, ToolDef } from "@agentium/core";
2
+ import { EventBus } from "@agentium/core";
3
+ import type { ContextPolicy } from "./context-policy.cjs";
4
+ import type { CompletionPolicy, ModelRoleBinding, StepController } from "./controller.cjs";
5
+ import { type HarnessEvent, type HarnessEventPayload, type HarnessReason, type HarnessResult, type HarnessStatus } from "./events.cjs";
6
+ import { type HarnessIdentity, HarnessResourcePool, type HarnessSessionStore, type ScopedResource } from "./session-bindings.cjs";
7
+ import type { HarnessDefinition } from "./types.cjs";
8
+ export type HarnessSendMode = "follow_up" | "steer" | "replace";
9
+ export declare class HarnessUnsupportedError extends Error {
10
+ readonly operation: string;
11
+ readonly code = "unsupported";
12
+ constructor(operation: string);
13
+ }
14
+ export declare class HarnessBudgetError extends Error {
15
+ readonly code = "budget_exhausted";
16
+ constructor(message: string);
17
+ }
18
+ export interface HarnessGrants {
19
+ toolIds: readonly string[];
20
+ requiredToolIds?: readonly string[];
21
+ modelRoles: readonly string[];
22
+ }
23
+ export interface HarnessBudgets {
24
+ maxModelCalls?: number;
25
+ maxToolCalls?: number;
26
+ maxTokens?: number;
27
+ maxRevisions?: number;
28
+ }
29
+ export interface HarnessRunRequest {
30
+ input: MessageContent;
31
+ identity: HarnessIdentity;
32
+ sessionId: string;
33
+ runId: string;
34
+ attemptId: string;
35
+ parentRunId?: string;
36
+ rootRunId: string;
37
+ signal: AbortSignal;
38
+ deadline?: number;
39
+ grants: HarnessGrants;
40
+ runMode: RunMode;
41
+ }
42
+ export interface HarnessDriverOutput {
43
+ status?: HarnessStatus;
44
+ text: string;
45
+ structured?: unknown;
46
+ reason?: HarnessReason;
47
+ usage?: TokenUsage;
48
+ history?: readonly ChatMessage[];
49
+ artifacts?: readonly {
50
+ id: string;
51
+ mimeType?: string;
52
+ }[];
53
+ }
54
+ export interface ExecutionDriver {
55
+ id: string;
56
+ version: number;
57
+ capabilities: {
58
+ controls: readonly HarnessSendMode[];
59
+ durable: boolean;
60
+ policyCoverage: "local" | "remote" | "none";
61
+ /** True only when each model/tool operation uses provided execution services. */
62
+ controlledExecution: boolean;
63
+ };
64
+ start: (request: HarnessRunRequest, services: HarnessExecutionServices) => Promise<HarnessDriverOutput>;
65
+ }
66
+ export interface HarnessExecutionServices extends ExecutionServices {
67
+ readonly definitionId?: string;
68
+ /** Agent-specific declarative options interpreted only by the configured Agent driver. */
69
+ readonly agentConfiguration?: {
70
+ defaults: import("./types.cjs").HarnessDefaults;
71
+ limits: NonNullable<import("./types.cjs").HarnessManifest["limits"]>;
72
+ projectRoot: string;
73
+ };
74
+ /** Independent, tool-free policy call using an explicitly granted host role and shared budgets.
75
+ * Skips task controllers, context projection and middleware to avoid policy recursion.
76
+ */
77
+ controlModel(role: string, messages: readonly ChatMessage[], options?: Pick<ModelConfig, "maxTokens" | "temperature">): Promise<ModelResponse>;
78
+ append(messages: readonly ChatMessage[]): void;
79
+ emit(payload: Exclude<HarnessEventPayload, {
80
+ type: "run.terminal" | "run.started";
81
+ }>): void;
82
+ takeInput(): {
83
+ input: MessageContent;
84
+ mode: HarnessSendMode;
85
+ } | undefined;
86
+ resource<T>(id: string, scope: "host" | "session" | "run", initialize: () => Promise<ScopedResource<T>>): Promise<T>;
87
+ putArtifact(value: unknown): string;
88
+ getArtifact(id: string): unknown;
89
+ }
90
+ export interface RunHandle {
91
+ readonly runId: string;
92
+ events(options?: {
93
+ after?: number;
94
+ }): AsyncGenerator<HarnessEvent>;
95
+ result(): Promise<HarnessResult>;
96
+ cancel(reason?: string): void;
97
+ send(input: MessageContent, options: {
98
+ mode: HarnessSendMode;
99
+ }): Promise<void>;
100
+ }
101
+ export interface HarnessRuntimeConfig {
102
+ /** Optional observer bus for the runtime and its direct model/controller calls.
103
+ * Keep Agent instrumentation on its own bus to avoid counting the same call twice. */
104
+ telemetry?: EventBus;
105
+ driver?: ExecutionDriver;
106
+ definition?: HarnessDefinition;
107
+ projectRoot?: string;
108
+ requirements?: readonly string[];
109
+ tools?: readonly ToolDef[];
110
+ models?: Readonly<Record<string, ModelRoleBinding>>;
111
+ grants: HarnessGrants;
112
+ budgets?: HarnessBudgets;
113
+ executionPolicy?: ExecutionPolicy;
114
+ approvalManager?: ApprovalManager;
115
+ controller?: StepController;
116
+ contextPolicy?: ContextPolicy;
117
+ completionPolicy?: CompletionPolicy;
118
+ /** Explicit opt-in to new tool effects in completion revisions. */
119
+ allowRevisionEffects?: boolean;
120
+ sessionStore?: HarnessSessionStore;
121
+ resources?: HarnessResourcePool;
122
+ eventCapacity?: number;
123
+ }
124
+ export interface HarnessStartOptions {
125
+ identity: HarnessIdentity;
126
+ sessionId: string;
127
+ parentRunId?: string;
128
+ rootRunId?: string;
129
+ signal?: AbortSignal;
130
+ deadline?: number;
131
+ grants?: HarnessGrants;
132
+ runMode?: RunMode;
133
+ }
134
+ /** Local lifecycle owner. Custom driver code is trusted; services enforce all intercepted effects. */
135
+ export declare class HarnessRuntime {
136
+ readonly sessions: HarnessSessionStore;
137
+ readonly resources: HarnessResourcePool;
138
+ private config;
139
+ private artifacts;
140
+ getArtifact(identity: HarnessIdentity, sessionId: string, id: string): unknown;
141
+ constructor(config: HarnessRuntimeConfig);
142
+ run(input: MessageContent, options: HarnessStartOptions): Promise<HarnessResult>;
143
+ stream(input: MessageContent, options: HarnessStartOptions): AsyncGenerator<HarnessEvent>;
144
+ start(input: MessageContent, options: HarnessStartOptions): RunHandle;
145
+ }
146
+ //# sourceMappingURL=driver.d.ts.map
@@ -0,0 +1,83 @@
1
+ import type { TokenUsage } from "@agentium/core";
2
+ export type HarnessStatus = "completed" | "failed" | "cancelled" | "stopped" | "awaiting_input";
3
+ export interface HarnessReason {
4
+ code: string;
5
+ message: string;
6
+ }
7
+ export interface HarnessResult {
8
+ status: HarnessStatus;
9
+ text: string;
10
+ structured?: unknown;
11
+ artifacts?: readonly {
12
+ id: string;
13
+ mimeType?: string;
14
+ }[];
15
+ reason?: HarnessReason;
16
+ usage: TokenUsage;
17
+ runId: string;
18
+ sessionId: string;
19
+ finalCursor: number;
20
+ cleanupDiagnostics?: readonly string[];
21
+ }
22
+ export type HarnessEventPayload = {
23
+ type: "run.started";
24
+ driverId: string;
25
+ } | {
26
+ type: "text.delta";
27
+ text: string;
28
+ } | {
29
+ type: "model.complete";
30
+ providerId: string;
31
+ modelId: string;
32
+ usage: TokenUsage;
33
+ } | {
34
+ type: "tool.complete";
35
+ toolName: string;
36
+ toolCallId: string;
37
+ denied: boolean;
38
+ } | {
39
+ type: "control";
40
+ operation: "cancel" | "follow_up" | "steer" | "replace";
41
+ reason?: string;
42
+ } | {
43
+ type: "completion";
44
+ action: string;
45
+ reason: string;
46
+ } | {
47
+ type: "run.terminal";
48
+ result: HarnessResult;
49
+ };
50
+ export interface HarnessEvent {
51
+ schemaVersion: 1;
52
+ eventId: string;
53
+ sequence: number;
54
+ timestamp: number;
55
+ sessionId: string;
56
+ runId: string;
57
+ attemptId: string;
58
+ parentRunId?: string;
59
+ rootRunId: string;
60
+ payload: HarnessEventPayload;
61
+ }
62
+ export declare class HarnessEventGapError extends Error {
63
+ readonly earliestCursor: number;
64
+ readonly code = "event_gap";
65
+ constructor(earliestCursor: number);
66
+ }
67
+ /** Bounded in-process history; no durability, network delivery, or audio backpressure promise. */
68
+ export declare class InMemoryHarnessEventStore {
69
+ private identity;
70
+ readonly capacity: number;
71
+ readonly durable = false;
72
+ private history;
73
+ private sequence;
74
+ private finished;
75
+ private listeners;
76
+ constructor(identity: Omit<HarnessEvent, "schemaVersion" | "eventId" | "sequence" | "timestamp" | "payload">, capacity?: number);
77
+ get cursor(): number;
78
+ append(payload: HarnessEventPayload): HarnessEvent;
79
+ events(options?: {
80
+ after?: number;
81
+ }): AsyncGenerator<HarnessEvent>;
82
+ }
83
+ //# sourceMappingURL=events.d.ts.map
@@ -0,0 +1,9 @@
1
+ export * from "./context-policy.cjs";
2
+ export * from "./controller.cjs";
3
+ export * from "./driver.cjs";
4
+ export * from "./events.cjs";
5
+ export * from "./resolve.cjs";
6
+ export * from "./runtime-registry.cjs";
7
+ export * from "./session-bindings.cjs";
8
+ export * from "./types.cjs";
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,10 @@
1
+ import type { RunContext } from "@agentium/core";
2
+ export { validateConversationTransform as validateHarnessMessages } from "@agentium/core";
3
+ import type { ChatMessage, ModelResponse, ToolCallResult } from "@agentium/core";
4
+ import type { HarnessMiddleware } from "./types.cjs";
5
+ /** Stable topological sort; declaration order breaks ties between ready nodes. */
6
+ export declare function sortHarnessMiddleware(middleware: readonly HarnessMiddleware[]): HarnessMiddleware[];
7
+ export declare function runBeforeModel(middleware: readonly HarnessMiddleware[], messages: readonly ChatMessage[], ctx: RunContext): Promise<ChatMessage[]>;
8
+ export declare function runAfterModel(middleware: readonly HarnessMiddleware[], response: ModelResponse, ctx: RunContext): Promise<void>;
9
+ export declare function runAfterTool(middleware: readonly HarnessMiddleware[], result: ToolCallResult, ctx: RunContext): Promise<void>;
10
+ //# sourceMappingURL=middleware.d.ts.map
@@ -0,0 +1,20 @@
1
+ import type { RunContext } from "@agentium/core";
2
+ import { type HarnessRuntimeRegistry } from "./runtime-registry.cjs";
3
+ import type { AbilityFactory, BoundHarness, HarnessDefinition, HarnessDefinitionInput, HarnessDescription, HarnessDiagnostic, HarnessExtension, HarnessManifest, ResolvedHarness } from "./types.cjs";
4
+ export declare class HarnessValidationError extends Error {
5
+ readonly diagnostics: readonly HarnessDiagnostic[];
6
+ constructor(path: string, message: string, code?: string);
7
+ }
8
+ export declare function validateHarnessManifest(input: unknown): HarnessManifest;
9
+ export declare function loadHarnessManifest(input: unknown, factories: readonly AbilityFactory[], runtimeRegistry?: HarnessRuntimeRegistry): HarnessDefinition;
10
+ export declare function createHarnessDefinition(input: HarnessDefinitionInput): HarnessDefinition;
11
+ export declare function extendHarnessDefinition(base: HarnessDefinition, extension: HarnessExtension): HarnessDefinition;
12
+ export declare function describeHarnessDefinition(input: HarnessDefinition): HarnessDescription;
13
+ export declare function resolveHarness(input: HarnessDefinition, options: {
14
+ projectRoot: string;
15
+ requirements?: readonly string[];
16
+ }): ResolvedHarness;
17
+ export declare function exportHarnessManifest(input: HarnessDefinition): HarnessManifest;
18
+ export declare function hashHarnessManifest(input: HarnessManifest): string;
19
+ export declare function bindHarness(resolved: ResolvedHarness, ctx: RunContext): Promise<BoundHarness>;
20
+ //# sourceMappingURL=resolve.d.ts.map
@@ -0,0 +1,35 @@
1
+ import type { ContextPolicy } from "./context-policy.cjs";
2
+ import type { CompletionPolicy, StepController } from "./controller.cjs";
3
+ import type { ExecutionDriver } from "./driver.cjs";
4
+ import type { HarnessDefinition } from "./types.cjs";
5
+ export interface HarnessRegistryReference {
6
+ id: string;
7
+ version: number;
8
+ }
9
+ export interface HarnessRuntimeReferences {
10
+ driver?: HarnessRegistryReference;
11
+ controller?: HarnessRegistryReference;
12
+ contextPolicy?: HarnessRegistryReference;
13
+ completionPolicy?: HarnessRegistryReference;
14
+ /** Role -> approved host binding name; credentials/providers stay host-owned. */
15
+ modelRoles?: Readonly<Record<string, string>>;
16
+ }
17
+ export interface HarnessRuntimeBindings {
18
+ driver?: ExecutionDriver;
19
+ controller?: StepController;
20
+ contextPolicy?: ContextPolicy;
21
+ completionPolicy?: CompletionPolicy;
22
+ modelRoles?: Readonly<Record<string, string>>;
23
+ }
24
+ export interface HarnessRegistryEntry<T> extends HarnessRegistryReference {
25
+ implementation: T;
26
+ }
27
+ export interface HarnessRuntimeRegistry {
28
+ driver?: readonly HarnessRegistryEntry<ExecutionDriver>[];
29
+ controller?: readonly HarnessRegistryEntry<StepController>[];
30
+ contextPolicy?: readonly HarnessRegistryEntry<ContextPolicy>[];
31
+ completionPolicy?: readonly HarnessRegistryEntry<CompletionPolicy>[];
32
+ }
33
+ /** Registry resolution is static; it never initializes providers or executes drivers. */
34
+ export declare function resolveHarnessRuntime(definition: HarnessDefinition): HarnessRuntimeBindings;
35
+ //# sourceMappingURL=runtime-registry.d.ts.map
@@ -0,0 +1,60 @@
1
+ import type { ChatMessage } from "@agentium/core";
2
+ export interface HarnessIdentity {
3
+ userId: string;
4
+ tenantId: string;
5
+ }
6
+ export interface HarnessSessionSnapshot {
7
+ conversations?: Record<string, ChatMessage[]>;
8
+ history: ChatMessage[];
9
+ state: Record<string, unknown>;
10
+ revision: number;
11
+ replayable: boolean;
12
+ }
13
+ export interface HarnessSessionLease {
14
+ read(): HarnessSessionSnapshot;
15
+ commit(snapshot: Omit<HarnessSessionSnapshot, "revision">): void;
16
+ release(): void;
17
+ }
18
+ export declare class HarnessSessionConflict extends Error {
19
+ readonly code = "session_conflict";
20
+ constructor();
21
+ }
22
+ export interface HarnessSessionStore {
23
+ readonly guarantees: {
24
+ durable: boolean;
25
+ compareAndSwap: boolean;
26
+ singleWriter: "process" | "distributed";
27
+ };
28
+ acquire(identity: HarnessIdentity, sessionId: string): Promise<HarnessSessionLease>;
29
+ }
30
+ export declare function harnessSessionKey(identity: HarnessIdentity, sessionId: string): string;
31
+ /** One writer per scoped session; deliberately rejects rather than silently interleaving. */
32
+ export declare class InMemoryHarnessSessionStore implements HarnessSessionStore {
33
+ readonly guarantees: {
34
+ durable: boolean;
35
+ compareAndSwap: boolean;
36
+ singleWriter: "process";
37
+ };
38
+ private records;
39
+ private active;
40
+ acquire(identity: HarnessIdentity, sessionId: string): Promise<HarnessSessionLease>;
41
+ /** Imported display-only transcripts are readable but never represented as complete replay state. */
42
+ importLegacy(identity: HarnessIdentity, sessionId: string, history: ChatMessage[]): void;
43
+ }
44
+ export interface ScopedResource<T = unknown> {
45
+ value: T;
46
+ ownership: "host" | "runtime";
47
+ dispose?: () => Promise<void>;
48
+ }
49
+ export interface SessionResourceLease<T> {
50
+ value: T;
51
+ release: () => Promise<void>;
52
+ }
53
+ /** Session resources live until explicit closeSession; run resources use their returned lease. */
54
+ export declare class HarnessResourcePool {
55
+ private sessions;
56
+ private pending;
57
+ acquire<T>(identity: HarnessIdentity, sessionId: string, id: string, scope: "host" | "session" | "run", initialize: () => Promise<ScopedResource<T>>): Promise<SessionResourceLease<T>>;
58
+ closeSession(identity: HarnessIdentity, sessionId: string): Promise<readonly string[]>;
59
+ }
60
+ //# sourceMappingURL=session-bindings.d.ts.map
@@ -0,0 +1,176 @@
1
+ import type { ChatMessage, ModelResponse, RunContext, ToolCallResult, ToolDef } from "@agentium/core";
2
+ import type { HarnessRuntimeBindings, HarnessRuntimeReferences, HarnessRuntimeRegistry } from "./runtime-registry.cjs";
3
+ export type JsonValue = null | boolean | number | string | JsonValue[] | {
4
+ [key: string]: JsonValue;
5
+ };
6
+ export type JsonObject = {
7
+ [key: string]: JsonValue;
8
+ };
9
+ export interface AbilitySelection {
10
+ instanceId: string;
11
+ type: string;
12
+ version: number;
13
+ options: JsonObject;
14
+ }
15
+ export interface HarnessDefaults {
16
+ workspace?: false | {
17
+ path: string;
18
+ mode: "read" | "write";
19
+ };
20
+ skillDirs?: readonly string[] | false;
21
+ contextFiles?: boolean;
22
+ filesystem?: boolean;
23
+ subagents?: boolean;
24
+ fileMemory?: boolean;
25
+ searchPastSessions?: boolean;
26
+ }
27
+ export interface HarnessManifest {
28
+ contractVersion: 1;
29
+ runtime?: HarnessRuntimeReferences;
30
+ id: string;
31
+ abilities: readonly AbilitySelection[];
32
+ defaults?: HarnessDefaults;
33
+ limits?: {
34
+ toolRoundtrips?: number;
35
+ maxChildDepth?: number;
36
+ };
37
+ }
38
+ export interface PromptFragment {
39
+ id: string;
40
+ text: string;
41
+ }
42
+ export interface HarnessContextBudget {
43
+ maxEntries: number;
44
+ maxBytes: number;
45
+ maxTokens?: number;
46
+ deadlineMs: number;
47
+ }
48
+ export interface HarnessContextEntry {
49
+ id: string;
50
+ text: string;
51
+ trust: "host" | "source";
52
+ source?: {
53
+ uri: string;
54
+ version?: string;
55
+ locator?: string;
56
+ };
57
+ expiresAt?: number;
58
+ estimatedTokens?: number;
59
+ byteLength: number;
60
+ }
61
+ export interface HarnessContextSource {
62
+ id: string;
63
+ fetch: (query: string, ctx: RunContext, budget: HarnessContextBudget) => Promise<readonly HarnessContextEntry[]>;
64
+ }
65
+ export interface HarnessMiddleware {
66
+ id: string;
67
+ before?: readonly string[];
68
+ after?: readonly string[];
69
+ beforeModel?: (messages: readonly ChatMessage[], ctx: RunContext) => Promise<ChatMessage[]>;
70
+ afterModel?: (response: ModelResponse, ctx: RunContext) => Promise<void>;
71
+ afterTool?: (result: ToolCallResult, ctx: RunContext) => Promise<void>;
72
+ }
73
+ export interface AbilityBinding {
74
+ tools: readonly ToolDef[];
75
+ promptFragments?: readonly PromptFragment[];
76
+ contextSources?: readonly HarnessContextSource[];
77
+ middleware?: readonly HarnessMiddleware[];
78
+ dispose?: () => Promise<void>;
79
+ }
80
+ export interface AbilityDescription {
81
+ toolNames: readonly string[];
82
+ requirements: readonly string[];
83
+ runtimeDependent?: boolean;
84
+ }
85
+ export interface AbilityFactory {
86
+ type: string;
87
+ version: number;
88
+ validateOptions: (input: JsonObject) => JsonObject;
89
+ describe: (options: JsonObject) => AbilityDescription;
90
+ bind: (options: JsonObject, ctx: RunContext) => Promise<AbilityBinding>;
91
+ }
92
+ export interface LocalAbilityUse {
93
+ instanceId: string;
94
+ validate: () => void;
95
+ describe: () => AbilityDescription;
96
+ bind: (ctx: RunContext) => Promise<AbilityBinding>;
97
+ portable?: AbilitySelection;
98
+ /** Trusted factory approved by the creator/host, never recovered from JSON. */
99
+ factory?: AbilityFactory;
100
+ }
101
+ export type HarnessDefinition = {
102
+ readonly kind: "portable";
103
+ readonly manifest: HarnessManifest;
104
+ readonly factories: readonly AbilityFactory[];
105
+ readonly runtimeRegistry?: HarnessRuntimeRegistry;
106
+ } | {
107
+ readonly kind: "local";
108
+ readonly id?: string;
109
+ readonly abilities: readonly LocalAbilityUse[];
110
+ readonly defaults?: HarnessDefaults;
111
+ readonly limits?: HarnessManifest["limits"];
112
+ readonly runtime?: HarnessRuntimeBindings;
113
+ readonly runtimeReferences?: HarnessRuntimeReferences;
114
+ readonly runtimeRegistry?: HarnessRuntimeRegistry;
115
+ };
116
+ export type HarnessDefinitionInput = HarnessDefinition | {
117
+ id?: string;
118
+ abilities?: readonly LocalAbilityUse[];
119
+ defaults?: HarnessDefaults;
120
+ limits?: HarnessManifest["limits"];
121
+ runtime?: HarnessRuntimeBindings;
122
+ runtimeReferences?: HarnessRuntimeReferences;
123
+ runtimeRegistry?: HarnessRuntimeRegistry;
124
+ };
125
+ export interface HarnessExtension {
126
+ runtime?: HarnessRuntimeBindings;
127
+ runtimeReferences?: HarnessRuntimeReferences;
128
+ runtimeRegistry?: HarnessRuntimeRegistry;
129
+ id?: string;
130
+ abilities?: readonly LocalAbilityUse[];
131
+ disable?: readonly string[];
132
+ replaceAbilities?: readonly LocalAbilityUse[];
133
+ defaults?: HarnessDefaults;
134
+ limits?: HarnessManifest["limits"];
135
+ }
136
+ export interface HarnessDiagnostic {
137
+ code: string;
138
+ path: string;
139
+ message: string;
140
+ severity: "info" | "warning" | "error";
141
+ }
142
+ export interface HarnessDescription {
143
+ id: string;
144
+ kind: "portable" | "local";
145
+ contractVersion: 1;
146
+ abilities: readonly (AbilityDescription & {
147
+ instanceId: string;
148
+ type?: string;
149
+ version?: number;
150
+ })[];
151
+ toolNames: readonly string[];
152
+ requirements: readonly string[];
153
+ runtimeDependent: boolean;
154
+ defaults: HarnessDefaults;
155
+ limits: NonNullable<HarnessManifest["limits"]>;
156
+ diagnostics: readonly HarnessDiagnostic[];
157
+ }
158
+ export interface HarnessProvenance {
159
+ path: string;
160
+ origin: string;
161
+ }
162
+ export interface ResolvedHarness {
163
+ readonly definition: HarnessDefinition;
164
+ readonly defaults: HarnessDefaults;
165
+ readonly limits: NonNullable<HarnessManifest["limits"]>;
166
+ readonly description: HarnessDescription;
167
+ readonly provenance: readonly HarnessProvenance[];
168
+ }
169
+ export interface BoundHarness {
170
+ readonly tools: ToolDef[];
171
+ readonly promptFragments: PromptFragment[];
172
+ readonly contextSources: HarnessContextSource[];
173
+ readonly middleware: HarnessMiddleware[];
174
+ dispose: () => Promise<readonly HarnessDiagnostic[]>;
175
+ }
176
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1,7 @@
1
+ import { type ExecutionDriver, type HarnessResult, type HarnessRuntimeConfig } from "./runtime/index.cjs";
2
+ /** No test-framework dependency. Calls the driver once and throws on violated public lifecycle invariants. */
3
+ export declare function testDriverContract(driver: ExecutionDriver, config?: Omit<HarnessRuntimeConfig, "driver">): Promise<{
4
+ result: HarnessResult;
5
+ eventCount: number;
6
+ }>;
7
+ //# sourceMappingURL=testing.d.ts.map
@@ -0,0 +1,11 @@
1
+ import type { WatchDefinition, WatchDefinitionInput } from "./types.cjs";
2
+ export declare function watchId(value: unknown): asserts value is string;
3
+ /** Pure definition: validates/copies JSON, without binding services or activating anything. */
4
+ export declare function defineWatch(input: WatchDefinitionInput): WatchDefinition;
5
+ export declare function describeWatch(definition: WatchDefinitionInput): {
6
+ definition: WatchDefinition;
7
+ hash: string;
8
+ activation: "explicit";
9
+ modelCalls: false;
10
+ };
11
+ //# sourceMappingURL=definition.d.ts.map
@@ -0,0 +1,104 @@
1
+ import type { WatchIdentity, WatchSource } from "./types.cjs";
2
+ type Result<T> = Promise<{
3
+ data: T;
4
+ }>;
5
+ type RequestOptions = {
6
+ signal: AbortSignal;
7
+ };
8
+ interface GmailMessage {
9
+ id?: string | null;
10
+ internalDate?: string | null;
11
+ snippet?: string | null;
12
+ payload?: {
13
+ headers?: Array<{
14
+ name?: string | null;
15
+ value?: string | null;
16
+ }>;
17
+ } | null;
18
+ }
19
+ /** Structural subset of an already-authenticated Gmail client; no SDK or credentials are loaded. */
20
+ export interface GmailWatchClient {
21
+ users: {
22
+ getProfile(params: {
23
+ userId: string;
24
+ }, options: RequestOptions): Result<{
25
+ historyId?: string | null;
26
+ emailAddress?: string | null;
27
+ }>;
28
+ watch(params: {
29
+ userId: string;
30
+ requestBody: {
31
+ topicName: string;
32
+ labelIds?: string[];
33
+ labelFilterBehavior?: "INCLUDE";
34
+ };
35
+ }, options: RequestOptions): Result<{
36
+ historyId?: string | null;
37
+ expiration?: string | null;
38
+ }>;
39
+ stop(params: {
40
+ userId: string;
41
+ }, options: RequestOptions): Promise<unknown>;
42
+ history: {
43
+ list(params: {
44
+ userId: string;
45
+ startHistoryId: string;
46
+ historyTypes: string[];
47
+ maxResults: number;
48
+ pageToken?: string;
49
+ }, options: RequestOptions): Result<{
50
+ historyId?: string | null;
51
+ nextPageToken?: string | null;
52
+ history?: Array<{
53
+ id?: string | null;
54
+ messagesAdded?: Array<{
55
+ message?: {
56
+ id?: string | null;
57
+ labelIds?: string[] | null;
58
+ } | null;
59
+ }>;
60
+ }>;
61
+ }>;
62
+ };
63
+ messages: {
64
+ list(params: {
65
+ userId: string;
66
+ maxResults: number;
67
+ pageToken?: string;
68
+ labelIds?: string[];
69
+ }, options: RequestOptions): Result<{
70
+ messages?: Array<{
71
+ id?: string | null;
72
+ }>;
73
+ nextPageToken?: string | null;
74
+ }>;
75
+ get(params: {
76
+ userId: string;
77
+ id: string;
78
+ format: "metadata";
79
+ metadataHeaders: string[];
80
+ }, options: RequestOptions): Result<GmailMessage>;
81
+ };
82
+ };
83
+ }
84
+ export interface GmailWatchOptions {
85
+ id: string;
86
+ mailbox: string;
87
+ identity: WatchIdentity;
88
+ topicName: string;
89
+ labelIds?: string[];
90
+ client: GmailWatchClient;
91
+ /** Host verifies Pub/Sub signature, audience and subscription ownership before decoding. */
92
+ verifyPush?: (raw: unknown) => Promise<{
93
+ identity: WatchIdentity;
94
+ messageId: string;
95
+ data: {
96
+ emailAddress: string;
97
+ historyId: string;
98
+ };
99
+ }>;
100
+ }
101
+ /** Optional Gmail source: daily renewal/polling are scheduled by DurableWatch, not in this constructor. */
102
+ export declare function gmailWatchSource(options: GmailWatchOptions): WatchSource;
103
+ export {};
104
+ //# sourceMappingURL=gmail.d.ts.map
@@ -0,0 +1,10 @@
1
+ import type { WatchQuietHours } from "./types.cjs";
2
+ export declare function watchClock(now: number, timeZone: string): {
3
+ day: string;
4
+ minute: number;
5
+ };
6
+ export declare function quietMinute(value: string): number;
7
+ export declare function isWatchQuiet(now: number, timeZone: string, quiet?: WatchQuietHours): boolean;
8
+ /** Scan actual instants: repeated local hours are both quiet; skipped boundaries advance naturally. */
9
+ export declare function nextWatchDelivery(now: number, timeZone: string, quiet?: WatchQuietHours, nextDay?: boolean): number;
10
+ //# sourceMappingURL=quiet-hours.d.ts.map
@@ -0,0 +1,42 @@
1
+ import type { WatchDefinition, WatchDefinitionInput, WatchServices, WatchState } from "./types.cjs";
2
+ /** A bounded, versioned watch. Construction is inert; all I/O requires an explicit method call. */
3
+ export declare class DurableWatch {
4
+ private readonly services;
5
+ readonly definition: WatchDefinition;
6
+ readonly key: {
7
+ tenantId: string;
8
+ taskId: string;
9
+ };
10
+ private readonly hash;
11
+ private readonly supervisor;
12
+ private readonly connectorVersion;
13
+ constructor(definition: WatchDefinitionInput, services: WatchServices);
14
+ private checkBindings;
15
+ private authorize;
16
+ private state;
17
+ private read;
18
+ private mutate;
19
+ private ensureRecord;
20
+ private owned;
21
+ private scheduleKey;
22
+ private syncSchedules;
23
+ private start;
24
+ private renewAt;
25
+ private deliveryAt;
26
+ activate(): Promise<void>;
27
+ resume(): Promise<void>;
28
+ inspect(): Promise<WatchState>;
29
+ pause(): Promise<void>;
30
+ delete(): Promise<void>;
31
+ /** Explicit fail-closed rollout. Old pending/unknown sends stay bound to the old definition. */
32
+ update(definition: WatchDefinitionInput, services?: WatchServices): Promise<DurableWatch>;
33
+ private validateCursor;
34
+ trigger(raw: unknown): Promise<void>;
35
+ poll(): Promise<void>;
36
+ renew(): Promise<void>;
37
+ /** Delivers at most one digest. It never retries an unresolved external effect. */
38
+ flush(): Promise<void>;
39
+ /** Reconciliation remains available after pause/delete/update; it never dispatches a send. */
40
+ reconcile(outboxId: string): Promise<void>;
41
+ }
42
+ //# sourceMappingURL=runtime.d.ts.map
@@ -0,0 +1,147 @@
1
+ import type { DurableActionConnector, DurableJSON, DurableTaskStore } from "@agentium/core";
2
+ export interface WatchIdentity {
3
+ tenantId: string;
4
+ actorId: string;
5
+ }
6
+ export interface WatchQuietHours {
7
+ start: string;
8
+ end: string;
9
+ }
10
+ export interface WatchLimits {
11
+ maxOperations: number;
12
+ maxWakes: number;
13
+ maxEventsPerWake: number;
14
+ maxPagesPerWake: number;
15
+ maxResyncEvents: number;
16
+ maxPendingEvents: number;
17
+ maxDecisions: number;
18
+ maxOutbox: number;
19
+ maxEventBytes: number;
20
+ maxStateBytes: number;
21
+ maxNotificationsPerDay: number;
22
+ }
23
+ export interface WatchDefinition {
24
+ id: string;
25
+ version: number;
26
+ identity: WatchIdentity;
27
+ sourceId: string;
28
+ sourceScope: string;
29
+ destination: string;
30
+ channel: string;
31
+ policyRevision: number;
32
+ grantRefs: string[];
33
+ timeZone: string;
34
+ quietHours?: WatchQuietHours;
35
+ pollIntervalMs: number;
36
+ renewalIntervalMs: number;
37
+ cooldownMs: number;
38
+ limits: WatchLimits;
39
+ }
40
+ export type WatchDefinitionInput = Omit<WatchDefinition, "limits" | "pollIntervalMs" | "renewalIntervalMs" | "cooldownMs"> & {
41
+ limits?: Partial<WatchLimits>;
42
+ pollIntervalMs?: number;
43
+ renewalIntervalMs?: number;
44
+ cooldownMs?: number;
45
+ };
46
+ export interface WatchEvent {
47
+ id: string;
48
+ occurredAt: number;
49
+ data: DurableJSON;
50
+ }
51
+ export interface WatchSubscription {
52
+ reference: string;
53
+ expiresAt: number;
54
+ }
55
+ export interface WatchSourceBatch {
56
+ cursor: string;
57
+ events: WatchEvent[];
58
+ resynced: boolean;
59
+ }
60
+ export interface VerifiedWatchTrigger extends WatchIdentity {
61
+ sourceId: string;
62
+ sourceScope: string;
63
+ eventId: string;
64
+ cursor: string;
65
+ }
66
+ /** A scoped, host-owned source. Implementations must honor read bounds before returning a cursor. */
67
+ export interface WatchSource {
68
+ id: string;
69
+ scope: string;
70
+ capabilities: {
71
+ idempotentActivation: true;
72
+ polling: true;
73
+ push: boolean;
74
+ };
75
+ baseline(signal: AbortSignal): Promise<string>;
76
+ activate(key: string, signal: AbortSignal): Promise<WatchSubscription>;
77
+ stop(subscription: WatchSubscription | null, signal: AbortSignal): Promise<void>;
78
+ read(cursor: string, limits: Pick<WatchLimits, "maxEventsPerWake" | "maxPagesPerWake" | "maxResyncEvents">, signal: AbortSignal): Promise<WatchSourceBatch>;
79
+ compareCursors(left: string, right: string): number;
80
+ /** Verify signature/audience and authenticated mailbox ownership before returning a trusted hint. */
81
+ verifyTrigger?(raw: unknown): Promise<VerifiedWatchTrigger>;
82
+ }
83
+ export type WatchScheduleKind = "poll" | "renew" | "flush";
84
+ export interface WatchSchedule {
85
+ key: string;
86
+ identity: WatchIdentity;
87
+ watchId: string;
88
+ configVersion: number;
89
+ kind: WatchScheduleKind;
90
+ at: number;
91
+ }
92
+ export interface WatchScheduler {
93
+ capabilities: {
94
+ durable: boolean;
95
+ idempotentUpsert: true;
96
+ };
97
+ schedule(job: WatchSchedule): Promise<void>;
98
+ cancel(key: string): Promise<void>;
99
+ }
100
+ export type WatchOperation = "activate" | "update" | "pause" | "resume" | "delete" | "trigger" | "poll" | "renew" | "flush" | "reconcile" | "inspect";
101
+ export interface WatchAuthorization {
102
+ operation: WatchOperation;
103
+ definition: Readonly<WatchDefinition>;
104
+ /** Notification count includes digests; authorization must validate destination/channel and amount. */
105
+ notifications: number;
106
+ events: number;
107
+ }
108
+ export interface WatchServices {
109
+ store: DurableTaskStore;
110
+ source: WatchSource;
111
+ scheduler: WatchScheduler;
112
+ notifications: DurableActionConnector & {
113
+ channel: string;
114
+ destination: string;
115
+ };
116
+ /** Trusted host authority, including exclusive ownership of a source mailbox where required. */
117
+ authorize(request: WatchAuthorization): Promise<boolean>;
118
+ /** Deterministic local classification only; no model/network work in this callback. */
119
+ filter?(event: Readonly<WatchEvent>): boolean;
120
+ leaseMs?: number;
121
+ requireDurability?: boolean;
122
+ }
123
+ export interface WatchOutbox {
124
+ id: string;
125
+ eventIds: string[];
126
+ events: WatchEvent[];
127
+ state: "pending" | "confirmed";
128
+ reservedDay: string | null;
129
+ resultRef: string | null;
130
+ }
131
+ export interface WatchState {
132
+ status: "inactive" | "activating" | "active" | "paused" | "deleted";
133
+ cursor: string | null;
134
+ subscription: WatchSubscription | null;
135
+ wakes: number;
136
+ decisions: Record<string, {
137
+ id: string;
138
+ decision: "pending" | "ignored" | "resync" | "outbox";
139
+ at: number;
140
+ }>;
141
+ pending: WatchEvent[];
142
+ outbox: Record<string, WatchOutbox>;
143
+ daily: Record<string, number>;
144
+ cooldownUntil: number;
145
+ schedules: Partial<Record<WatchScheduleKind, number>>;
146
+ }
147
+ //# sourceMappingURL=types.d.ts.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agentium/harness",
3
- "version": "4.1.0",
3
+ "version": "4.5.0",
4
4
  "description": "Composable harness developer kit for Agentium tools, context, middleware and presets",
5
5
  "license": "MIT",
6
6
  "publishConfig": {
@@ -25,15 +25,25 @@
25
25
  "types": "./dist/index.d.ts",
26
26
  "exports": {
27
27
  ".": {
28
- "types": "./dist/index.d.ts",
29
- "import": "./dist/index.js",
30
- "require": "./dist/index.cjs",
28
+ "import": {
29
+ "types": "./dist/index.d.ts",
30
+ "default": "./dist/index.js"
31
+ },
32
+ "require": {
33
+ "types": "./dist/index.d.cts",
34
+ "default": "./dist/index.cjs"
35
+ },
31
36
  "default": "./dist/index.js"
32
37
  },
33
38
  "./testing": {
34
- "types": "./dist/testing.d.ts",
35
- "import": "./dist/testing.js",
36
- "require": "./dist/testing.cjs",
39
+ "import": {
40
+ "types": "./dist/testing.d.ts",
41
+ "default": "./dist/testing.js"
42
+ },
43
+ "require": {
44
+ "types": "./dist/testing.d.cts",
45
+ "default": "./dist/testing.cjs"
46
+ },
37
47
  "default": "./dist/testing.js"
38
48
  }
39
49
  },
@@ -41,13 +51,13 @@
41
51
  "dist"
42
52
  ],
43
53
  "scripts": {
44
- "build": "tsdown --config ../../tsdown.config.ts && tsc -p tsconfig.build.json --emitDeclarationOnly --declaration --pretty false",
54
+ "build": "tsdown --config ../../tsdown.config.ts && tsc -p tsconfig.build.json --emitDeclarationOnly --declaration --pretty false && node ../../scripts/cjs-declarations.mjs",
45
55
  "dev": "tsdown --config ../../tsdown.config.ts --watch",
46
56
  "prepublishOnly": "npm run build",
47
57
  "test:package": "cd ../.. && AGENTIUM_TEST_PACKAGES=1 vitest run packages/harness/src/__tests__/package-consumption.test.ts"
48
58
  },
49
59
  "peerDependencies": {
50
- "@agentium/core": "^4.1.0"
60
+ "@agentium/core": "^4.5.0"
51
61
  },
52
62
  "dependencies": {
53
63
  "zod": "^4.6.5"