@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.
@@ -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.2.0",
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. It 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.
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
 
@@ -3,6 +3,6 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@modelprofile.com/flexharness',
6
- version: '5.2.0',
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
  }