@modelprofile.com/flexharness 4.1.0 → 4.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,56 @@
1
+ import { normalizeJsonValue } from './utils.json.js';
2
+ function isAsyncIterable(value) {
3
+ return Boolean(value
4
+ && (typeof value === 'object' || typeof value === 'function')
5
+ && typeof value[Symbol.asyncIterator] === 'function');
6
+ }
7
+ async function* normalizeAsyncIterable(iterable, limits, projectError) {
8
+ try {
9
+ for await (const value of iterable)
10
+ yield normalizeJsonValue(value, limits);
11
+ }
12
+ catch (error) {
13
+ throw projectError(error);
14
+ }
15
+ }
16
+ export function wrapToolSet(tools, limits, projectError) {
17
+ const wrapped = {};
18
+ for (const [name, tool] of Object.entries(tools)) {
19
+ const toolRecord = tool;
20
+ if (typeof toolRecord.execute !== 'function') {
21
+ wrapped[name] = tool;
22
+ continue;
23
+ }
24
+ const execute = toolRecord.execute;
25
+ wrapped[name] = {
26
+ ...toolRecord,
27
+ execute(input, options) {
28
+ let output;
29
+ try {
30
+ output = execute.call(tool, input, options);
31
+ if (isAsyncIterable(output)) {
32
+ return normalizeAsyncIterable(output, limits, projectError);
33
+ }
34
+ }
35
+ catch (error) {
36
+ throw projectError(error);
37
+ }
38
+ return Promise.resolve(output).then((value) => {
39
+ try {
40
+ if (isAsyncIterable(value)) {
41
+ return normalizeAsyncIterable(value, limits, projectError);
42
+ }
43
+ return normalizeJsonValue(value, limits);
44
+ }
45
+ catch (error) {
46
+ throw projectError(error);
47
+ }
48
+ }, (error) => {
49
+ throw projectError(error);
50
+ });
51
+ },
52
+ };
53
+ }
54
+ return wrapped;
55
+ }
56
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMudG9vbG91dHB1dC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL3V0aWxzLnRvb2xvdXRwdXQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFNckQsU0FBUyxlQUFlLENBQUMsS0FBYztJQUNyQyxPQUFPLE9BQU8sQ0FDWixLQUFLO1dBQ0YsQ0FBQyxPQUFPLEtBQUssS0FBSyxRQUFRLElBQUksT0FBTyxLQUFLLEtBQUssVUFBVSxDQUFDO1dBQzFELE9BQVEsS0FBOEMsQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUFDLEtBQUssVUFBVSxDQUMvRixDQUFDO0FBQ0osQ0FBQztBQUVELEtBQUssU0FBUyxDQUFDLENBQUMsc0JBQXNCLENBQ3BDLFFBQWdDLEVBQ2hDLE1BQStFLEVBQy9FLFlBQXVDO0lBRXZDLElBQUksQ0FBQztRQUNILElBQUksS0FBSyxFQUFFLE1BQU0sS0FBSyxJQUFJLFFBQVE7WUFBRSxNQUFNLGtCQUFrQixDQUFDLEtBQUssRUFBRSxNQUFNLENBQUMsQ0FBQztJQUM5RSxDQUFDO0lBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztRQUNmLE1BQU0sWUFBWSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQzVCLENBQUM7QUFDSCxDQUFDO0FBRUQsTUFBTSxVQUFVLFdBQVcsQ0FDekIsS0FBd0IsRUFDeEIsTUFBK0UsRUFDL0UsWUFBdUM7SUFFdkMsTUFBTSxPQUFPLEdBQTRCLEVBQUUsQ0FBQztJQUM1QyxLQUFLLE1BQU0sQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLElBQUksTUFBTSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDO1FBQ2pELE1BQU0sVUFBVSxHQUFHLElBQXdDLENBQUM7UUFDNUQsSUFBSSxPQUFPLFVBQVUsQ0FBQyxPQUFPLEtBQUssVUFBVSxFQUFFLENBQUM7WUFDN0MsT0FBTyxDQUFDLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQztZQUNyQixTQUFTO1FBQ1gsQ0FBQztRQUNELE1BQU0sT0FBTyxHQUFHLFVBQVUsQ0FBQyxPQUFPLENBQUM7UUFDbkMsT0FBTyxDQUFDLElBQUksQ0FBQyxHQUFHO1lBQ2QsR0FBRyxVQUFVO1lBQ2IsT0FBTyxDQUFDLEtBQWMsRUFBRSxPQUFnQjtnQkFDdEMsSUFBSSxNQUFlLENBQUM7Z0JBQ3BCLElBQUksQ0FBQztvQkFDSCxNQUFNLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsS0FBSyxFQUFFLE9BQU8sQ0FBQyxDQUFDO29CQUM1QyxJQUFJLGVBQWUsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDO3dCQUM1QixPQUFPLHNCQUFzQixDQUFDLE1BQU0sRUFBRSxNQUFNLEVBQUUsWUFBWSxDQUFDLENBQUM7b0JBQzlELENBQUM7Z0JBQ0gsQ0FBQztnQkFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO29CQUNmLE1BQU0sWUFBWSxDQUFDLEtBQUssQ0FBQyxDQUFDO2dCQUM1QixDQUFDO2dCQUNELE9BQU8sT0FBTyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQyxJQUFJLENBQ2pDLENBQUMsS0FBSyxFQUFFLEVBQUU7b0JBQ1IsSUFBSSxDQUFDO3dCQUNILElBQUksZUFBZSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUM7NEJBQzNCLE9BQU8sc0JBQXNCLENBQUMsS0FBSyxFQUFFLE1BQU0sRUFBRSxZQUFZLENBQUMsQ0FBQzt3QkFDN0QsQ0FBQzt3QkFDRCxPQUFPLGtCQUFrQixDQUFDLEtBQUssRUFBRSxNQUFNLENBQUMsQ0FBQztvQkFDM0MsQ0FBQztvQkFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO3dCQUNmLE1BQU0sWUFBWSxDQUFDLEtBQUssQ0FBQyxDQUFDO29CQUM1QixDQUFDO2dCQUNILENBQUMsRUFDRCxDQUFDLEtBQWMsRUFBRSxFQUFFO29CQUNqQixNQUFNLFlBQVksQ0FBQyxLQUFLLENBQUMsQ0FBQztnQkFDNUIsQ0FBQyxDQUNGLENBQUM7WUFDSixDQUFDO1NBQ0YsQ0FBQztJQUNKLENBQUM7SUFDRCxPQUFPLE9BQTRCLENBQUM7QUFDdEMsQ0FBQyJ9
@@ -0,0 +1,24 @@
1
+ import type { IFlexAttachmentMessagePart, IFlexMessage, IFlexModelIdentity, IFlexResolvedModel, IFlexUsage, TFlexAgentRunResult, TFlexPromptPart } from './interfaces.js';
2
+ export interface IRunResultProjection {
3
+ text: string;
4
+ steps: number;
5
+ finishReason: string;
6
+ usage: IFlexUsage;
7
+ }
8
+ export declare const maxMessagePageSize = 50;
9
+ export declare const maxMessagePageCursorBytes = 4096;
10
+ export declare const maxTransferIdentifierBytes = 512;
11
+ export declare const maxTransferMetadataBytes = 2048;
12
+ export declare const maxTransferTextBytes: number;
13
+ export declare const maxTransferPageBytes: number;
14
+ export declare function publicSnapshot<TValue>(value: TValue): TValue;
15
+ export declare function jsonBytes(value: unknown): number;
16
+ export declare function truncateUtf8(value: string, maxBytes: number): string;
17
+ export declare function requireTransferIdentifier(value: string, field: string): void;
18
+ export declare function normalizeModelIdentity(identity: IFlexModelIdentity): IFlexModelIdentity;
19
+ export declare function normalizeResolvedModel(resolvedModel: IFlexResolvedModel): IFlexResolvedModel;
20
+ export declare function normalizeRunResult(result: TFlexAgentRunResult): IRunResultProjection;
21
+ export declare function describeAttachment(part: Exclude<TFlexPromptPart, {
22
+ type: 'text';
23
+ }>): Omit<IFlexAttachmentMessagePart, 'partId' | 'type' | 'attachmentType'>;
24
+ export declare function createBoundedTransferMessage(message: IFlexMessage): IFlexMessage;
@@ -0,0 +1,195 @@
1
+ import { FlexHarnessValidationError } from './errors.js';
2
+ import { cloneSerializable, deepFreeze } from './utils.json.js';
3
+ import { validateIdentifier } from './utils.validation.js';
4
+ export const maxMessagePageSize = 50;
5
+ export const maxMessagePageCursorBytes = 4096;
6
+ export const maxTransferIdentifierBytes = 512;
7
+ export const maxTransferMetadataBytes = 2048;
8
+ export const maxTransferTextBytes = 96 * 1024;
9
+ const maxTransferMessageBytes = 480 * 1024;
10
+ export const maxTransferPageBytes = 512 * 1024;
11
+ export function publicSnapshot(value) {
12
+ return deepFreeze(cloneSerializable(value));
13
+ }
14
+ export function jsonBytes(value) {
15
+ return Buffer.byteLength(JSON.stringify(value), 'utf8');
16
+ }
17
+ export function truncateUtf8(value, maxBytes) {
18
+ if (Buffer.byteLength(value, 'utf8') <= maxBytes)
19
+ return value;
20
+ const suffix = ' [truncated]';
21
+ const suffixBytes = Buffer.byteLength(suffix, 'utf8');
22
+ let truncated = Buffer.from(value, 'utf8')
23
+ .subarray(0, Math.max(0, maxBytes - suffixBytes))
24
+ .toString('utf8')
25
+ .replace(/\uFFFD$/u, '');
26
+ while (Buffer.byteLength(`${truncated}${suffix}`, 'utf8') > maxBytes) {
27
+ truncated = truncated.slice(0, -1);
28
+ }
29
+ return `${truncated}${suffix}`;
30
+ }
31
+ export function requireTransferIdentifier(value, field) {
32
+ if (Buffer.byteLength(value, 'utf8') > maxTransferIdentifierBytes) {
33
+ throw new FlexHarnessValidationError(`${field} exceeds the transfer limit.`);
34
+ }
35
+ }
36
+ export function normalizeModelIdentity(identity) {
37
+ const normalized = {
38
+ provider: identity.provider,
39
+ model: identity.model,
40
+ ...(identity.displayName === undefined ? {} : { displayName: identity.displayName }),
41
+ ...(identity.variant === undefined ? {} : { variant: identity.variant }),
42
+ };
43
+ validateIdentifier(normalized.provider, 'model identity provider');
44
+ validateIdentifier(normalized.model, 'model identity model');
45
+ if (normalized.displayName !== undefined) {
46
+ validateIdentifier(normalized.displayName, 'model identity displayName');
47
+ }
48
+ if (normalized.variant !== undefined)
49
+ validateIdentifier(normalized.variant, 'model identity variant');
50
+ if (Buffer.byteLength(normalized.provider, 'utf8') > maxTransferIdentifierBytes
51
+ || Buffer.byteLength(normalized.model, 'utf8') > maxTransferIdentifierBytes
52
+ || (normalized.displayName !== undefined
53
+ && Buffer.byteLength(normalized.displayName, 'utf8') > maxTransferMetadataBytes)
54
+ || (normalized.variant !== undefined && Buffer.byteLength(normalized.variant, 'utf8') > 128)) {
55
+ throw new FlexHarnessValidationError('Model identity exceeds its transfer limit.');
56
+ }
57
+ return normalized;
58
+ }
59
+ export function normalizeResolvedModel(resolvedModel) {
60
+ return {
61
+ model: resolvedModel.model,
62
+ identity: normalizeModelIdentity(resolvedModel.identity),
63
+ ...(resolvedModel.system === undefined ? {} : { system: resolvedModel.system }),
64
+ ...(resolvedModel.providerOptions === undefined
65
+ ? {}
66
+ : { providerOptions: resolvedModel.providerOptions }),
67
+ ...(resolvedModel.cache === undefined ? {} : { cache: resolvedModel.cache }),
68
+ ...(resolvedModel.maxSteps === undefined ? {} : { maxSteps: resolvedModel.maxSteps }),
69
+ };
70
+ }
71
+ export function normalizeRunResult(result) {
72
+ const normalized = {
73
+ text: result.text,
74
+ steps: result.steps,
75
+ finishReason: result.finishReason,
76
+ usage: {
77
+ inputTokens: result.usage.inputTokens,
78
+ outputTokens: result.usage.outputTokens,
79
+ totalTokens: result.usage.totalTokens,
80
+ cacheReadTokens: result.usage.cacheReadTokens,
81
+ cacheWriteTokens: result.usage.cacheWriteTokens,
82
+ },
83
+ };
84
+ if (typeof normalized.text !== 'string'
85
+ || typeof normalized.finishReason !== 'string'
86
+ || !Number.isSafeInteger(normalized.steps)
87
+ || normalized.steps < 0
88
+ || Object.values(normalized.usage).some((value) => !Number.isFinite(value) || value < 0)) {
89
+ throw new FlexHarnessValidationError('Agent generation result is invalid.');
90
+ }
91
+ return normalized;
92
+ }
93
+ function base64Size(data) {
94
+ const compact = data.replace(/\s/g, '');
95
+ if (!/^[A-Za-z0-9+/]*={0,2}$/.test(compact) || compact.length % 4 === 1)
96
+ return undefined;
97
+ return Buffer.from(compact, 'base64').byteLength;
98
+ }
99
+ export function describeAttachment(part) {
100
+ let source = 'inline-base64';
101
+ let sizeBytes;
102
+ let inferredMediaType;
103
+ if (/^data:/i.test(part.data)) {
104
+ source = 'data-url';
105
+ const commaIndex = part.data.indexOf(',');
106
+ if (commaIndex >= 0) {
107
+ const metadata = part.data.slice(5, commaIndex);
108
+ const payload = part.data.slice(commaIndex + 1);
109
+ const metadataParts = metadata.split(';');
110
+ if (metadataParts[0]?.includes('/'))
111
+ inferredMediaType = metadataParts[0];
112
+ if (metadataParts.some((entry) => entry.toLowerCase() === 'base64')) {
113
+ sizeBytes = base64Size(payload);
114
+ }
115
+ else {
116
+ try {
117
+ sizeBytes = Buffer.byteLength(decodeURIComponent(payload));
118
+ }
119
+ catch {
120
+ // Malformed URL encoding leaves size unknown without exposing the payload.
121
+ }
122
+ }
123
+ }
124
+ }
125
+ else {
126
+ try {
127
+ const url = new URL(part.data);
128
+ if (url.protocol === 'http:' || url.protocol === 'https:')
129
+ source = 'remote-url';
130
+ else
131
+ sizeBytes = base64Size(part.data);
132
+ }
133
+ catch {
134
+ sizeBytes = base64Size(part.data);
135
+ }
136
+ }
137
+ return {
138
+ source,
139
+ ...(sizeBytes === undefined ? {} : { sizeBytes }),
140
+ ...(part.mediaType ?? inferredMediaType
141
+ ? { mediaType: part.mediaType ?? inferredMediaType }
142
+ : {}),
143
+ ...(part.name ? { name: part.name } : {}),
144
+ };
145
+ }
146
+ export function createBoundedTransferMessage(message) {
147
+ const projected = cloneSerializable(message);
148
+ requireTransferIdentifier(projected.messageId, 'messageId');
149
+ requireTransferIdentifier(projected.sessionId, 'sessionId');
150
+ requireTransferIdentifier(projected.runId, 'runId');
151
+ projected.createdAt = truncateUtf8(projected.createdAt, 128);
152
+ if (projected.completedAt !== undefined)
153
+ projected.completedAt = truncateUtf8(projected.completedAt, 128);
154
+ if (projected.error !== undefined)
155
+ projected.error = truncateUtf8(projected.error, maxTransferMetadataBytes);
156
+ if (projected.model) {
157
+ projected.model.provider = truncateUtf8(projected.model.provider, maxTransferIdentifierBytes);
158
+ projected.model.model = truncateUtf8(projected.model.model, maxTransferIdentifierBytes);
159
+ if (projected.model.displayName !== undefined) {
160
+ projected.model.displayName = truncateUtf8(projected.model.displayName, maxTransferMetadataBytes);
161
+ }
162
+ if (projected.model.variant !== undefined)
163
+ projected.model.variant = truncateUtf8(projected.model.variant, 128);
164
+ }
165
+ for (const part of projected.parts) {
166
+ requireTransferIdentifier(part.partId, 'partId');
167
+ if (part.type === 'text' || part.type === 'reasoning') {
168
+ part.text = truncateUtf8(part.text, maxTransferTextBytes);
169
+ }
170
+ else if (part.type === 'tool') {
171
+ part.toolCallId = truncateUtf8(part.toolCallId, maxTransferIdentifierBytes);
172
+ part.toolName = truncateUtf8(part.toolName, maxTransferIdentifierBytes);
173
+ if (part.error !== undefined)
174
+ part.error = truncateUtf8(part.error, maxTransferMetadataBytes);
175
+ }
176
+ else {
177
+ if (part.mediaType !== undefined)
178
+ part.mediaType = truncateUtf8(part.mediaType, maxTransferIdentifierBytes);
179
+ if (part.name !== undefined)
180
+ part.name = truncateUtf8(part.name, maxTransferMetadataBytes);
181
+ }
182
+ }
183
+ if (jsonBytes(projected) > maxTransferMessageBytes) {
184
+ projected.parts = [{
185
+ partId: 'transfer-elided',
186
+ type: 'text',
187
+ text: '[elided: message exceeds the transfer budget]',
188
+ }];
189
+ }
190
+ if (jsonBytes(projected) > maxTransferMessageBytes) {
191
+ throw new FlexHarnessValidationError('Stored message metadata exceeds the transfer limit.');
192
+ }
193
+ return projected;
194
+ }
195
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMudHJhbnNmZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy91dGlscy50cmFuc2Zlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsMEJBQTBCLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFXekQsT0FBTyxFQUFFLGlCQUFpQixFQUFFLFVBQVUsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ2hFLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBUzNELE1BQU0sQ0FBQyxNQUFNLGtCQUFrQixHQUFHLEVBQUUsQ0FBQztBQUNyQyxNQUFNLENBQUMsTUFBTSx5QkFBeUIsR0FBRyxJQUFJLENBQUM7QUFDOUMsTUFBTSxDQUFDLE1BQU0sMEJBQTBCLEdBQUcsR0FBRyxDQUFDO0FBQzlDLE1BQU0sQ0FBQyxNQUFNLHdCQUF3QixHQUFHLElBQUksQ0FBQztBQUM3QyxNQUFNLENBQUMsTUFBTSxvQkFBb0IsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDO0FBQzlDLE1BQU0sdUJBQXVCLEdBQUcsR0FBRyxHQUFHLElBQUksQ0FBQztBQUMzQyxNQUFNLENBQUMsTUFBTSxvQkFBb0IsR0FBRyxHQUFHLEdBQUcsSUFBSSxDQUFDO0FBRS9DLE1BQU0sVUFBVSxjQUFjLENBQVMsS0FBYTtJQUNsRCxPQUFPLFVBQVUsQ0FBQyxpQkFBaUIsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO0FBQzlDLENBQUM7QUFFRCxNQUFNLFVBQVUsU0FBUyxDQUFDLEtBQWM7SUFDdEMsT0FBTyxNQUFNLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLEVBQUUsTUFBTSxDQUFDLENBQUM7QUFDMUQsQ0FBQztBQUVELE1BQU0sVUFBVSxZQUFZLENBQUMsS0FBYSxFQUFFLFFBQWdCO0lBQzFELElBQUksTUFBTSxDQUFDLFVBQVUsQ0FBQyxLQUFLLEVBQUUsTUFBTSxDQUFDLElBQUksUUFBUTtRQUFFLE9BQU8sS0FBSyxDQUFDO0lBQy9ELE1BQU0sTUFBTSxHQUFHLGNBQWMsQ0FBQztJQUM5QixNQUFNLFdBQVcsR0FBRyxNQUFNLENBQUMsVUFBVSxDQUFDLE1BQU0sRUFBRSxNQUFNLENBQUMsQ0FBQztJQUN0RCxJQUFJLFNBQVMsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxNQUFNLENBQUM7U0FDdkMsUUFBUSxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxRQUFRLEdBQUcsV0FBVyxDQUFDLENBQUM7U0FDaEQsUUFBUSxDQUFDLE1BQU0sQ0FBQztTQUNoQixPQUFPLENBQUMsVUFBVSxFQUFFLEVBQUUsQ0FBQyxDQUFDO0lBQzNCLE9BQU8sTUFBTSxDQUFDLFVBQVUsQ0FBQyxHQUFHLFNBQVMsR0FBRyxNQUFNLEVBQUUsRUFBRSxNQUFNLENBQUMsR0FBRyxRQUFRLEVBQUUsQ0FBQztRQUNyRSxTQUFTLEdBQUcsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNyQyxDQUFDO0lBQ0QsT0FBTyxHQUFHLFNBQVMsR0FBRyxNQUFNLEVBQUUsQ0FBQztBQUNqQyxDQUFDO0FBRUQsTUFBTSxVQUFVLHlCQUF5QixDQUFDLEtBQWEsRUFBRSxLQUFhO0lBQ3BFLElBQUksTUFBTSxDQUFDLFVBQVUsQ0FBQyxLQUFLLEVBQUUsTUFBTSxDQUFDLEdBQUcsMEJBQTBCLEVBQUUsQ0FBQztRQUNsRSxNQUFNLElBQUksMEJBQTBCLENBQUMsR0FBRyxLQUFLLDhCQUE4QixDQUFDLENBQUM7SUFDL0UsQ0FBQztBQUNILENBQUM7QUFFRCxNQUFNLFVBQVUsc0JBQXNCLENBQUMsUUFBNEI7SUFDakUsTUFBTSxVQUFVLEdBQXVCO1FBQ3JDLFFBQVEsRUFBRSxRQUFRLENBQUMsUUFBUTtRQUMzQixLQUFLLEVBQUUsUUFBUSxDQUFDLEtBQUs7UUFDckIsR0FBRyxDQUFDLFFBQVEsQ0FBQyxXQUFXLEtBQUssU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsV0FBVyxFQUFFLFFBQVEsQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUNwRixHQUFHLENBQUMsUUFBUSxDQUFDLE9BQU8sS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxPQUFPLEVBQUUsUUFBUSxDQUFDLE9BQU8sRUFBRSxDQUFDO0tBQ3pFLENBQUM7SUFDRixrQkFBa0IsQ0FBQyxVQUFVLENBQUMsUUFBUSxFQUFFLHlCQUF5QixDQUFDLENBQUM7SUFDbkUsa0JBQWtCLENBQUMsVUFBVSxDQUFDLEtBQUssRUFBRSxzQkFBc0IsQ0FBQyxDQUFDO0lBQzdELElBQUksVUFBVSxDQUFDLFdBQVcsS0FBSyxTQUFTLEVBQUUsQ0FBQztRQUN6QyxrQkFBa0IsQ0FBQyxVQUFVLENBQUMsV0FBVyxFQUFFLDRCQUE0QixDQUFDLENBQUM7SUFDM0UsQ0FBQztJQUNELElBQUksVUFBVSxDQUFDLE9BQU8sS0FBSyxTQUFTO1FBQUUsa0JBQWtCLENBQUMsVUFBVSxDQUFDLE9BQU8sRUFBRSx3QkFBd0IsQ0FBQyxDQUFDO0lBQ3ZHLElBQ0UsTUFBTSxDQUFDLFVBQVUsQ0FBQyxVQUFVLENBQUMsUUFBUSxFQUFFLE1BQU0sQ0FBQyxHQUFHLDBCQUEwQjtXQUN4RSxNQUFNLENBQUMsVUFBVSxDQUFDLFVBQVUsQ0FBQyxLQUFLLEVBQUUsTUFBTSxDQUFDLEdBQUcsMEJBQTBCO1dBQ3hFLENBQUMsVUFBVSxDQUFDLFdBQVcsS0FBSyxTQUFTO2VBQ25DLE1BQU0sQ0FBQyxVQUFVLENBQUMsVUFBVSxDQUFDLFdBQVcsRUFBRSxNQUFNLENBQUMsR0FBRyx3QkFBd0IsQ0FBQztXQUMvRSxDQUFDLFVBQVUsQ0FBQyxPQUFPLEtBQUssU0FBUyxJQUFJLE1BQU0sQ0FBQyxVQUFVLENBQUMsVUFBVSxDQUFDLE9BQU8sRUFBRSxNQUFNLENBQUMsR0FBRyxHQUFHLENBQUMsRUFDNUYsQ0FBQztRQUNELE1BQU0sSUFBSSwwQkFBMEIsQ0FBQyw0Q0FBNEMsQ0FBQyxDQUFDO0lBQ3JGLENBQUM7SUFDRCxPQUFPLFVBQVUsQ0FBQztBQUNwQixDQUFDO0FBRUQsTUFBTSxVQUFVLHNCQUFzQixDQUFDLGFBQWlDO0lBQ3RFLE9BQU87UUFDTCxLQUFLLEVBQUUsYUFBYSxDQUFDLEtBQUs7UUFDMUIsUUFBUSxFQUFFLHNCQUFzQixDQUFDLGFBQWEsQ0FBQyxRQUFRLENBQUM7UUFDeEQsR0FBRyxDQUFDLGFBQWEsQ0FBQyxNQUFNLEtBQUssU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsTUFBTSxFQUFFLGFBQWEsQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUMvRSxHQUFHLENBQUMsYUFBYSxDQUFDLGVBQWUsS0FBSyxTQUFTO1lBQzdDLENBQUMsQ0FBQyxFQUFFO1lBQ0osQ0FBQyxDQUFDLEVBQUUsZUFBZSxFQUFFLGFBQWEsQ0FBQyxlQUFlLEVBQUUsQ0FBQztRQUN2RCxHQUFHLENBQUMsYUFBYSxDQUFDLEtBQUssS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxLQUFLLEVBQUUsYUFBYSxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQzVFLEdBQUcsQ0FBQyxhQUFhLENBQUMsUUFBUSxLQUFLLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLFFBQVEsRUFBRSxhQUFhLENBQUMsUUFBUSxFQUFFLENBQUM7S0FDdEYsQ0FBQztBQUNKLENBQUM7QUFFRCxNQUFNLFVBQVUsa0JBQWtCLENBQUMsTUFBMkI7SUFDNUQsTUFBTSxVQUFVLEdBQXlCO1FBQ3ZDLElBQUksRUFBRSxNQUFNLENBQUMsSUFBSTtRQUNqQixLQUFLLEVBQUUsTUFBTSxDQUFDLEtBQUs7UUFDbkIsWUFBWSxFQUFFLE1BQU0sQ0FBQyxZQUFZO1FBQ2pDLEtBQUssRUFBRTtZQUNMLFdBQVcsRUFBRSxNQUFNLENBQUMsS0FBSyxDQUFDLFdBQVc7WUFDckMsWUFBWSxFQUFFLE1BQU0sQ0FBQyxLQUFLLENBQUMsWUFBWTtZQUN2QyxXQUFXLEVBQUUsTUFBTSxDQUFDLEtBQUssQ0FBQyxXQUFXO1lBQ3JDLGVBQWUsRUFBRSxNQUFNLENBQUMsS0FBSyxDQUFDLGVBQWU7WUFDN0MsZ0JBQWdCLEVBQUUsTUFBTSxDQUFDLEtBQUssQ0FBQyxnQkFBZ0I7U0FDaEQ7S0FDRixDQUFDO0lBQ0YsSUFDRSxPQUFPLFVBQVUsQ0FBQyxJQUFJLEtBQUssUUFBUTtXQUNoQyxPQUFPLFVBQVUsQ0FBQyxZQUFZLEtBQUssUUFBUTtXQUMzQyxDQUFDLE1BQU0sQ0FBQyxhQUFhLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQztXQUN2QyxVQUFVLENBQUMsS0FBSyxHQUFHLENBQUM7V0FDcEIsTUFBTSxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLElBQUksS0FBSyxHQUFHLENBQUMsQ0FBQyxFQUN4RixDQUFDO1FBQ0QsTUFBTSxJQUFJLDBCQUEwQixDQUFDLHFDQUFxQyxDQUFDLENBQUM7SUFDOUUsQ0FBQztJQUNELE9BQU8sVUFBVSxDQUFDO0FBQ3BCLENBQUM7QUFFRCxTQUFTLFVBQVUsQ0FBQyxJQUFZO0lBQzlCLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDO0lBQ3hDLElBQUksQ0FBQyx3QkFBd0IsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksT0FBTyxDQUFDLE1BQU0sR0FBRyxDQUFDLEtBQUssQ0FBQztRQUFFLE9BQU8sU0FBUyxDQUFDO0lBQzFGLE9BQU8sTUFBTSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsUUFBUSxDQUFDLENBQUMsVUFBVSxDQUFDO0FBQ25ELENBQUM7QUFFRCxNQUFNLFVBQVUsa0JBQWtCLENBQ2hDLElBQWdEO0lBRWhELElBQUksTUFBTSxHQUEwQixlQUFlLENBQUM7SUFDcEQsSUFBSSxTQUE2QixDQUFDO0lBQ2xDLElBQUksaUJBQXFDLENBQUM7SUFDMUMsSUFBSSxTQUFTLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDO1FBQzlCLE1BQU0sR0FBRyxVQUFVLENBQUM7UUFDcEIsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDMUMsSUFBSSxVQUFVLElBQUksQ0FBQyxFQUFFLENBQUM7WUFDcEIsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLFVBQVUsQ0FBQyxDQUFDO1lBQ2hELE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLFVBQVUsR0FBRyxDQUFDLENBQUMsQ0FBQztZQUNoRCxNQUFNLGFBQWEsR0FBRyxRQUFRLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQzFDLElBQUksYUFBYSxDQUFDLENBQUMsQ0FBQyxFQUFFLFFBQVEsQ0FBQyxHQUFHLENBQUM7Z0JBQUUsaUJBQWlCLEdBQUcsYUFBYSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQzFFLElBQUksYUFBYSxDQUFDLElBQUksQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsS0FBSyxDQUFDLFdBQVcsRUFBRSxLQUFLLFFBQVEsQ0FBQyxFQUFFLENBQUM7Z0JBQ3BFLFNBQVMsR0FBRyxVQUFVLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDbEMsQ0FBQztpQkFBTSxDQUFDO2dCQUNOLElBQUksQ0FBQztvQkFDSCxTQUFTLEdBQUcsTUFBTSxDQUFDLFVBQVUsQ0FBQyxrQkFBa0IsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDO2dCQUM3RCxDQUFDO2dCQUFDLE1BQU0sQ0FBQztvQkFDUCwyRUFBMkU7Z0JBQzdFLENBQUM7WUFDSCxDQUFDO1FBQ0gsQ0FBQztJQUNILENBQUM7U0FBTSxDQUFDO1FBQ04sSUFBSSxDQUFDO1lBQ0gsTUFBTSxHQUFHLEdBQUcsSUFBSSxHQUFHLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQy9CLElBQUksR0FBRyxDQUFDLFFBQVEsS0FBSyxPQUFPLElBQUksR0FBRyxDQUFDLFFBQVEsS0FBSyxRQUFRO2dCQUFFLE1BQU0sR0FBRyxZQUFZLENBQUM7O2dCQUM1RSxTQUFTLEdBQUcsVUFBVSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUN6QyxDQUFDO1FBQUMsTUFBTSxDQUFDO1lBQ1AsU0FBUyxHQUFHLFVBQVUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDcEMsQ0FBQztJQUNILENBQUM7SUFDRCxPQUFPO1FBQ0wsTUFBTTtRQUNOLEdBQUcsQ0FBQyxTQUFTLEtBQUssU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsU0FBUyxFQUFFLENBQUM7UUFDakQsR0FBRyxDQUFDLElBQUksQ0FBQyxTQUFTLElBQUksaUJBQWlCO1lBQ3JDLENBQUMsQ0FBQyxFQUFFLFNBQVMsRUFBRSxJQUFJLENBQUMsU0FBUyxJQUFJLGlCQUFpQixFQUFFO1lBQ3BELENBQUMsQ0FBQyxFQUFFLENBQUM7UUFDUCxHQUFHLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7S0FDMUMsQ0FBQztBQUNKLENBQUM7QUFFRCxNQUFNLFVBQVUsNEJBQTRCLENBQUMsT0FBcUI7SUFDaEUsTUFBTSxTQUFTLEdBQUcsaUJBQWlCLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDN0MseUJBQXlCLENBQUMsU0FBUyxDQUFDLFNBQVMsRUFBRSxXQUFXLENBQUMsQ0FBQztJQUM1RCx5QkFBeUIsQ0FBQyxTQUFTLENBQUMsU0FBUyxFQUFFLFdBQVcsQ0FBQyxDQUFDO0lBQzVELHlCQUF5QixDQUFDLFNBQVMsQ0FBQyxLQUFLLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFDcEQsU0FBUyxDQUFDLFNBQVMsR0FBRyxZQUFZLENBQUMsU0FBUyxDQUFDLFNBQVMsRUFBRSxHQUFHLENBQUMsQ0FBQztJQUM3RCxJQUFJLFNBQVMsQ0FBQyxXQUFXLEtBQUssU0FBUztRQUFFLFNBQVMsQ0FBQyxXQUFXLEdBQUcsWUFBWSxDQUFDLFNBQVMsQ0FBQyxXQUFXLEVBQUUsR0FBRyxDQUFDLENBQUM7SUFDMUcsSUFBSSxTQUFTLENBQUMsS0FBSyxLQUFLLFNBQVM7UUFBRSxTQUFTLENBQUMsS0FBSyxHQUFHLFlBQVksQ0FBQyxTQUFTLENBQUMsS0FBSyxFQUFFLHdCQUF3QixDQUFDLENBQUM7SUFDN0csSUFBSSxTQUFTLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDcEIsU0FBUyxDQUFDLEtBQUssQ0FBQyxRQUFRLEdBQUcsWUFBWSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsUUFBUSxFQUFFLDBCQUEwQixDQUFDLENBQUM7UUFDOUYsU0FBUyxDQUFDLEtBQUssQ0FBQyxLQUFLLEdBQUcsWUFBWSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsS0FBSyxFQUFFLDBCQUEwQixDQUFDLENBQUM7UUFDeEYsSUFBSSxTQUFTLENBQUMsS0FBSyxDQUFDLFdBQVcsS0FBSyxTQUFTLEVBQUUsQ0FBQztZQUM5QyxTQUFTLENBQUMsS0FBSyxDQUFDLFdBQVcsR0FBRyxZQUFZLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxXQUFXLEVBQUUsd0JBQXdCLENBQUMsQ0FBQztRQUNwRyxDQUFDO1FBQ0QsSUFBSSxTQUFTLENBQUMsS0FBSyxDQUFDLE9BQU8sS0FBSyxTQUFTO1lBQUUsU0FBUyxDQUFDLEtBQUssQ0FBQyxPQUFPLEdBQUcsWUFBWSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsT0FBTyxFQUFFLEdBQUcsQ0FBQyxDQUFDO0lBQ2xILENBQUM7SUFDRCxLQUFLLE1BQU0sSUFBSSxJQUFJLFNBQVMsQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUNuQyx5QkFBeUIsQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLFFBQVEsQ0FBQyxDQUFDO1FBQ2pELElBQUksSUFBSSxDQUFDLElBQUksS0FBSyxNQUFNLElBQUksSUFBSSxDQUFDLElBQUksS0FBSyxXQUFXLEVBQUUsQ0FBQztZQUN0RCxJQUFJLENBQUMsSUFBSSxHQUFHLFlBQVksQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLG9CQUFvQixDQUFDLENBQUM7UUFDNUQsQ0FBQzthQUFNLElBQUksSUFBSSxDQUFDLElBQUksS0FBSyxNQUFNLEVBQUUsQ0FBQztZQUNoQyxJQUFJLENBQUMsVUFBVSxHQUFHLFlBQVksQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFFLDBCQUEwQixDQUFDLENBQUM7WUFDNUUsSUFBSSxDQUFDLFFBQVEsR0FBRyxZQUFZLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSwwQkFBMEIsQ0FBQyxDQUFDO1lBQ3hFLElBQUksSUFBSSxDQUFDLEtBQUssS0FBSyxTQUFTO2dCQUFFLElBQUksQ0FBQyxLQUFLLEdBQUcsWUFBWSxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsd0JBQXdCLENBQUMsQ0FBQztRQUNoRyxDQUFDO2FBQU0sQ0FBQztZQUNOLElBQUksSUFBSSxDQUFDLFNBQVMsS0FBSyxTQUFTO2dCQUFFLElBQUksQ0FBQyxTQUFTLEdBQUcsWUFBWSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsMEJBQTBCLENBQUMsQ0FBQztZQUM1RyxJQUFJLElBQUksQ0FBQyxJQUFJLEtBQUssU0FBUztnQkFBRSxJQUFJLENBQUMsSUFBSSxHQUFHLFlBQVksQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLHdCQUF3QixDQUFDLENBQUM7UUFDN0YsQ0FBQztJQUNILENBQUM7SUFDRCxJQUFJLFNBQVMsQ0FBQyxTQUFTLENBQUMsR0FBRyx1QkFBdUIsRUFBRSxDQUFDO1FBQ25ELFNBQVMsQ0FBQyxLQUFLLEdBQUcsQ0FBQztnQkFDakIsTUFBTSxFQUFFLGlCQUFpQjtnQkFDekIsSUFBSSxFQUFFLE1BQU07Z0JBQ1osSUFBSSxFQUFFLCtDQUErQzthQUN0RCxDQUFDLENBQUM7SUFDTCxDQUFDO0lBQ0QsSUFBSSxTQUFTLENBQUMsU0FBUyxDQUFDLEdBQUcsdUJBQXVCLEVBQUUsQ0FBQztRQUNuRCxNQUFNLElBQUksMEJBQTBCLENBQUMscURBQXFELENBQUMsQ0FBQztJQUM5RixDQUFDO0lBQ0QsT0FBTyxTQUFTLENBQUM7QUFDbkIsQ0FBQyJ9
@@ -0,0 +1,13 @@
1
+ import type { IFlexCreateProjectTaskInput, IFlexErrorInfo, IFlexPromptOptions, IFlexSlashCommandExecutionOptions, IFlexUpdateProjectTaskInput, IFlexUpdateSessionOptions, TFlexProjectTaskPriority, TFlexProjectTaskStatus } from './interfaces.js';
2
+ export declare function validateIdentifier(value: string, name: string): void;
3
+ export declare function validateUtf8String(value: unknown, name: string, maxBytes: number, nonEmpty?: boolean): asserts value is string;
4
+ export declare function validateProjectedErrorInfo(value: unknown): IFlexErrorInfo;
5
+ export declare function validateUpdateSessionOptions(options: IFlexUpdateSessionOptions): void;
6
+ export declare function validateProjectTaskStatus(value: unknown): asserts value is TFlexProjectTaskStatus;
7
+ export declare function validateProjectTaskPriority(value: unknown): asserts value is TFlexProjectTaskPriority;
8
+ export declare function validateProjectTaskId(value: unknown): asserts value is string;
9
+ export declare function validateProjectTaskContent(value: unknown): asserts value is string;
10
+ export declare function validateCreateProjectTaskInput(input: IFlexCreateProjectTaskInput): void;
11
+ export declare function validateUpdateProjectTaskInput(input: IFlexUpdateProjectTaskInput): void;
12
+ export declare function validatePromptOptions(options: IFlexPromptOptions, scheduled: boolean): void;
13
+ export declare function validateSlashCommandExecutionOptions(options: IFlexSlashCommandExecutionOptions): IFlexPromptOptions;
@@ -0,0 +1,158 @@
1
+ import { FlexHarnessValidationError } from './errors.js';
2
+ import { FLEX_PROJECT_MANAGEMENT_LIMITS } from './interfaces.js';
3
+ const maxProjectedErrorNameBytes = 128;
4
+ const maxProjectedErrorMessageBytes = 2048;
5
+ const maxProjectedErrorCodeBytes = 128;
6
+ export function validateIdentifier(value, name) {
7
+ if (typeof value !== 'string' || value.length === 0) {
8
+ throw new FlexHarnessValidationError(`${name} must be a non-empty string.`);
9
+ }
10
+ }
11
+ export function validateUtf8String(value, name, maxBytes, nonEmpty = false) {
12
+ if (typeof value !== 'string'
13
+ || (nonEmpty && !value.trim())
14
+ || Buffer.byteLength(value, 'utf8') > maxBytes) {
15
+ throw new FlexHarnessValidationError(`${name} must be ${nonEmpty ? 'a non-empty ' : 'a '}string of at most ${maxBytes} UTF-8 bytes.`);
16
+ }
17
+ }
18
+ export function validateProjectedErrorInfo(value) {
19
+ if (!value
20
+ || typeof value !== 'object'
21
+ || Array.isArray(value)
22
+ || ![Object.prototype, null].includes(Object.getPrototypeOf(value))) {
23
+ throw new FlexHarnessValidationError('External error projection is invalid.');
24
+ }
25
+ const descriptors = Object.getOwnPropertyDescriptors(value);
26
+ const unsupportedKey = Reflect.ownKeys(descriptors).find((key) => typeof key !== 'string' || !['name', 'message', 'code'].includes(key));
27
+ const name = descriptors.name?.value;
28
+ const message = descriptors.message?.value;
29
+ const code = descriptors.code?.value;
30
+ if (unsupportedKey
31
+ || descriptors.name?.get !== undefined
32
+ || descriptors.name?.set !== undefined
33
+ || descriptors.message?.get !== undefined
34
+ || descriptors.message?.set !== undefined
35
+ || descriptors.code?.get !== undefined
36
+ || descriptors.code?.set !== undefined
37
+ || typeof name !== 'string'
38
+ || !name
39
+ || Buffer.byteLength(name, 'utf8') > maxProjectedErrorNameBytes
40
+ || typeof message !== 'string'
41
+ || !message
42
+ || Buffer.byteLength(message, 'utf8') > maxProjectedErrorMessageBytes
43
+ || (code !== undefined
44
+ && (typeof code !== 'string'
45
+ || !code
46
+ || Buffer.byteLength(code, 'utf8') > maxProjectedErrorCodeBytes))) {
47
+ throw new FlexHarnessValidationError('External error projection is invalid.');
48
+ }
49
+ return Object.freeze({ name, message, ...(code === undefined ? {} : { code }) });
50
+ }
51
+ export function validateUpdateSessionOptions(options) {
52
+ if (!options || typeof options !== 'object' || Array.isArray(options)) {
53
+ throw new FlexHarnessValidationError('updateSession options must be a plain object.');
54
+ }
55
+ const keys = Object.keys(options);
56
+ if (keys.length === 0)
57
+ throw new FlexHarnessValidationError('updateSession requires title or archived.');
58
+ const unsupportedKey = keys.find((key) => key !== 'title' && key !== 'archived');
59
+ if (unsupportedKey)
60
+ throw new FlexHarnessValidationError(`updateSession does not support "${unsupportedKey}".`);
61
+ if (Object.prototype.hasOwnProperty.call(options, 'title') && options.title !== null) {
62
+ validateUtf8String(options.title, 'title', FLEX_PROJECT_MANAGEMENT_LIMITS.maxTitleBytes, true);
63
+ }
64
+ if (Object.prototype.hasOwnProperty.call(options, 'archived') && typeof options.archived !== 'boolean') {
65
+ throw new FlexHarnessValidationError('archived must be a boolean.');
66
+ }
67
+ }
68
+ export function validateProjectTaskStatus(value) {
69
+ if (!['pending', 'in_progress', 'completed', 'cancelled'].includes(String(value))) {
70
+ throw new FlexHarnessValidationError('Project task status is invalid.');
71
+ }
72
+ }
73
+ export function validateProjectTaskPriority(value) {
74
+ if (!['high', 'medium', 'low'].includes(String(value))) {
75
+ throw new FlexHarnessValidationError('Project task priority is invalid.');
76
+ }
77
+ }
78
+ export function validateProjectTaskId(value) {
79
+ validateUtf8String(value, 'project task id', FLEX_PROJECT_MANAGEMENT_LIMITS.maxTaskIdBytes, true);
80
+ }
81
+ export function validateProjectTaskContent(value) {
82
+ validateUtf8String(value, 'project task content', FLEX_PROJECT_MANAGEMENT_LIMITS.maxTaskContentBytes, true);
83
+ }
84
+ export function validateCreateProjectTaskInput(input) {
85
+ if (!input || typeof input !== 'object' || Array.isArray(input)) {
86
+ throw new FlexHarnessValidationError('Project task create input must be a plain object.');
87
+ }
88
+ const unsupported = Object.keys(input)
89
+ .find((key) => !['id', 'content', 'status', 'priority'].includes(key));
90
+ if (unsupported) {
91
+ throw new FlexHarnessValidationError(`Project task create input does not support "${unsupported}".`);
92
+ }
93
+ validateProjectTaskId(input.id);
94
+ validateProjectTaskContent(input.content);
95
+ if (input.status !== undefined)
96
+ validateProjectTaskStatus(input.status);
97
+ if (input.priority !== undefined)
98
+ validateProjectTaskPriority(input.priority);
99
+ }
100
+ export function validateUpdateProjectTaskInput(input) {
101
+ if (!input || typeof input !== 'object' || Array.isArray(input)) {
102
+ throw new FlexHarnessValidationError('Project task update input must be a plain object.');
103
+ }
104
+ const keys = Object.keys(input);
105
+ const unsupported = keys.find((key) => !['id', 'content', 'status', 'priority'].includes(key));
106
+ if (unsupported) {
107
+ throw new FlexHarnessValidationError(`Project task update input does not support "${unsupported}".`);
108
+ }
109
+ if (!keys.some((key) => key !== 'id')) {
110
+ throw new FlexHarnessValidationError('Project task update requires a changed field.');
111
+ }
112
+ validateProjectTaskId(input.id);
113
+ if (input.content !== undefined)
114
+ validateProjectTaskContent(input.content);
115
+ if (input.status !== undefined)
116
+ validateProjectTaskStatus(input.status);
117
+ if (input.priority !== undefined)
118
+ validateProjectTaskPriority(input.priority);
119
+ }
120
+ export function validatePromptOptions(options, scheduled) {
121
+ if (!options || typeof options !== 'object' || Array.isArray(options)) {
122
+ throw new FlexHarnessValidationError('Prompt options must be a plain object.');
123
+ }
124
+ const supported = scheduled
125
+ ? ['modelHint', 'system', 'maxSteps', 'debounceMs']
126
+ : ['modelHint', 'system', 'maxSteps'];
127
+ const unsupported = Object.keys(options).find((key) => !supported.includes(key));
128
+ if (unsupported)
129
+ throw new FlexHarnessValidationError(`Prompt options do not support "${unsupported}".`);
130
+ if (options.modelHint !== undefined)
131
+ validateIdentifier(options.modelHint, 'modelHint');
132
+ if (options.system !== undefined)
133
+ validateIdentifier(options.system, 'system');
134
+ if (options.maxSteps !== undefined && (!Number.isSafeInteger(options.maxSteps) || options.maxSteps < 1)) {
135
+ throw new FlexHarnessValidationError('maxSteps must be a positive integer.');
136
+ }
137
+ }
138
+ export function validateSlashCommandExecutionOptions(options) {
139
+ if (!options || typeof options !== 'object' || Array.isArray(options)) {
140
+ throw new FlexHarnessValidationError('Slash command execution options must be a plain object.');
141
+ }
142
+ const unsupported = Object.keys(options)
143
+ .find((key) => !['modelHint', 'system', 'maxSteps', 'signal'].includes(key));
144
+ if (unsupported) {
145
+ throw new FlexHarnessValidationError(`Slash command execution options do not support "${unsupported}".`);
146
+ }
147
+ if (options.signal !== undefined && !(options.signal instanceof AbortSignal)) {
148
+ throw new FlexHarnessValidationError('Slash command signal must be an AbortSignal.');
149
+ }
150
+ const promptOptions = {
151
+ ...(options.modelHint === undefined ? {} : { modelHint: options.modelHint }),
152
+ ...(options.system === undefined ? {} : { system: options.system }),
153
+ ...(options.maxSteps === undefined ? {} : { maxSteps: options.maxSteps }),
154
+ };
155
+ validatePromptOptions(promptOptions, false);
156
+ return promptOptions;
157
+ }
158
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMudmFsaWRhdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL3V0aWxzLnZhbGlkYXRpb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLDBCQUEwQixFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQ3pELE9BQU8sRUFBRSw4QkFBOEIsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBWWpFLE1BQU0sMEJBQTBCLEdBQUcsR0FBRyxDQUFDO0FBQ3ZDLE1BQU0sNkJBQTZCLEdBQUcsSUFBSSxDQUFDO0FBQzNDLE1BQU0sMEJBQTBCLEdBQUcsR0FBRyxDQUFDO0FBRXZDLE1BQU0sVUFBVSxrQkFBa0IsQ0FBQyxLQUFhLEVBQUUsSUFBWTtJQUM1RCxJQUFJLE9BQU8sS0FBSyxLQUFLLFFBQVEsSUFBSSxLQUFLLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO1FBQ3BELE1BQU0sSUFBSSwwQkFBMEIsQ0FBQyxHQUFHLElBQUksOEJBQThCLENBQUMsQ0FBQztJQUM5RSxDQUFDO0FBQ0gsQ0FBQztBQUVELE1BQU0sVUFBVSxrQkFBa0IsQ0FDaEMsS0FBYyxFQUNkLElBQVksRUFDWixRQUFnQixFQUNoQixRQUFRLEdBQUcsS0FBSztJQUVoQixJQUNFLE9BQU8sS0FBSyxLQUFLLFFBQVE7V0FDdEIsQ0FBQyxRQUFRLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLENBQUM7V0FDM0IsTUFBTSxDQUFDLFVBQVUsQ0FBQyxLQUFLLEVBQUUsTUFBTSxDQUFDLEdBQUcsUUFBUSxFQUM5QyxDQUFDO1FBQ0QsTUFBTSxJQUFJLDBCQUEwQixDQUNsQyxHQUFHLElBQUksWUFBWSxRQUFRLENBQUMsQ0FBQyxDQUFDLGNBQWMsQ0FBQyxDQUFDLENBQUMsSUFBSSxxQkFBcUIsUUFBUSxlQUFlLENBQ2hHLENBQUM7SUFDSixDQUFDO0FBQ0gsQ0FBQztBQUVELE1BQU0sVUFBVSwwQkFBMEIsQ0FBQyxLQUFjO0lBQ3ZELElBQ0Us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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@modelprofile.com/flexharness",
3
- "version": "4.1.0",
3
+ "version": "4.1.1",
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.hints.md CHANGED
@@ -2,6 +2,13 @@
2
2
 
