@lumifai/harness 0.0.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.
package/README.md ADDED
@@ -0,0 +1,368 @@
1
+ # @lumifai/harness
2
+
3
+ Lumif's thin harness factory around Mastra's `AgentController` runtime. The controller is shared;
4
+ each conversation is owned by a Mastra `Session`. Server integrations add scoped identity,
5
+ durable lifecycle, reconnect, and transport behavior.
6
+
7
+ ## Layered install
8
+
9
+ 1. **Core** — `@lumifai/harness`, `@lumifai/harness-protocol`
10
+ 2. **Presets** — `@lumifai/harness-presets`
11
+ 3. **Tool packs** — individual `@lumifai/harness-tool-pack-*` packages
12
+ 4. **Server** — `@lumifai/harness-server`, `@lumifai/harness-server-fastify`, `@lumifai/harness-server-nest`
13
+ 5. **Client / React** — `@lumifai/harness-client`, `@lumifai/harness-react`, `@lumifai/harness-react-mantine`
14
+
15
+ ## Usage
16
+
17
+ ```typescript
18
+ import { LibSQLStore } from '@mastra/libsql';
19
+ import { createLumifHarness } from '@lumifai/harness';
20
+ import { createPresetHarnessConfig, createPresetWorkspace } from '@lumifai/harness-presets';
21
+
22
+ const presets = createPresetHarnessConfig({
23
+ includeRequestAccess: true,
24
+ });
25
+
26
+ const controller = createLumifHarness({
27
+ id: 'my-service-agent',
28
+ storage: new LibSQLStore({ url: 'file:./data.db' }),
29
+ workspace: createPresetWorkspace({
30
+ workspaceMode: 'local',
31
+ sandboxEnabled: true,
32
+ }),
33
+ modes: presets.modes,
34
+ subagents: presets.subagents,
35
+ tools: presets.tools,
36
+ });
37
+
38
+ await controller.init();
39
+ const session = await controller.createSession({
40
+ id: 'session-1',
41
+ ownerId: 'user-1',
42
+ resourceId: 'resource-1',
43
+ });
44
+ await session.sendMessage({ content: 'Hello!' });
45
+ ```
46
+
47
+ `workspace` is required. Everything else is forwarded to Mastra's harness and can be overridden as needed.
48
+
49
+ ## Production defaults
50
+
51
+ The server wrapper in `@lumifai/harness-server` makes persistence and tenancy explicit:
52
+
53
+ - `storage` defaults to a local LibSQL file store under the workspace path
54
+ - `memory` defaults to `new Memory({ storage })`, but you can pass any Mastra memory or a factory
55
+ - `threadLock` can be supplied for multi-pod / multi-process coordination
56
+ - `contextResolver` lets adapters inject `tenantId`, `userId`, `resourceId`, `sessionId`, `threadId`, and arbitrary request context
57
+ - `authorize` lets adapters enforce route-level access control before state changes or reads
58
+ - `allowClientResourceId` is `false` by default so resource scope comes from server context, not the browser
59
+ - `/healthz` and `/readyz` are exposed by the Fastify server
60
+
61
+ ## Workspace modes
62
+
63
+ `createPresetWorkspace()` and `createHarnessServerWorkspace()` make the workspace shape explicit:
64
+
65
+ - `workspaceMode: 'local'` - `LocalFilesystem` plus optional `LocalSandbox`
66
+ - `workspaceMode: 'filesystem'` - a single filesystem provider, no sandbox
67
+ - `workspaceMode: 'mounts'` - mount-backed workspace for sandbox-visible cloud storage
68
+
69
+ `filesystem` and `mounts` are mutually exclusive. Use `mounts` when the sandbox must see cloud storage paths directly.
70
+
71
+ Sandbox is off by default. In local mode, set `sandboxEnabled: true` to attach a `LocalSandbox` whose `workingDirectory` matches the `LocalFilesystem` `basePath`. You can also pass a custom `sandbox` or tune local sandbox settings via `localSandboxOptions`.
72
+
73
+ Mount-backed example for cloud storage visible inside the sandbox:
74
+
75
+ ```typescript
76
+ import { LocalSandbox } from '@mastra/core/workspace';
77
+
78
+ createPresetWorkspace({
79
+ workspaceMode: 'mounts',
80
+ mounts: { '/data': myCloudFilesystem },
81
+ sandbox: new LocalSandbox({ workingDirectory: './workspace' }),
82
+ });
83
+ ```
84
+
85
+ ## Persistence and resume
86
+
87
+ The server integration uses two Mastra storage layers:
88
+
89
+ - Mastra's `harness` domain stores one scoped session record containing tenant/owner/resource
90
+ identity, the active thread, mode/model, configuration, lifecycle status, and all pending native
91
+ suspensions.
92
+ - Mastra memory/thread storage remains the source of truth for messages, threads, and AgentController
93
+ state. The session record is a registry and lifecycle index, not a second message store.
94
+
95
+ The external `sessionId` is a client handle. The durable record ID is a versioned SHA-256 scope key
96
+ over tenant, owner, resource, and external session ID, so identical browser IDs cannot collide
97
+ across users or tenants. Explicit destroy deletes owned threads and soft-deletes the record with
98
+ `deletedAt`; storage retention/pruning handles physical cleanup.
99
+
100
+ Tool _approvals_ are intentionally **not** persisted: the approval gate is an in-memory parked promise that does not survive a restart, so a pending approval is resolvable only within the live process. Interactive tool _suspensions_ (`ask_user`, `submit_plan`, `request_access`) are the durable, resumable primitive.
101
+
102
+ Resume flow:
103
+
104
+ 1. A request comes in with `sessionId`
105
+ 2. `HarnessSessionManager` derives the trusted scope and looks up the harness record directly
106
+ 3. A fresh `HarnessSession` is created on the current pod
107
+ 4. The harness is reattached to the persisted `threadId` and `resourceId`
108
+ 5. Every persisted native suspension is re-registered from the record
109
+ 6. SSE/event subscriptions attach to the new in-memory session instance
110
+
111
+ This is what makes the harness resumable across pods. Pod-local memory is not the source of truth.
112
+
113
+ Display state and SSE events include `currentRunId` plus an array of pending suspensions. Each item
114
+ has its own `toolCallId` and optional `runId`, so parallel human-input prompts can be rendered and
115
+ resumed independently.
116
+
117
+ Mastra approvals are deliberately process-local. If a process dies while an approval is parked,
118
+ the next runtime reports the session as `interrupted`; an old approval response cannot be replayed.
119
+ Native tool suspensions are the durable human-input primitive.
120
+
121
+ While a session is running, `sendMessage` starts a normal run, `followUp` queues input behind the
122
+ current run, and `steer` aborts the current run and redirects it. A session waiting on native input
123
+ does not keep a model process alive: it can be evicted from the in-memory LRU and reconstructed
124
+ when the user returns minutes or days later.
125
+
126
+ ## Human-in-the-loop tools
127
+
128
+ Lumif presets replace Mastra's built-in `ask_user` and `submit_plan` with host-owned versions
129
+ (same tool ids) and disable those builtins via `disableBuiltinTools`:
130
+
131
+ - `ask_user` — free-text or choice questions, including `selectionMode`. Coerces free-form mistakes
132
+ (`selectionMode` without options) into a real free-text suspend instead of Mastra's soft failure
133
+ - `submit_plan` — plan review and approval in plan mode
134
+ - `request_access` — sandbox directory access prompts (only when `includeRequestAccess: true` and the workspace exposes a `LocalFilesystem`)
135
+
136
+ All interactive flows suspend via Mastra's tool suspension API instead of ad-hoc harness events.
137
+ Presets keep `autoResumeSuspendedTools` off so the host (Studio / API
138
+ `respondToToolSuspension`) owns resumes — Mastra's auto-resume path otherwise coaches the model
139
+ to stuff `resumeData` into tool-call arguments. Lumif keeps the public
140
+ `{ answer: string | string[] }` response shape for `ask_user` and converts it to Mastra's native
141
+ resume value at the server boundary.
142
+
143
+ The server disables Mastra builtins for each same-id preset tool that is registered. Turn a tool
144
+ off entirely with `toolToggles.ask_user = false` (also disables the Mastra builtin).
145
+
146
+ Studio treats empty options and single “Use free text” proxy choices as a textarea so free-form
147
+ questions still render correctly when the model mis-shapes the payload.
148
+
149
+ ## Server integration
150
+
151
+ Use `@lumifai/harness-server` with Fastify or NestJS adapters. Boot config owns workspace shape, tool packs, and permission rules:
152
+
153
+ ```typescript
154
+ import { createHarnessSessionManager } from '@lumifai/harness-server';
155
+ // Fastify: harnessFastifyPlugin from '@lumifai/harness-server-fastify'
156
+ // NestJS: HarnessModule from '@lumifai/harness-server-nest'
157
+
158
+ createHarnessSessionManager({
159
+ bootConfig: {
160
+ workspaceBasePath: './workspace',
161
+ workspaceMode: 'local',
162
+ sandboxEnabled: true,
163
+ storage: new LibSQLStore({ url: 'file:/absolute/path/to/harness.db' }),
164
+ threadLock: {
165
+ acquire: async ({ threadId }) => {
166
+ /* distributed lock */
167
+ },
168
+ release: async ({ threadId }) => {
169
+ /* distributed unlock */
170
+ },
171
+ },
172
+ toolPacks: [
173
+ /* ... */
174
+ ],
175
+ permissionRules: { categories: { execute: 'ask' } },
176
+ },
177
+ });
178
+ ```
179
+
180
+ Built-in workspace boot options (ignored when `workspace` is provided):
181
+
182
+ - `workspaceMode` — `'local' | 'filesystem' | 'mounts'`
183
+ - `workspaceFilesystem` — custom filesystem provider
184
+ - `workspaceMounts` — mount map for `mounts` mode
185
+ - `sandboxEnabled`, `sandbox`, `localSandboxOptions`
186
+ - `onMount` — hook before mounting cloud filesystems into a sandbox
187
+
188
+ Adapter hooks available on the HTTP layer:
189
+
190
+ - `contextResolver(request)` — derive tenancy and ownership from auth/session headers
191
+ - `authorize({ action, request, context })` — gate create/read/write/resume operations
192
+ - `allowClientResourceId` — only enable for local development or trusted callers
193
+
194
+ NestJS standalone server:
195
+
196
+ ```typescript
197
+ import { createStandaloneHarnessNestServer } from '@lumifai/harness-server-nest';
198
+
199
+ await createStandaloneHarnessNestServer({
200
+ port: 4310,
201
+ bootConfig: { workspaceMode: 'local', sandboxEnabled: true },
202
+ });
203
+ ```
204
+
205
+ ## Tool permissions
206
+
207
+ The server applies preset permission defaults automatically via `buildHarnessOptions()`:
208
+
209
+ - **Read** tools (workspace reads, schema inspection) → auto-approved
210
+ - **Edit / execute / other** categories → prompt for approval (`ask`)
211
+ - **Tool pack defaults** → per-tool overrides from each pack's `toolConfig`
212
+ - `request_access` is only enabled when the workspace exposes a local filesystem, because that path is persisted via local filesystem state.
213
+
214
+ Override from server boot (recommended):
215
+
216
+ ```typescript
217
+ import { createHarnessSessionManager } from '@lumifai/harness-server';
218
+ import { createPostgresToolPack } from '@lumifai/harness-tool-pack-postgres';
219
+
220
+ createHarnessSessionManager({
221
+ bootConfig: {
222
+ toolPacks: [createPostgresToolPack({ connectionString: process.env.DATABASE_URL! })],
223
+ permissionRules: {
224
+ tools: { my_custom_tool: 'ask' },
225
+ categories: { execute: 'deny' },
226
+ },
227
+ },
228
+ });
229
+ ```
230
+
231
+ Direct harness construction:
232
+
233
+ ```typescript
234
+ import { createPresetPermissionConfig } from '@lumifai/harness-presets';
235
+
236
+ createLumifHarness({
237
+ ...createPresetPermissionConfig({
238
+ packs: [
239
+ /* tool packs */
240
+ ],
241
+ overrides: { tools: { my_custom_tool: 'ask' } },
242
+ }),
243
+ // workspace, modes, tools, ...
244
+ });
245
+ ```
246
+
247
+ Custom tools:
248
+
249
+ - Add via `bootConfig.extraTools` (Fastify/Nest) or `createPresetTools({ extra: { my_tool: createTool({...}) } })`
250
+ - Set deployment policy in `bootConfig.permissionRules.tools.my_tool`
251
+ - Use `requireApproval` on `createTool` only when approval is intrinsic to the tool design
252
+ - Optional: wrap reusable custom tools in a local `ToolPack` with `toolConfig` / `permissionPolicies`
253
+ - For durable HITL, give the tool `suspendSchema` / `resumeSchema` and call `suspend()`; pair with a
254
+ client `defineSuspensionRenderer` (see Browser UI)
255
+
256
+ Permissions are server-owned and are not exposed on the session `HarnessConfigPatch` API.
257
+
258
+ ## Browser UI
259
+
260
+ - `@lumifai/harness-client` — framework-agnostic browser client and shared reducer/state helpers
261
+ - `@lumifai/harness-react` — headless provider, hooks, browser client, session store, suspension renderer registry
262
+ - `@lumifai/harness-react-mantine` — Mantine `HarnessStudio` components
263
+
264
+ The browser client refreshes its authoritative session snapshot after an SSE failure,
265
+ and the serialized display state retains the latest run error as `lastError`. The
266
+ Mantine studio renders concurrent pending suspensions and supports free-text,
267
+ single-select, and multi-select `ask_user` responses.
268
+
269
+ Custom suspension UIs: pass `suspensionRenderers` to `HarnessProvider` and/or `HarnessStudio`.
270
+ Studio merges builtins (`ask_user`, `submit_plan`, `request_access`) then provider then studio
271
+ props (later wins by `toolName`). Headless apps can call `useResolvedSuspensionRenderer(suspension)`
272
+ and `resumeToolSuspension(data, toolCallId)`.
273
+
274
+ ## Presets
275
+
276
+ Import configurable presets from `@lumifai/harness-presets`:
277
+
278
+ - `createPresetModes()` — `plan` and `build` modes
279
+ - `createPresetCustomModes()` — returns the built-in modes plus your custom list when you need the final array yourself
280
+ - `createPresetSubagents()` — `explore` subagent; opt-in `websearch` subagent via `includeWebSearch: true`
281
+ - `createPresetTools()` — Lumif baseline with `ask_user` and `submit_plan` (displaces Mastra builtins). Pass `packs`, `toolPackToggles`, `toolToggles`, `includeRequestAccess`, and/or `extra`
282
+ - `createPresetSkills()` — default `.agents/skills` resolver paths
283
+ - `createPresetHarnessConfig()` — combines the above and merges enabled pack skill paths
284
+ - `createPresetPermissionConfig()` — default category resolver and merged `permissionRules` for harness init
285
+
286
+ ## Tool packs
287
+
288
+ Import opt-in capability bundles from `@lumifai/harness-tool-pack-*` packages. Shared types and merge helpers live in `@lumifai/harness-tool-packs`:
289
+
290
+ - `ToolPack` — named bundle of related tools (and optional skills) that flattens into `tools` at harness init
291
+ - `createPostgresToolPack()` — read-only PostgreSQL schema inspection and query tools (`@lumifai/harness-tool-pack-postgres`)
292
+ - `createWorkspaceDataToolPack()` — workspace JSON, CSV, and jq query tools (`@lumifai/harness-tool-pack-workspace-data`)
293
+ - `createServerlessWorkflowToolPack()` — serverless runtime tool pack (`@lumifai/harness-tool-pack-serverless-workflow`)
294
+ - `createWebSearchToolPack()` — provider-native web search with structured output (`@lumifai/harness-tool-pack-web-search`)
295
+ - `createFileProcessingToolPack()` — PDF text extraction to `/processed/` (`@lumifai/harness-tool-pack-file-processing`)
296
+
297
+ Override any preset or pack via the options objects on each factory.
298
+
299
+ Example:
300
+
301
+ ```ts
302
+ import { createPresetHarnessConfig } from '@lumifai/harness-presets';
303
+ import { createPostgresToolPack } from '@lumifai/harness-tool-pack-postgres';
304
+ import { createServerlessWorkflowToolPack } from '@lumifai/harness-tool-pack-serverless-workflow';
305
+ import { createWebSearchToolPack } from '@lumifai/harness-tool-pack-web-search';
306
+ import { createFileProcessingToolPack } from '@lumifai/harness-tool-pack-file-processing';
307
+ import { createWorkspaceDataToolPack } from '@lumifai/harness-tool-pack-workspace-data';
308
+ import { Agent } from '@mastra/core/agent';
309
+
310
+ const presets = createPresetHarnessConfig({
311
+ subagents: {
312
+ includeWebSearch: true,
313
+ webSearchProvider: 'openai',
314
+ },
315
+ customModes: [
316
+ {
317
+ id: 'review',
318
+ name: 'Review',
319
+ defaultModelId: 'openai/gpt-5.4-mini',
320
+ color: '#059669',
321
+ agent: new Agent({
322
+ id: 'lumif-review-agent',
323
+ name: 'Review Agent',
324
+ instructions: 'Review the user changes and report issues.',
325
+ model: 'openai/gpt-5.4-mini',
326
+ }),
327
+ },
328
+ ],
329
+ skills: {
330
+ paths: ['.agents/skills'],
331
+ },
332
+ tools: {
333
+ packs: [
334
+ createWorkspaceDataToolPack(),
335
+ createPostgresToolPack({
336
+ connectionString: process.env.DATABASE_URL,
337
+ allowAllRoleVisible: true,
338
+ // or resolveAccessPolicy / resolveConnectionString for production tenants
339
+ }),
340
+ createServerlessWorkflowToolPack({
341
+ runtimeHost: process.env.RUNTIME_HOST!,
342
+ workflowNamespace: 'lumif',
343
+ resolveAuthContext: (ctx) => ({
344
+ accessToken: ctx.requestContext?.auth?.accessToken ?? '',
345
+ }),
346
+ }),
347
+ createWebSearchToolPack({
348
+ defaultProvider: 'openai',
349
+ }),
350
+ createFileProcessingToolPack(),
351
+ ],
352
+ toolPackToggles: {
353
+ postgres: true,
354
+ },
355
+ toolToggles: {
356
+ postgres_query: true,
357
+ },
358
+ },
359
+ });
360
+ ```
361
+
362
+ ### Tool pack toggles
363
+
364
+ - `toolPackToggles` — enable or disable an entire pack (tools and bundled skills)
365
+ - `toolToggles` — enable or disable individual tools by id within enabled packs
366
+ - `toolConfig.enabledByDefault` on a pack — default per-tool state before `toolToggles` overrides
367
+
368
+ Tool packs are published as separate `@lumifai/harness-tool-pack-*` packages. Their bundled skills are merged into `workspace.skills` automatically when the pack is enabled.
@@ -0,0 +1,3 @@
1
+ import { AgentController } from '@mastra/core/agent-controller';
2
+ import type { LumifHarnessOptions } from './types';
3
+ export declare function createLumifHarness<TState = {}>(options: LumifHarnessOptions<TState>): AgentController<TState>;
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createLumifHarness = createLumifHarness;
4
+ const agent_controller_1 = require("@mastra/core/agent-controller");
5
+ const workspace_1 = require("@mastra/core/workspace");
6
+ function assertWorkspace(workspace) {
7
+ if (workspace === undefined || workspace === null) {
8
+ throw new Error('LumifHarness requires a workspace. Pass a Workspace instance, WorkspaceConfig, or a factory function.');
9
+ }
10
+ }
11
+ function createLumifHarness(options) {
12
+ assertWorkspace(options.workspace);
13
+ const workspace = normalizeWorkspace(options.workspace);
14
+ const { heartbeatHandlers, intervalHandlers, ...config } = options;
15
+ if (heartbeatHandlers && intervalHandlers) {
16
+ throw new Error('Pass either heartbeatHandlers or intervalHandlers, not both.');
17
+ }
18
+ return new agent_controller_1.AgentController({
19
+ ...config,
20
+ workspace,
21
+ intervalHandlers: intervalHandlers ?? heartbeatHandlers,
22
+ });
23
+ }
24
+ function isPromiseLike(value) {
25
+ return value != null && typeof value.then === 'function';
26
+ }
27
+ function normalizeWorkspace(workspace) {
28
+ if (typeof workspace === 'function') {
29
+ const factory = workspace;
30
+ return (input) => {
31
+ const resolved = factory(input);
32
+ if (isPromiseLike(resolved)) {
33
+ return Promise.resolve(resolved).then((value) => value ? normalizeWorkspaceValue(value) : undefined);
34
+ }
35
+ return resolved ? normalizeWorkspaceValue(resolved) : undefined;
36
+ };
37
+ }
38
+ return normalizeWorkspaceValue(workspace);
39
+ }
40
+ function normalizeWorkspaceValue(workspace) {
41
+ return workspace instanceof workspace_1.Workspace
42
+ ? workspace
43
+ : new workspace_1.Workspace(workspace);
44
+ }
45
+ //# sourceMappingURL=create-lumif-harness.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-lumif-harness.js","sourceRoot":"","sources":["../src/create-lumif-harness.ts"],"names":[],"mappings":";;AAoBA,gDAiBC;AArCD,oEAA4F;AAE5F,sDAAyE;AAQzE,SAAS,eAAe,CACtB,SAA2C;IAE3C,IAAI,SAAS,KAAK,SAAS,IAAI,SAAS,KAAK,IAAI,EAAE,CAAC;QAClD,MAAM,IAAI,KAAK,CACb,uGAAuG,CACxG,CAAC;IACJ,CAAC;AACH,CAAC;AAED,SAAgB,kBAAkB,CAChC,OAAoC;IAEpC,eAAe,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAEnC,MAAM,SAAS,GAAG,kBAAkB,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IACxD,MAAM,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,GAAG,MAAM,EAAE,GAAG,OAAO,CAAC;IAEnE,IAAI,iBAAiB,IAAI,gBAAgB,EAAE,CAAC;QAC1C,MAAM,IAAI,KAAK,CAAC,8DAA8D,CAAC,CAAC;IAClF,CAAC;IAED,OAAO,IAAI,kCAAe,CAAC;QACzB,GAAG,MAAM;QACT,SAAS;QACT,gBAAgB,EAAE,gBAAgB,IAAI,iBAAiB;KACvB,CAAC,CAAC;AACtC,CAAC;AAED,SAAS,aAAa,CAAI,KAAyB;IACjD,OAAO,KAAK,IAAI,IAAI,IAAI,OAAQ,KAAwB,CAAC,IAAI,KAAK,UAAU,CAAC;AAC/E,CAAC;AAED,SAAS,kBAAkB,CACzB,SAA+D;IAE/D,IAAI,OAAO,SAAS,KAAK,UAAU,EAAE,CAAC;QACpC,MAAM,OAAO,GAAG,SAAS,CAAC;QAC1B,OAAO,CAAC,KAAK,EAAE,EAAE;YACf,MAAM,QAAQ,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;YAChC,IAAI,aAAa,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAC5B,OAAO,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAC9C,KAAK,CAAC,CAAC,CAAC,uBAAuB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CACnD,CAAC;YACJ,CAAC;YACD,OAAO,QAAQ,CAAC,CAAC,CAAC,uBAAuB,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAClE,CAAC,CAAC;IACJ,CAAC;IAED,OAAO,uBAAuB,CAAC,SAAS,CAAC,CAAC;AAC5C,CAAC;AAED,SAAS,uBAAuB,CAC9B,SAAuF;IAEvF,OAAO,SAAS,YAAY,qBAAS;QACnC,CAAC,CAAE,SAAuB;QAC1B,CAAC,CAAC,IAAI,qBAAS,CAAC,SAA4B,CAAC,CAAC;AAClD,CAAC"}
@@ -0,0 +1,6 @@
1
+ export { createLumifHarness } from './create-lumif-harness';
2
+ export type { LumifHarnessOptions, LumifWorkspace, LumifWorkspaceFactory } from './types';
3
+ export { AgentController, Session } from '@mastra/core/agent-controller';
4
+ /** Lumif's stable Harness export, backed by Mastra's AgentController runtime. */
5
+ export { AgentController as Harness } from '@mastra/core/agent-controller';
6
+ export type { AgentControllerConfig, AgentControllerDisplayState, AgentControllerEvent, AgentControllerMode, AgentControllerSubagent, AgentControllerThread, AgentControllerConfig as HarnessConfig, AgentControllerDisplayState as HarnessDisplayState, AgentControllerEvent as HarnessEvent, AgentControllerMode as HarnessMode, AgentControllerSubagent as HarnessSubagent, AgentControllerThread as HarnessThread, } from '@mastra/core/agent-controller';
package/dist/index.js ADDED
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Harness = exports.Session = exports.AgentController = exports.createLumifHarness = void 0;
4
+ var create_lumif_harness_1 = require("./create-lumif-harness");
5
+ Object.defineProperty(exports, "createLumifHarness", { enumerable: true, get: function () { return create_lumif_harness_1.createLumifHarness; } });
6
+ var agent_controller_1 = require("@mastra/core/agent-controller");
7
+ Object.defineProperty(exports, "AgentController", { enumerable: true, get: function () { return agent_controller_1.AgentController; } });
8
+ Object.defineProperty(exports, "Session", { enumerable: true, get: function () { return agent_controller_1.Session; } });
9
+ /** Lumif's stable Harness export, backed by Mastra's AgentController runtime. */
10
+ var agent_controller_2 = require("@mastra/core/agent-controller");
11
+ Object.defineProperty(exports, "Harness", { enumerable: true, get: function () { return agent_controller_2.AgentController; } });
12
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,+DAA4D;AAAnD,0HAAA,kBAAkB,OAAA;AAG3B,kEAAyE;AAAhE,mHAAA,eAAe,OAAA;AAAE,2GAAA,OAAO,OAAA;AACjC,iFAAiF;AACjF,kEAA2E;AAAlE,2GAAA,eAAe,OAAW"}
@@ -0,0 +1,18 @@
1
+ import type { AgentControllerConfig } from '@mastra/core/agent-controller';
2
+ import type { RequestContext } from '@mastra/core/request-context';
3
+ import type { Mastra } from '@mastra/core';
4
+ import type { Workspace, WorkspaceConfig, WorkspaceFilesystem, WorkspaceSandbox } from '@mastra/core/workspace';
5
+ type MountCapableWorkspaceConfig = WorkspaceConfig<WorkspaceFilesystem | undefined, WorkspaceSandbox | undefined, Record<string, WorkspaceFilesystem> | undefined>;
6
+ type MountCapableWorkspace = Workspace<WorkspaceFilesystem | undefined, WorkspaceSandbox | undefined, Record<string, WorkspaceFilesystem> | undefined>;
7
+ export type LumifWorkspaceFactory = (input: {
8
+ requestContext: RequestContext;
9
+ mastra?: Mastra;
10
+ }) => Workspace | MountCapableWorkspace | MountCapableWorkspaceConfig | undefined | Promise<Workspace | MountCapableWorkspace | MountCapableWorkspaceConfig | undefined>;
11
+ export type LumifWorkspace<_TState = {}> = Workspace | MountCapableWorkspace | MountCapableWorkspaceConfig | LumifWorkspaceFactory;
12
+ export type LumifHarnessOptions<TState = {}> = Omit<AgentControllerConfig<TState>, 'workspace' | 'intervalHandlers'> & {
13
+ workspace: LumifWorkspace<TState>;
14
+ /** @deprecated Renamed to `intervalHandlers` by Mastra. */
15
+ heartbeatHandlers?: AgentControllerConfig<TState>['intervalHandlers'];
16
+ intervalHandlers?: AgentControllerConfig<TState>['intervalHandlers'];
17
+ };
18
+ export {};
package/dist/types.js ADDED
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
package/package.json ADDED
@@ -0,0 +1,34 @@
1
+ {
2
+ "name": "@lumifai/harness",
3
+ "version": "0.0.1",
4
+ "license": "UNLICENSED",
5
+ "engines": {
6
+ "node": ">=22.13.0"
7
+ },
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js",
12
+ "require": "./dist/index.js",
13
+ "default": "./dist/index.js"
14
+ },
15
+ "./package.json": "./package.json"
16
+ },
17
+ "main": "dist/index.js",
18
+ "types": "dist/index.d.ts",
19
+ "files": [
20
+ "dist",
21
+ "!dist/**/*.test.*",
22
+ "README.md"
23
+ ],
24
+ "dependencies": {
25
+ "@mastra/core": "1.50.1"
26
+ },
27
+ "publishConfig": {
28
+ "access": "public",
29
+ "registry": "https://registry.npmjs.org/"
30
+ },
31
+ "scripts": {
32
+ "build": "tsc -p tsconfig.json"
33
+ }
34
+ }