@portel/photon-core 1.0.2 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,93 @@
1
+ /**
2
+ * Elicit - Cross-platform user input for Photon
3
+ *
4
+ * Provides a unified API for requesting user input that works across:
5
+ * - Native OS dialogs (default - works standalone without photon runtime)
6
+ * - CLI readline (photon CLI overrides via globalThis.__photon_prompt__)
7
+ * - MCP elicitation (photon MCP overrides when client supports it)
8
+ *
9
+ * Design:
10
+ * - Photon files call the simple `prompt()` function (no imports needed)
11
+ * - Standalone: Uses native OS dialogs
12
+ * - Photon runtime: Overrides globalThis.__photon_prompt__ with appropriate handler
13
+ */
14
+ export interface ElicitOptions {
15
+ /** The prompt/message to display to the user */
16
+ prompt: string;
17
+ /** Title for the dialog (used in GUI dialogs) */
18
+ title?: string;
19
+ /** Default value to pre-fill */
20
+ defaultValue?: string;
21
+ /** Type of input */
22
+ type?: 'text' | 'password' | 'confirm';
23
+ /** JSON schema for validation (used in MCP elicitation) */
24
+ schema?: object;
25
+ /** Timeout in milliseconds (0 = no timeout) */
26
+ timeout?: number;
27
+ }
28
+ export interface ElicitResult {
29
+ /** Whether the user provided input (vs cancelled) */
30
+ success: boolean;
31
+ /** The user's input value */
32
+ value?: string;
33
+ /** True if user confirmed (for confirm type) */
34
+ confirmed?: boolean;
35
+ /** Error message if failed */
36
+ error?: string;
37
+ }
38
+ /** Prompt handler type - simple string in, string out */
39
+ export type PromptHandler = (message: string, defaultValue?: string) => Promise<string | null>;
40
+ /** Full elicit handler type */
41
+ export type ElicitHandler = (options: ElicitOptions) => Promise<ElicitResult>;
42
+ declare global {
43
+ var __photon_prompt__: PromptHandler | undefined;
44
+ var __photon_elicit__: ElicitHandler | undefined;
45
+ }
46
+ /**
47
+ * Set the prompt handler (simple string-based)
48
+ * Runtimes use this to override with readline, MCP elicitation, etc.
49
+ */
50
+ export declare function setPromptHandler(handler: PromptHandler | null): void;
51
+ /**
52
+ * Set the full elicit handler (with options)
53
+ */
54
+ export declare function setElicitHandler(handler: ElicitHandler | null): void;
55
+ /**
56
+ * Simple prompt function - can be called directly from photon files
57
+ * No imports needed - uses global override or falls back to native dialog
58
+ *
59
+ * @example
60
+ * ```typescript
61
+ * // In a photon file - works standalone or with photon runtime
62
+ * const code = await prompt('Enter the 6-digit code:');
63
+ * if (code) {
64
+ * console.log('User entered:', code);
65
+ * }
66
+ * ```
67
+ */
68
+ export declare function prompt(message: string, defaultValue?: string): Promise<string | null>;
69
+ /**
70
+ * Confirm dialog - returns true/false
71
+ */
72
+ export declare function confirm(message: string): Promise<boolean>;
73
+ /**
74
+ * Full elicit with options
75
+ */
76
+ export declare function elicit(options: ElicitOptions): Promise<ElicitResult>;
77
+ /**
78
+ * Get the current prompt handler
79
+ */
80
+ export declare function getPromptHandler(): PromptHandler | undefined;
81
+ /**
82
+ * Get the current elicit handler
83
+ */
84
+ export declare function getElicitHandler(): ElicitHandler | undefined;
85
+ /**
86
+ * Elicit using readline (for CLI/terminal)
87
+ */
88
+ export declare function elicitReadline(options: ElicitOptions): Promise<ElicitResult>;
89
+ /**
90
+ * Elicit using native OS dialog
91
+ */
92
+ export declare function elicitNativeDialog(options: ElicitOptions): Promise<ElicitResult>;
93
+ //# sourceMappingURL=elicit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"elicit.d.ts","sourceRoot":"","sources":["../src/elicit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAMH,MAAM,WAAW,aAAa;IAC5B,gDAAgD;IAChD,MAAM,EAAE,MAAM,CAAC;IACf,iDAAiD;IACjD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,gCAAgC;IAChC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,oBAAoB;IACpB,IAAI,CAAC,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAAC;IACvC,2DAA2D;IAC3D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,+CAA+C;IAC/C,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,YAAY;IAC3B,qDAAqD;IACrD,OAAO,EAAE,OAAO,CAAC;IACjB,6BAA6B;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,gDAAgD;IAChD,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,8BAA8B;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,yDAAyD;AACzD,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;AAE/F,+BAA+B;AAC/B,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,EAAE,aAAa,KAAK,OAAO,CAAC,YAAY,CAAC,CAAC;AAG9E,OAAO,CAAC,MAAM,CAAC;IACb,IAAI,iBAAiB,EAAE,aAAa,GAAG,SAAS,CAAC;IACjD,IAAI,iBAAiB,EAAE,aAAa,GAAG,SAAS,CAAC;CAClD;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI,GAAG,IAAI,CAEpE;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI,GAAG,IAAI,CAEpE;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAc3F;AAED;;GAEG;AACH,wBAAsB,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAe/D;AAED;;GAEG;AACH,wBAAsB,MAAM,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC,CAa1E;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,aAAa,GAAG,SAAS,CAE5D;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,aAAa,GAAG,SAAS,CAE5D;AAED;;GAEG;AACH,wBAAsB,cAAc,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC,CA2ClF;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC,CAqBtF"}
package/dist/elicit.js ADDED
@@ -0,0 +1,373 @@
1
+ /**
2
+ * Elicit - Cross-platform user input for Photon
3
+ *
4
+ * Provides a unified API for requesting user input that works across:
5
+ * - Native OS dialogs (default - works standalone without photon runtime)
6
+ * - CLI readline (photon CLI overrides via globalThis.__photon_prompt__)
7
+ * - MCP elicitation (photon MCP overrides when client supports it)
8
+ *
9
+ * Design:
10
+ * - Photon files call the simple `prompt()` function (no imports needed)
11
+ * - Standalone: Uses native OS dialogs
12
+ * - Photon runtime: Overrides globalThis.__photon_prompt__ with appropriate handler
13
+ */
14
+ import { exec } from 'child_process';
15
+ import * as os from 'os';
16
+ import * as readline from 'readline';
17
+ /**
18
+ * Set the prompt handler (simple string-based)
19
+ * Runtimes use this to override with readline, MCP elicitation, etc.
20
+ */
21
+ export function setPromptHandler(handler) {
22
+ globalThis.__photon_prompt__ = handler || undefined;
23
+ }
24
+ /**
25
+ * Set the full elicit handler (with options)
26
+ */
27
+ export function setElicitHandler(handler) {
28
+ globalThis.__photon_elicit__ = handler || undefined;
29
+ }
30
+ /**
31
+ * Simple prompt function - can be called directly from photon files
32
+ * No imports needed - uses global override or falls back to native dialog
33
+ *
34
+ * @example
35
+ * ```typescript
36
+ * // In a photon file - works standalone or with photon runtime
37
+ * const code = await prompt('Enter the 6-digit code:');
38
+ * if (code) {
39
+ * console.log('User entered:', code);
40
+ * }
41
+ * ```
42
+ */
43
+ export async function prompt(message, defaultValue) {
44
+ // Check for runtime override
45
+ if (globalThis.__photon_prompt__) {
46
+ return globalThis.__photon_prompt__(message, defaultValue);
47
+ }
48
+ // Fall back to native dialog
49
+ const result = await elicitNativeDialog({
50
+ prompt: message,
51
+ defaultValue,
52
+ type: 'text',
53
+ });
54
+ return result.success ? (result.value ?? null) : null;
55
+ }
56
+ /**
57
+ * Confirm dialog - returns true/false
58
+ */
59
+ export async function confirm(message) {
60
+ if (globalThis.__photon_elicit__) {
61
+ const result = await globalThis.__photon_elicit__({
62
+ prompt: message,
63
+ type: 'confirm',
64
+ });
65
+ return result.confirmed ?? false;
66
+ }
67
+ const result = await elicitNativeDialog({
68
+ prompt: message,
69
+ type: 'confirm',
70
+ });
71
+ return result.confirmed ?? false;
72
+ }
73
+ /**
74
+ * Full elicit with options
75
+ */
76
+ export async function elicit(options) {
77
+ // Use custom handler if set
78
+ if (globalThis.__photon_elicit__) {
79
+ return globalThis.__photon_elicit__(options);
80
+ }
81
+ // Check if we're in a TTY (interactive terminal)
82
+ if (process.stdin.isTTY && process.stdout.isTTY) {
83
+ return elicitReadline(options);
84
+ }
85
+ // Default to native OS dialog
86
+ return elicitNativeDialog(options);
87
+ }
88
+ /**
89
+ * Get the current prompt handler
90
+ */
91
+ export function getPromptHandler() {
92
+ return globalThis.__photon_prompt__;
93
+ }
94
+ /**
95
+ * Get the current elicit handler
96
+ */
97
+ export function getElicitHandler() {
98
+ return globalThis.__photon_elicit__;
99
+ }
100
+ /**
101
+ * Elicit using readline (for CLI/terminal)
102
+ */
103
+ export async function elicitReadline(options) {
104
+ return new Promise((resolve) => {
105
+ const rl = readline.createInterface({
106
+ input: process.stdin,
107
+ output: process.stdout,
108
+ });
109
+ const prompt = options.defaultValue
110
+ ? `${options.prompt} [${options.defaultValue}]: `
111
+ : `${options.prompt}: `;
112
+ if (options.type === 'confirm') {
113
+ rl.question(`${options.prompt} (y/n): `, (answer) => {
114
+ rl.close();
115
+ const confirmed = answer.toLowerCase().startsWith('y');
116
+ resolve({
117
+ success: true,
118
+ confirmed,
119
+ value: confirmed ? 'yes' : 'no',
120
+ });
121
+ });
122
+ }
123
+ else {
124
+ rl.question(prompt, (answer) => {
125
+ rl.close();
126
+ const value = answer || options.defaultValue || '';
127
+ resolve({
128
+ success: true,
129
+ value,
130
+ });
131
+ });
132
+ }
133
+ // Handle timeout
134
+ if (options.timeout && options.timeout > 0) {
135
+ setTimeout(() => {
136
+ rl.close();
137
+ resolve({
138
+ success: false,
139
+ error: 'Input timeout',
140
+ });
141
+ }, options.timeout);
142
+ }
143
+ });
144
+ }
145
+ /**
146
+ * Elicit using native OS dialog
147
+ */
148
+ export async function elicitNativeDialog(options) {
149
+ const platform = os.platform();
150
+ try {
151
+ switch (platform) {
152
+ case 'darwin':
153
+ return elicitMacOS(options);
154
+ case 'win32':
155
+ return elicitWindows(options);
156
+ case 'linux':
157
+ return elicitLinux(options);
158
+ default:
159
+ // Fallback to readline for unsupported platforms
160
+ return elicitReadline(options);
161
+ }
162
+ }
163
+ catch (error) {
164
+ return {
165
+ success: false,
166
+ error: error.message,
167
+ };
168
+ }
169
+ }
170
+ /**
171
+ * macOS: Use osascript (AppleScript) for dialogs
172
+ */
173
+ function elicitMacOS(options) {
174
+ return new Promise((resolve) => {
175
+ const title = options.title || 'Input Required';
176
+ const prompt = options.prompt;
177
+ const defaultValue = options.defaultValue || '';
178
+ const isPassword = options.type === 'password';
179
+ const isConfirm = options.type === 'confirm';
180
+ let script;
181
+ if (isConfirm) {
182
+ script = `
183
+ display dialog "${escapeAppleScript(prompt)}" ¬
184
+ with title "${escapeAppleScript(title)}" ¬
185
+ buttons {"Cancel", "No", "Yes"} ¬
186
+ default button "Yes"
187
+ set buttonPressed to button returned of result
188
+ return buttonPressed
189
+ `;
190
+ }
191
+ else if (isPassword) {
192
+ script = `
193
+ display dialog "${escapeAppleScript(prompt)}" ¬
194
+ with title "${escapeAppleScript(title)}" ¬
195
+ default answer "${escapeAppleScript(defaultValue)}" ¬
196
+ with hidden answer ¬
197
+ buttons {"Cancel", "OK"} ¬
198
+ default button "OK"
199
+ return text returned of result
200
+ `;
201
+ }
202
+ else {
203
+ script = `
204
+ display dialog "${escapeAppleScript(prompt)}" ¬
205
+ with title "${escapeAppleScript(title)}" ¬
206
+ default answer "${escapeAppleScript(defaultValue)}" ¬
207
+ buttons {"Cancel", "OK"} ¬
208
+ default button "OK"
209
+ return text returned of result
210
+ `;
211
+ }
212
+ exec(`osascript -e '${script.replace(/'/g, "'\"'\"'")}'`, (error, stdout, stderr) => {
213
+ if (error) {
214
+ // User cancelled
215
+ if (error.code === 1) {
216
+ resolve({
217
+ success: false,
218
+ error: 'User cancelled',
219
+ });
220
+ }
221
+ else {
222
+ resolve({
223
+ success: false,
224
+ error: stderr || error.message,
225
+ });
226
+ }
227
+ return;
228
+ }
229
+ const value = stdout.trim();
230
+ if (isConfirm) {
231
+ resolve({
232
+ success: true,
233
+ confirmed: value === 'Yes',
234
+ value,
235
+ });
236
+ }
237
+ else {
238
+ resolve({
239
+ success: true,
240
+ value,
241
+ });
242
+ }
243
+ });
244
+ });
245
+ }
246
+ /**
247
+ * Windows: Use PowerShell for dialogs
248
+ */
249
+ function elicitWindows(options) {
250
+ return new Promise((resolve) => {
251
+ const title = options.title || 'Input Required';
252
+ const prompt = options.prompt;
253
+ const defaultValue = options.defaultValue || '';
254
+ const isConfirm = options.type === 'confirm';
255
+ let script;
256
+ if (isConfirm) {
257
+ script = `
258
+ Add-Type -AssemblyName System.Windows.Forms
259
+ $result = [System.Windows.Forms.MessageBox]::Show('${escapePowerShell(prompt)}', '${escapePowerShell(title)}', 'YesNoCancel', 'Question')
260
+ Write-Output $result
261
+ `;
262
+ }
263
+ else {
264
+ script = `
265
+ Add-Type -AssemblyName Microsoft.VisualBasic
266
+ $result = [Microsoft.VisualBasic.Interaction]::InputBox('${escapePowerShell(prompt)}', '${escapePowerShell(title)}', '${escapePowerShell(defaultValue)}')
267
+ Write-Output $result
268
+ `;
269
+ }
270
+ exec(`powershell -Command "${script.replace(/"/g, '\\"')}"`, (error, stdout, stderr) => {
271
+ if (error) {
272
+ resolve({
273
+ success: false,
274
+ error: stderr || error.message,
275
+ });
276
+ return;
277
+ }
278
+ const value = stdout.trim();
279
+ if (isConfirm) {
280
+ if (value === 'Cancel') {
281
+ resolve({
282
+ success: false,
283
+ error: 'User cancelled',
284
+ });
285
+ }
286
+ else {
287
+ resolve({
288
+ success: true,
289
+ confirmed: value === 'Yes',
290
+ value,
291
+ });
292
+ }
293
+ }
294
+ else {
295
+ if (value === '') {
296
+ resolve({
297
+ success: false,
298
+ error: 'User cancelled',
299
+ });
300
+ }
301
+ else {
302
+ resolve({
303
+ success: true,
304
+ value,
305
+ });
306
+ }
307
+ }
308
+ });
309
+ });
310
+ }
311
+ /**
312
+ * Linux: Use zenity or kdialog
313
+ */
314
+ function elicitLinux(options) {
315
+ return new Promise((resolve) => {
316
+ const title = options.title || 'Input Required';
317
+ const prompt = options.prompt;
318
+ const defaultValue = options.defaultValue || '';
319
+ const isPassword = options.type === 'password';
320
+ const isConfirm = options.type === 'confirm';
321
+ // Try zenity first, then kdialog
322
+ let command;
323
+ if (isConfirm) {
324
+ command = `zenity --question --title="${escapeShell(title)}" --text="${escapeShell(prompt)}" 2>/dev/null || kdialog --yesno "${escapeShell(prompt)}" --title "${escapeShell(title)}" 2>/dev/null`;
325
+ }
326
+ else if (isPassword) {
327
+ command = `zenity --password --title="${escapeShell(title)}" 2>/dev/null || kdialog --password "${escapeShell(prompt)}" --title "${escapeShell(title)}" 2>/dev/null`;
328
+ }
329
+ else {
330
+ command = `zenity --entry --title="${escapeShell(title)}" --text="${escapeShell(prompt)}" --entry-text="${escapeShell(defaultValue)}" 2>/dev/null || kdialog --inputbox "${escapeShell(prompt)}" "${escapeShell(defaultValue)}" --title "${escapeShell(title)}" 2>/dev/null`;
331
+ }
332
+ exec(command, (error, stdout, stderr) => {
333
+ if (error) {
334
+ if (error.code === 1) {
335
+ resolve({
336
+ success: false,
337
+ error: 'User cancelled',
338
+ });
339
+ }
340
+ else {
341
+ // Neither zenity nor kdialog available, fall back to readline
342
+ elicitReadline(options).then(resolve);
343
+ }
344
+ return;
345
+ }
346
+ const value = stdout.trim();
347
+ if (isConfirm) {
348
+ resolve({
349
+ success: true,
350
+ confirmed: true,
351
+ value: 'yes',
352
+ });
353
+ }
354
+ else {
355
+ resolve({
356
+ success: true,
357
+ value,
358
+ });
359
+ }
360
+ });
361
+ });
362
+ }
363
+ // Helper functions for escaping strings
364
+ function escapeAppleScript(str) {
365
+ return str.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
366
+ }
367
+ function escapePowerShell(str) {
368
+ return str.replace(/'/g, "''");
369
+ }
370
+ function escapeShell(str) {
371
+ return str.replace(/"/g, '\\"').replace(/\$/g, '\\$').replace(/`/g, '\\`');
372
+ }
373
+ //# sourceMappingURL=elicit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"elicit.js","sourceRoot":"","sources":["../src/elicit.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,205 @@
1
+ /**
2
+ * Generator-based Tool Execution
3
+ *
4
+ * Enables photon tools to use generator functions with `yield` for:
5
+ * - User prompts (text, password, confirm, select)
6
+ * - Progress updates
7
+ * - Streaming responses
8
+ * - Multi-step wizards
9
+ *
10
+ * The runtime handles yields appropriately based on the protocol:
11
+ * - REST: Extract yields as optional parameters
12
+ * - WebSocket/MCP: Interactive prompts
13
+ * - CLI: readline prompts
14
+ * - Fallback: Native OS dialogs
15
+ *
16
+ * @example
17
+ * ```typescript
18
+ * async *connect(params: { ip: string }) {
19
+ * await this.startConnection(params.ip);
20
+ *
21
+ * const code: string = yield {
22
+ * prompt: 'Enter the 6-digit code:',
23
+ * type: 'text'
24
+ * };
25
+ *
26
+ * await this.sendCode(code);
27
+ * return { success: true };
28
+ * }
29
+ * ```
30
+ */
31
+ /**
32
+ * Text input prompt
33
+ */
34
+ export interface PromptYield {
35
+ prompt: string;
36
+ type?: 'text' | 'password';
37
+ default?: string;
38
+ /** Unique identifier for this prompt (auto-generated if not provided) */
39
+ id?: string;
40
+ /** Validation pattern */
41
+ pattern?: string;
42
+ /** Whether this prompt is required */
43
+ required?: boolean;
44
+ }
45
+ /**
46
+ * Confirmation dialog
47
+ */
48
+ export interface ConfirmYield {
49
+ confirm: string;
50
+ /** Mark as dangerous action (UI can show warning styling) */
51
+ dangerous?: boolean;
52
+ id?: string;
53
+ }
54
+ /**
55
+ * Selection from options
56
+ */
57
+ export interface SelectYield {
58
+ select: string;
59
+ options: Array<string | {
60
+ value: string;
61
+ label: string;
62
+ }>;
63
+ /** Allow multiple selections */
64
+ multi?: boolean;
65
+ id?: string;
66
+ }
67
+ /**
68
+ * Progress update (for long-running operations)
69
+ */
70
+ export interface ProgressYield {
71
+ progress: number;
72
+ status?: string;
73
+ /** Additional data to stream to client */
74
+ data?: any;
75
+ }
76
+ /**
77
+ * Stream data to client
78
+ */
79
+ export interface StreamYield {
80
+ stream: any;
81
+ /** Whether this is the final chunk */
82
+ final?: boolean;
83
+ }
84
+ /**
85
+ * Log/debug message
86
+ */
87
+ export interface LogYield {
88
+ log: string;
89
+ level?: 'debug' | 'info' | 'warn' | 'error';
90
+ }
91
+ /**
92
+ * All possible yield types
93
+ */
94
+ export type PhotonYield = PromptYield | ConfirmYield | SelectYield | ProgressYield | StreamYield | LogYield;
95
+ /**
96
+ * Check if a yield requires user input
97
+ */
98
+ export declare function isInputYield(y: PhotonYield): y is PromptYield | ConfirmYield | SelectYield;
99
+ /**
100
+ * Check if a yield is a progress update
101
+ */
102
+ export declare function isProgressYield(y: PhotonYield): y is ProgressYield;
103
+ /**
104
+ * Check if a yield is streaming data
105
+ */
106
+ export declare function isStreamYield(y: PhotonYield): y is StreamYield;
107
+ /**
108
+ * Check if a yield is a log message
109
+ */
110
+ export declare function isLogYield(y: PhotonYield): y is LogYield;
111
+ /**
112
+ * Function that provides input for a yield
113
+ * Runtimes implement this based on their protocol
114
+ */
115
+ export type InputProvider = (yielded: PhotonYield) => Promise<any>;
116
+ /**
117
+ * Handler for non-input yields (progress, stream, log)
118
+ */
119
+ export type OutputHandler = (yielded: PhotonYield) => void | Promise<void>;
120
+ /**
121
+ * Configuration for generator execution
122
+ */
123
+ export interface GeneratorExecutorConfig {
124
+ /** Provides input for prompt/confirm/select yields */
125
+ inputProvider: InputProvider;
126
+ /** Handles progress/stream/log yields */
127
+ outputHandler?: OutputHandler;
128
+ /** Pre-provided inputs (for REST APIs) */
129
+ preProvidedInputs?: Record<string, any>;
130
+ /** Timeout for waiting for input (ms) */
131
+ inputTimeout?: number;
132
+ }
133
+ /**
134
+ * Execute a generator-based tool
135
+ *
136
+ * @param generator - The async generator to execute
137
+ * @param config - Configuration for handling yields
138
+ * @returns The final return value of the generator
139
+ *
140
+ * @example
141
+ * ```typescript
142
+ * const result = await executeGenerator(tool.connect({ ip: '192.168.1.1' }), {
143
+ * inputProvider: async (y) => {
144
+ * if ('prompt' in y) return await readline(y.prompt);
145
+ * if ('confirm' in y) return await confirm(y.confirm);
146
+ * },
147
+ * outputHandler: (y) => {
148
+ * if ('progress' in y) console.log(`Progress: ${y.progress}%`);
149
+ * }
150
+ * });
151
+ * ```
152
+ */
153
+ export declare function executeGenerator<T>(generator: AsyncGenerator<PhotonYield, T, any>, config: GeneratorExecutorConfig): Promise<T>;
154
+ /**
155
+ * Check if a function is an async generator function
156
+ */
157
+ export declare function isAsyncGeneratorFunction(fn: any): fn is (...args: any[]) => AsyncGenerator;
158
+ /**
159
+ * Check if a value is an async generator (already invoked)
160
+ */
161
+ export declare function isAsyncGenerator(obj: any): obj is AsyncGenerator;
162
+ /**
163
+ * Information about a yield point extracted from a generator
164
+ */
165
+ export interface ExtractedYield {
166
+ id: string;
167
+ type: 'prompt' | 'confirm' | 'select';
168
+ prompt?: string;
169
+ options?: Array<string | {
170
+ value: string;
171
+ label: string;
172
+ }>;
173
+ default?: string;
174
+ required?: boolean;
175
+ pattern?: string;
176
+ dangerous?: boolean;
177
+ multi?: boolean;
178
+ }
179
+ /**
180
+ * Extract yield information by running generator with mock provider
181
+ * This is used for REST API schema generation
182
+ *
183
+ * Note: This only extracts yields that are reachable with default/empty inputs
184
+ * Complex conditional yields may not be extracted
185
+ */
186
+ export declare function extractYields(generatorFn: (...args: any[]) => AsyncGenerator<PhotonYield, any, any>, mockParams?: any): Promise<ExtractedYield[]>;
187
+ /**
188
+ * Create an input provider from pre-provided values
189
+ * Throws if a required value is missing
190
+ */
191
+ export declare function createPrefilledProvider(inputs: Record<string, any>): InputProvider;
192
+ /**
193
+ * Error thrown when input is needed but not available
194
+ * Runtimes can catch this to return appropriate responses
195
+ */
196
+ export declare class NeedsInputError extends Error {
197
+ readonly yielded: PhotonYield;
198
+ constructor(yielded: PhotonYield);
199
+ }
200
+ /**
201
+ * Wrap a regular async function to behave like a generator
202
+ * Useful for uniform handling in runtimes
203
+ */
204
+ export declare function wrapAsGenerator<T>(asyncFn: () => Promise<T>): AsyncGenerator<never, T, unknown>;
205
+ //# sourceMappingURL=generator.d.ts.map