@optique/prompt 1.3.0-dev.2456 → 1.3.0-dev.2464
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 +2 -1
- package/dist/index.cjs +70 -11
- package/dist/index.d.cts +60 -6
- package/dist/index.d.ts +60 -6
- package/dist/index.js +70 -11
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -27,7 +27,8 @@ Documentation
|
|
|
27
27
|
|
|
28
28
|
For full documentation, visit the [prompt integration docs].
|
|
29
29
|
The guide covers dependency-derived configurations with
|
|
30
|
-
`derivePromptConfig()
|
|
30
|
+
`derivePromptConfig()`, shared validation and retries, abort signals, and
|
|
31
|
+
adapter construction.
|
|
31
32
|
|
|
32
33
|
[prompt integration docs]: https://optique.dev/integrations/prompt
|
|
33
34
|
|
package/dist/index.cjs
CHANGED
|
@@ -179,6 +179,40 @@ function unwrapCompleteResult(result) {
|
|
|
179
179
|
value: (0, __optique_core_extension.unwrapInjectedAnnotationState)(result.value)
|
|
180
180
|
};
|
|
181
181
|
}
|
|
182
|
+
function throwIfPromptAborted(signal) {
|
|
183
|
+
if (signal?.aborted === true) throw signal.reason;
|
|
184
|
+
}
|
|
185
|
+
function racePromptWorkWithAbort(signal, work) {
|
|
186
|
+
if (signal == null) try {
|
|
187
|
+
return work();
|
|
188
|
+
} catch (error) {
|
|
189
|
+
return Promise.reject(error);
|
|
190
|
+
}
|
|
191
|
+
if (signal.aborted) return Promise.reject(signal.reason);
|
|
192
|
+
return new Promise((resolve, reject) => {
|
|
193
|
+
const onAbort = () => {
|
|
194
|
+
signal.removeEventListener("abort", onAbort);
|
|
195
|
+
reject(signal.reason);
|
|
196
|
+
};
|
|
197
|
+
const cleanup = () => signal.removeEventListener("abort", onAbort);
|
|
198
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
199
|
+
let outcome;
|
|
200
|
+
try {
|
|
201
|
+
outcome = work();
|
|
202
|
+
} catch (error) {
|
|
203
|
+
cleanup();
|
|
204
|
+
reject(error);
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
outcome.then((value) => {
|
|
208
|
+
cleanup();
|
|
209
|
+
resolve(value);
|
|
210
|
+
}, (error) => {
|
|
211
|
+
cleanup();
|
|
212
|
+
reject(error);
|
|
213
|
+
});
|
|
214
|
+
});
|
|
215
|
+
}
|
|
182
216
|
/**
|
|
183
217
|
* Creates a `prompt()` parser wrapper for a prompt library adapter.
|
|
184
218
|
*
|
|
@@ -190,13 +224,16 @@ function unwrapCompleteResult(result) {
|
|
|
190
224
|
*
|
|
191
225
|
* @typeParam TConfig Prompt configuration accepted by the adapter.
|
|
192
226
|
* @param adapter Library-specific prompt executor.
|
|
193
|
-
* @returns A `prompt(parser, config)` wrapper that always produces
|
|
194
|
-
* parser. The configuration may be a static `TConfig` or a
|
|
227
|
+
* @returns A `prompt(parser, config, options?)` wrapper that always produces
|
|
228
|
+
* an async parser. The configuration may be a static `TConfig` or a
|
|
195
229
|
* {@link DerivedPromptConfig} whose resolver returns `TConfig`.
|
|
230
|
+
* @throws {RangeError} If `maxAttempts` is not a positive integer.
|
|
196
231
|
* @since 1.2.0
|
|
197
232
|
*/
|
|
198
233
|
function createPromptAdapter(adapter) {
|
|
199
|
-
return function prompt(parser, config) {
|
|
234
|
+
return function prompt(parser, config, options = {}) {
|
|
235
|
+
if (options.maxAttempts !== void 0 && (!Number.isInteger(options.maxAttempts) || options.maxAttempts < 1)) throw new RangeError("maxAttempts must be an integer greater than or equal to 1.");
|
|
236
|
+
const { validate, maxAttempts, signal } = options;
|
|
200
237
|
const promptBindStateKey = Symbol("@optique/prompt/promptState");
|
|
201
238
|
const completionCacheKeys = /* @__PURE__ */ new Map();
|
|
202
239
|
const completionCacheSymbolIds = /* @__PURE__ */ new Map();
|
|
@@ -246,14 +283,36 @@ function createPromptAdapter(adapter) {
|
|
|
246
283
|
success: true,
|
|
247
284
|
value: config.otherwise
|
|
248
285
|
};
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
286
|
+
throwIfPromptAborted(signal);
|
|
287
|
+
let resolvedConfig;
|
|
288
|
+
if (!isDerivedPromptConfig(config)) resolvedConfig = config;
|
|
289
|
+
else {
|
|
290
|
+
const source = promptedParser.dependencyMetadata?.source;
|
|
291
|
+
const resolved = await resolveDerivedPromptConfig(config, exec, source?.sourceId, source?.metavar);
|
|
292
|
+
throwIfPromptAborted(signal);
|
|
293
|
+
if (!resolved.ok) return {
|
|
294
|
+
success: false,
|
|
295
|
+
error: resolved.error
|
|
296
|
+
};
|
|
297
|
+
resolvedConfig = resolved.config;
|
|
298
|
+
}
|
|
299
|
+
let previousValidationMessage;
|
|
300
|
+
for (let attempt = 1;; attempt++) {
|
|
301
|
+
const context = {
|
|
302
|
+
attempt,
|
|
303
|
+
...previousValidationMessage === void 0 ? {} : { previousValidationMessage },
|
|
304
|
+
...signal === void 0 ? {} : { signal }
|
|
305
|
+
};
|
|
306
|
+
const result = await racePromptWorkWithAbort(signal, () => adapter.execute(resolvedConfig, context));
|
|
307
|
+
if (!result.success || validate == null) return result;
|
|
308
|
+
const validationMessage = await racePromptWorkWithAbort(signal, () => Promise.resolve(validate(result.value)));
|
|
309
|
+
if (validationMessage === void 0) return result;
|
|
310
|
+
if (maxAttempts !== void 0 && attempt >= maxAttempts) return {
|
|
311
|
+
success: false,
|
|
312
|
+
error: validationMessage
|
|
313
|
+
};
|
|
314
|
+
previousValidationMessage = validationMessage;
|
|
315
|
+
}
|
|
257
316
|
}
|
|
258
317
|
const parserInheritsAnnotations = (0, __optique_core_extension.getTraits)(parser).inheritsAnnotations === true;
|
|
259
318
|
const promptedParser = {
|
package/dist/index.d.cts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { AnyDependencySource, DependencyValue, DependencyValues } from "@optique/core/dependency";
|
|
2
|
+
import { Message } from "@optique/core/message";
|
|
2
3
|
import { FluentParser } from "@optique/core/fluent";
|
|
3
4
|
import { Mode, Parser } from "@optique/core/parser";
|
|
4
5
|
import { ValueParserResult } from "@optique/core/valueparser";
|
|
@@ -23,13 +24,63 @@ type PromptCondition<TValue> = {
|
|
|
23
24
|
readonly when: () => boolean | Promise<boolean>;
|
|
24
25
|
readonly otherwise: NoInfer<TValue>;
|
|
25
26
|
};
|
|
27
|
+
/**
|
|
28
|
+
* Validates a value returned by a prompt adapter.
|
|
29
|
+
*
|
|
30
|
+
* Return `undefined` to accept the value, or a structured message to reject it
|
|
31
|
+
* and ask the adapter to try again. The validator receives the prompted value
|
|
32
|
+
* directly; it is not converted back into command-line input or passed through
|
|
33
|
+
* the wrapped value parser.
|
|
34
|
+
*
|
|
35
|
+
* @typeParam TValue Value type produced by the wrapped parser.
|
|
36
|
+
* @since 1.3.0
|
|
37
|
+
*/
|
|
38
|
+
type PromptValidator<TValue> = (value: TValue) => Message | undefined | Promise<Message | undefined>;
|
|
39
|
+
/**
|
|
40
|
+
* Shared validation, retry, and cancellation options for a prompt fallback.
|
|
41
|
+
*
|
|
42
|
+
* These options are separate from adapter-native validation fields. They
|
|
43
|
+
* apply only when the interactive fallback runs; CLI values, source-bound
|
|
44
|
+
* values, and skipped runtime conditions do not consult them.
|
|
45
|
+
*
|
|
46
|
+
* @typeParam TValue Value type produced by the wrapped parser.
|
|
47
|
+
* @since 1.3.0
|
|
48
|
+
*/
|
|
49
|
+
interface PromptOptions<TValue> {
|
|
50
|
+
/** Validator applied to each value returned by the adapter. */
|
|
51
|
+
readonly validate?: PromptValidator<TValue>;
|
|
52
|
+
/**
|
|
53
|
+
* Maximum number of adapter executions in one completion. Must be a
|
|
54
|
+
* positive integer. When omitted, validation may retry without a limit.
|
|
55
|
+
*/
|
|
56
|
+
readonly maxAttempts?: number;
|
|
57
|
+
/**
|
|
58
|
+
* Signal that stops the active adapter execution or validator. Its reason
|
|
59
|
+
* is propagated to the caller without becoming a parse failure.
|
|
60
|
+
*/
|
|
61
|
+
readonly signal?: AbortSignal;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Context passed to one execution of a prompt adapter.
|
|
65
|
+
*
|
|
66
|
+
* @since 1.3.0
|
|
67
|
+
*/
|
|
68
|
+
interface PromptExecutionContext {
|
|
69
|
+
/** One-based number of the current adapter execution. */
|
|
70
|
+
readonly attempt: number;
|
|
71
|
+
/** Message returned by the validator after the preceding execution. */
|
|
72
|
+
readonly previousValidationMessage?: Message;
|
|
73
|
+
/** Signal supplied through the prompt's shared options, when present. */
|
|
74
|
+
readonly signal?: AbortSignal;
|
|
75
|
+
}
|
|
26
76
|
/**
|
|
27
77
|
* Prompt adapter used by {@link createPromptAdapter}.
|
|
28
78
|
*
|
|
29
79
|
* The adapter owns library-specific prompt execution and maps the result into
|
|
30
80
|
* Optique's value-parser result shape. The shared parser wrapping behavior,
|
|
31
81
|
* including CLI priority, source bindings, deferred completion, suggestions,
|
|
32
|
-
*
|
|
82
|
+
* usage metadata, validation retries, and abort handling, is handled by
|
|
83
|
+
* *@optique/prompt*.
|
|
33
84
|
*
|
|
34
85
|
* @typeParam TConfig Prompt configuration accepted by the adapter.
|
|
35
86
|
* @since 1.2.0
|
|
@@ -41,10 +92,12 @@ interface PromptAdapter<TConfig> {
|
|
|
41
92
|
* @typeParam TValue Value type produced by the wrapped parser.
|
|
42
93
|
* @param config Prompt configuration supplied to the generated `prompt()`
|
|
43
94
|
* wrapper.
|
|
95
|
+
* @param context Attempt number, preceding validation message, and optional
|
|
96
|
+
* abort signal for this execution.
|
|
44
97
|
* @returns The prompted value or a prompt failure.
|
|
45
98
|
* @throws Any unexpected prompt execution failure.
|
|
46
99
|
*/
|
|
47
|
-
readonly execute: <TValue>(config: TConfig) => Promise<ValueParserResult<TValue>>;
|
|
100
|
+
readonly execute: <TValue>(config: TConfig, context: PromptExecutionContext) => Promise<ValueParserResult<TValue>>;
|
|
48
101
|
/**
|
|
49
102
|
* Returns a default value from the prompt config for documentation purposes.
|
|
50
103
|
*
|
|
@@ -238,11 +291,12 @@ type PromptConfigInput<TConfig, TValue> = (TConfig & PromptCondition<TValue>) |
|
|
|
238
291
|
*
|
|
239
292
|
* @typeParam TConfig Prompt configuration accepted by the adapter.
|
|
240
293
|
* @param adapter Library-specific prompt executor.
|
|
241
|
-
* @returns A `prompt(parser, config)` wrapper that always produces
|
|
242
|
-
* parser. The configuration may be a static `TConfig` or a
|
|
294
|
+
* @returns A `prompt(parser, config, options?)` wrapper that always produces
|
|
295
|
+
* an async parser. The configuration may be a static `TConfig` or a
|
|
243
296
|
* {@link DerivedPromptConfig} whose resolver returns `TConfig`.
|
|
297
|
+
* @throws {RangeError} If `maxAttempts` is not a positive integer.
|
|
244
298
|
* @since 1.2.0
|
|
245
299
|
*/
|
|
246
|
-
declare function createPromptAdapter<TConfig>(adapter: PromptAdapter<TConfig>): <M extends Mode, TValue, TState>(parser: Parser<M, TValue, TState>, config: PromptConfigInput<TConfig, TValue
|
|
300
|
+
declare function createPromptAdapter<TConfig>(adapter: PromptAdapter<TConfig>): <M extends Mode, TValue, TState>(parser: Parser<M, TValue, TState>, config: PromptConfigInput<TConfig, TValue>, options?: PromptOptions<NoInfer<TValue>>) => FluentParser<"async", TValue, TState>;
|
|
247
301
|
//#endregion
|
|
248
|
-
export { DerivePromptConfigContext, DerivePromptConfigOptions, DerivePromptConfigsContext, DerivePromptConfigsOptions, DerivedPromptConfig, PromptAdapter, PromptCondition, PromptConfigInput, createPromptAdapter, derivePromptConfig, isDerivedPromptConfig };
|
|
302
|
+
export { DerivePromptConfigContext, DerivePromptConfigOptions, DerivePromptConfigsContext, DerivePromptConfigsOptions, DerivedPromptConfig, PromptAdapter, PromptCondition, PromptConfigInput, PromptExecutionContext, PromptOptions, PromptValidator, createPromptAdapter, derivePromptConfig, isDerivedPromptConfig };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { AnyDependencySource, DependencyValue, DependencyValues } from "@optique/core/dependency";
|
|
2
|
+
import { Message } from "@optique/core/message";
|
|
2
3
|
import { FluentParser } from "@optique/core/fluent";
|
|
3
4
|
import { Mode, Parser } from "@optique/core/parser";
|
|
4
5
|
import { ValueParserResult } from "@optique/core/valueparser";
|
|
@@ -23,13 +24,63 @@ type PromptCondition<TValue> = {
|
|
|
23
24
|
readonly when: () => boolean | Promise<boolean>;
|
|
24
25
|
readonly otherwise: NoInfer<TValue>;
|
|
25
26
|
};
|
|
27
|
+
/**
|
|
28
|
+
* Validates a value returned by a prompt adapter.
|
|
29
|
+
*
|
|
30
|
+
* Return `undefined` to accept the value, or a structured message to reject it
|
|
31
|
+
* and ask the adapter to try again. The validator receives the prompted value
|
|
32
|
+
* directly; it is not converted back into command-line input or passed through
|
|
33
|
+
* the wrapped value parser.
|
|
34
|
+
*
|
|
35
|
+
* @typeParam TValue Value type produced by the wrapped parser.
|
|
36
|
+
* @since 1.3.0
|
|
37
|
+
*/
|
|
38
|
+
type PromptValidator<TValue> = (value: TValue) => Message | undefined | Promise<Message | undefined>;
|
|
39
|
+
/**
|
|
40
|
+
* Shared validation, retry, and cancellation options for a prompt fallback.
|
|
41
|
+
*
|
|
42
|
+
* These options are separate from adapter-native validation fields. They
|
|
43
|
+
* apply only when the interactive fallback runs; CLI values, source-bound
|
|
44
|
+
* values, and skipped runtime conditions do not consult them.
|
|
45
|
+
*
|
|
46
|
+
* @typeParam TValue Value type produced by the wrapped parser.
|
|
47
|
+
* @since 1.3.0
|
|
48
|
+
*/
|
|
49
|
+
interface PromptOptions<TValue> {
|
|
50
|
+
/** Validator applied to each value returned by the adapter. */
|
|
51
|
+
readonly validate?: PromptValidator<TValue>;
|
|
52
|
+
/**
|
|
53
|
+
* Maximum number of adapter executions in one completion. Must be a
|
|
54
|
+
* positive integer. When omitted, validation may retry without a limit.
|
|
55
|
+
*/
|
|
56
|
+
readonly maxAttempts?: number;
|
|
57
|
+
/**
|
|
58
|
+
* Signal that stops the active adapter execution or validator. Its reason
|
|
59
|
+
* is propagated to the caller without becoming a parse failure.
|
|
60
|
+
*/
|
|
61
|
+
readonly signal?: AbortSignal;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Context passed to one execution of a prompt adapter.
|
|
65
|
+
*
|
|
66
|
+
* @since 1.3.0
|
|
67
|
+
*/
|
|
68
|
+
interface PromptExecutionContext {
|
|
69
|
+
/** One-based number of the current adapter execution. */
|
|
70
|
+
readonly attempt: number;
|
|
71
|
+
/** Message returned by the validator after the preceding execution. */
|
|
72
|
+
readonly previousValidationMessage?: Message;
|
|
73
|
+
/** Signal supplied through the prompt's shared options, when present. */
|
|
74
|
+
readonly signal?: AbortSignal;
|
|
75
|
+
}
|
|
26
76
|
/**
|
|
27
77
|
* Prompt adapter used by {@link createPromptAdapter}.
|
|
28
78
|
*
|
|
29
79
|
* The adapter owns library-specific prompt execution and maps the result into
|
|
30
80
|
* Optique's value-parser result shape. The shared parser wrapping behavior,
|
|
31
81
|
* including CLI priority, source bindings, deferred completion, suggestions,
|
|
32
|
-
*
|
|
82
|
+
* usage metadata, validation retries, and abort handling, is handled by
|
|
83
|
+
* *@optique/prompt*.
|
|
33
84
|
*
|
|
34
85
|
* @typeParam TConfig Prompt configuration accepted by the adapter.
|
|
35
86
|
* @since 1.2.0
|
|
@@ -41,10 +92,12 @@ interface PromptAdapter<TConfig> {
|
|
|
41
92
|
* @typeParam TValue Value type produced by the wrapped parser.
|
|
42
93
|
* @param config Prompt configuration supplied to the generated `prompt()`
|
|
43
94
|
* wrapper.
|
|
95
|
+
* @param context Attempt number, preceding validation message, and optional
|
|
96
|
+
* abort signal for this execution.
|
|
44
97
|
* @returns The prompted value or a prompt failure.
|
|
45
98
|
* @throws Any unexpected prompt execution failure.
|
|
46
99
|
*/
|
|
47
|
-
readonly execute: <TValue>(config: TConfig) => Promise<ValueParserResult<TValue>>;
|
|
100
|
+
readonly execute: <TValue>(config: TConfig, context: PromptExecutionContext) => Promise<ValueParserResult<TValue>>;
|
|
48
101
|
/**
|
|
49
102
|
* Returns a default value from the prompt config for documentation purposes.
|
|
50
103
|
*
|
|
@@ -238,11 +291,12 @@ type PromptConfigInput<TConfig, TValue> = (TConfig & PromptCondition<TValue>) |
|
|
|
238
291
|
*
|
|
239
292
|
* @typeParam TConfig Prompt configuration accepted by the adapter.
|
|
240
293
|
* @param adapter Library-specific prompt executor.
|
|
241
|
-
* @returns A `prompt(parser, config)` wrapper that always produces
|
|
242
|
-
* parser. The configuration may be a static `TConfig` or a
|
|
294
|
+
* @returns A `prompt(parser, config, options?)` wrapper that always produces
|
|
295
|
+
* an async parser. The configuration may be a static `TConfig` or a
|
|
243
296
|
* {@link DerivedPromptConfig} whose resolver returns `TConfig`.
|
|
297
|
+
* @throws {RangeError} If `maxAttempts` is not a positive integer.
|
|
244
298
|
* @since 1.2.0
|
|
245
299
|
*/
|
|
246
|
-
declare function createPromptAdapter<TConfig>(adapter: PromptAdapter<TConfig>): <M extends Mode, TValue, TState>(parser: Parser<M, TValue, TState>, config: PromptConfigInput<TConfig, TValue
|
|
300
|
+
declare function createPromptAdapter<TConfig>(adapter: PromptAdapter<TConfig>): <M extends Mode, TValue, TState>(parser: Parser<M, TValue, TState>, config: PromptConfigInput<TConfig, TValue>, options?: PromptOptions<NoInfer<TValue>>) => FluentParser<"async", TValue, TState>;
|
|
247
301
|
//#endregion
|
|
248
|
-
export { DerivePromptConfigContext, DerivePromptConfigOptions, DerivePromptConfigsContext, DerivePromptConfigsOptions, DerivedPromptConfig, PromptAdapter, PromptCondition, PromptConfigInput, createPromptAdapter, derivePromptConfig, isDerivedPromptConfig };
|
|
302
|
+
export { DerivePromptConfigContext, DerivePromptConfigOptions, DerivePromptConfigsContext, DerivePromptConfigsOptions, DerivedPromptConfig, PromptAdapter, PromptCondition, PromptConfigInput, PromptExecutionContext, PromptOptions, PromptValidator, createPromptAdapter, derivePromptConfig, isDerivedPromptConfig };
|
package/dist/index.js
CHANGED
|
@@ -156,6 +156,40 @@ function unwrapCompleteResult(result) {
|
|
|
156
156
|
value: unwrapInjectedAnnotationState(result.value)
|
|
157
157
|
};
|
|
158
158
|
}
|
|
159
|
+
function throwIfPromptAborted(signal) {
|
|
160
|
+
if (signal?.aborted === true) throw signal.reason;
|
|
161
|
+
}
|
|
162
|
+
function racePromptWorkWithAbort(signal, work) {
|
|
163
|
+
if (signal == null) try {
|
|
164
|
+
return work();
|
|
165
|
+
} catch (error) {
|
|
166
|
+
return Promise.reject(error);
|
|
167
|
+
}
|
|
168
|
+
if (signal.aborted) return Promise.reject(signal.reason);
|
|
169
|
+
return new Promise((resolve, reject) => {
|
|
170
|
+
const onAbort = () => {
|
|
171
|
+
signal.removeEventListener("abort", onAbort);
|
|
172
|
+
reject(signal.reason);
|
|
173
|
+
};
|
|
174
|
+
const cleanup = () => signal.removeEventListener("abort", onAbort);
|
|
175
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
176
|
+
let outcome;
|
|
177
|
+
try {
|
|
178
|
+
outcome = work();
|
|
179
|
+
} catch (error) {
|
|
180
|
+
cleanup();
|
|
181
|
+
reject(error);
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
outcome.then((value) => {
|
|
185
|
+
cleanup();
|
|
186
|
+
resolve(value);
|
|
187
|
+
}, (error) => {
|
|
188
|
+
cleanup();
|
|
189
|
+
reject(error);
|
|
190
|
+
});
|
|
191
|
+
});
|
|
192
|
+
}
|
|
159
193
|
/**
|
|
160
194
|
* Creates a `prompt()` parser wrapper for a prompt library adapter.
|
|
161
195
|
*
|
|
@@ -167,13 +201,16 @@ function unwrapCompleteResult(result) {
|
|
|
167
201
|
*
|
|
168
202
|
* @typeParam TConfig Prompt configuration accepted by the adapter.
|
|
169
203
|
* @param adapter Library-specific prompt executor.
|
|
170
|
-
* @returns A `prompt(parser, config)` wrapper that always produces
|
|
171
|
-
* parser. The configuration may be a static `TConfig` or a
|
|
204
|
+
* @returns A `prompt(parser, config, options?)` wrapper that always produces
|
|
205
|
+
* an async parser. The configuration may be a static `TConfig` or a
|
|
172
206
|
* {@link DerivedPromptConfig} whose resolver returns `TConfig`.
|
|
207
|
+
* @throws {RangeError} If `maxAttempts` is not a positive integer.
|
|
173
208
|
* @since 1.2.0
|
|
174
209
|
*/
|
|
175
210
|
function createPromptAdapter(adapter) {
|
|
176
|
-
return function prompt(parser, config) {
|
|
211
|
+
return function prompt(parser, config, options = {}) {
|
|
212
|
+
if (options.maxAttempts !== void 0 && (!Number.isInteger(options.maxAttempts) || options.maxAttempts < 1)) throw new RangeError("maxAttempts must be an integer greater than or equal to 1.");
|
|
213
|
+
const { validate, maxAttempts, signal } = options;
|
|
177
214
|
const promptBindStateKey = Symbol("@optique/prompt/promptState");
|
|
178
215
|
const completionCacheKeys = /* @__PURE__ */ new Map();
|
|
179
216
|
const completionCacheSymbolIds = /* @__PURE__ */ new Map();
|
|
@@ -223,14 +260,36 @@ function createPromptAdapter(adapter) {
|
|
|
223
260
|
success: true,
|
|
224
261
|
value: config.otherwise
|
|
225
262
|
};
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
263
|
+
throwIfPromptAborted(signal);
|
|
264
|
+
let resolvedConfig;
|
|
265
|
+
if (!isDerivedPromptConfig(config)) resolvedConfig = config;
|
|
266
|
+
else {
|
|
267
|
+
const source = promptedParser.dependencyMetadata?.source;
|
|
268
|
+
const resolved = await resolveDerivedPromptConfig(config, exec, source?.sourceId, source?.metavar);
|
|
269
|
+
throwIfPromptAborted(signal);
|
|
270
|
+
if (!resolved.ok) return {
|
|
271
|
+
success: false,
|
|
272
|
+
error: resolved.error
|
|
273
|
+
};
|
|
274
|
+
resolvedConfig = resolved.config;
|
|
275
|
+
}
|
|
276
|
+
let previousValidationMessage;
|
|
277
|
+
for (let attempt = 1;; attempt++) {
|
|
278
|
+
const context = {
|
|
279
|
+
attempt,
|
|
280
|
+
...previousValidationMessage === void 0 ? {} : { previousValidationMessage },
|
|
281
|
+
...signal === void 0 ? {} : { signal }
|
|
282
|
+
};
|
|
283
|
+
const result = await racePromptWorkWithAbort(signal, () => adapter.execute(resolvedConfig, context));
|
|
284
|
+
if (!result.success || validate == null) return result;
|
|
285
|
+
const validationMessage = await racePromptWorkWithAbort(signal, () => Promise.resolve(validate(result.value)));
|
|
286
|
+
if (validationMessage === void 0) return result;
|
|
287
|
+
if (maxAttempts !== void 0 && attempt >= maxAttempts) return {
|
|
288
|
+
success: false,
|
|
289
|
+
error: validationMessage
|
|
290
|
+
};
|
|
291
|
+
previousValidationMessage = validationMessage;
|
|
292
|
+
}
|
|
234
293
|
}
|
|
235
294
|
const parserInheritsAnnotations = getTraits(parser).inheritsAnnotations === true;
|
|
236
295
|
const promptedParser = {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@optique/prompt",
|
|
3
|
-
"version": "1.3.0-dev.
|
|
3
|
+
"version": "1.3.0-dev.2464",
|
|
4
4
|
"description": "Generic prompt adapter support for Optique",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"CLI",
|
|
@@ -60,12 +60,12 @@
|
|
|
60
60
|
},
|
|
61
61
|
"sideEffects": false,
|
|
62
62
|
"dependencies": {
|
|
63
|
-
"@optique/core": "1.3.0-dev.
|
|
63
|
+
"@optique/core": "1.3.0-dev.2464+e4795e6e"
|
|
64
64
|
},
|
|
65
65
|
"devDependencies": {
|
|
66
|
-
"@optique/config": "1.3.0-dev.
|
|
67
|
-
"@optique/env": "1.3.0-dev.
|
|
68
|
-
"@optique/run": "1.3.0-dev.
|
|
66
|
+
"@optique/config": "1.3.0-dev.2464+e4795e6e",
|
|
67
|
+
"@optique/env": "1.3.0-dev.2464+e4795e6e",
|
|
68
|
+
"@optique/run": "1.3.0-dev.2464+e4795e6e",
|
|
69
69
|
"@types/node": "^24.0.0",
|
|
70
70
|
"fast-check": "^4.7.0",
|
|
71
71
|
"tsdown": "^0.13.0",
|