@nightowlsdev/engine-ai-sdk 0.1.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.
- package/LICENSE +21 -0
- package/README.md +119 -0
- package/dist/index.cjs +1360 -0
- package/dist/index.d.cts +210 -0
- package/dist/index.d.ts +210 -0
- package/dist/index.js +1349 -0
- package/package.json +53 -0
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
import { EngineCapabilities, Engine, AssembledEngineOpts, RunInput, SwarmContext, SwarmEvent, SwarmMessage, ThreadSummary, ScratchpadEntry, ActiveRun, AgentSummary } from '@nightowlsdev/core';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The AI-SDK-native engine's static capability descriptor (P3 v0). Tier 3 declared with
|
|
5
|
+
* `swarm.handoff` absent from `emits` — handoff is delegation-only (this engine's `delegation` is
|
|
6
|
+
* `false`); `emits` is authoritative over the declared tier for which events actually stream.
|
|
7
|
+
*
|
|
8
|
+
* Kept in its OWN module (not `index.ts`) so `src/engine.ts` (Task 5+) can import it without a
|
|
9
|
+
* circular dependency once `index.ts`'s `aiSdkEngine()` factory constructs `AiSdkEngine` directly
|
|
10
|
+
* (Task 10) — `index.ts` re-exports this same constant, so the public export path
|
|
11
|
+
* (`@nightowlsdev/engine-ai-sdk`'s `AI_SDK_ENGINE_CAPABILITIES`) is unchanged.
|
|
12
|
+
*/
|
|
13
|
+
declare const AI_SDK_ENGINE_CAPABILITIES: EngineCapabilities;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* The AI-SDK-native engine (P3) — a governed `ai@^6` `streamText` turn loop behind the `Engine` seam, single-
|
|
17
|
+
* agent v1 (no delegation/workflows). `run()` carries the full pre-loop + lifecycle scaffolding (rows, floor
|
|
18
|
+
* serialization, the preGeneration reserve, the persisted-not-yielded user message, telemetry spans); `resume()`
|
|
19
|
+
* recovers a parked run's snapshot, turns the human/approval/client answer into the tool-call's result, and
|
|
20
|
+
* re-enters the SAME governed loop (`drive()`) from there. Both share `drive()`: tool assembly (Task 4),
|
|
21
|
+
* system-prompt assembly (Task 3), the `streamText` multi-step loop, per-generation metering + cost caps,
|
|
22
|
+
* mid-stream cancellation, completion supervision (nudge-on-incomplete), and suspend/resume parking (ask /
|
|
23
|
+
* native tool approvals / client actions).
|
|
24
|
+
*/
|
|
25
|
+
declare class AiSdkEngine implements Engine {
|
|
26
|
+
private readonly opts;
|
|
27
|
+
readonly capabilities: EngineCapabilities;
|
|
28
|
+
private readonly hooks;
|
|
29
|
+
private readonly floor;
|
|
30
|
+
private readonly telemetry;
|
|
31
|
+
constructor(opts: AssembledEngineOpts, extra: {
|
|
32
|
+
durable: boolean;
|
|
33
|
+
});
|
|
34
|
+
/**
|
|
35
|
+
* SP2 — the preGeneration DECISION seam, awaited immediately before every model launch. Verbatim mirror of
|
|
36
|
+
* the reference engine's private `guardGeneration` (`packages/core/src/engine.ts:543-553`): the dispatcher is
|
|
37
|
+
* fail-closed (a throwing hook ⇒ deny), so this only ever sees a clean allow/deny; a deny THROWS
|
|
38
|
+
* `ReserveDenied` (re-exported from core, not redefined here) so the caller's model launch never happens and
|
|
39
|
+
* the run/resume catch-all maps it to a terminal `run_failed` stage `"reserve"` (never the generic
|
|
40
|
+
* `"exception"`).
|
|
41
|
+
*/
|
|
42
|
+
private guardGeneration;
|
|
43
|
+
/**
|
|
44
|
+
* SP5 truth-fix — resolve whether a tool WILL require approval, for the `swarm.tool_call` event's advisory
|
|
45
|
+
* `needsApproval` field. Verbatim mirror of the reference engine's private `gatesApproval`
|
|
46
|
+
* (`packages/core/src/engine.ts:528-534`): the tool's resolved `needsApproval` (its own flag, defaulting by
|
|
47
|
+
* origin) run through the dispatcher's SYNC `policyDecision` (`ask` ⇒ true). The async `preToolCall` hook can
|
|
48
|
+
* still escalate a specific call at execute time (that's what actually drives the tool's native pause — see
|
|
49
|
+
* `tools.ts`'s `buildServerTool`); this is only the truthful baseline the event carries.
|
|
50
|
+
*/
|
|
51
|
+
private gatesApproval;
|
|
52
|
+
/**
|
|
53
|
+
* T9 (T8-review fix) — best-effort recall of the thread's request text for the completion verifier's
|
|
54
|
+
* `request` param on RESUME (the engine doesn't hold the original prompt there — `resume()` only carries the
|
|
55
|
+
* suspended tool's answer). Mirrors the reference engine's `recallRequest`, but deliberately the LAST user
|
|
56
|
+
* turn (not the first): a resume continues whichever prompt MOST RECENTLY triggered this run, not the
|
|
57
|
+
* thread's opening message. Fail-safe: gated behind `verifyCompletion` (a no-verifier config never pays for
|
|
58
|
+
* the read) and never throws — any failure yields `""`, matching the reference's own fallback.
|
|
59
|
+
*/
|
|
60
|
+
private recallRequest;
|
|
61
|
+
/** Run the completion supervisor (`EngineOpts.verifyCompletion`), FAIL-OPEN: no verifier, or a throwing one,
|
|
62
|
+
* yields `{ complete: true }` so a missing/broken judge never traps a run in a verify loop. Mirrors the
|
|
63
|
+
* reference engine's private `safeVerify`. */
|
|
64
|
+
private safeVerify;
|
|
65
|
+
/** FR-024 — resolve the host's per-run advisory system-context block. FAIL-SAFE: a throwing/rejecting resolver
|
|
66
|
+
* is swallowed (logged) and yields no block, so a broken context source never breaks the run. Mirrors the
|
|
67
|
+
* reference engine's private `safeSystemContext`. */
|
|
68
|
+
private safeSystemContext;
|
|
69
|
+
/** FR-027 — resolve the host's opt-in per-request instruction-only (dynamic/imported) skills, by name.
|
|
70
|
+
* FAIL-SAFE: a throwing/rejecting resolver yields no dynamic skills (never breaks the run). No memoization —
|
|
71
|
+
* v1 has no delegation, so there is only ever ONE resolution per segment (no sub-agent to share it with);
|
|
72
|
+
* re-resolved fresh on every `resume()` segment too (never carried over the suspend boundary). */
|
|
73
|
+
private safeDynamicSkills;
|
|
74
|
+
/**
|
|
75
|
+
* Resolve the CONCRETE model instance for one generation launch: tier routing (a sentinel `modelId` routes to
|
|
76
|
+
* the configured tier; a concrete pin passes verbatim), THEN the allow-list `opts.model.resolve` (a deny
|
|
77
|
+
* throws — this is the security-critical re-validation the plan calls out: EVERY resolved id, tier-routed or
|
|
78
|
+
* not, goes through the allow-list, never just the stored one), THEN `opts.modelFactory`. Mirrors the
|
|
79
|
+
* reference engine's private `modelFor` (`packages/core/src/mastra-map.ts:284-292`). Called once for the
|
|
80
|
+
* `streamText` call's outer `model` field AND again from `prepareStep` for EVERY step (including the first) —
|
|
81
|
+
* so a revoked/rotated allow-list entry is caught mid-run, not just at the top of the segment.
|
|
82
|
+
*/
|
|
83
|
+
private resolveModel;
|
|
84
|
+
/** Build this segment's `ToolAssemblyOpts` — identical wiring for `run()` and `resume()` (both rebuild tools
|
|
85
|
+
* fresh from the CURRENT agent row; only `runCtx` differs). */
|
|
86
|
+
private toolAssemblyOpts;
|
|
87
|
+
/**
|
|
88
|
+
* The shared governed `streamText` drive — Task 6's loop, generalized so both `run()` (segmentIndex 0) and
|
|
89
|
+
* `resume()` (segmentIndex = the snapshot's genIndex) call the SAME implementation: per-step metering + cost
|
|
90
|
+
* caps, mid-stream cancellation, suspend-parking (ask / native tool approvals / client actions), and
|
|
91
|
+
* completion-supervisor nudging. Returns the segment's terminal outcome as the generator's return value (the
|
|
92
|
+
* caller captures it via `const outcome = yield* this.drive(...)`); every terminal event (`done`/`run_failed`/
|
|
93
|
+
* `run_cancelled`/the park's `waiting`+`question`/`client_action`) is yielded from INSIDE this loop — the
|
|
94
|
+
* caller only needs the returned outcome for its own `onRunEnd` reporting.
|
|
95
|
+
*/
|
|
96
|
+
private drive;
|
|
97
|
+
run(input: RunInput, ctx: SwarmContext, signal?: AbortSignal): AsyncIterable<SwarmEvent>;
|
|
98
|
+
/**
|
|
99
|
+
* Resume a parked run: `markFollowupAnswered` EARLY (CAS, replay-safe) → `loadSnapshot` → reload the agent
|
|
100
|
+
* row fresh (same as `run()`) → re-acquire the floor → emit `swarm.answer` → preGeneration re-fire (kind
|
|
101
|
+
* 'resume', at the snapshot's genIndex) → per-kind append the answer to the snapshot's messages → re-enter
|
|
102
|
+
* the SHARED `drive()` with rebuilt tools (`approvedToolCallIds` pre-populated on an approval-approve, BEFORE
|
|
103
|
+
* `buildTools`/`streamText` — Task 4's blocker-fix contract) + restored messages. A re-park persists
|
|
104
|
+
* `genIndex = (this segment's own segmentIndex) + 1` — the same bookkeeping `drive()` already does for
|
|
105
|
+
* `run()`'s park, generalized.
|
|
106
|
+
*
|
|
107
|
+
* ⚠ `onRunStart` deliberately does NOT fire here — this is a CONTINUATION of the run `onRunStart` already
|
|
108
|
+
* announced (in `run()`), not a new one. Mirrors the reference (Mastra) engine exactly: `packages/core/src/
|
|
109
|
+
* engine.ts`'s own `resume()` never calls `this.opts.onRunStart` either (only `run()` does — see that file's
|
|
110
|
+
* `onRunStart` doc comment: "fires on `run()` only"). A host that seeds per-run state in `onRunStart` gets it
|
|
111
|
+
* back via `snap.state` → `resumedState` below, so nothing is lost across the suspend/resume boundary.
|
|
112
|
+
*/
|
|
113
|
+
resume(args: {
|
|
114
|
+
runId: string;
|
|
115
|
+
toolCallId: string;
|
|
116
|
+
followupId: string;
|
|
117
|
+
answer: unknown;
|
|
118
|
+
context?: Record<string, unknown>;
|
|
119
|
+
}, ctx: SwarmContext, signal?: AbortSignal): AsyncIterable<SwarmEvent>;
|
|
120
|
+
/**
|
|
121
|
+
* T9 — events-derived thread history (no Mastra memory in this engine: the events log IS the store).
|
|
122
|
+
* `container(threadId)` resolves the root container; `events.listForContainer` (optional on `StorageAdapter`
|
|
123
|
+
* — absent ⇒ `[]`, matching the reference's "no memory ⇒ []" degradation) returns the FULL container log
|
|
124
|
+
* (root + any lane sub-threads), each event tagged with its OWN run's `threadId`. Filtered LANE-EXACT to the
|
|
125
|
+
* REQUESTED `threadId` (so a root read never leaks a lane's side-chat and vice versa), then folded into
|
|
126
|
+
* `SwarmMessage[]` by `messagesFromEvents` (structural attribution; decode-only legacy prefix stripping — see
|
|
127
|
+
* its doc comment). Hard-capped to the most recent `limit` (default 200, mirrors the reference).
|
|
128
|
+
*/
|
|
129
|
+
history(threadId: string, ctx: SwarmContext, opts?: {
|
|
130
|
+
limit?: number;
|
|
131
|
+
}): Promise<SwarmMessage[]>;
|
|
132
|
+
/** T9 helper — one container's `ThreadSummary`: title = its first (oldest) user message's text, falling back
|
|
133
|
+
* to the bare container id (an empty/title-less container, matching the reference's "no Mastra row" fallback
|
|
134
|
+
* shape: `{ threadId: container, title: container, lastActivityAt: 0 }`). `lastActivityAt` = the max `seq`
|
|
135
|
+
* seen on the container's BARE (non-lane) events (T9-review fix): `seq` is the storage-assigned, GLOBALLY
|
|
136
|
+
* monotonic append counter, so a newer run's events always rank above an older run's — whereas `ts` is a
|
|
137
|
+
* per-segment ordinal (restarts at 0/1000 every segment, see `emit.ts`) and is meaningless across runs. Same
|
|
138
|
+
* seq-over-ts preference the react timeline established (react/timeline.ts). NOT a wall-clock epoch (no
|
|
139
|
+
* adapter in the `StorageAdapter` contract exposes one for runs/events) — a recency-ORDERING proxy only.
|
|
140
|
+
*/
|
|
141
|
+
private threadSummaryFor;
|
|
142
|
+
/**
|
|
143
|
+
* T9 — R14 participation-based thread listing (mirrors the reference `listThreads`, minus the Mastra memory
|
|
144
|
+
* dependency): `runs.listUserContainers` (optional) gives the containers this user has a run in,
|
|
145
|
+
* newest-active first; each is summarized via `threadSummaryFor` (concurrently, order preserved).
|
|
146
|
+
* FALLBACK (an adapter without `listUserContainers`): the reference degrades to the CURRENT container under
|
|
147
|
+
* multi-user (no cross-container Mastra listing to fall back on here either) — a single-entry list for
|
|
148
|
+
* `ctx.threadId`'s own container.
|
|
149
|
+
*/
|
|
150
|
+
listThreads(ctx: SwarmContext, opts?: {
|
|
151
|
+
limit?: number;
|
|
152
|
+
}): Promise<ThreadSummary[]>;
|
|
153
|
+
/** The PUBLIC entries of a conversation's scratchpad (empty array when the feature is off or unset).
|
|
154
|
+
* Mirrors the reference engine's `scratchpadPublic` verbatim (storage-backed, engine-neutral). */
|
|
155
|
+
scratchpadPublic(container: string, ctx: SwarmContext): Promise<ScratchpadEntry[]>;
|
|
156
|
+
/** In-flight runs (running|suspended) for a container + its lanes. Mirrors the reference engine's
|
|
157
|
+
* `activeRuns` verbatim (storage-backed, engine-neutral). */
|
|
158
|
+
activeRuns(container: string, ctx: SwarmContext): Promise<ActiveRun[]>;
|
|
159
|
+
/** The full, globally-ordered event log for a thread's CONTAINER (all its runs + lane sub-threads) — unlike
|
|
160
|
+
* `history()`, NOT lane-filtered: this is the rich raw timeline (tool calls + status, not just messages).
|
|
161
|
+
* Mirrors the reference engine's `threadEvents` verbatim (storage-backed, engine-neutral). Returns `[]` when
|
|
162
|
+
* the store has no `events.listForContainer`. */
|
|
163
|
+
threadEvents(threadId: string, ctx: SwarmContext): Promise<SwarmEvent[]>;
|
|
164
|
+
/**
|
|
165
|
+
* T9 (REQUIRED on `Engine`) — the tenant's agent roster as wall-safe `AgentSummary[]`: `agents.listSlugs` →
|
|
166
|
+
* `head` per slug (dropping any slug whose head resolves to `null`, a race with a mid-listing deletion).
|
|
167
|
+
* `delegateSlugs` is ALWAYS `[]` — a deliberate divergence from the reference engine (which surfaces the
|
|
168
|
+
* stored `AgentVersion.delegateSlugs`): this engine's `capabilities.delegation` is `false` (v1, single-agent),
|
|
169
|
+
* so there is no addressable delegate graph to report regardless of what a row happens to store.
|
|
170
|
+
*/
|
|
171
|
+
listAgents(ctx: SwarmContext): Promise<AgentSummary[]>;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Engine factory for `defineSwarm({ engine: aiSdkEngine() })` — constructs the wired `AiSdkEngine` (a
|
|
176
|
+
* governed `ai@^6` `streamText` loop, single-agent v1; see `src/engine.ts`). Mirrors the reference
|
|
177
|
+
* (Mastra) engine's own `durable` ctor param: `durableResume` is a per-INSTANCE capability flip
|
|
178
|
+
* (`AI_SDK_ENGINE_CAPABILITIES.hitl.durableResume`), never inferred from the injected `StorageAdapter`.
|
|
179
|
+
* Pass `aiSdkEngine({ durable: true })` only when that storage persists suspend/resume snapshots
|
|
180
|
+
* CROSS-PROCESS (e.g. `@nightowlsdev/storage-supabase`) — otherwise leave the default `false` so
|
|
181
|
+
* consumers (mcp-server/runner-background) keep treating `ask`/approval resumes as non-durable.
|
|
182
|
+
*/
|
|
183
|
+
declare function aiSdkEngine({ durable }?: {
|
|
184
|
+
durable?: boolean;
|
|
185
|
+
}): (opts: AssembledEngineOpts) => Engine;
|
|
186
|
+
/**
|
|
187
|
+
* The declarative Night Owls plugin manifest consumed by `@nightowlsdev/cli`. STRUCTURALLY matches the CLI's
|
|
188
|
+
* `NightOwlsPlugin` type but does NOT import it (no dependency cycle): all codegen lives in `@nightowlsdev/cli`;
|
|
189
|
+
* this adapter stays data-only.
|
|
190
|
+
*/
|
|
191
|
+
declare const nightOwlsPlugin: {
|
|
192
|
+
readonly name: "engine-ai-sdk";
|
|
193
|
+
readonly version: "0.0.0";
|
|
194
|
+
readonly kind: "engine";
|
|
195
|
+
readonly pkg: "@nightowlsdev/engine-ai-sdk";
|
|
196
|
+
readonly description: "The AI-SDK-native engine as a named engine package (single-agent v1, governed ai@6 streamText loop).";
|
|
197
|
+
readonly env: readonly [];
|
|
198
|
+
readonly config: {
|
|
199
|
+
readonly import: "import { aiSdkEngine } from \"@nightowlsdev/engine-ai-sdk\";";
|
|
200
|
+
readonly snippet: "engine = aiSdkEngine();";
|
|
201
|
+
readonly marker: "engine";
|
|
202
|
+
};
|
|
203
|
+
readonly init: (ctx: {
|
|
204
|
+
cwd: string;
|
|
205
|
+
log: (m: string) => void;
|
|
206
|
+
}) => void;
|
|
207
|
+
readonly commands: readonly [];
|
|
208
|
+
};
|
|
209
|
+
|
|
210
|
+
export { AI_SDK_ENGINE_CAPABILITIES, AiSdkEngine, aiSdkEngine, nightOwlsPlugin };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
import { EngineCapabilities, Engine, AssembledEngineOpts, RunInput, SwarmContext, SwarmEvent, SwarmMessage, ThreadSummary, ScratchpadEntry, ActiveRun, AgentSummary } from '@nightowlsdev/core';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The AI-SDK-native engine's static capability descriptor (P3 v0). Tier 3 declared with
|
|
5
|
+
* `swarm.handoff` absent from `emits` — handoff is delegation-only (this engine's `delegation` is
|
|
6
|
+
* `false`); `emits` is authoritative over the declared tier for which events actually stream.
|
|
7
|
+
*
|
|
8
|
+
* Kept in its OWN module (not `index.ts`) so `src/engine.ts` (Task 5+) can import it without a
|
|
9
|
+
* circular dependency once `index.ts`'s `aiSdkEngine()` factory constructs `AiSdkEngine` directly
|
|
10
|
+
* (Task 10) — `index.ts` re-exports this same constant, so the public export path
|
|
11
|
+
* (`@nightowlsdev/engine-ai-sdk`'s `AI_SDK_ENGINE_CAPABILITIES`) is unchanged.
|
|
12
|
+
*/
|
|
13
|
+
declare const AI_SDK_ENGINE_CAPABILITIES: EngineCapabilities;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* The AI-SDK-native engine (P3) — a governed `ai@^6` `streamText` turn loop behind the `Engine` seam, single-
|
|
17
|
+
* agent v1 (no delegation/workflows). `run()` carries the full pre-loop + lifecycle scaffolding (rows, floor
|
|
18
|
+
* serialization, the preGeneration reserve, the persisted-not-yielded user message, telemetry spans); `resume()`
|
|
19
|
+
* recovers a parked run's snapshot, turns the human/approval/client answer into the tool-call's result, and
|
|
20
|
+
* re-enters the SAME governed loop (`drive()`) from there. Both share `drive()`: tool assembly (Task 4),
|
|
21
|
+
* system-prompt assembly (Task 3), the `streamText` multi-step loop, per-generation metering + cost caps,
|
|
22
|
+
* mid-stream cancellation, completion supervision (nudge-on-incomplete), and suspend/resume parking (ask /
|
|
23
|
+
* native tool approvals / client actions).
|
|
24
|
+
*/
|
|
25
|
+
declare class AiSdkEngine implements Engine {
|
|
26
|
+
private readonly opts;
|
|
27
|
+
readonly capabilities: EngineCapabilities;
|
|
28
|
+
private readonly hooks;
|
|
29
|
+
private readonly floor;
|
|
30
|
+
private readonly telemetry;
|
|
31
|
+
constructor(opts: AssembledEngineOpts, extra: {
|
|
32
|
+
durable: boolean;
|
|
33
|
+
});
|
|
34
|
+
/**
|
|
35
|
+
* SP2 — the preGeneration DECISION seam, awaited immediately before every model launch. Verbatim mirror of
|
|
36
|
+
* the reference engine's private `guardGeneration` (`packages/core/src/engine.ts:543-553`): the dispatcher is
|
|
37
|
+
* fail-closed (a throwing hook ⇒ deny), so this only ever sees a clean allow/deny; a deny THROWS
|
|
38
|
+
* `ReserveDenied` (re-exported from core, not redefined here) so the caller's model launch never happens and
|
|
39
|
+
* the run/resume catch-all maps it to a terminal `run_failed` stage `"reserve"` (never the generic
|
|
40
|
+
* `"exception"`).
|
|
41
|
+
*/
|
|
42
|
+
private guardGeneration;
|
|
43
|
+
/**
|
|
44
|
+
* SP5 truth-fix — resolve whether a tool WILL require approval, for the `swarm.tool_call` event's advisory
|
|
45
|
+
* `needsApproval` field. Verbatim mirror of the reference engine's private `gatesApproval`
|
|
46
|
+
* (`packages/core/src/engine.ts:528-534`): the tool's resolved `needsApproval` (its own flag, defaulting by
|
|
47
|
+
* origin) run through the dispatcher's SYNC `policyDecision` (`ask` ⇒ true). The async `preToolCall` hook can
|
|
48
|
+
* still escalate a specific call at execute time (that's what actually drives the tool's native pause — see
|
|
49
|
+
* `tools.ts`'s `buildServerTool`); this is only the truthful baseline the event carries.
|
|
50
|
+
*/
|
|
51
|
+
private gatesApproval;
|
|
52
|
+
/**
|
|
53
|
+
* T9 (T8-review fix) — best-effort recall of the thread's request text for the completion verifier's
|
|
54
|
+
* `request` param on RESUME (the engine doesn't hold the original prompt there — `resume()` only carries the
|
|
55
|
+
* suspended tool's answer). Mirrors the reference engine's `recallRequest`, but deliberately the LAST user
|
|
56
|
+
* turn (not the first): a resume continues whichever prompt MOST RECENTLY triggered this run, not the
|
|
57
|
+
* thread's opening message. Fail-safe: gated behind `verifyCompletion` (a no-verifier config never pays for
|
|
58
|
+
* the read) and never throws — any failure yields `""`, matching the reference's own fallback.
|
|
59
|
+
*/
|
|
60
|
+
private recallRequest;
|
|
61
|
+
/** Run the completion supervisor (`EngineOpts.verifyCompletion`), FAIL-OPEN: no verifier, or a throwing one,
|
|
62
|
+
* yields `{ complete: true }` so a missing/broken judge never traps a run in a verify loop. Mirrors the
|
|
63
|
+
* reference engine's private `safeVerify`. */
|
|
64
|
+
private safeVerify;
|
|
65
|
+
/** FR-024 — resolve the host's per-run advisory system-context block. FAIL-SAFE: a throwing/rejecting resolver
|
|
66
|
+
* is swallowed (logged) and yields no block, so a broken context source never breaks the run. Mirrors the
|
|
67
|
+
* reference engine's private `safeSystemContext`. */
|
|
68
|
+
private safeSystemContext;
|
|
69
|
+
/** FR-027 — resolve the host's opt-in per-request instruction-only (dynamic/imported) skills, by name.
|
|
70
|
+
* FAIL-SAFE: a throwing/rejecting resolver yields no dynamic skills (never breaks the run). No memoization —
|
|
71
|
+
* v1 has no delegation, so there is only ever ONE resolution per segment (no sub-agent to share it with);
|
|
72
|
+
* re-resolved fresh on every `resume()` segment too (never carried over the suspend boundary). */
|
|
73
|
+
private safeDynamicSkills;
|
|
74
|
+
/**
|
|
75
|
+
* Resolve the CONCRETE model instance for one generation launch: tier routing (a sentinel `modelId` routes to
|
|
76
|
+
* the configured tier; a concrete pin passes verbatim), THEN the allow-list `opts.model.resolve` (a deny
|
|
77
|
+
* throws — this is the security-critical re-validation the plan calls out: EVERY resolved id, tier-routed or
|
|
78
|
+
* not, goes through the allow-list, never just the stored one), THEN `opts.modelFactory`. Mirrors the
|
|
79
|
+
* reference engine's private `modelFor` (`packages/core/src/mastra-map.ts:284-292`). Called once for the
|
|
80
|
+
* `streamText` call's outer `model` field AND again from `prepareStep` for EVERY step (including the first) —
|
|
81
|
+
* so a revoked/rotated allow-list entry is caught mid-run, not just at the top of the segment.
|
|
82
|
+
*/
|
|
83
|
+
private resolveModel;
|
|
84
|
+
/** Build this segment's `ToolAssemblyOpts` — identical wiring for `run()` and `resume()` (both rebuild tools
|
|
85
|
+
* fresh from the CURRENT agent row; only `runCtx` differs). */
|
|
86
|
+
private toolAssemblyOpts;
|
|
87
|
+
/**
|
|
88
|
+
* The shared governed `streamText` drive — Task 6's loop, generalized so both `run()` (segmentIndex 0) and
|
|
89
|
+
* `resume()` (segmentIndex = the snapshot's genIndex) call the SAME implementation: per-step metering + cost
|
|
90
|
+
* caps, mid-stream cancellation, suspend-parking (ask / native tool approvals / client actions), and
|
|
91
|
+
* completion-supervisor nudging. Returns the segment's terminal outcome as the generator's return value (the
|
|
92
|
+
* caller captures it via `const outcome = yield* this.drive(...)`); every terminal event (`done`/`run_failed`/
|
|
93
|
+
* `run_cancelled`/the park's `waiting`+`question`/`client_action`) is yielded from INSIDE this loop — the
|
|
94
|
+
* caller only needs the returned outcome for its own `onRunEnd` reporting.
|
|
95
|
+
*/
|
|
96
|
+
private drive;
|
|
97
|
+
run(input: RunInput, ctx: SwarmContext, signal?: AbortSignal): AsyncIterable<SwarmEvent>;
|
|
98
|
+
/**
|
|
99
|
+
* Resume a parked run: `markFollowupAnswered` EARLY (CAS, replay-safe) → `loadSnapshot` → reload the agent
|
|
100
|
+
* row fresh (same as `run()`) → re-acquire the floor → emit `swarm.answer` → preGeneration re-fire (kind
|
|
101
|
+
* 'resume', at the snapshot's genIndex) → per-kind append the answer to the snapshot's messages → re-enter
|
|
102
|
+
* the SHARED `drive()` with rebuilt tools (`approvedToolCallIds` pre-populated on an approval-approve, BEFORE
|
|
103
|
+
* `buildTools`/`streamText` — Task 4's blocker-fix contract) + restored messages. A re-park persists
|
|
104
|
+
* `genIndex = (this segment's own segmentIndex) + 1` — the same bookkeeping `drive()` already does for
|
|
105
|
+
* `run()`'s park, generalized.
|
|
106
|
+
*
|
|
107
|
+
* ⚠ `onRunStart` deliberately does NOT fire here — this is a CONTINUATION of the run `onRunStart` already
|
|
108
|
+
* announced (in `run()`), not a new one. Mirrors the reference (Mastra) engine exactly: `packages/core/src/
|
|
109
|
+
* engine.ts`'s own `resume()` never calls `this.opts.onRunStart` either (only `run()` does — see that file's
|
|
110
|
+
* `onRunStart` doc comment: "fires on `run()` only"). A host that seeds per-run state in `onRunStart` gets it
|
|
111
|
+
* back via `snap.state` → `resumedState` below, so nothing is lost across the suspend/resume boundary.
|
|
112
|
+
*/
|
|
113
|
+
resume(args: {
|
|
114
|
+
runId: string;
|
|
115
|
+
toolCallId: string;
|
|
116
|
+
followupId: string;
|
|
117
|
+
answer: unknown;
|
|
118
|
+
context?: Record<string, unknown>;
|
|
119
|
+
}, ctx: SwarmContext, signal?: AbortSignal): AsyncIterable<SwarmEvent>;
|
|
120
|
+
/**
|
|
121
|
+
* T9 — events-derived thread history (no Mastra memory in this engine: the events log IS the store).
|
|
122
|
+
* `container(threadId)` resolves the root container; `events.listForContainer` (optional on `StorageAdapter`
|
|
123
|
+
* — absent ⇒ `[]`, matching the reference's "no memory ⇒ []" degradation) returns the FULL container log
|
|
124
|
+
* (root + any lane sub-threads), each event tagged with its OWN run's `threadId`. Filtered LANE-EXACT to the
|
|
125
|
+
* REQUESTED `threadId` (so a root read never leaks a lane's side-chat and vice versa), then folded into
|
|
126
|
+
* `SwarmMessage[]` by `messagesFromEvents` (structural attribution; decode-only legacy prefix stripping — see
|
|
127
|
+
* its doc comment). Hard-capped to the most recent `limit` (default 200, mirrors the reference).
|
|
128
|
+
*/
|
|
129
|
+
history(threadId: string, ctx: SwarmContext, opts?: {
|
|
130
|
+
limit?: number;
|
|
131
|
+
}): Promise<SwarmMessage[]>;
|
|
132
|
+
/** T9 helper — one container's `ThreadSummary`: title = its first (oldest) user message's text, falling back
|
|
133
|
+
* to the bare container id (an empty/title-less container, matching the reference's "no Mastra row" fallback
|
|
134
|
+
* shape: `{ threadId: container, title: container, lastActivityAt: 0 }`). `lastActivityAt` = the max `seq`
|
|
135
|
+
* seen on the container's BARE (non-lane) events (T9-review fix): `seq` is the storage-assigned, GLOBALLY
|
|
136
|
+
* monotonic append counter, so a newer run's events always rank above an older run's — whereas `ts` is a
|
|
137
|
+
* per-segment ordinal (restarts at 0/1000 every segment, see `emit.ts`) and is meaningless across runs. Same
|
|
138
|
+
* seq-over-ts preference the react timeline established (react/timeline.ts). NOT a wall-clock epoch (no
|
|
139
|
+
* adapter in the `StorageAdapter` contract exposes one for runs/events) — a recency-ORDERING proxy only.
|
|
140
|
+
*/
|
|
141
|
+
private threadSummaryFor;
|
|
142
|
+
/**
|
|
143
|
+
* T9 — R14 participation-based thread listing (mirrors the reference `listThreads`, minus the Mastra memory
|
|
144
|
+
* dependency): `runs.listUserContainers` (optional) gives the containers this user has a run in,
|
|
145
|
+
* newest-active first; each is summarized via `threadSummaryFor` (concurrently, order preserved).
|
|
146
|
+
* FALLBACK (an adapter without `listUserContainers`): the reference degrades to the CURRENT container under
|
|
147
|
+
* multi-user (no cross-container Mastra listing to fall back on here either) — a single-entry list for
|
|
148
|
+
* `ctx.threadId`'s own container.
|
|
149
|
+
*/
|
|
150
|
+
listThreads(ctx: SwarmContext, opts?: {
|
|
151
|
+
limit?: number;
|
|
152
|
+
}): Promise<ThreadSummary[]>;
|
|
153
|
+
/** The PUBLIC entries of a conversation's scratchpad (empty array when the feature is off or unset).
|
|
154
|
+
* Mirrors the reference engine's `scratchpadPublic` verbatim (storage-backed, engine-neutral). */
|
|
155
|
+
scratchpadPublic(container: string, ctx: SwarmContext): Promise<ScratchpadEntry[]>;
|
|
156
|
+
/** In-flight runs (running|suspended) for a container + its lanes. Mirrors the reference engine's
|
|
157
|
+
* `activeRuns` verbatim (storage-backed, engine-neutral). */
|
|
158
|
+
activeRuns(container: string, ctx: SwarmContext): Promise<ActiveRun[]>;
|
|
159
|
+
/** The full, globally-ordered event log for a thread's CONTAINER (all its runs + lane sub-threads) — unlike
|
|
160
|
+
* `history()`, NOT lane-filtered: this is the rich raw timeline (tool calls + status, not just messages).
|
|
161
|
+
* Mirrors the reference engine's `threadEvents` verbatim (storage-backed, engine-neutral). Returns `[]` when
|
|
162
|
+
* the store has no `events.listForContainer`. */
|
|
163
|
+
threadEvents(threadId: string, ctx: SwarmContext): Promise<SwarmEvent[]>;
|
|
164
|
+
/**
|
|
165
|
+
* T9 (REQUIRED on `Engine`) — the tenant's agent roster as wall-safe `AgentSummary[]`: `agents.listSlugs` →
|
|
166
|
+
* `head` per slug (dropping any slug whose head resolves to `null`, a race with a mid-listing deletion).
|
|
167
|
+
* `delegateSlugs` is ALWAYS `[]` — a deliberate divergence from the reference engine (which surfaces the
|
|
168
|
+
* stored `AgentVersion.delegateSlugs`): this engine's `capabilities.delegation` is `false` (v1, single-agent),
|
|
169
|
+
* so there is no addressable delegate graph to report regardless of what a row happens to store.
|
|
170
|
+
*/
|
|
171
|
+
listAgents(ctx: SwarmContext): Promise<AgentSummary[]>;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Engine factory for `defineSwarm({ engine: aiSdkEngine() })` — constructs the wired `AiSdkEngine` (a
|
|
176
|
+
* governed `ai@^6` `streamText` loop, single-agent v1; see `src/engine.ts`). Mirrors the reference
|
|
177
|
+
* (Mastra) engine's own `durable` ctor param: `durableResume` is a per-INSTANCE capability flip
|
|
178
|
+
* (`AI_SDK_ENGINE_CAPABILITIES.hitl.durableResume`), never inferred from the injected `StorageAdapter`.
|
|
179
|
+
* Pass `aiSdkEngine({ durable: true })` only when that storage persists suspend/resume snapshots
|
|
180
|
+
* CROSS-PROCESS (e.g. `@nightowlsdev/storage-supabase`) — otherwise leave the default `false` so
|
|
181
|
+
* consumers (mcp-server/runner-background) keep treating `ask`/approval resumes as non-durable.
|
|
182
|
+
*/
|
|
183
|
+
declare function aiSdkEngine({ durable }?: {
|
|
184
|
+
durable?: boolean;
|
|
185
|
+
}): (opts: AssembledEngineOpts) => Engine;
|
|
186
|
+
/**
|
|
187
|
+
* The declarative Night Owls plugin manifest consumed by `@nightowlsdev/cli`. STRUCTURALLY matches the CLI's
|
|
188
|
+
* `NightOwlsPlugin` type but does NOT import it (no dependency cycle): all codegen lives in `@nightowlsdev/cli`;
|
|
189
|
+
* this adapter stays data-only.
|
|
190
|
+
*/
|
|
191
|
+
declare const nightOwlsPlugin: {
|
|
192
|
+
readonly name: "engine-ai-sdk";
|
|
193
|
+
readonly version: "0.0.0";
|
|
194
|
+
readonly kind: "engine";
|
|
195
|
+
readonly pkg: "@nightowlsdev/engine-ai-sdk";
|
|
196
|
+
readonly description: "The AI-SDK-native engine as a named engine package (single-agent v1, governed ai@6 streamText loop).";
|
|
197
|
+
readonly env: readonly [];
|
|
198
|
+
readonly config: {
|
|
199
|
+
readonly import: "import { aiSdkEngine } from \"@nightowlsdev/engine-ai-sdk\";";
|
|
200
|
+
readonly snippet: "engine = aiSdkEngine();";
|
|
201
|
+
readonly marker: "engine";
|
|
202
|
+
};
|
|
203
|
+
readonly init: (ctx: {
|
|
204
|
+
cwd: string;
|
|
205
|
+
log: (m: string) => void;
|
|
206
|
+
}) => void;
|
|
207
|
+
readonly commands: readonly [];
|
|
208
|
+
};
|
|
209
|
+
|
|
210
|
+
export { AI_SDK_ENGINE_CAPABILITIES, AiSdkEngine, aiSdkEngine, nightOwlsPlugin };
|