@orkestrel/study 0.0.1 → 0.0.3
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 +63 -1
- package/dist/bin/main.js +2 -5399
- package/dist/bin/main.js.map +1 -1
- package/dist/src/core/index.cjs +105 -19
- package/dist/src/core/index.cjs.map +1 -1
- package/dist/src/core/index.d.cts +83 -12
- package/dist/src/core/index.d.ts +83 -12
- package/dist/src/core/index.js +104 -21
- package/dist/src/core/index.js.map +1 -1
- package/dist/src/server/index.cjs +3941 -3595
- package/dist/src/server/index.cjs.map +1 -1
- package/dist/src/server/index.d.cts +1018 -451
- package/dist/src/server/index.d.ts +1018 -451
- package/dist/src/server/index.js +3115 -2823
- package/dist/src/server/index.js.map +1 -1
- package/package.json +18 -9
|
@@ -84,8 +84,8 @@ export declare function computeStudyOutputStop(bytes: number, limit: number, out
|
|
|
84
84
|
export declare function computeStudyScores(manifest: StudyManifest, rubric: StudyRubric, grading: StudyGrading): readonly StudyScore[];
|
|
85
85
|
|
|
86
86
|
/**
|
|
87
|
-
* Records an error
|
|
88
|
-
* @param ticket - The admitted request whose work
|
|
87
|
+
* Records an error thrown by admitted work as the failure of its ticket.
|
|
88
|
+
* @param ticket - The admitted request whose work threw
|
|
89
89
|
* @param error - The caught value, read through `readStudyFailure`
|
|
90
90
|
* @param role - The responsibility that replaces any role the reading carries; Default: the carried role, else the ticket's admitted role
|
|
91
91
|
* @remarks
|
|
@@ -94,7 +94,7 @@ export declare function computeStudyScores(manifest: StudyManifest, rubric: Stud
|
|
|
94
94
|
* so the parent's ownership is respected rather than inferred as local settlement. A refusal
|
|
95
95
|
* thrown by the ticket's own settlement propagates.
|
|
96
96
|
* @throws Thrown when the ticket's settlement refuses the failure.
|
|
97
|
-
* @example Fail an
|
|
97
|
+
* @example Fail an admitted request
|
|
98
98
|
* ```ts
|
|
99
99
|
* import type { StudyTicket } from '@orkestrel/study'
|
|
100
100
|
* import { failStudyTicket } from '@orkestrel/study'
|
|
@@ -112,6 +112,17 @@ export declare function failStudyTicket(ticket: StudyTicket, error: unknown, rol
|
|
|
112
112
|
*/
|
|
113
113
|
export declare function failureToStudyError(failure: StudyFailure): StudyError;
|
|
114
114
|
|
|
115
|
+
/**
|
|
116
|
+
* Checks whether a value is a gauge with a finite positive scale and a finite nonnegative overhead.
|
|
117
|
+
* @param value - The candidate gauge; additional members are admitted
|
|
118
|
+
* @returns True if the gauge readings are finite and within their bounds; false otherwise
|
|
119
|
+
* @example
|
|
120
|
+
* ```ts
|
|
121
|
+
* isStudyAgentGauge({ scale: 1, overhead: 0 }) // true
|
|
122
|
+
* ```
|
|
123
|
+
*/
|
|
124
|
+
export declare function isStudyAgentGauge(value: unknown): value is LedgerGauge;
|
|
125
|
+
|
|
115
126
|
/**
|
|
116
127
|
* Checks whether a namespace exposes the Agent capabilities the instrumentation invokes.
|
|
117
128
|
* @remarks
|
|
@@ -147,6 +158,16 @@ export declare const isStudyCause: Guard<StudyCause>;
|
|
|
147
158
|
*/
|
|
148
159
|
export declare function isStudyCriterion(value: unknown): value is StudyCriterion;
|
|
149
160
|
|
|
161
|
+
/** Checks whether an owned daemon declaration pins an absolute executable and distinct models.
|
|
162
|
+
* @param value - The candidate declaration.
|
|
163
|
+
* @returns True if executable, version, environment, and model identities are valid; false otherwise.
|
|
164
|
+
* @example
|
|
165
|
+
* ```ts
|
|
166
|
+
* isStudyDaemon({ executable: 'ollama' }) // false
|
|
167
|
+
* ```
|
|
168
|
+
*/
|
|
169
|
+
export declare function isStudyDaemon(value: unknown): value is StudyDaemon;
|
|
170
|
+
|
|
150
171
|
/**
|
|
151
172
|
* Checks whether a study freezes a complete arm order for every repetition.
|
|
152
173
|
* @param value - The candidate definition
|
|
@@ -170,14 +191,15 @@ export declare function isStudyDefinition(value: unknown): value is StudyDefinit
|
|
|
170
191
|
export declare function isStudyDigest(value: unknown): value is string;
|
|
171
192
|
|
|
172
193
|
/**
|
|
173
|
-
* Narrows a caught value to
|
|
194
|
+
* Narrows a caught value to a branded study error with valid failure attribution.
|
|
174
195
|
* @remarks
|
|
175
|
-
* Recognition combines the native `Error` base, a subclass prototype,
|
|
176
|
-
*
|
|
196
|
+
* Recognition combines the native `Error` base, a subclass prototype, a declared study code,
|
|
197
|
+
* valid optional failure members, and an own {@link STUDY_ERROR_BRAND} descriptor whose value is
|
|
198
|
+
* the error itself. Subclasses can replace the name.
|
|
177
199
|
* The global key is recognized across package, ESM, CommonJS and captured module copies; it is
|
|
178
|
-
* not
|
|
200
|
+
* not proof of origin. A transparent proxy is refused because its forwarded descriptor
|
|
179
201
|
* stores the target, and an unbranded copy, an inherited brand, or a property-only lookalike
|
|
180
|
-
* stays outside the type.
|
|
202
|
+
* stays outside the type. Throwing property access returns false instead of throwing.
|
|
181
203
|
* @param value - The caught value
|
|
182
204
|
* @returns True if the value is a study error; false otherwise
|
|
183
205
|
* @example
|
|
@@ -300,6 +322,12 @@ export declare function isStudyProfile(value: unknown): value is StudyProfile;
|
|
|
300
322
|
*/
|
|
301
323
|
export declare function isStudyProvider(value: unknown): value is StudyProvider;
|
|
302
324
|
|
|
325
|
+
/** Checks whether a recording declaration bounds every serialized sidecar byte.
|
|
326
|
+
* @param value - The candidate declaration.
|
|
327
|
+
* @returns True if its byte allowance is a positive safe integer; false otherwise.
|
|
328
|
+
*/
|
|
329
|
+
export declare function isStudyRecord(value: unknown): value is StudyRecord;
|
|
330
|
+
|
|
303
331
|
/** Checks whether a value names a measured request role. */
|
|
304
332
|
export declare const isStudyRole: Guard<StudyRole>;
|
|
305
333
|
|
|
@@ -521,8 +549,8 @@ export declare const STUDY_CAUSES: readonly StudyCause[];
|
|
|
521
549
|
* Keys the own self-identity every study error stamps on itself.
|
|
522
550
|
* @remarks
|
|
523
551
|
* The global symbol registry lets every package, ESM, CommonJS and captured copy read the same
|
|
524
|
-
* key. The registry makes the key discoverable; it
|
|
525
|
-
*
|
|
552
|
+
* key. The registry makes the key discoverable; it recognizes the contract without proving
|
|
553
|
+
* its origin.
|
|
526
554
|
*/
|
|
527
555
|
export declare const STUDY_ERROR_BRAND: unique symbol;
|
|
528
556
|
|
|
@@ -743,6 +771,32 @@ export declare interface StudyCriterion {
|
|
|
743
771
|
readonly assertion: JSONValue;
|
|
744
772
|
}
|
|
745
773
|
|
|
774
|
+
/** Pins an executable and the model population an execution owns until cleanup.
|
|
775
|
+
* @remarks
|
|
776
|
+
* Study owns this declaration independently of Ollama's server API. The executable is an absolute
|
|
777
|
+
* canonical path; digest is its SHA-256 and version is the exact expected version reply. The
|
|
778
|
+
* provider URL must be a dedicated loopback origin outside port 11434. Environment entries are
|
|
779
|
+
* explicit non-secret overrides, merged by case-folded name; the host owns OLLAMA_HOST. Models
|
|
780
|
+
* have distinct names and SHA-256 digests equal to the provider's model and judge pins; shared
|
|
781
|
+
* pins require one entry. Execution
|
|
782
|
+
* verifies identity before use, unloads this population before each trial, and stops and joins
|
|
783
|
+
* on every ending. Offline replay never creates this daemon.
|
|
784
|
+
*/
|
|
785
|
+
export declare interface StudyDaemon {
|
|
786
|
+
readonly executable: string;
|
|
787
|
+
readonly digest: string;
|
|
788
|
+
readonly version: string;
|
|
789
|
+
/** Holds explicit overrides with distinct case-folded names and no NUL characters. */
|
|
790
|
+
readonly environment?: Readonly<Record<string, string>> | undefined;
|
|
791
|
+
readonly models: readonly StudyDaemonModel[];
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
/** Pins one model the declared daemon verifies and unloads before each trial. */
|
|
795
|
+
export declare interface StudyDaemonModel {
|
|
796
|
+
readonly name: string;
|
|
797
|
+
readonly digest: string;
|
|
798
|
+
}
|
|
799
|
+
|
|
746
800
|
/** Bounds each independent operation with a fresh failure owner and deadline. */
|
|
747
801
|
export declare class StudyDeadline implements StudyDeadlineInterface {
|
|
748
802
|
#private;
|
|
@@ -922,6 +976,8 @@ export declare interface StudyManifest {
|
|
|
922
976
|
readonly bounds: StudyBounds;
|
|
923
977
|
readonly qualification: string | undefined;
|
|
924
978
|
readonly host: Readonly<Record<string, string>>;
|
|
979
|
+
/** Copies the profile's recording declaration before any trial starts. */
|
|
980
|
+
readonly record?: StudyRecord | undefined;
|
|
925
981
|
}
|
|
926
982
|
|
|
927
983
|
/** Admits request ceilings across every enclosing scope before dispatch. */
|
|
@@ -989,6 +1045,8 @@ export declare interface StudyProfile {
|
|
|
989
1045
|
readonly qualification: string | undefined;
|
|
990
1046
|
/** Holds driver-owned JSON; the driver owns its interpretation and Study only validates and owns the object. */
|
|
991
1047
|
readonly settings: Readonly<Record<string, JSONValue>> | undefined;
|
|
1048
|
+
/** Requires one bounded exchange sidecar for every trial when present. */
|
|
1049
|
+
readonly record?: StudyRecord | undefined;
|
|
992
1050
|
}
|
|
993
1051
|
|
|
994
1052
|
/** Holds caller-selected provider artifacts and model identities. */
|
|
@@ -1004,11 +1062,24 @@ export declare interface StudyProvider {
|
|
|
1004
1062
|
/** Pins the judge model; declared together with its name or both absent. */
|
|
1005
1063
|
readonly judge: string | undefined;
|
|
1006
1064
|
};
|
|
1065
|
+
/** Declares an execution-owned daemon at this provider's dedicated URL. */
|
|
1066
|
+
readonly daemon?: StudyDaemon;
|
|
1007
1067
|
}
|
|
1008
1068
|
|
|
1009
1069
|
/** Names the evidence a study can establish. */
|
|
1010
1070
|
export declare type StudyPurpose = 'mechanism' | 'quality' | 'capacity';
|
|
1011
1071
|
|
|
1072
|
+
/** Bounds the serialized exchange sidecar retained for each scheduled trial.
|
|
1073
|
+
* @remarks
|
|
1074
|
+
* Bytes is a positive safe integer counting all UTF-8 JSONL bytes, including declarations,
|
|
1075
|
+
* base64 expansion, terminal records, and LF separators. Recording is independent of passive
|
|
1076
|
+
* observation. Sidecars have their own trial allowance and also consume series custody capacity;
|
|
1077
|
+
* they do not consume the goal evidence allowance or the model's request quota.
|
|
1078
|
+
*/
|
|
1079
|
+
export declare interface StudyRecord {
|
|
1080
|
+
readonly bytes: number;
|
|
1081
|
+
}
|
|
1082
|
+
|
|
1012
1083
|
/** Settles an admitted request once and propagates operational failure to its owner. */
|
|
1013
1084
|
export declare class StudyRequest implements StudyTicket {
|
|
1014
1085
|
#private;
|
|
@@ -1039,7 +1110,7 @@ export declare interface StudyRequestOptions {
|
|
|
1039
1110
|
}
|
|
1040
1111
|
|
|
1041
1112
|
/** Names a request's measured responsibility. */
|
|
1042
|
-
export declare type StudyRole = 'agent' | 'judge' | 'summary' | 'metadata' | 'tool';
|
|
1113
|
+
export declare type StudyRole = 'agent' | 'judge' | 'summary' | 'metadata' | 'maintenance' | 'tool';
|
|
1043
1114
|
|
|
1044
1115
|
/** Holds the model context and generation allowance as separate measurements. */
|
|
1045
1116
|
export declare interface StudyRoom {
|
|
@@ -1308,7 +1379,7 @@ export declare function validateStudyAgentUsage(usage: ProviderResult['usage'],
|
|
|
1308
1379
|
* @param rubric - The independently held grading declaration
|
|
1309
1380
|
* @param profile - The execution bounds and model room
|
|
1310
1381
|
* @returns Nothing when every cross-input invariant holds
|
|
1311
|
-
* @throws StudyError - Thrown when any input or cross-reference is invalid
|
|
1382
|
+
* @throws StudyError - Thrown when any input or cross-reference is invalid, or a quality study has no capacity qualification
|
|
1312
1383
|
* @example
|
|
1313
1384
|
* ```ts
|
|
1314
1385
|
* validateStudyInputs(definition, scenarios, rubric, profile)
|
package/dist/src/core/index.d.ts
CHANGED
|
@@ -84,8 +84,8 @@ export declare function computeStudyOutputStop(bytes: number, limit: number, out
|
|
|
84
84
|
export declare function computeStudyScores(manifest: StudyManifest, rubric: StudyRubric, grading: StudyGrading): readonly StudyScore[];
|
|
85
85
|
|
|
86
86
|
/**
|
|
87
|
-
* Records an error
|
|
88
|
-
* @param ticket - The admitted request whose work
|
|
87
|
+
* Records an error thrown by admitted work as the failure of its ticket.
|
|
88
|
+
* @param ticket - The admitted request whose work threw
|
|
89
89
|
* @param error - The caught value, read through `readStudyFailure`
|
|
90
90
|
* @param role - The responsibility that replaces any role the reading carries; Default: the carried role, else the ticket's admitted role
|
|
91
91
|
* @remarks
|
|
@@ -94,7 +94,7 @@ export declare function computeStudyScores(manifest: StudyManifest, rubric: Stud
|
|
|
94
94
|
* so the parent's ownership is respected rather than inferred as local settlement. A refusal
|
|
95
95
|
* thrown by the ticket's own settlement propagates.
|
|
96
96
|
* @throws Thrown when the ticket's settlement refuses the failure.
|
|
97
|
-
* @example Fail an
|
|
97
|
+
* @example Fail an admitted request
|
|
98
98
|
* ```ts
|
|
99
99
|
* import type { StudyTicket } from '@orkestrel/study'
|
|
100
100
|
* import { failStudyTicket } from '@orkestrel/study'
|
|
@@ -112,6 +112,17 @@ export declare function failStudyTicket(ticket: StudyTicket, error: unknown, rol
|
|
|
112
112
|
*/
|
|
113
113
|
export declare function failureToStudyError(failure: StudyFailure): StudyError;
|
|
114
114
|
|
|
115
|
+
/**
|
|
116
|
+
* Checks whether a value is a gauge with a finite positive scale and a finite nonnegative overhead.
|
|
117
|
+
* @param value - The candidate gauge; additional members are admitted
|
|
118
|
+
* @returns True if the gauge readings are finite and within their bounds; false otherwise
|
|
119
|
+
* @example
|
|
120
|
+
* ```ts
|
|
121
|
+
* isStudyAgentGauge({ scale: 1, overhead: 0 }) // true
|
|
122
|
+
* ```
|
|
123
|
+
*/
|
|
124
|
+
export declare function isStudyAgentGauge(value: unknown): value is LedgerGauge;
|
|
125
|
+
|
|
115
126
|
/**
|
|
116
127
|
* Checks whether a namespace exposes the Agent capabilities the instrumentation invokes.
|
|
117
128
|
* @remarks
|
|
@@ -147,6 +158,16 @@ export declare const isStudyCause: Guard<StudyCause>;
|
|
|
147
158
|
*/
|
|
148
159
|
export declare function isStudyCriterion(value: unknown): value is StudyCriterion;
|
|
149
160
|
|
|
161
|
+
/** Checks whether an owned daemon declaration pins an absolute executable and distinct models.
|
|
162
|
+
* @param value - The candidate declaration.
|
|
163
|
+
* @returns True if executable, version, environment, and model identities are valid; false otherwise.
|
|
164
|
+
* @example
|
|
165
|
+
* ```ts
|
|
166
|
+
* isStudyDaemon({ executable: 'ollama' }) // false
|
|
167
|
+
* ```
|
|
168
|
+
*/
|
|
169
|
+
export declare function isStudyDaemon(value: unknown): value is StudyDaemon;
|
|
170
|
+
|
|
150
171
|
/**
|
|
151
172
|
* Checks whether a study freezes a complete arm order for every repetition.
|
|
152
173
|
* @param value - The candidate definition
|
|
@@ -170,14 +191,15 @@ export declare function isStudyDefinition(value: unknown): value is StudyDefinit
|
|
|
170
191
|
export declare function isStudyDigest(value: unknown): value is string;
|
|
171
192
|
|
|
172
193
|
/**
|
|
173
|
-
* Narrows a caught value to
|
|
194
|
+
* Narrows a caught value to a branded study error with valid failure attribution.
|
|
174
195
|
* @remarks
|
|
175
|
-
* Recognition combines the native `Error` base, a subclass prototype,
|
|
176
|
-
*
|
|
196
|
+
* Recognition combines the native `Error` base, a subclass prototype, a declared study code,
|
|
197
|
+
* valid optional failure members, and an own {@link STUDY_ERROR_BRAND} descriptor whose value is
|
|
198
|
+
* the error itself. Subclasses can replace the name.
|
|
177
199
|
* The global key is recognized across package, ESM, CommonJS and captured module copies; it is
|
|
178
|
-
* not
|
|
200
|
+
* not proof of origin. A transparent proxy is refused because its forwarded descriptor
|
|
179
201
|
* stores the target, and an unbranded copy, an inherited brand, or a property-only lookalike
|
|
180
|
-
* stays outside the type.
|
|
202
|
+
* stays outside the type. Throwing property access returns false instead of throwing.
|
|
181
203
|
* @param value - The caught value
|
|
182
204
|
* @returns True if the value is a study error; false otherwise
|
|
183
205
|
* @example
|
|
@@ -300,6 +322,12 @@ export declare function isStudyProfile(value: unknown): value is StudyProfile;
|
|
|
300
322
|
*/
|
|
301
323
|
export declare function isStudyProvider(value: unknown): value is StudyProvider;
|
|
302
324
|
|
|
325
|
+
/** Checks whether a recording declaration bounds every serialized sidecar byte.
|
|
326
|
+
* @param value - The candidate declaration.
|
|
327
|
+
* @returns True if its byte allowance is a positive safe integer; false otherwise.
|
|
328
|
+
*/
|
|
329
|
+
export declare function isStudyRecord(value: unknown): value is StudyRecord;
|
|
330
|
+
|
|
303
331
|
/** Checks whether a value names a measured request role. */
|
|
304
332
|
export declare const isStudyRole: Guard<StudyRole>;
|
|
305
333
|
|
|
@@ -521,8 +549,8 @@ export declare const STUDY_CAUSES: readonly StudyCause[];
|
|
|
521
549
|
* Keys the own self-identity every study error stamps on itself.
|
|
522
550
|
* @remarks
|
|
523
551
|
* The global symbol registry lets every package, ESM, CommonJS and captured copy read the same
|
|
524
|
-
* key. The registry makes the key discoverable; it
|
|
525
|
-
*
|
|
552
|
+
* key. The registry makes the key discoverable; it recognizes the contract without proving
|
|
553
|
+
* its origin.
|
|
526
554
|
*/
|
|
527
555
|
export declare const STUDY_ERROR_BRAND: unique symbol;
|
|
528
556
|
|
|
@@ -743,6 +771,32 @@ export declare interface StudyCriterion {
|
|
|
743
771
|
readonly assertion: JSONValue;
|
|
744
772
|
}
|
|
745
773
|
|
|
774
|
+
/** Pins an executable and the model population an execution owns until cleanup.
|
|
775
|
+
* @remarks
|
|
776
|
+
* Study owns this declaration independently of Ollama's server API. The executable is an absolute
|
|
777
|
+
* canonical path; digest is its SHA-256 and version is the exact expected version reply. The
|
|
778
|
+
* provider URL must be a dedicated loopback origin outside port 11434. Environment entries are
|
|
779
|
+
* explicit non-secret overrides, merged by case-folded name; the host owns OLLAMA_HOST. Models
|
|
780
|
+
* have distinct names and SHA-256 digests equal to the provider's model and judge pins; shared
|
|
781
|
+
* pins require one entry. Execution
|
|
782
|
+
* verifies identity before use, unloads this population before each trial, and stops and joins
|
|
783
|
+
* on every ending. Offline replay never creates this daemon.
|
|
784
|
+
*/
|
|
785
|
+
export declare interface StudyDaemon {
|
|
786
|
+
readonly executable: string;
|
|
787
|
+
readonly digest: string;
|
|
788
|
+
readonly version: string;
|
|
789
|
+
/** Holds explicit overrides with distinct case-folded names and no NUL characters. */
|
|
790
|
+
readonly environment?: Readonly<Record<string, string>> | undefined;
|
|
791
|
+
readonly models: readonly StudyDaemonModel[];
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
/** Pins one model the declared daemon verifies and unloads before each trial. */
|
|
795
|
+
export declare interface StudyDaemonModel {
|
|
796
|
+
readonly name: string;
|
|
797
|
+
readonly digest: string;
|
|
798
|
+
}
|
|
799
|
+
|
|
746
800
|
/** Bounds each independent operation with a fresh failure owner and deadline. */
|
|
747
801
|
export declare class StudyDeadline implements StudyDeadlineInterface {
|
|
748
802
|
#private;
|
|
@@ -922,6 +976,8 @@ export declare interface StudyManifest {
|
|
|
922
976
|
readonly bounds: StudyBounds;
|
|
923
977
|
readonly qualification: string | undefined;
|
|
924
978
|
readonly host: Readonly<Record<string, string>>;
|
|
979
|
+
/** Copies the profile's recording declaration before any trial starts. */
|
|
980
|
+
readonly record?: StudyRecord | undefined;
|
|
925
981
|
}
|
|
926
982
|
|
|
927
983
|
/** Admits request ceilings across every enclosing scope before dispatch. */
|
|
@@ -989,6 +1045,8 @@ export declare interface StudyProfile {
|
|
|
989
1045
|
readonly qualification: string | undefined;
|
|
990
1046
|
/** Holds driver-owned JSON; the driver owns its interpretation and Study only validates and owns the object. */
|
|
991
1047
|
readonly settings: Readonly<Record<string, JSONValue>> | undefined;
|
|
1048
|
+
/** Requires one bounded exchange sidecar for every trial when present. */
|
|
1049
|
+
readonly record?: StudyRecord | undefined;
|
|
992
1050
|
}
|
|
993
1051
|
|
|
994
1052
|
/** Holds caller-selected provider artifacts and model identities. */
|
|
@@ -1004,11 +1062,24 @@ export declare interface StudyProvider {
|
|
|
1004
1062
|
/** Pins the judge model; declared together with its name or both absent. */
|
|
1005
1063
|
readonly judge: string | undefined;
|
|
1006
1064
|
};
|
|
1065
|
+
/** Declares an execution-owned daemon at this provider's dedicated URL. */
|
|
1066
|
+
readonly daemon?: StudyDaemon;
|
|
1007
1067
|
}
|
|
1008
1068
|
|
|
1009
1069
|
/** Names the evidence a study can establish. */
|
|
1010
1070
|
export declare type StudyPurpose = 'mechanism' | 'quality' | 'capacity';
|
|
1011
1071
|
|
|
1072
|
+
/** Bounds the serialized exchange sidecar retained for each scheduled trial.
|
|
1073
|
+
* @remarks
|
|
1074
|
+
* Bytes is a positive safe integer counting all UTF-8 JSONL bytes, including declarations,
|
|
1075
|
+
* base64 expansion, terminal records, and LF separators. Recording is independent of passive
|
|
1076
|
+
* observation. Sidecars have their own trial allowance and also consume series custody capacity;
|
|
1077
|
+
* they do not consume the goal evidence allowance or the model's request quota.
|
|
1078
|
+
*/
|
|
1079
|
+
export declare interface StudyRecord {
|
|
1080
|
+
readonly bytes: number;
|
|
1081
|
+
}
|
|
1082
|
+
|
|
1012
1083
|
/** Settles an admitted request once and propagates operational failure to its owner. */
|
|
1013
1084
|
export declare class StudyRequest implements StudyTicket {
|
|
1014
1085
|
#private;
|
|
@@ -1039,7 +1110,7 @@ export declare interface StudyRequestOptions {
|
|
|
1039
1110
|
}
|
|
1040
1111
|
|
|
1041
1112
|
/** Names a request's measured responsibility. */
|
|
1042
|
-
export declare type StudyRole = 'agent' | 'judge' | 'summary' | 'metadata' | 'tool';
|
|
1113
|
+
export declare type StudyRole = 'agent' | 'judge' | 'summary' | 'metadata' | 'maintenance' | 'tool';
|
|
1043
1114
|
|
|
1044
1115
|
/** Holds the model context and generation allowance as separate measurements. */
|
|
1045
1116
|
export declare interface StudyRoom {
|
|
@@ -1308,7 +1379,7 @@ export declare function validateStudyAgentUsage(usage: ProviderResult['usage'],
|
|
|
1308
1379
|
* @param rubric - The independently held grading declaration
|
|
1309
1380
|
* @param profile - The execution bounds and model room
|
|
1310
1381
|
* @returns Nothing when every cross-input invariant holds
|
|
1311
|
-
* @throws StudyError - Thrown when any input or cross-reference is invalid
|
|
1382
|
+
* @throws StudyError - Thrown when any input or cross-reference is invalid, or a quality study has no capacity qualification
|
|
1312
1383
|
* @example
|
|
1313
1384
|
* ```ts
|
|
1314
1385
|
* validateStudyInputs(definition, scenarios, rubric, profile)
|
package/dist/src/core/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { attempt, canonicalStringify, cloneJSONValue, holds, isArray, isError, isFiniteNumber, isJSONValue, isNonEmptyString, isObject, isRecord, literalOf } from "@orkestrel/contract";
|
|
1
|
+
import { INTRINSICS, attempt, canonicalStringify, cloneJSONValue, holds, isArray, isError, isFiniteNumber, isJSONValue, isNonEmptyString, isNumber, isObject, isRecord, literalOf } from "@orkestrel/contract";
|
|
2
2
|
import { MAX_TIMEOUT_MS, Timeout } from "@orkestrel/timeout";
|
|
3
3
|
import { Budget, isBudgetError } from "@orkestrel/budget";
|
|
4
4
|
import { Abort, linkSignal } from "@orkestrel/abort";
|
|
@@ -7,8 +7,8 @@ import { Abort, linkSignal } from "@orkestrel/abort";
|
|
|
7
7
|
* Keys the own self-identity every study error stamps on itself.
|
|
8
8
|
* @remarks
|
|
9
9
|
* The global symbol registry lets every package, ESM, CommonJS and captured copy read the same
|
|
10
|
-
* key. The registry makes the key discoverable; it
|
|
11
|
-
*
|
|
10
|
+
* key. The registry makes the key discoverable; it recognizes the contract without proving
|
|
11
|
+
* its origin.
|
|
12
12
|
*/
|
|
13
13
|
var STUDY_ERROR_BRAND = Symbol.for("@orkestrel/study.error");
|
|
14
14
|
/** Caps a declared trial population before schedule allocation. */
|
|
@@ -23,6 +23,7 @@ var STUDY_ROLES = Object.freeze([
|
|
|
23
23
|
"judge",
|
|
24
24
|
"summary",
|
|
25
25
|
"metadata",
|
|
26
|
+
"maintenance",
|
|
26
27
|
"tool"
|
|
27
28
|
]);
|
|
28
29
|
/** Lists every ceiling a run can stop at in report order. */
|
|
@@ -66,16 +67,18 @@ function omitStudyAbsent(value) {
|
|
|
66
67
|
* ```
|
|
67
68
|
*/
|
|
68
69
|
function normalizeStudyProfile(profile) {
|
|
69
|
-
const { provider, qualification, settings, room, ...required } = profile;
|
|
70
|
+
const { provider, qualification, settings, record, room, ...required } = profile;
|
|
70
71
|
return {
|
|
71
72
|
...required,
|
|
72
73
|
room: omitStudyAbsent(room),
|
|
73
74
|
...provider === void 0 ? {} : { provider: {
|
|
74
75
|
...omitStudyAbsent(provider),
|
|
75
|
-
digest: omitStudyAbsent(provider.digest)
|
|
76
|
+
digest: omitStudyAbsent(provider.digest),
|
|
77
|
+
...provider.daemon === void 0 ? {} : { daemon: omitStudyAbsent(provider.daemon) }
|
|
76
78
|
} },
|
|
77
79
|
...qualification === void 0 ? {} : { qualification },
|
|
78
|
-
...settings === void 0 ? {} : { settings }
|
|
80
|
+
...settings === void 0 ? {} : { settings },
|
|
81
|
+
...record === void 0 ? {} : { record }
|
|
79
82
|
};
|
|
80
83
|
}
|
|
81
84
|
/**
|
|
@@ -149,7 +152,7 @@ function buildStudySchedule(definition, scenarios) {
|
|
|
149
152
|
* @param rubric - The independently held grading declaration
|
|
150
153
|
* @param profile - The execution bounds and model room
|
|
151
154
|
* @returns Nothing when every cross-input invariant holds
|
|
152
|
-
* @throws StudyError - Thrown when any input or cross-reference is invalid
|
|
155
|
+
* @throws StudyError - Thrown when any input or cross-reference is invalid, or a quality study has no capacity qualification
|
|
153
156
|
* @example
|
|
154
157
|
* ```ts
|
|
155
158
|
* validateStudyInputs(definition, scenarios, rubric, profile)
|
|
@@ -166,6 +169,7 @@ function validateStudyInputs(definition, scenarios, rubric, profile) {
|
|
|
166
169
|
}
|
|
167
170
|
const covered = new Set(rubric.criteria.map((criterion) => canonicalStringify([criterion.scenario, criterion.goal]) ?? ""));
|
|
168
171
|
for (const scenario of scenarios) for (const goal of scenario.goals) if (!covered.has(canonicalStringify([scenario.id, goal.id]) ?? "")) throw new StudyError("CONFIG", "Every declared goal needs a criterion");
|
|
172
|
+
if (definition.purpose === "quality" && profile.qualification === void 0) throw new StudyError("CONFIG", "Quality studies require a capacity qualification");
|
|
169
173
|
}
|
|
170
174
|
/**
|
|
171
175
|
* Computes arm intervals over the complete declared criterion horizon.
|
|
@@ -416,15 +420,46 @@ function isStudyProvider(value) {
|
|
|
416
420
|
"url",
|
|
417
421
|
"model",
|
|
418
422
|
"digest"
|
|
419
|
-
], ["judge"]) || ![
|
|
423
|
+
], ["judge", "daemon"]) || ![
|
|
420
424
|
"entry",
|
|
421
425
|
"url",
|
|
422
426
|
"model"
|
|
423
427
|
].every((key) => isNonEmptyString(value[key])) || typeof value.url !== "string" || !isRecord(value.digest) || !matchesStudyKeys(value.digest, ["model"], ["judge"]) || !isStudyDigest(value.digest.model) || value.judge === void 0 !== (value.digest.judge === void 0) || value.judge !== void 0 && (!isNonEmptyString(value.judge) || !isStudyDigest(value.digest.judge))) return false;
|
|
424
428
|
const url = new URL(value.url);
|
|
429
|
+
if (value.daemon !== void 0) {
|
|
430
|
+
if (!isStudyDaemon(value.daemon) || !/^http:\/\/127\.0\.0\.1:[0-9]+\/?$/.test(value.url) || Number(url.port) <= 0 || Number(url.port) === 11434) return false;
|
|
431
|
+
const daemon = value.daemon;
|
|
432
|
+
const digest = value.digest;
|
|
433
|
+
if (!daemon.models.every((model) => model.name === value.model && model.digest === digest.model || value.judge !== void 0 && model.name === value.judge && model.digest === digest.judge) || !daemon.models.some((model) => model.name === value.model && model.digest === digest.model) || value.judge !== void 0 && !daemon.models.some((model) => model.name === value.judge && model.digest === digest.judge)) return false;
|
|
434
|
+
}
|
|
425
435
|
return ["http:", "https:"].includes(url.protocol) && url.username === "" && url.password === "" && url.search === "" && url.hash === "" && url.pathname === "/";
|
|
426
436
|
});
|
|
427
437
|
}
|
|
438
|
+
/** Checks whether an owned daemon declaration pins an absolute executable and distinct models.
|
|
439
|
+
* @param value - The candidate declaration.
|
|
440
|
+
* @returns True if executable, version, environment, and model identities are valid; false otherwise.
|
|
441
|
+
* @example
|
|
442
|
+
* ```ts
|
|
443
|
+
* isStudyDaemon({ executable: 'ollama' }) // false
|
|
444
|
+
* ```
|
|
445
|
+
*/
|
|
446
|
+
function isStudyDaemon(value) {
|
|
447
|
+
return holds(() => {
|
|
448
|
+
if (!isRecord(value) || !matchesStudyKeys(value, [
|
|
449
|
+
"executable",
|
|
450
|
+
"digest",
|
|
451
|
+
"version",
|
|
452
|
+
"models"
|
|
453
|
+
], ["environment"]) || typeof value.executable !== "string" || !/^(?:[A-Za-z]:[\\/]|\/(?!\/)|\\\\[^\\]+\\[^\\]+\\)/.test(value.executable) || value.executable.includes("\0") || value.executable.split(/[\\/]/).some((part) => part === "." || part === "..") || !isStudyDigest(value.digest) || !isNonEmptyString(value.version) || value.version.trim().length === 0 || value.version.includes("\0") || !isArray(value.models) || value.models.length === 0 || !value.models.every((model) => isRecord(model) && matchesStudyKeys(model, ["name", "digest"]) && isNonEmptyString(model.name) && model.name.trim().length > 0 && !model.name.includes("\0") && isStudyDigest(model.digest))) return false;
|
|
454
|
+
if (new Set(value.models.map((model) => isRecord(model) ? model.name : void 0)).size !== value.models.length) return false;
|
|
455
|
+
if (value.environment !== void 0) {
|
|
456
|
+
if (!isRecord(value.environment) || !matchesStudyKeys(value.environment, [], Object.keys(value.environment))) return false;
|
|
457
|
+
const entries = Object.entries(value.environment);
|
|
458
|
+
if (new Set(entries.map(([name]) => name.toLowerCase())).size !== entries.length || entries.some(([name, entry]) => name.length === 0 || /[=\0]/.test(name) || typeof entry !== "string" || entry.includes("\0"))) return false;
|
|
459
|
+
}
|
|
460
|
+
return true;
|
|
461
|
+
});
|
|
462
|
+
}
|
|
428
463
|
/**
|
|
429
464
|
* Checks whether a profile carries finite bounds and an optional explicit provider.
|
|
430
465
|
* @param value - The candidate profile
|
|
@@ -446,10 +481,18 @@ function isStudyProfile(value) {
|
|
|
446
481
|
], [
|
|
447
482
|
"provider",
|
|
448
483
|
"qualification",
|
|
449
|
-
"settings"
|
|
450
|
-
|
|
484
|
+
"settings",
|
|
485
|
+
"record"
|
|
486
|
+
]) && isStudyName(value.name) && isNonEmptyString(value.agent) && isArray(value.roots) && isJSONValue(value.roots) && value.roots.length > 0 && value.roots.every((root) => typeof root === "string" && root.trim().length > 0) && new Set(value.roots).size === value.roots.length && isNonEmptyString(value.subject) && isStudyBounds(value.bounds) && isStudyRoom(value.room) && (value.provider === void 0 || isStudyProvider(value.provider)) && (value.record === void 0 || isStudyRecord(value.record)) && (value.qualification === void 0 || isNonEmptyString(value.qualification)) && (value.settings === void 0 || isRecord(value.settings) && isJSONValue(value.settings));
|
|
451
487
|
});
|
|
452
488
|
}
|
|
489
|
+
/** Checks whether a recording declaration bounds every serialized sidecar byte.
|
|
490
|
+
* @param value - The candidate declaration.
|
|
491
|
+
* @returns True if its byte allowance is a positive safe integer; false otherwise.
|
|
492
|
+
*/
|
|
493
|
+
function isStudyRecord(value) {
|
|
494
|
+
return holds(() => isRecord(value) && matchesStudyKeys(value, ["bytes"]) && typeof value.bytes === "number" && Number.isSafeInteger(value.bytes) && value.bytes > 0);
|
|
495
|
+
}
|
|
453
496
|
/**
|
|
454
497
|
* Checks whether a byte identity is a lowercase SHA-256 digest.
|
|
455
498
|
* @param value - The candidate identity
|
|
@@ -630,8 +673,10 @@ var StudyError = class extends Error {
|
|
|
630
673
|
*/
|
|
631
674
|
constructor(code, message, failure) {
|
|
632
675
|
super(message);
|
|
633
|
-
|
|
676
|
+
INTRINSICS.define(this, STUDY_ERROR_BRAND, {
|
|
634
677
|
value: this,
|
|
678
|
+
enumerable: false,
|
|
679
|
+
writable: false,
|
|
635
680
|
configurable: true
|
|
636
681
|
});
|
|
637
682
|
this.name = "StudyError";
|
|
@@ -640,14 +685,15 @@ var StudyError = class extends Error {
|
|
|
640
685
|
}
|
|
641
686
|
};
|
|
642
687
|
/**
|
|
643
|
-
* Narrows a caught value to
|
|
688
|
+
* Narrows a caught value to a branded study error with valid failure attribution.
|
|
644
689
|
* @remarks
|
|
645
|
-
* Recognition combines the native `Error` base, a subclass prototype,
|
|
646
|
-
*
|
|
690
|
+
* Recognition combines the native `Error` base, a subclass prototype, a declared study code,
|
|
691
|
+
* valid optional failure members, and an own {@link STUDY_ERROR_BRAND} descriptor whose value is
|
|
692
|
+
* the error itself. Subclasses can replace the name.
|
|
647
693
|
* The global key is recognized across package, ESM, CommonJS and captured module copies; it is
|
|
648
|
-
* not
|
|
694
|
+
* not proof of origin. A transparent proxy is refused because its forwarded descriptor
|
|
649
695
|
* stores the target, and an unbranded copy, an inherited brand, or a property-only lookalike
|
|
650
|
-
* stays outside the type.
|
|
696
|
+
* stays outside the type. Throwing property access returns false instead of throwing.
|
|
651
697
|
* @param value - The caught value
|
|
652
698
|
* @returns True if the value is a study error; false otherwise
|
|
653
699
|
* @example
|
|
@@ -656,7 +702,28 @@ var StudyError = class extends Error {
|
|
|
656
702
|
* ```
|
|
657
703
|
*/
|
|
658
704
|
function isStudyError(value) {
|
|
659
|
-
return
|
|
705
|
+
return holds(() => {
|
|
706
|
+
if (!(value instanceof INTRINSICS.error) || INTRINSICS.prototype(value) === INTRINSICS.error.prototype) return false;
|
|
707
|
+
const brand = INTRINSICS.describe(value, STUDY_ERROR_BRAND)?.value;
|
|
708
|
+
const code = INTRINSICS.reflect.read(value, "code");
|
|
709
|
+
const failure = INTRINSICS.reflect.read(value, "failure");
|
|
710
|
+
const stack = INTRINSICS.reflect.read(value, "stack");
|
|
711
|
+
if (brand !== value || !isStudyErrorCode(code) || typeof INTRINSICS.reflect.read(value, "name") !== "string" || typeof INTRINSICS.reflect.read(value, "message") !== "string" || stack !== void 0 && typeof stack !== "string") return false;
|
|
712
|
+
if (failure === void 0) return true;
|
|
713
|
+
if (!isObject(failure)) return false;
|
|
714
|
+
const cause = INTRINSICS.reflect.read(failure, "cause");
|
|
715
|
+
const message = INTRINSICS.reflect.read(failure, "message");
|
|
716
|
+
const role = INTRINSICS.reflect.read(failure, "role");
|
|
717
|
+
const stop = INTRINSICS.reflect.read(failure, "stop");
|
|
718
|
+
if (!isStudyCause(cause) || typeof message !== "string" || role !== void 0 && !isStudyRole(role)) return false;
|
|
719
|
+
if (stop === void 0) return true;
|
|
720
|
+
if (!isObject(stop)) return false;
|
|
721
|
+
const layer = INTRINSICS.reflect.read(stop, "layer");
|
|
722
|
+
const id = INTRINSICS.reflect.read(stop, "id");
|
|
723
|
+
const max = INTRINSICS.reflect.read(stop, "max");
|
|
724
|
+
const consumed = INTRINSICS.reflect.read(stop, "consumed");
|
|
725
|
+
return isStudyLayer(layer) && typeof id === "string" && (max === void 0 || isNumber(max)) && (consumed === void 0 || isNumber(consumed));
|
|
726
|
+
});
|
|
660
727
|
}
|
|
661
728
|
//#endregion
|
|
662
729
|
//#region src/core/parsers.ts
|
|
@@ -920,8 +987,8 @@ function computeStudyOutputStop(bytes, limit, outputs) {
|
|
|
920
987
|
};
|
|
921
988
|
}
|
|
922
989
|
/**
|
|
923
|
-
* Records an error
|
|
924
|
-
* @param ticket - The admitted request whose work
|
|
990
|
+
* Records an error thrown by admitted work as the failure of its ticket.
|
|
991
|
+
* @param ticket - The admitted request whose work threw
|
|
925
992
|
* @param error - The caught value, read through `readStudyFailure`
|
|
926
993
|
* @param role - The responsibility that replaces any role the reading carries; Default: the carried role, else the ticket's admitted role
|
|
927
994
|
* @remarks
|
|
@@ -930,7 +997,7 @@ function computeStudyOutputStop(bytes, limit, outputs) {
|
|
|
930
997
|
* so the parent's ownership is respected rather than inferred as local settlement. A refusal
|
|
931
998
|
* thrown by the ticket's own settlement propagates.
|
|
932
999
|
* @throws Thrown when the ticket's settlement refuses the failure.
|
|
933
|
-
* @example Fail an
|
|
1000
|
+
* @example Fail an admitted request
|
|
934
1001
|
* ```ts
|
|
935
1002
|
* import type { StudyTicket } from '@orkestrel/study'
|
|
936
1003
|
* import { failStudyTicket } from '@orkestrel/study'
|
|
@@ -1876,6 +1943,22 @@ function buildStudyAgentDispatch(dispatch) {
|
|
|
1876
1943
|
//#endregion
|
|
1877
1944
|
//#region src/core/agents/validators.ts
|
|
1878
1945
|
/**
|
|
1946
|
+
* Checks whether a value is a gauge with a finite positive scale and a finite nonnegative overhead.
|
|
1947
|
+
* @param value - The candidate gauge; additional members are admitted
|
|
1948
|
+
* @returns True if the gauge readings are finite and within their bounds; false otherwise
|
|
1949
|
+
* @example
|
|
1950
|
+
* ```ts
|
|
1951
|
+
* isStudyAgentGauge({ scale: 1, overhead: 0 }) // true
|
|
1952
|
+
* ```
|
|
1953
|
+
*/
|
|
1954
|
+
function isStudyAgentGauge(value) {
|
|
1955
|
+
return holds(() => {
|
|
1956
|
+
if (!isObject(value) || !("scale" in value) || !("overhead" in value)) return false;
|
|
1957
|
+
const { scale, overhead } = value;
|
|
1958
|
+
return isFiniteNumber(scale) && scale > 0 && isFiniteNumber(overhead) && overhead >= 0;
|
|
1959
|
+
});
|
|
1960
|
+
}
|
|
1961
|
+
/**
|
|
1879
1962
|
* Checks whether a namespace exposes the Agent capabilities the instrumentation invokes.
|
|
1880
1963
|
* @remarks
|
|
1881
1964
|
* The guard reads only `estimateRequest`, `measureRequest`, and `isAgentError`, so a namespace
|
|
@@ -1995,6 +2078,6 @@ var StudyAgentJudge = class {
|
|
|
1995
2078
|
}
|
|
1996
2079
|
};
|
|
1997
2080
|
//#endregion
|
|
1998
|
-
export { STUDY_CAUSES, STUDY_ERROR_BRAND, STUDY_GOALS, STUDY_LAYERS, STUDY_NAME, STUDY_ROLES, STUDY_TRIALS, StudyAgentJudge, StudyAgentObserver, StudyControl, StudyDeadline, StudyError, StudyMeter, StudyRequest, StudyScope, StudySeries, buildStudyAgentDispatch, buildStudyAgentParts, buildStudySchedule, computeStudyAdmittedStop, computeStudyOutputStop, computeStudyScores, failStudyTicket, failureToStudyError, isStudyAgentRuntime, isStudyBounds, isStudyCause, isStudyCriterion, isStudyDefinition, isStudyDigest, isStudyError, isStudyErrorCode, isStudyGoal, isStudyGrading, isStudyJudgment, isStudyLabeling, isStudyLayer, isStudyLimit, isStudyName, isStudyProduct, isStudyProfile, isStudyProvider, isStudyRole, isStudyRoom, isStudyRubric, isStudyScenario, isStudyStop, isStudyTimestamp, isStudyUsage, matchesStudyKeys, normalizeStudyProfile, omitStudyAbsent, parseStudyDefinition, parseStudyGrading, parseStudyLabeling, parseStudyProfile, parseStudyReading, parseStudyRubric, parseStudyScenario, projectStudyAgentRequest, readStudyFailure, studyStopToJSON, translateStudyAgentError, translateStudyAgentStop, validateStudyAgentUsage, validateStudyInputs };
|
|
2081
|
+
export { STUDY_CAUSES, STUDY_ERROR_BRAND, STUDY_GOALS, STUDY_LAYERS, STUDY_NAME, STUDY_ROLES, STUDY_TRIALS, StudyAgentJudge, StudyAgentObserver, StudyControl, StudyDeadline, StudyError, StudyMeter, StudyRequest, StudyScope, StudySeries, buildStudyAgentDispatch, buildStudyAgentParts, buildStudySchedule, computeStudyAdmittedStop, computeStudyOutputStop, computeStudyScores, failStudyTicket, failureToStudyError, isStudyAgentGauge, isStudyAgentRuntime, isStudyBounds, isStudyCause, isStudyCriterion, isStudyDaemon, isStudyDefinition, isStudyDigest, isStudyError, isStudyErrorCode, isStudyGoal, isStudyGrading, isStudyJudgment, isStudyLabeling, isStudyLayer, isStudyLimit, isStudyName, isStudyProduct, isStudyProfile, isStudyProvider, isStudyRecord, isStudyRole, isStudyRoom, isStudyRubric, isStudyScenario, isStudyStop, isStudyTimestamp, isStudyUsage, matchesStudyKeys, normalizeStudyProfile, omitStudyAbsent, parseStudyDefinition, parseStudyGrading, parseStudyLabeling, parseStudyProfile, parseStudyReading, parseStudyRubric, parseStudyScenario, projectStudyAgentRequest, readStudyFailure, studyStopToJSON, translateStudyAgentError, translateStudyAgentStop, validateStudyAgentUsage, validateStudyInputs };
|
|
1999
2082
|
|
|
2000
2083
|
//# sourceMappingURL=index.js.map
|