3
3
  Implementation findings for flexharness.
4
4
 
5
+ ## Internal module boundaries
6
+
7
+ - `classes.flexharness.ts` owns stateful coordination: admission, queues, canonical finalization, permissions, reversion, persistence reconciliation, resource cleanup, retirement, and disposal. Stateless boundary policy must not be added back to this class.
8
+ - Constructor policy belongs in `utils.harnessoptions.ts`; reusable public-input checks belong in `utils.validation.ts`; public projection and transfer bounds belong in `utils.transfer.ts`; tool-result normalization belongs in `utils.tooloutput.ts`.
9
+ - Store adapters remain in `classes.stores.ts`, while strict Agent-event and Tool-job codecs belong in `utils.storecodecs.ts`. Store codecs do not own CAS, queue, filesystem, or provider lifecycle behavior.
10
+ - Internal utility modules are implementation details and are not re-exported from `index.ts`. Shared policy such as reserved slash-command names and subagent name bounds has one owner and is imported by every caller.
11
+
5
12
  ## SmartAgent boundary
6
13
 
7
14
  - SmartAgent is the canonical private conversation and execution runtime. FlexHarness creates one transactional `AgentSession` per public session and derives its public model, prompt, provider-option, tool-set, and result aliases from SmartAgent exports.
@@ -3,6 +3,6 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@modelprofile.com/flexharness',
6
- version: '4.1.0',
6
+ version: '4.1.1',
7
7
  description: 'Provider-neutral model-session runtime with durable history, permissions, typed events, and pluggable local or remote tool execution.'
8
8
  }