@modelprofile.com/flexharness 5.4.0 → 6.0.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/dist_ts/00_commitinfo_data.js +3 -3
- package/dist_ts/plugins.d.ts +2 -2
- package/dist_ts/plugins.js +2 -2
- package/package.json +15 -30
- package/readme.md +95 -19
- package/ts/00_commitinfo_data.ts +2 -2
- package/ts/plugins.ts +2 -2
- package/ts/readme.md +942 -0
- package/.smartconfig.json +0 -34
- package/changelog.md +0 -273
- package/readme.hints.md +0 -71
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export const commitinfo = {
|
|
5
5
|
name: '@modelprofile.com/flexharness',
|
|
6
|
-
version: '
|
|
7
|
-
description: '
|
|
6
|
+
version: '6.0.0',
|
|
7
|
+
description: 'The FlexHarness toolbox source repository and shared dependency catalog.'
|
|
8
8
|
};
|
|
9
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
9
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvMDBfY29tbWl0aW5mb19kYXRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHO0lBQ3hCLElBQUksRUFBRSwrQkFBK0I7SUFDckMsT0FBTyxFQUFFLE9BQU87SUFDaEIsV0FBVyxFQUFFLDBFQUEwRTtDQUN4RixDQUFBIn0=
|
package/dist_ts/plugins.d.ts
CHANGED
|
@@ -3,6 +3,6 @@ import * as crypto from 'node:crypto';
|
|
|
3
3
|
import * as fs from 'node:fs/promises';
|
|
4
4
|
import * as path from 'node:path';
|
|
5
5
|
export { AsyncLocalStorage, crypto, fs, path };
|
|
6
|
-
import { AgentEventStoreConflictError, AgentSession, buildModelMessages, ToolJobStoreConflictError, createAgentEvent, filterModelVisibleAgentEvents, getAgentGenerationTransactions, modelMessagesToAgentEvents, tool, validateAgentEventArchiveV2, validateAgentEventSnapshotV2, z } from '@
|
|
6
|
+
import { AgentEventStoreConflictError, AgentSession, buildModelMessages, ToolJobStoreConflictError, createAgentEvent, filterModelVisibleAgentEvents, getAgentGenerationTransactions, modelMessagesToAgentEvents, tool, validateAgentEventArchiveV2, validateAgentEventSnapshotV2, z } from '@modelprofile.com/flexharness-agent';
|
|
7
7
|
export { AgentEventStoreConflictError, AgentSession, buildModelMessages, ToolJobStoreConflictError, createAgentEvent, filterModelVisibleAgentEvents, getAgentGenerationTransactions, modelMessagesToAgentEvents, tool, validateAgentEventArchiveV2, validateAgentEventSnapshotV2, z, };
|
|
8
|
-
export type { IAgentEventArchiveV2, IAgentContextCompactionOptions, IAgentEventSnapshotV2, IAgentEventStoreV2, IAgentGenerateResult, IAgentGenerationHandle, IAgentGenerationLease, IAgentRunResult, IAgentSession, IAgentSessionOptions, IAgentToolCallUpdateEvent, IAgentRuntimeEventPayload, IGenerationBegunEvent, IGenerationExecutionCompletedEvent, IGenerationExecutionStartedEvent, IGenerationOutcomeEvent, IToolExecutionContext, IToolExecutionIntentEvent, IToolJobSnapshot, IToolJobState, IToolJobStore, TAgentContextBuilder, TAgentContextCompactor, TAgentEvent, TAgentGenerationOutcome, TAgentToolCallFinishEvent, TAgentToolExecutionReconciliationOptions, } from '@
|
|
8
|
+
export type { IAgentEventArchiveV2, IAgentContextCompactionOptions, IAgentEventSnapshotV2, IAgentEventStoreV2, IAgentGenerateResult, IAgentGenerationHandle, IAgentGenerationLease, IAgentRunResult, IAgentSession, IAgentSessionOptions, IAgentToolCallUpdateEvent, IAgentRuntimeEventPayload, IGenerationBegunEvent, IGenerationExecutionCompletedEvent, IGenerationExecutionStartedEvent, IGenerationOutcomeEvent, IToolExecutionContext, IToolExecutionIntentEvent, IToolJobSnapshot, IToolJobState, IToolJobStore, TAgentContextBuilder, TAgentContextCompactor, TAgentEvent, TAgentGenerationOutcome, TAgentToolCallFinishEvent, TAgentToolExecutionReconciliationOptions, } from '@modelprofile.com/flexharness-agent';
|
package/dist_ts/plugins.js
CHANGED
|
@@ -5,6 +5,6 @@ import * as fs from 'node:fs/promises';
|
|
|
5
5
|
import * as path from 'node:path';
|
|
6
6
|
export { AsyncLocalStorage, crypto, fs, path };
|
|
7
7
|
// @push.rocks scope
|
|
8
|
-
import { AgentEventStoreConflictError, AgentSession, buildModelMessages, ToolJobStoreConflictError, createAgentEvent, filterModelVisibleAgentEvents, getAgentGenerationTransactions, modelMessagesToAgentEvents, tool, validateAgentEventArchiveV2, validateAgentEventSnapshotV2, z, } from '@
|
|
8
|
+
import { AgentEventStoreConflictError, AgentSession, buildModelMessages, ToolJobStoreConflictError, createAgentEvent, filterModelVisibleAgentEvents, getAgentGenerationTransactions, modelMessagesToAgentEvents, tool, validateAgentEventArchiveV2, validateAgentEventSnapshotV2, z, } from '@modelprofile.com/flexharness-agent';
|
|
9
9
|
export { AgentEventStoreConflictError, AgentSession, buildModelMessages, ToolJobStoreConflictError, createAgentEvent, filterModelVisibleAgentEvents, getAgentGenerationTransactions, modelMessagesToAgentEvents, tool, validateAgentEventArchiveV2, validateAgentEventSnapshotV2, z, };
|
|
10
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
10
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGx1Z2lucy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL3BsdWdpbnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsb0JBQW9CO0FBQ3BCLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQ3JELE9BQU8sS0FBSyxNQUFNLE1BQU0sYUFBYSxDQUFDO0FBQ3RDLE9BQU8sS0FBSyxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDdkMsT0FBTyxLQUFLLElBQUksTUFBTSxXQUFXLENBQUM7QUFFbEMsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sRUFBRSxFQUFFLEVBQUUsSUFBSSxFQUFFLENBQUM7QUFFL0Msb0JBQW9CO0FBQ3BCLE9BQU8sRUFDTCw0QkFBNEIsRUFDNUIsWUFBWSxFQUNaLGtCQUFrQixFQUNsQix5QkFBeUIsRUFDekIsZ0JBQWdCLEVBQ2hCLDZCQUE2QixFQUM3Qiw4QkFBOEIsRUFDOUIsMEJBQTBCLEVBQzFCLElBQUksRUFDSiwyQkFBMkIsRUFDM0IsNEJBQTRCLEVBQzVCLENBQUMsR0FDRixNQUFNLHFDQUFxQyxDQUFDO0FBRTdDLE9BQU8sRUFDTCw0QkFBNEIsRUFDNUIsWUFBWSxFQUNaLGtCQUFrQixFQUNsQix5QkFBeUIsRUFDekIsZ0JBQWdCLEVBQ2hCLDZCQUE2QixFQUM3Qiw4QkFBOEIsRUFDOUIsMEJBQTBCLEVBQzFCLElBQUksRUFDSiwyQkFBMkIsRUFDM0IsNEJBQTRCLEVBQzVCLENBQUMsR0FDRixDQUFDIn0=
|
package/package.json
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
{
|
|
2
|
+
"author": "Task Venture Capital GmbH",
|
|
3
|
+
"license": "MIT",
|
|
2
4
|
"name": "@modelprofile.com/flexharness",
|
|
3
|
-
"version": "
|
|
4
|
-
"private": false,
|
|
5
|
-
"description": "Provider-neutral model-session runtime with durable history, permissions, typed events, and pluggable local or remote tool execution.",
|
|
6
|
-
"main": "dist_ts/index.js",
|
|
7
|
-
"typings": "dist_ts/index.d.ts",
|
|
5
|
+
"version": "6.0.0",
|
|
8
6
|
"type": "module",
|
|
7
|
+
"description": "Managed multi-scope agent harness with permissions, public projections and persistence coordination.",
|
|
8
|
+
"main": "./dist_ts/index.js",
|
|
9
|
+
"types": "./dist_ts/index.d.ts",
|
|
9
10
|
"exports": {
|
|
10
11
|
".": {
|
|
11
12
|
"types": "./dist_ts/index.d.ts",
|
|
@@ -16,35 +17,19 @@
|
|
|
16
17
|
"import": "./dist_ts_migration/index.js"
|
|
17
18
|
}
|
|
18
19
|
},
|
|
19
|
-
"author": "Task Venture Capital GmbH",
|
|
20
|
-
"license": "MIT",
|
|
21
|
-
"engines": {
|
|
22
|
-
"node": ">=24"
|
|
23
|
-
},
|
|
24
20
|
"dependencies": {
|
|
25
|
-
"@
|
|
26
|
-
"@types/json-schema": "7.0.15"
|
|
21
|
+
"@modelprofile.com/flexharness-agent": "6.0.0"
|
|
27
22
|
},
|
|
28
|
-
"
|
|
29
|
-
"
|
|
30
|
-
"@git.zone/tsrun": "2.0.6",
|
|
31
|
-
"@git.zone/tstest": "4.0.0",
|
|
32
|
-
"@types/node": "26.4.1",
|
|
33
|
-
"ai": "7.0.79"
|
|
23
|
+
"engines": {
|
|
24
|
+
"node": ">=24"
|
|
34
25
|
},
|
|
26
|
+
"sideEffects": false,
|
|
35
27
|
"files": [
|
|
36
|
-
"ts
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
"dist_ts_migration
|
|
40
|
-
".smartconfig.json",
|
|
28
|
+
"ts",
|
|
29
|
+
"dist_ts",
|
|
30
|
+
"ts_migration",
|
|
31
|
+
"dist_ts_migration",
|
|
41
32
|
"readme.md",
|
|
42
|
-
"changelog.md",
|
|
43
33
|
"license.md"
|
|
44
|
-
]
|
|
45
|
-
"scripts": {
|
|
46
|
-
"build": "tsbuild tsfolders",
|
|
47
|
-
"test": "pnpm run build && tstest test/ --verbose --logfile",
|
|
48
|
-
"check:test": "tsbuild check 'test/**/*'"
|
|
49
|
-
}
|
|
34
|
+
]
|
|
50
35
|
}
|
package/readme.md
CHANGED
|
@@ -1,12 +1,56 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
Provider-neutral model-session runtime with durable history, permissions, typed events, and pluggable local or remote tool execution.
|
|
1
|
+
FlexHarness is a modular toolbox for model inference, standalone agents, managed sessions, tools and provider capabilities. It brings SmartAI and SmartAgent into one repository while publishing independently installable packages through tspublish.
|
|
4
2
|
|
|
5
3
|
## Issue Reporting and Security
|
|
6
4
|
|
|
7
5
|
For reporting bugs, issues, or security vulnerabilities, please visit [community.foss.global/](https://community.foss.global/). This is the central community hub for all issue reporting. Developers who sign and comply with our contribution agreement and go through identification can also get a [code.foss.global/](https://code.foss.global/) account to submit Pull Requests directly.
|
|
8
6
|
|
|
9
|
-
##
|
|
7
|
+
## Choose components
|
|
8
|
+
|
|
9
|
+
All package names below use the `@modelprofile.com/` scope. Components share a release version; each published package declares only its own dependencies. The private repository root is a development dependency catalog, not an install-everything package.
|
|
10
|
+
|
|
11
|
+
| Package | Responsibility |
|
|
12
|
+
| --- | --- |
|
|
13
|
+
| `flexharness-models` | Model contracts, explicit `ModelRegistry`, AI SDK helpers and prompt caching |
|
|
14
|
+
| `flexharness-provider-{anthropic,openai,google,groq,mistral,xai,perplexity,ollama}` | One explicitly selected model provider per package |
|
|
15
|
+
| `flexharness-agent` | `runAgent`, `AgentSession`, canonical events, generation transactions and tool contracts |
|
|
16
|
+
| `flexharness` | Managed scopes, sessions, permissions, public projections and persistence coordination |
|
|
17
|
+
| `flexharness-tools` | Tool factories using a host-supplied execution context, HTTP and JSON tools |
|
|
18
|
+
| `flexharness-tools-node` | Local filesystem/process contexts, `filesystemTool`, `shellTool` and file-backed job stores |
|
|
19
|
+
| `flexharness-compaction` | Model-driven conversation compaction |
|
|
20
|
+
| `flexharness-mcp` | MCP clients and AI SDK tool conversion |
|
|
21
|
+
| `flexharness-openai-auth` | ChatGPT device/browser authentication, refresh and model connections |
|
|
22
|
+
| `flexharness-openai-account` | Account lifecycle, model catalog, rate limits and credential envelopes |
|
|
23
|
+
| `flexharness-openai-auth-files` | Explicit interoperability with existing external credential files |
|
|
24
|
+
| `flexharness-media` | Vision recipes for an injected model |
|
|
25
|
+
| `flexharness-media-openai` | OpenAI audio and image capabilities |
|
|
26
|
+
| `flexharness-document` | PDF processing; this component alone brings SmartPDF |
|
|
27
|
+
| `flexharness-ocr` | OCR contracts with an injected transport; no runtime dependencies |
|
|
28
|
+
| `flexharness-research` | Anthropic research capabilities |
|
|
29
|
+
|
|
30
|
+
For model inference without an agent:
|
|
31
|
+
|
|
32
|
+
```sh
|
|
33
|
+
pnpm add @modelprofile.com/flexharness-models @modelprofile.com/flexharness-provider-openai
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
```typescript
|
|
37
|
+
import { ModelRegistry, generateText } from '@modelprofile.com/flexharness-models';
|
|
38
|
+
import { createOpenAiModelProvider } from '@modelprofile.com/flexharness-provider-openai';
|
|
39
|
+
|
|
40
|
+
const models = new ModelRegistry().register(createOpenAiModelProvider());
|
|
41
|
+
const setup = models.getModelSetup({
|
|
42
|
+
provider: 'openai',
|
|
43
|
+
model: 'gpt-5.5',
|
|
44
|
+
apiKey: process.env.OPENAI_API_KEY,
|
|
45
|
+
});
|
|
46
|
+
const result = await generateText({ ...setup, prompt: 'Hello' });
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
For a standalone agent, add `@modelprofile.com/flexharness-agent` and pass the same model setup to `runAgent({ ...setup, prompt: 'Hello' })`. Providers are registered on caller-owned registries; duplicate IDs and unknown providers fail explicitly. Importing a provider, agent or harness does not register anything globally.
|
|
50
|
+
|
|
51
|
+
For OpenAI ChatGPT authentication, add `flexharness-openai-auth` and set `connection: createOpenAiChatGptModelConnection(credentials)` in the OpenAI model options. This connection supplies the existing authentication settings and system-instruction middleware. API-key inference does not depend on the authentication or account packages.
|
|
52
|
+
|
|
53
|
+
## Install the managed harness
|
|
10
54
|
|
|
11
55
|
```bash
|
|
12
56
|
pnpm add @modelprofile.com/flexharness
|
|
@@ -16,7 +60,39 @@ Node.js 24 or newer is required.
|
|
|
16
60
|
|
|
17
61
|
## Overview
|
|
18
62
|
|
|
19
|
-
FlexHarness owns scope isolation, public session and message projections, permission decisions, event delivery, cancellation, and persistence coordination. Each session is backed by
|
|
63
|
+
FlexHarness owns scope isolation, public session and message projections, permission decisions, event delivery, cancellation, and persistence coordination. Each session is backed by the `flexharness-agent` component's `AgentSession`, which owns the canonical private conversation and runtime event history. Model selection, tool execution, and optional execution-context creation remain application-defined extension points. The managed harness depends on the standalone agent; it does not install provider SDKs, MCP, document processing or local execution tools.
|
|
64
|
+
|
|
65
|
+
## Migrating from SmartAI and SmartAgent
|
|
66
|
+
|
|
67
|
+
Update all related imports together and install the components they reference. The old packages are superseded; their published versions remain available so existing installations can be migrated deliberately.
|
|
68
|
+
|
|
69
|
+
| Previous import/API | Replacement |
|
|
70
|
+
| --- | --- |
|
|
71
|
+
| `@push.rocks/smartai` model/cache/AI SDK contracts | `@modelprofile.com/flexharness-models` |
|
|
72
|
+
| Global `getModel` / `getModelSetup` | A `ModelRegistry` with explicit provider registrations |
|
|
73
|
+
| Provider-specific request types | The relevant `flexharness-provider-*` package |
|
|
74
|
+
| `openAiChatGptAuth` model option | `connection: createOpenAiChatGptModelConnection(credentials)` from `flexharness-openai-auth` |
|
|
75
|
+
| SmartAI root authentication functions/types | `flexharness-openai-auth` |
|
|
76
|
+
| `@push.rocks/smartai/providers` | `flexharness-openai-account` |
|
|
77
|
+
| `@push.rocks/smartai/openai-chatgpt-auth` | `flexharness-openai-auth-files` |
|
|
78
|
+
| SmartAI `/vision`, `/audio`, `/image` | `flexharness-media`, `flexharness-media-openai`, `flexharness-media-openai` |
|
|
79
|
+
| SmartAI `/document`, `/ocr`, `/research` | `flexharness-document`, `flexharness-ocr`, `flexharness-research` |
|
|
80
|
+
| `@push.rocks/smartagent` agent/event/persistence/adapter contracts | `flexharness-agent` |
|
|
81
|
+
| SmartAgent `/tools` factories and output formatting | `flexharness-tools` |
|
|
82
|
+
| Local contexts, `filesystemTool`, `shellTool`, `FileToolJobStore` | `flexharness-tools-node` |
|
|
83
|
+
| SmartAgent `/compaction`, `/mcp` | `flexharness-compaction`, `flexharness-mcp` |
|
|
84
|
+
|
|
85
|
+
Existing `ISmartAi*` and `TSmartAi*` contract names remain where their semantics are unchanged. The models package accepts provider IDs as strings; applications that expose a fixed set of providers should own that narrower union. The OpenAI account registry remains `SmartAiProviderRegistry`; it manages account adapters and is distinct from inference's `ModelRegistry`.
|
|
86
|
+
|
|
87
|
+
Durable Agent event/job schemas, FlexHarness projection schemas, credential envelopes, and external credential-source names and paths are preserved. The package move does not require a data migration. Existing FlexHarness versioned migration APIs remain at `@modelprofile.com/flexharness/migration`.
|
|
88
|
+
|
|
89
|
+
## Developing and releasing the toolbox
|
|
90
|
+
|
|
91
|
+
Each `ts_*` component has a `tspublish.json` declaring its dependencies, owned folders and published exports. Cross-component source imports use package names. TypeScript mappings provide source entrypoints for tsrun and declaration entrypoints for tsbuild's compiled-folder resolution; no workspace links are required.
|
|
92
|
+
|
|
93
|
+
`pnpm build` builds the components in declared dependency order. `pnpm test` runs the deterministic model, agent and harness regressions. Live provider tests and the browser authentication smoke test are preserved in `test_integration/` and run only when explicitly selected; they are not part of release preflight.
|
|
94
|
+
|
|
95
|
+
GitZone's `release.targets.npm.packageSource: "tspublish"` prepares and packs every component once, publishes the dependency order to the configured registries, and records the exact artifacts in its release journal. A partial release resumes those stored artifacts. Third-party OpenAI Codex notices accompany the authentication and account packages.
|
|
20
96
|
|
|
21
97
|
## Core Setup
|
|
22
98
|
|
|
@@ -226,7 +302,7 @@ The tools use strict action-discriminated inputs:
|
|
|
226
302
|
|
|
227
303
|
Every project action returns the authoritative revision and state; task mutations also return the affected task, and clear returns the removed tasks. Reads never save. A set, clear, append, update, idempotent create, or empty task clear that makes no state change returns the current revision without writing. Mutations load once, apply once, validate the complete next snapshot, and issue one compare-and-swap save at `revision + 1`. FlexHarness never retries or merges an external conflict.
|
|
228
304
|
|
|
229
|
-
Tool task creation accepts an optional `id`. When omitted, FlexHarness requires the stable
|
|
305
|
+
Tool task creation accepts an optional `id`. When omitted, FlexHarness requires the stable AgentSession `toolCallId` and derives `task_` plus the SHA-256 of `JSON.stringify(['flexharness-project-task-v1', storageKey, sessionId, runId, toolCallId])`. Repeating an explicit or deterministic ID with identical content, status, and priority is idempotent; different creation data conflicts. Application callers must supply an explicit `id` to `createProjectTask()` because no tool-call identity exists at that boundary.
|
|
230
306
|
|
|
231
307
|
The same engine is available to applications:
|
|
232
308
|
|
|
@@ -294,7 +370,7 @@ The parent tool part receives `childSessionId` in a cumulative `part.updated` ev
|
|
|
294
370
|
}
|
|
295
371
|
```
|
|
296
372
|
|
|
297
|
-
Omitting `taskId` creates a deterministic child for the parent session, run, and tool call. The model-visible tool description and `taskId` schema state this creation rule directly. Repeating that same invocation does not create another child. If the deterministic child already has messages, FlexHarness reports an uncertain prior execution and never silently reruns it. This preserves
|
|
373
|
+
Omitting `taskId` creates a deterministic child for the parent session, run, and tool call. The model-visible tool description and `taskId` schema state this creation rule directly. Repeating that same invocation does not create another child. If the deterministic child already has messages, FlexHarness reports an uncertain prior execution and never silently reruns it. This preserves AgentSession's durable parent tool intent as crash authority; controllers use `listUncertainToolExecutions()` and `reconcileToolExecution()` for uncertain parent calls.
|
|
298
374
|
|
|
299
375
|
Supplying `taskId` deliberately resumes an idle, live child from a later run of the same immutable parent session and the same configured agent. The caller must use the exact ID returned by an earlier completed delegate call; an unknown ID fails with safe corrective guidance and never creates a child under the supplied label. Resume starts a new child prompt while retaining the child's original parent run and tool-call origin. A child owned by another parent or agent, a deleted child, an active child, a same-run resume, or a second acquisition of the same child within one later parent run is rejected. Parent cancellation propagates only to the exact child run started by that delegate call.
|
|
300
376
|
|
|
@@ -332,7 +408,7 @@ delegatedRunAdmissionProvider: {
|
|
|
332
408
|
|
|
333
409
|
Acquisition completes before generation-side branch reversion, context compaction, model resolution, application or resource tool-provider callbacks, and model execution. Child session store and runtime initialization may already have occurred before acquisition. Providers must honor the supplied `AbortSignal`; an abort can settle the active child and parent without waiting for an acquisition that ignores cancellation, while FlexHarness retains ownership and closes any lease returned later.
|
|
334
410
|
|
|
335
|
-
For a normally acquired lease, FlexHarness gives `close()` an awaited attempt after
|
|
411
|
+
For a normally acquired lease, FlexHarness gives `close()` an awaited attempt after AgentSession generation and before canonical accepted, rejected, or interrupted finalization and the terminal `prompt.finished` event. If an abort detaches an acquisition that ignores its signal, the run may settle before acquisition returns; FlexHarness retains that owner and closes any late lease. `close()` must be idempotent and safe to retry after rejection. A close failure prevents successful child acceptance and remains owned by the exact child session generation for retry by later exact-session deletion, scope retirement, or disposal. Retirement and disposal truthfully wait for late acquisition and lease cleanup.
|
|
336
412
|
|
|
337
413
|
Limits are validated and frozen at construction: at most 32 unique definitions; names are non-empty and at most 128 UTF-8 bytes; descriptions 2048 bytes; optional model hints 512 bytes; optional system prompts 64 KiB; and optional `maxSteps` a positive safe integer. `maxSubagentDepth` defaults to 1 and must be a positive safe integer at most 8. `maxSubagentCallsPerRun` defaults to 32 and must be a positive safe integer at most 128. A call slot is consumed synchronously at the start of every schema-valid delegate execution, before semantic bounds, subagent type/depth validation, permission, or child work. Inputs rejected by the tool schema never start delegate execution and do not consume a slot. After successful semantic validation, the child ID candidate is reserved for the rest of the parent run, including after permission rejection or later failure. Permission rejection creates no child session. Omitting `taskId` reserves a deterministic new child ID; supplying `taskId` reserves that unverified candidate and attempts resume after permission only if it identifies a resumable child. Delegate descriptions are non-empty and at most 256 UTF-8 bytes, prompts non-empty and at most 64 KiB, subagent types at most 128 bytes, and task IDs at most 512 bytes.
|
|
338
414
|
|
|
@@ -370,7 +446,7 @@ console.log(result.usage);
|
|
|
370
446
|
- `{ type: 'image', data, mediaType?, name? }`
|
|
371
447
|
- `{ type: 'file', data, mediaType, name? }`
|
|
372
448
|
|
|
373
|
-
Attachment `data` is a string containing base64, a data URL, or a remote URL. Public input never requires `Buffer` or `URL` objects. Remote URL strings are converted only at the private
|
|
449
|
+
Attachment `data` is a string containing base64, a data URL, or a remote URL. Public input never requires `Buffer` or `URL` objects. Remote URL strings are converted only at the private AgentSession invocation boundary.
|
|
374
450
|
|
|
375
451
|
Attachment payloads are never copied into public audit messages or events. Public attachment parts contain metadata only:
|
|
376
452
|
|
|
@@ -463,7 +539,7 @@ Queue entries expose `queued`, `starting`, `scheduled`, `running`, `completed`,
|
|
|
463
539
|
|
|
464
540
|
The displayed queue limits are the defaults. Outstanding count and byte limits apply per session and include every non-terminal queued or active prompt until it settles. Pending-admission limits apply to the complete harness while scope aliases are unresolved. Terminal retention applies per session. Exceeding an admission limit throws `FlexHarnessQueueFullError`.
|
|
465
541
|
|
|
466
|
-
Queue payloads, status records, and `prompt.*` queue events are process-local. The existing stores do not have a private generic queue domain: projections are deliberately redacted, Agent events are canonical conversation transactions, and jobs are
|
|
542
|
+
Queue payloads, status records, and `prompt.*` queue events are process-local. The existing stores do not have a private generic queue domain: projections are deliberately redacted, Agent events are canonical conversation transactions, and jobs are AgentSession background executions. FlexHarness therefore never writes a never-started prompt into those unrelated domains. A process restart drops never-started entries; a prompt that reached durable run admission continues to use the existing canonical recovery policy and is repaired to a safe terminal state instead of being replayed.
|
|
467
543
|
|
|
468
544
|
`schedulePrompt()` waits for its FIFO turn, performs the same durable admission, exposes session status `scheduled`, and starts model preparation after its bounded `debounceMs` delay. Schedule keys remain unique across waiting and active prompts. `cancelScheduledPrompt()` returns `true` only while the matching schedule key can still be cancelled. Cancelling while it is still waiting rejects the `schedulePrompt()` call itself; cancelling after durable admission rejects the returned completion and marks its reserved audit messages cancelled.
|
|
469
545
|
|
|
@@ -638,7 +714,7 @@ The protocol is durable and inspectable:
|
|
|
638
714
|
|
|
639
715
|
Under `workspace-required`, a group is a barrier when any segment is pending, nonrevertible, or legacy transcript-only history. It is a candidate when at least one segment is revertible and none is a barrier; otherwise it is no-change. Only candidates can be traversed. No-change groups after a candidate travel with that candidate until the next candidate or barrier. Leading no-change groups remain visible. A retained barrier blocks older groups, while later candidates remain undoable. A mixed revertible/nonrevertible group is a barrier.
|
|
640
716
|
|
|
641
|
-
Inspection, recovery, finalization, and release use fresh maintenance signals bounded by the top-level `reversionMaintenanceTimeoutMs` option. It must be a positive safe integer no greater than 30 minutes. When omitted, FlexHarness uses `agentSessionPolicy.generationLeaseCleanupTimeoutMs` as a compatibility fallback, then defaults to 30 seconds when neither option is supplied. The agent-session setting continues to govern
|
|
717
|
+
Inspection, recovery, finalization, and release use fresh maintenance signals bounded by the top-level `reversionMaintenanceTimeoutMs` option. It must be a positive safe integer no greater than 30 minutes. When omitted, FlexHarness uses `agentSessionPolicy.generationLeaseCleanupTimeoutMs` as a compatibility fallback, then defaults to 30 seconds when neither option is supplied. The agent-session setting continues to govern AgentSession generation-lease cleanup independently. Providers must observe every supplied signal and must serialize ownership for a storage namespace. A provider with the matching persisted `protocolVersion` must remain configured whenever a capture-backed session is reopened, retired, disposed, or deleted. Capture-backed recovery and deletion fail closed without it.
|
|
642
718
|
|
|
643
719
|
Workspace reversion is generic and application-defined. It does not reverse network, database, billing, or other side effects unless the provider deliberately captures them. References are normalized with `toolOutputLimits` and have an absolute 256 KiB encoded cap.
|
|
644
720
|
|
|
@@ -659,11 +735,11 @@ Applications removing a scope must stop and serialize new admission across every
|
|
|
659
735
|
|
|
660
736
|
## History And Audit Behavior
|
|
661
737
|
|
|
662
|
-
The model context is built by the session's canonical
|
|
738
|
+
The model context is built by the session's canonical AgentSession event history as:
|
|
663
739
|
|
|
664
740
|
1. Previous canonically accepted generations.
|
|
665
741
|
2. The normalized current user message.
|
|
666
|
-
3.
|
|
742
|
+
3. AgentSession's result messages.
|
|
667
743
|
|
|
668
744
|
A failed or cancelled prompt remains visible through `getMessages()`, with `failed` or `cancelled` status, but is not included in future model context. Canonical Agent events remain private and are not exposed by the session or message APIs.
|
|
669
745
|
|
|
@@ -697,7 +773,7 @@ Pending requests are runtime-only and queryable with `listPendingPermissions()`.
|
|
|
697
773
|
|
|
698
774
|
## Tool Output Safety
|
|
699
775
|
|
|
700
|
-
FlexHarness wraps every provided tool `execute` method before
|
|
776
|
+
FlexHarness wraps every provided tool `execute` method before AgentSession receives it. Direct outputs and every `AsyncIterable` yield are converted into bounded JSON-safe values. Circular references, functions, symbols, bigint values, dates, URLs, and binary values receive deterministic descriptions or records. Returned error objects and unreadable getter values receive fixed descriptions without their original messages. Thrown errors and iterator failures remain failures but are converted to the safe external-error projection before AgentSession observes them.
|
|
701
777
|
|
|
702
778
|
`toolOutputLimits` in the complete setup above bounds traversal depth and encoded bytes. The normalizer enforces its byte allowance incrementally: oversized strings are replaced before entering output, and arrays/objects stop reading entries once only truncation metadata fits.
|
|
703
779
|
|
|
@@ -715,9 +791,9 @@ Model resolver, tool provider, delegated run admission provider, AgentSession, t
|
|
|
715
791
|
|
|
716
792
|
Transactional tool calls persist an execution intent before the tool side effect starts. After an interrupted process, `listUncertainToolExecutions()` exposes intents whose outcome cannot be proven. A controller must inspect the external system and call `reconcileToolExecution()` with `executed`, `not-executed`, or `abandoned-unknown` before allowing dependent work to continue. Reconciliation output is normalized using the same tool-output limits.
|
|
717
793
|
|
|
718
|
-
`agentSessionPolicy` forwards bounded
|
|
794
|
+
`agentSessionPolicy` forwards bounded AgentSession session controls for context building, compaction, event retention, change-listener pressure, lease cleanup, archived transaction tombstones, and context-overflow retries. A configured `contextCompactor` receives the projected model messages, only the filtered model-visible covered events, AgentSession's existing `reason` and `abortSignal`, and the exact resolved `scopeId`, `scope`, `storageKey`, and `sessionId` for the invocation causing compaction. The invocation context remains isolated when aliases share one storage key, so integrations can resolve the correct model without global mutable state. If no events are eligible for compaction, `compactSession()` returns without calling the compactor or writing a compaction event; otherwise it writes the canonical event. `archiveSessionEvents()` moves events covered by that compaction into the configured Agent event archive store and returns public archive metadata.
|
|
719
795
|
|
|
720
|
-
`executionContextProvider` can construct a
|
|
796
|
+
`executionContextProvider` can construct a AgentSession execution context for each session. FlexHarness supplies the resolved scope, storage key, and the session's private job store. The public background APIs expose only execution ID, type, state, exit code, and timestamps; command payloads, stdout, and stderr remain private. The provider's optional `close()` is owned by session deletion, scope retirement, and harness disposal.
|
|
721
797
|
|
|
722
798
|
## Events
|
|
723
799
|
|
|
@@ -780,7 +856,7 @@ Current FlexHarness persistence is separated by trust and lifecycle domain throu
|
|
|
780
856
|
- `projections`: public audit messages and hidden terminal stages per session.
|
|
781
857
|
- `permissions`: remembered permission keys per session.
|
|
782
858
|
- `projectManagement`: generation-fenced task, goal, and scratchpad state per session.
|
|
783
|
-
- `agentEvents`: canonical private
|
|
859
|
+
- `agentEvents`: canonical private AgentSession events and archives per session.
|
|
784
860
|
- `jobs`: private background execution state per session.
|
|
785
861
|
|
|
786
862
|
`InMemoryFlexHarnessStores` implements all six required domains with revision-based compare-and-swap behavior for tests and ephemeral processes. It is the default when `stores` is omitted. Custom `IFlexHarnessStores` implementations must provide `projectManagement` even when project-management tools are disabled, because deletion cleanup always writes the generation fence.
|
|
@@ -800,7 +876,7 @@ After every harness using a `JsonFileFlexHarnessStores` instance has been dispos
|
|
|
800
876
|
|
|
801
877
|
The JSON stores are explicitly not cross-process safe. When several processes can access the same storage namespace, every core `IFlexHarnessStores` domain and `stores.projectManagement` must use database-backed or equivalent cross-process CAS. Process-local CAS for the core stores or for PM alone is insufficient: session generation creation, cleanup tombstones, PM replacement, and stale-writer rejection must all retain their respective atomic preconditions across processes.
|
|
802
878
|
|
|
803
|
-
Direct store operations and non-run session mutations surface conflicts as `FlexHarnessStoreConflictError` or the corresponding
|
|
879
|
+
Direct store operations and non-run session mutations surface conflicts as `FlexHarnessStoreConflictError` or the corresponding AgentSession store conflict. Malformed, wrong-schema, or non-JSON snapshots are surfaced as `FlexHarnessStoreFormatError`. A write or deletion that changed its target but cannot confirm parent-directory durability surfaces `FlexHarnessStoreCommitUncertainError` with the affected path, operation, and cause. Run persistence failures cross the external error boundary and therefore become `FlexHarnessExternalError`. FlexHarness does not merge conflicts.
|
|
804
880
|
|
|
805
881
|
Each domain serializes its own mutations. A successful run first persists a hidden completed projection, then finalizes the canonical Agent generation as `accepted`, then promotes the hidden projection publicly. Recovery uses the canonical generation outcome to promote an accepted stage or publish a failed/cancelled projection. Failed and cancelled generations remain auditable but never enter future model context.
|
|
806
882
|
|
|
@@ -830,7 +906,7 @@ const stores = new JsonFileFlexHarnessStores({
|
|
|
830
906
|
await migrateLegacyFlexHarnessSnapshot(storageKey, legacySnapshot, stores);
|
|
831
907
|
```
|
|
832
908
|
|
|
833
|
-
`loadLegacySnapshot()` is application-owned access to the snapshot written by the `2.x` store. The migration validates the complete source and every public run before writing. A run left streaming by a process crash is deterministically repaired to the same cancelled state that the `2.x` loader produced in memory. The migration then converts private model messages into generationless canonical Agent conversation events, records terminal
|
|
909
|
+
`loadLegacySnapshot()` is application-owned access to the snapshot written by the `2.x` store. The migration validates the complete source and every public run before writing. A run left streaming by a process crash is deterministically repaired to the same cancelled state that the `2.x` loader produced in memory. The migration then converts private model messages into generationless canonical Agent conversation events, records terminal AgentSession transactions for completed, failed, and cancelled public runs, and writes schema-3 projections with empty reversion state. Migrated history therefore remains visible and auditable but is not retroactively undoable; turns created after migration receive normal reversion segments and optional workspace captures. The migration preflights the scope, projection, permission, Agent event, and job destinations before any write, applies missing per-session domains first, and publishes scope discovery last. It is safe to rerun after no work, a completed prefix, or a complete migration when existing destination content is identical. It fails closed when a destination contains conflicting content or non-empty jobs. Keep the legacy snapshot until the migrated application has loaded and verified every storage namespace.
|
|
834
910
|
|
|
835
911
|
## Shutdown
|
|
836
912
|
|
package/ts/00_commitinfo_data.ts
CHANGED
|
@@ -3,6 +3,6 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export const commitinfo = {
|
|
5
5
|
name: '@modelprofile.com/flexharness',
|
|
6
|
-
version: '
|
|
7
|
-
description: '
|
|
6
|
+
version: '6.0.0',
|
|
7
|
+
description: 'The FlexHarness toolbox source repository and shared dependency catalog.'
|
|
8
8
|
}
|
package/ts/plugins.ts
CHANGED
|
@@ -20,7 +20,7 @@ import {
|
|
|
20
20
|
validateAgentEventArchiveV2,
|
|
21
21
|
validateAgentEventSnapshotV2,
|
|
22
22
|
z,
|
|
23
|
-
} from '@
|
|
23
|
+
} from '@modelprofile.com/flexharness-agent';
|
|
24
24
|
|
|
25
25
|
export {
|
|
26
26
|
AgentEventStoreConflictError,
|
|
@@ -64,4 +64,4 @@ export type {
|
|
|
64
64
|
TAgentGenerationOutcome,
|
|
65
65
|
TAgentToolCallFinishEvent,
|
|
66
66
|
TAgentToolExecutionReconciliationOptions,
|
|
67
|
-
} from '@
|
|
67
|
+
} from '@modelprofile.com/flexharness-agent';
|