@modelprofile.com/flexharness 5.2.0 → 5.3.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/changelog.md +10 -0
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/classes.flexharness.d.ts +10 -0
- package/dist_ts/classes.flexharness.js +338 -14
- package/dist_ts/interfaces.d.ts +28 -1
- package/package.json +1 -1
- package/readme.md +38 -4
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/classes.flexharness.ts +469 -16
- package/ts/interfaces.ts +33 -0
package/dist_ts/interfaces.d.ts
CHANGED
|
@@ -691,7 +691,7 @@ export interface IFlexUndoSessionResult {
|
|
|
691
691
|
export interface IFlexRedoSessionResult {
|
|
692
692
|
restoredRunId: string;
|
|
693
693
|
}
|
|
694
|
-
export type TFlexExternalErrorSource = 'modelResolver' | 'toolProvider' | 'toolExecution' | 'toolCallback' | 'toolCleanup' | 'agentSession' | 'persistence' | 'slashCommand' | 'turnReversion';
|
|
694
|
+
export type TFlexExternalErrorSource = 'modelResolver' | 'toolProvider' | 'delegatedRunAdmissionProvider' | 'toolExecution' | 'toolCallback' | 'toolCleanup' | 'agentSession' | 'persistence' | 'slashCommand' | 'turnReversion';
|
|
695
695
|
export interface IFlexExternalErrorContext {
|
|
696
696
|
source: TFlexExternalErrorSource;
|
|
697
697
|
scopeId: string;
|
|
@@ -699,6 +699,32 @@ export interface IFlexExternalErrorContext {
|
|
|
699
699
|
runId: string;
|
|
700
700
|
}
|
|
701
701
|
export type TFlexExternalErrorProjector = (error: unknown, context: IFlexExternalErrorContext) => IFlexErrorInfo;
|
|
702
|
+
export interface IFlexDelegatedRunAdmissionContext<TScope> extends IFlexSessionGeneration {
|
|
703
|
+
readonly scopeId: string;
|
|
704
|
+
readonly scope: TScope;
|
|
705
|
+
readonly storageKey: string;
|
|
706
|
+
readonly sessionId: string;
|
|
707
|
+
readonly sessionGenerationId: string;
|
|
708
|
+
readonly sessionGenerationSequence: number;
|
|
709
|
+
readonly queueId: string;
|
|
710
|
+
readonly runId: string;
|
|
711
|
+
readonly parentSessionId: string;
|
|
712
|
+
readonly parentSessionGenerationId: string;
|
|
713
|
+
readonly parentSessionGenerationSequence: number;
|
|
714
|
+
readonly parentQueueId: string;
|
|
715
|
+
readonly parentRunId: string;
|
|
716
|
+
readonly parentToolCallId: string;
|
|
717
|
+
readonly agent: string;
|
|
718
|
+
readonly depth: number;
|
|
719
|
+
readonly signal: AbortSignal;
|
|
720
|
+
}
|
|
721
|
+
export interface IFlexDelegatedRunAdmissionLease {
|
|
722
|
+
/** Must be idempotent and safe to retry after a rejected close attempt. */
|
|
723
|
+
close(): Promise<void> | void;
|
|
724
|
+
}
|
|
725
|
+
export interface IFlexDelegatedRunAdmissionProvider<TScope> {
|
|
726
|
+
acquireDelegatedRunAdmission(context: IFlexDelegatedRunAdmissionContext<TScope>): Promise<IFlexDelegatedRunAdmissionLease> | IFlexDelegatedRunAdmissionLease;
|
|
727
|
+
}
|
|
702
728
|
export interface IFlexExecutionContextProviderContext<TScope> {
|
|
703
729
|
scopeId: string;
|
|
704
730
|
scope: TScope;
|
|
@@ -754,6 +780,7 @@ export interface IFlexHarnessOptions<TScope> {
|
|
|
754
780
|
toolProvider?: IFlexToolProvider<TScope>;
|
|
755
781
|
resourceToolProviderResolver?: IFlexResourceToolProviderResolver<TScope>;
|
|
756
782
|
executionContextProvider?: IFlexExecutionContextProvider<TScope>;
|
|
783
|
+
delegatedRunAdmissionProvider?: IFlexDelegatedRunAdmissionProvider<TScope>;
|
|
757
784
|
stores?: IFlexHarnessStores;
|
|
758
785
|
agentSessionPolicy?: IFlexAgentSessionPolicy<TScope>;
|
|
759
786
|
toolOutputLimits?: IFlexJsonLimits;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@modelprofile.com/flexharness",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.3.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Provider-neutral model-session runtime with durable history, permissions, typed events, and pluggable local or remote tool execution.",
|
|
6
6
|
"main": "dist_ts/index.js",
|
package/readme.md
CHANGED
|
@@ -290,9 +290,43 @@ The parent tool part receives `childSessionId` in a cumulative `part.updated` ev
|
|
|
290
290
|
}
|
|
291
291
|
```
|
|
292
292
|
|
|
293
|
-
Omitting `taskId` creates a deterministic child for the parent session, run, and tool call. 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 SmartAgent's durable parent tool intent as crash authority; controllers use `listUncertainToolExecutions()` and `reconcileToolExecution()` for uncertain parent calls.
|
|
293
|
+
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 SmartAgent's durable parent tool intent as crash authority; controllers use `listUncertainToolExecutions()` and `reconcileToolExecution()` for uncertain parent calls.
|
|
294
294
|
|
|
295
|
-
Supplying `taskId` deliberately resumes an idle, live child from a later run of the same immutable parent session and the same configured agent.
|
|
295
|
+
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.
|
|
296
|
+
|
|
297
|
+
`delegatedRunAdmissionProvider` optionally adds an application-owned admission lease around each internally delegated child run. The public contracts are `IFlexDelegatedRunAdmissionProvider<TScope>`, `IFlexDelegatedRunAdmissionContext<TScope>`, and `IFlexDelegatedRunAdmissionLease`. The provider is never called for root prompts or direct public prompt APIs. It receives a frozen context containing the resolved `scopeId`, exact captured `scope`, and `storageKey`; the exact child `sessionId`, session generation, queue, and run; the exact current parent session generation, queue, run, and delegate `toolCallId`; the child agent and depth; and the child run `AbortSignal`. For `taskId` resume, `parentQueueId`, `parentRunId`, and `parentToolCallId` identify the current delegate invocation, while the durable child session retains its original `parentRunId` and `parentToolCallId` creation metadata.
|
|
298
|
+
|
|
299
|
+
```typescript
|
|
300
|
+
delegatedRunAdmissionProvider: {
|
|
301
|
+
async acquireDelegatedRunAdmission(context) {
|
|
302
|
+
const admission = await controller.acquireDelegatedRun({
|
|
303
|
+
child: {
|
|
304
|
+
sessionId: context.sessionId,
|
|
305
|
+
sessionGenerationId: context.sessionGenerationId,
|
|
306
|
+
sessionGenerationSequence: context.sessionGenerationSequence,
|
|
307
|
+
queueId: context.queueId,
|
|
308
|
+
runId: context.runId,
|
|
309
|
+
},
|
|
310
|
+
parent: {
|
|
311
|
+
sessionId: context.parentSessionId,
|
|
312
|
+
sessionGenerationId: context.parentSessionGenerationId,
|
|
313
|
+
sessionGenerationSequence: context.parentSessionGenerationSequence,
|
|
314
|
+
queueId: context.parentQueueId,
|
|
315
|
+
runId: context.parentRunId,
|
|
316
|
+
toolCallId: context.parentToolCallId,
|
|
317
|
+
},
|
|
318
|
+
signal: context.signal,
|
|
319
|
+
});
|
|
320
|
+
return {
|
|
321
|
+
close: () => admission.close(),
|
|
322
|
+
};
|
|
323
|
+
},
|
|
324
|
+
},
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
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.
|
|
328
|
+
|
|
329
|
+
For a normally acquired lease, FlexHarness gives `close()` an awaited attempt after SmartAgent 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.
|
|
296
330
|
|
|
297
331
|
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 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 and resumes that existing child after permission. 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.
|
|
298
332
|
|
|
@@ -661,9 +695,9 @@ FlexHarness wraps every provided tool `execute` method before SmartAgent receive
|
|
|
661
695
|
|
|
662
696
|
Streaming callbacks use run-local synchronous state rather than one persistence promise per source delta. Text and reasoning accumulate only in the run-local terminal projection while each source delta remains an immediate exact public event. Every distinct async-iterable tool output appears immediately as a bounded cumulative `part.updated` snapshot while the tool remains `running`, including the final yielded value before completion. Only the authoritative `part.completed` output enters the terminal projection, and failed or interrupted tools discard their transient output. `callbackLimits` bounds callback events, accumulated output bytes, and part count; overflow aborts internally with `FlexHarnessCallbackOverflowError` and the turn is recorded as failed. Reservation and terminal finalization are the normal persistence checkpoints, with permission state changes as explicit additional checkpoints.
|
|
663
697
|
|
|
664
|
-
Model resolver, tool provider, AgentSession, tool execution, tool callback, tool cleanup, and run-persistence failures cross an untrusted error boundary. By default they become a fixed immutable `FlexHarnessExternalError` before completion rejection, persistence, events, or detached-cleanup reporting. Raw external messages and aggregate members are not retained. A failed `onToolCallFinish` callback stores and accounts for only the bounded projected message; it does not otherwise reject completion, although exceeding the configured callback limits still fails the run. Scope resolution and the initial store load happen before a run exists and remain outside this boundary.
|
|
698
|
+
Model resolver, tool provider, delegated run admission provider, AgentSession, tool execution, tool callback, tool cleanup, and run-persistence failures cross an untrusted error boundary. By default they become a fixed immutable `FlexHarnessExternalError` before completion rejection, persistence, events, or detached-cleanup reporting. Raw external messages and aggregate members are not retained. A failed `onToolCallFinish` callback stores and accounts for only the bounded projected message; it does not otherwise reject completion, although exceeding the configured callback limits still fails the run. Scope resolution and the initial store load happen before a run exists and remain outside this boundary.
|
|
665
699
|
|
|
666
|
-
`externalErrorProjector` receives one of `modelResolver`, `toolProvider`, `agentSession`, `toolExecution`, `toolCallback`, `toolCleanup`, `persistence`, `slashCommand`, or `turnReversion` as its source. It may synchronously return an application-approved plain data object `{ name, message, code? }`, limited to a 128-byte name, 2048-byte message, and optional 128-byte code. Accessors, extra keys, throwing projectors, and malformed or oversized results fall back to the fixed error. Even exported FlexHarness error subclasses thrown by external integrations are reprojected. Internally created cancellation, callback-overflow, and permission errors retain their typed behavior.
|
|
700
|
+
`externalErrorProjector` receives one of `modelResolver`, `toolProvider`, `delegatedRunAdmissionProvider`, `agentSession`, `toolExecution`, `toolCallback`, `toolCleanup`, `persistence`, `slashCommand`, or `turnReversion` as its source. It may synchronously return an application-approved plain data object `{ name, message, code? }`, limited to a 128-byte name, 2048-byte message, and optional 128-byte code. Accessors, extra keys, throwing projectors, and malformed or oversized results fall back to the fixed error. Even exported FlexHarness error subclasses thrown by external integrations are reprojected. Internally created cancellation, callback-overflow, and permission errors retain their typed behavior.
|
|
667
701
|
|
|
668
702
|
`normalizeJsonValue()` is also exported for integrations that need the same conversion independently.
|
|
669
703
|
|
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: '5.
|
|
6
|
+
version: '5.3.0',
|
|
7
7
|
description: 'Provider-neutral model-session runtime with durable history, permissions, typed events, and pluggable local or remote tool execution.'
|
|
8
8
|
}
|