@portel/photon-core 1.0.2 → 1.2.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.
- package/dist/elicit.d.ts +93 -0
- package/dist/elicit.d.ts.map +1 -0
- package/dist/elicit.js +373 -0
- package/dist/elicit.js.map +1 -0
- package/dist/generator.d.ts +685 -0
- package/dist/generator.d.ts.map +1 -0
- package/dist/generator.js +410 -0
- package/dist/generator.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +25 -0
- package/dist/index.js.map +1 -1
- package/dist/schema-extractor.d.ts +6 -0
- package/dist/schema-extractor.d.ts.map +1 -1
- package/dist/schema-extractor.js +26 -1
- package/dist/schema-extractor.js.map +1 -1
- package/dist/types.d.ts +22 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +1 -1
- package/src/elicit.ts +438 -0
- package/src/generator.ts +963 -0
- package/src/index.ts +91 -0
- package/src/schema-extractor.ts +32 -2
- package/src/types.ts +20 -0
|
@@ -0,0 +1,410 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generator-based Tool Execution with Ask/Emit Pattern
|
|
3
|
+
*
|
|
4
|
+
* Enables photon tools to use async generator functions with `yield` for:
|
|
5
|
+
* - Interactive user input (ask) - blocks until user responds
|
|
6
|
+
* - Real-time output (emit) - fire and forget, no response needed
|
|
7
|
+
*
|
|
8
|
+
* ══════════════════════════════════════════════════════════════════════════════
|
|
9
|
+
* DESIGN PHILOSOPHY
|
|
10
|
+
* ══════════════════════════════════════════════════════════════════════════════
|
|
11
|
+
*
|
|
12
|
+
* The `ask` vs `emit` pattern provides instant clarity:
|
|
13
|
+
* - `ask` = "I need something FROM the user" (blocks, returns value)
|
|
14
|
+
* - `emit` = "I'm sending something TO the user" (non-blocking, void)
|
|
15
|
+
*
|
|
16
|
+
* This maps naturally to all runtime contexts:
|
|
17
|
+
*
|
|
18
|
+
* | Runtime | ask (input) | emit (output) |
|
|
19
|
+
* |------------|--------------------------|----------------------------|
|
|
20
|
+
* | REST API | Returns 202 + continue | Included in response or SSE|
|
|
21
|
+
* | WebSocket | Server request → client | Server push to client |
|
|
22
|
+
* | CLI | Readline prompt | Console output |
|
|
23
|
+
* | MCP | Elicitation dialog | Notification/logging |
|
|
24
|
+
* | Chatbot | Bot question → user reply| Status message, typing... |
|
|
25
|
+
*
|
|
26
|
+
* ══════════════════════════════════════════════════════════════════════════════
|
|
27
|
+
* REST API CONTINUATION PATTERN
|
|
28
|
+
* ══════════════════════════════════════════════════════════════════════════════
|
|
29
|
+
*
|
|
30
|
+
* When a generator yields `ask`, REST APIs can implement a continuation flow:
|
|
31
|
+
*
|
|
32
|
+
* ```
|
|
33
|
+
* POST /api/google-tv/connect
|
|
34
|
+
* Body: { ip: "192.168.1.100" }
|
|
35
|
+
*
|
|
36
|
+
* Response (202 Accepted):
|
|
37
|
+
* {
|
|
38
|
+
* "status": "awaiting_input",
|
|
39
|
+
* "continuation_id": "ctx_abc123",
|
|
40
|
+
* "ask": { "type": "text", "id": "pairing_code", "message": "Enter code:" },
|
|
41
|
+
* "continue": "/api/google-tv/connect/ctx_abc123"
|
|
42
|
+
* }
|
|
43
|
+
*
|
|
44
|
+
* POST /api/google-tv/connect/ctx_abc123
|
|
45
|
+
* Body: { "pairing_code": "123456" }
|
|
46
|
+
*
|
|
47
|
+
* Response (200 OK):
|
|
48
|
+
* { "status": "complete", "result": { "success": true } }
|
|
49
|
+
* ```
|
|
50
|
+
*
|
|
51
|
+
* ══════════════════════════════════════════════════════════════════════════════
|
|
52
|
+
* USAGE EXAMPLE
|
|
53
|
+
* ══════════════════════════════════════════════════════════════════════════════
|
|
54
|
+
*
|
|
55
|
+
* ```typescript
|
|
56
|
+
* async *connect(params: { ip: string }) {
|
|
57
|
+
* yield { emit: 'status', message: 'Connecting to TV...' };
|
|
58
|
+
*
|
|
59
|
+
* await this.startPairing(params.ip);
|
|
60
|
+
*
|
|
61
|
+
* yield { emit: 'progress', value: 0.3, message: 'Waiting for code...' };
|
|
62
|
+
*
|
|
63
|
+
* // Blocks until user provides input
|
|
64
|
+
* const code: string = yield {
|
|
65
|
+
* ask: 'text',
|
|
66
|
+
* id: 'pairing_code',
|
|
67
|
+
* message: 'Enter the 6-digit code shown on TV:',
|
|
68
|
+
* pattern: '^[0-9]{6}$',
|
|
69
|
+
* required: true
|
|
70
|
+
* };
|
|
71
|
+
*
|
|
72
|
+
* yield { emit: 'status', message: 'Verifying code...' };
|
|
73
|
+
*
|
|
74
|
+
* await this.sendCode(code);
|
|
75
|
+
*
|
|
76
|
+
* yield { emit: 'toast', message: 'Connected!', type: 'success' };
|
|
77
|
+
*
|
|
78
|
+
* return { success: true, paired: true };
|
|
79
|
+
* }
|
|
80
|
+
* ```
|
|
81
|
+
*
|
|
82
|
+
* @module generator
|
|
83
|
+
*/
|
|
84
|
+
// ══════════════════════════════════════════════════════════════════════════════
|
|
85
|
+
// TYPE GUARDS - Check what kind of yield we have
|
|
86
|
+
// ══════════════════════════════════════════════════════════════════════════════
|
|
87
|
+
/**
|
|
88
|
+
* Check if yield is an ask (requires user input)
|
|
89
|
+
*
|
|
90
|
+
* @example
|
|
91
|
+
* if (isAskYield(yielded)) {
|
|
92
|
+
* const userInput = await promptUser(yielded);
|
|
93
|
+
* generator.next(userInput);
|
|
94
|
+
* }
|
|
95
|
+
*/
|
|
96
|
+
export function isAskYield(y) {
|
|
97
|
+
return 'ask' in y;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Check if yield is an emit (output only, no response needed)
|
|
101
|
+
*
|
|
102
|
+
* @example
|
|
103
|
+
* if (isEmitYield(yielded)) {
|
|
104
|
+
* handleOutput(yielded);
|
|
105
|
+
* generator.next(); // Continue without value
|
|
106
|
+
* }
|
|
107
|
+
*/
|
|
108
|
+
export function isEmitYield(y) {
|
|
109
|
+
return 'emit' in y;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Get the type of an ask yield
|
|
113
|
+
*/
|
|
114
|
+
export function getAskType(y) {
|
|
115
|
+
return y.ask;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Get the type of an emit yield
|
|
119
|
+
*/
|
|
120
|
+
export function getEmitType(y) {
|
|
121
|
+
return y.emit;
|
|
122
|
+
}
|
|
123
|
+
// ══════════════════════════════════════════════════════════════════════════════
|
|
124
|
+
// GENERATOR DETECTION
|
|
125
|
+
// ══════════════════════════════════════════════════════════════════════════════
|
|
126
|
+
/**
|
|
127
|
+
* Check if a function is an async generator function
|
|
128
|
+
*
|
|
129
|
+
* @example
|
|
130
|
+
* if (isAsyncGeneratorFunction(method)) {
|
|
131
|
+
* const gen = method.call(instance, params);
|
|
132
|
+
* await executeGenerator(gen, config);
|
|
133
|
+
* }
|
|
134
|
+
*/
|
|
135
|
+
export function isAsyncGeneratorFunction(fn) {
|
|
136
|
+
if (!fn)
|
|
137
|
+
return false;
|
|
138
|
+
const constructor = fn.constructor;
|
|
139
|
+
if (!constructor)
|
|
140
|
+
return false;
|
|
141
|
+
if (constructor.name === 'AsyncGeneratorFunction')
|
|
142
|
+
return true;
|
|
143
|
+
const prototype = Object.getPrototypeOf(fn);
|
|
144
|
+
return prototype?.constructor?.name === 'AsyncGeneratorFunction';
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Check if a value is an async generator instance (already invoked)
|
|
148
|
+
*
|
|
149
|
+
* @example
|
|
150
|
+
* const result = method.call(instance, params);
|
|
151
|
+
* if (isAsyncGenerator(result)) {
|
|
152
|
+
* await executeGenerator(result, config);
|
|
153
|
+
* }
|
|
154
|
+
*/
|
|
155
|
+
export function isAsyncGenerator(obj) {
|
|
156
|
+
return obj &&
|
|
157
|
+
typeof obj.next === 'function' &&
|
|
158
|
+
typeof obj.return === 'function' &&
|
|
159
|
+
typeof obj.throw === 'function' &&
|
|
160
|
+
typeof obj[Symbol.asyncIterator] === 'function';
|
|
161
|
+
}
|
|
162
|
+
// ══════════════════════════════════════════════════════════════════════════════
|
|
163
|
+
// GENERATOR EXECUTOR - Runs generator tools to completion
|
|
164
|
+
// ══════════════════════════════════════════════════════════════════════════════
|
|
165
|
+
/**
|
|
166
|
+
* Execute a generator-based photon tool to completion.
|
|
167
|
+
*
|
|
168
|
+
* Handles the yield/resume loop:
|
|
169
|
+
* 1. Run generator until it yields
|
|
170
|
+
* 2. If ask yield: get input from provider (or pre-provided), resume with value
|
|
171
|
+
* 3. If emit yield: call output handler, resume without value
|
|
172
|
+
* 4. Repeat until generator returns
|
|
173
|
+
*
|
|
174
|
+
* @param generator - The async generator to execute
|
|
175
|
+
* @param config - Configuration for handling yields
|
|
176
|
+
* @returns The final return value of the generator
|
|
177
|
+
*
|
|
178
|
+
* @example
|
|
179
|
+
* const result = await executeGenerator(photon.connect({ ip: '192.168.1.1' }), {
|
|
180
|
+
* inputProvider: async (ask) => {
|
|
181
|
+
* if (ask.ask === 'text') return await readline(ask.message);
|
|
182
|
+
* if (ask.ask === 'confirm') return await confirm(ask.message);
|
|
183
|
+
* },
|
|
184
|
+
* outputHandler: (emit) => {
|
|
185
|
+
* if (emit.emit === 'progress') console.log(`${emit.value * 100}%`);
|
|
186
|
+
* }
|
|
187
|
+
* });
|
|
188
|
+
*/
|
|
189
|
+
export async function executeGenerator(generator, config) {
|
|
190
|
+
const { inputProvider, outputHandler, preProvidedInputs } = config;
|
|
191
|
+
let askIndex = 0;
|
|
192
|
+
let result = await generator.next();
|
|
193
|
+
while (!result.done) {
|
|
194
|
+
const yielded = result.value;
|
|
195
|
+
// Handle ask yields (need input)
|
|
196
|
+
if (isAskYield(yielded)) {
|
|
197
|
+
// Generate id if not provided
|
|
198
|
+
const askId = yielded.id || `ask_${askIndex++}`;
|
|
199
|
+
// Check for pre-provided input (REST API style)
|
|
200
|
+
if (preProvidedInputs && askId in preProvidedInputs) {
|
|
201
|
+
result = await generator.next(preProvidedInputs[askId]);
|
|
202
|
+
continue;
|
|
203
|
+
}
|
|
204
|
+
// Get input from provider
|
|
205
|
+
const input = await inputProvider(yielded);
|
|
206
|
+
result = await generator.next(input);
|
|
207
|
+
}
|
|
208
|
+
// Handle emit yields (output only)
|
|
209
|
+
else if (isEmitYield(yielded)) {
|
|
210
|
+
if (outputHandler) {
|
|
211
|
+
await outputHandler(yielded);
|
|
212
|
+
}
|
|
213
|
+
// Continue without providing a value
|
|
214
|
+
result = await generator.next();
|
|
215
|
+
}
|
|
216
|
+
// Unknown yield type - skip
|
|
217
|
+
else {
|
|
218
|
+
console.warn('[generator] Unknown yield type:', yielded);
|
|
219
|
+
result = await generator.next();
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
return result.value;
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Extract ask yield information by running generator with mock provider.
|
|
226
|
+
*
|
|
227
|
+
* This is used for REST API schema generation - each ask becomes
|
|
228
|
+
* an optional request parameter.
|
|
229
|
+
*
|
|
230
|
+
* Note: Only extracts asks reachable with default/empty inputs.
|
|
231
|
+
* Conditional asks may not be discovered.
|
|
232
|
+
*
|
|
233
|
+
* @example
|
|
234
|
+
* const asks = await extractAsks(Photon.prototype.connect, { ip: '' });
|
|
235
|
+
* // Returns: [{ id: 'pairing_code', type: 'text', message: '...' }]
|
|
236
|
+
* // These become optional query/body params in REST API
|
|
237
|
+
*/
|
|
238
|
+
export async function extractAsks(generatorFn, mockParams = {}) {
|
|
239
|
+
const asks = [];
|
|
240
|
+
let askIndex = 0;
|
|
241
|
+
try {
|
|
242
|
+
const generator = generatorFn(mockParams);
|
|
243
|
+
let result = await generator.next();
|
|
244
|
+
while (!result.done) {
|
|
245
|
+
const yielded = result.value;
|
|
246
|
+
if (isAskYield(yielded)) {
|
|
247
|
+
const id = yielded.id || `ask_${askIndex++}`;
|
|
248
|
+
const extracted = {
|
|
249
|
+
id,
|
|
250
|
+
type: yielded.ask,
|
|
251
|
+
message: yielded.message,
|
|
252
|
+
required: yielded.required,
|
|
253
|
+
};
|
|
254
|
+
// Extract type-specific properties
|
|
255
|
+
if (yielded.ask === 'text') {
|
|
256
|
+
extracted.default = yielded.default;
|
|
257
|
+
extracted.pattern = yielded.pattern;
|
|
258
|
+
}
|
|
259
|
+
else if (yielded.ask === 'confirm') {
|
|
260
|
+
extracted.default = yielded.default;
|
|
261
|
+
}
|
|
262
|
+
else if (yielded.ask === 'select') {
|
|
263
|
+
extracted.options = yielded.options;
|
|
264
|
+
extracted.default = yielded.default;
|
|
265
|
+
}
|
|
266
|
+
else if (yielded.ask === 'number') {
|
|
267
|
+
extracted.default = yielded.default;
|
|
268
|
+
extracted.min = yielded.min;
|
|
269
|
+
extracted.max = yielded.max;
|
|
270
|
+
}
|
|
271
|
+
asks.push(extracted);
|
|
272
|
+
// Provide mock value to continue
|
|
273
|
+
const mockValue = getMockValue(yielded);
|
|
274
|
+
result = await generator.next(mockValue);
|
|
275
|
+
}
|
|
276
|
+
else {
|
|
277
|
+
// Skip emit yields
|
|
278
|
+
result = await generator.next();
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
catch (error) {
|
|
283
|
+
// Generator may throw if it needs real resources
|
|
284
|
+
// Return what we've extracted so far
|
|
285
|
+
console.warn('[generator] Ask extraction incomplete:', error);
|
|
286
|
+
}
|
|
287
|
+
return asks;
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* Get a mock value for an ask yield (for extraction purposes)
|
|
291
|
+
*/
|
|
292
|
+
function getMockValue(ask) {
|
|
293
|
+
switch (ask.ask) {
|
|
294
|
+
case 'text':
|
|
295
|
+
case 'password':
|
|
296
|
+
return ask.default || '';
|
|
297
|
+
case 'confirm':
|
|
298
|
+
return ask.default ?? true;
|
|
299
|
+
case 'select':
|
|
300
|
+
const select = ask;
|
|
301
|
+
const firstOpt = select.options[0];
|
|
302
|
+
const firstVal = typeof firstOpt === 'string' ? firstOpt : firstOpt.value;
|
|
303
|
+
return select.multi ? [firstVal] : firstVal;
|
|
304
|
+
case 'number':
|
|
305
|
+
return ask.default ?? 0;
|
|
306
|
+
case 'file':
|
|
307
|
+
return null;
|
|
308
|
+
case 'date':
|
|
309
|
+
return ask.default || new Date().toISOString();
|
|
310
|
+
default:
|
|
311
|
+
return null;
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
// ══════════════════════════════════════════════════════════════════════════════
|
|
315
|
+
// BUILT-IN INPUT PROVIDERS
|
|
316
|
+
// ══════════════════════════════════════════════════════════════════════════════
|
|
317
|
+
/**
|
|
318
|
+
* Error thrown when input is required but not available.
|
|
319
|
+
*
|
|
320
|
+
* REST APIs can catch this to return a continuation response.
|
|
321
|
+
*
|
|
322
|
+
* @example
|
|
323
|
+
* try {
|
|
324
|
+
* await executeGenerator(gen, { inputProvider: createPrefilledProvider({}) });
|
|
325
|
+
* } catch (e) {
|
|
326
|
+
* if (e instanceof NeedsInputError) {
|
|
327
|
+
* return {
|
|
328
|
+
* status: 'awaiting_input',
|
|
329
|
+
* ask: e.ask,
|
|
330
|
+
* continuation_id: saveContinuation(gen)
|
|
331
|
+
* };
|
|
332
|
+
* }
|
|
333
|
+
* }
|
|
334
|
+
*/
|
|
335
|
+
export class NeedsInputError extends Error {
|
|
336
|
+
ask;
|
|
337
|
+
constructor(ask) {
|
|
338
|
+
super(`Input required: ${ask.message}`);
|
|
339
|
+
this.name = 'NeedsInputError';
|
|
340
|
+
this.ask = ask;
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
/**
|
|
344
|
+
* Create an input provider from pre-provided values.
|
|
345
|
+
* Throws NeedsInputError if a required value is missing.
|
|
346
|
+
*
|
|
347
|
+
* Use for REST APIs where all inputs are provided upfront.
|
|
348
|
+
*
|
|
349
|
+
* @example
|
|
350
|
+
* const provider = createPrefilledProvider({
|
|
351
|
+
* name: 'John',
|
|
352
|
+
* confirmed: true
|
|
353
|
+
* });
|
|
354
|
+
*/
|
|
355
|
+
export function createPrefilledProvider(inputs) {
|
|
356
|
+
let askIndex = 0;
|
|
357
|
+
return async (ask) => {
|
|
358
|
+
const id = ask.id || `ask_${askIndex++}`;
|
|
359
|
+
if (id in inputs) {
|
|
360
|
+
return inputs[id];
|
|
361
|
+
}
|
|
362
|
+
// Check for default value
|
|
363
|
+
if ('default' in ask && ask.default !== undefined) {
|
|
364
|
+
return ask.default;
|
|
365
|
+
}
|
|
366
|
+
// No input available
|
|
367
|
+
throw new NeedsInputError(ask);
|
|
368
|
+
};
|
|
369
|
+
}
|
|
370
|
+
// ══════════════════════════════════════════════════════════════════════════════
|
|
371
|
+
// UTILITY: Wrap regular function as generator
|
|
372
|
+
// ══════════════════════════════════════════════════════════════════════════════
|
|
373
|
+
/**
|
|
374
|
+
* Wrap a regular async function to behave like a generator.
|
|
375
|
+
* Useful for uniform handling in runtimes.
|
|
376
|
+
*
|
|
377
|
+
* @example
|
|
378
|
+
* const gen = wrapAsGenerator(() => photon.simpleMethod(params));
|
|
379
|
+
* const result = await executeGenerator(gen, config);
|
|
380
|
+
*/
|
|
381
|
+
export async function* wrapAsGenerator(asyncFn) {
|
|
382
|
+
return await asyncFn();
|
|
383
|
+
}
|
|
384
|
+
/**
|
|
385
|
+
* @deprecated Use isAskYield instead
|
|
386
|
+
*/
|
|
387
|
+
export const isInputYield = isAskYield;
|
|
388
|
+
/**
|
|
389
|
+
* @deprecated Use isEmitYield instead
|
|
390
|
+
*/
|
|
391
|
+
export function isProgressYield(y) {
|
|
392
|
+
return isEmitYield(y) && y.emit === 'progress';
|
|
393
|
+
}
|
|
394
|
+
/**
|
|
395
|
+
* @deprecated Use isEmitYield instead
|
|
396
|
+
*/
|
|
397
|
+
export function isStreamYield(y) {
|
|
398
|
+
return isEmitYield(y) && y.emit === 'stream';
|
|
399
|
+
}
|
|
400
|
+
/**
|
|
401
|
+
* @deprecated Use isEmitYield instead
|
|
402
|
+
*/
|
|
403
|
+
export function isLogYield(y) {
|
|
404
|
+
return isEmitYield(y) && y.emit === 'log';
|
|
405
|
+
}
|
|
406
|
+
/**
|
|
407
|
+
* @deprecated Use extractAsks instead
|
|
408
|
+
*/
|
|
409
|
+
export const extractYields = extractAsks;
|
|
410
|
+
//# sourceMappingURL=generator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generator.js","sourceRoot":"","sources":["../src/generator.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -38,4 +38,6 @@ export { SchemaExtractor } from './schema-extractor.js';
|
|
|
38
38
|
export { formatOutput, detectFormat, renderPrimitive, renderList, renderTable, renderTree, renderNone, formatKey, formatValue, formatToMimeType, printSuccess, printError, printInfo, printWarning, printHeader, STATUS, } from './cli-formatter.js';
|
|
39
39
|
export { resolvePath, listFiles, ensureDir, resolvePhotonPath, listPhotonFiles, ensurePhotonDir, DEFAULT_PHOTON_DIR, type ResolverOptions, } from './path-resolver.js';
|
|
40
40
|
export * from './types.js';
|
|
41
|
+
export { isAskYield, isEmitYield, getAskType, getEmitType, isAsyncGeneratorFunction, isAsyncGenerator, executeGenerator, extractAsks, createPrefilledProvider, NeedsInputError, wrapAsGenerator, type AskYield, type AskText, type AskPassword, type AskConfirm, type AskSelect, type AskNumber, type AskFile, type AskDate, type EmitYield, type EmitStatus, type EmitProgress, type EmitStream, type EmitLog, type EmitToast, type EmitThinking, type EmitArtifact, type PhotonYield, type InputProvider, type OutputHandler, type GeneratorExecutorConfig, type ExtractedAsk, isInputYield, isProgressYield, isStreamYield, isLogYield, extractYields, type PromptYield, type ConfirmYield, type SelectYield, type ProgressYield, type StreamYield, type LogYield, type ExtractedYield, } from './generator.js';
|
|
42
|
+
export { prompt, confirm, elicit, elicitReadline, elicitNativeDialog, setPromptHandler, getPromptHandler, setElicitHandler, getElicitHandler, type ElicitOptions, type ElicitResult, type ElicitHandler, type PromptHandler, } from './elicit.js';
|
|
41
43
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAGH,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAGtC,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAG5D,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAGxD,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,eAAe,EACf,UAAU,EACV,WAAW,EACX,UAAU,EACV,UAAU,EACV,SAAS,EACT,WAAW,EACX,gBAAgB,EAChB,YAAY,EACZ,UAAU,EACV,SAAS,EACT,YAAY,EACZ,WAAW,EACX,MAAM,GACP,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EACL,WAAW,EACX,SAAS,EACT,SAAS,EACT,iBAAiB,EACjB,eAAe,EACf,eAAe,EACf,kBAAkB,EAClB,KAAK,eAAe,GACrB,MAAM,oBAAoB,CAAC;AAG5B,cAAc,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAGH,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAGtC,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAG5D,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAGxD,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,eAAe,EACf,UAAU,EACV,WAAW,EACX,UAAU,EACV,UAAU,EACV,SAAS,EACT,WAAW,EACX,gBAAgB,EAChB,YAAY,EACZ,UAAU,EACV,SAAS,EACT,YAAY,EACZ,WAAW,EACX,MAAM,GACP,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EACL,WAAW,EACX,SAAS,EACT,SAAS,EACT,iBAAiB,EACjB,eAAe,EACf,eAAe,EACf,kBAAkB,EAClB,KAAK,eAAe,GACrB,MAAM,oBAAoB,CAAC;AAG5B,cAAc,YAAY,CAAC;AAI3B,OAAO,EAEL,UAAU,EACV,WAAW,EACX,UAAU,EACV,WAAW,EAGX,wBAAwB,EACxB,gBAAgB,EAGhB,gBAAgB,EAGhB,WAAW,EAGX,uBAAuB,EACvB,eAAe,EAGf,eAAe,EAGf,KAAK,QAAQ,EACb,KAAK,OAAO,EACZ,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,KAAK,SAAS,EACd,KAAK,SAAS,EACd,KAAK,OAAO,EACZ,KAAK,OAAO,EAGZ,KAAK,SAAS,EACd,KAAK,UAAU,EACf,KAAK,YAAY,EACjB,KAAK,UAAU,EACf,KAAK,OAAO,EACZ,KAAK,SAAS,EACd,KAAK,YAAY,EACjB,KAAK,YAAY,EAGjB,KAAK,WAAW,EAGhB,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,KAAK,uBAAuB,EAC5B,KAAK,YAAY,EAGjB,YAAY,EACZ,eAAe,EACf,aAAa,EACb,UAAU,EACV,aAAa,EACb,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,KAAK,aAAa,EAClB,KAAK,WAAW,EAChB,KAAK,QAAQ,EACb,KAAK,cAAc,GACpB,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EAEL,MAAM,EACN,OAAO,EAEP,MAAM,EACN,cAAc,EACd,kBAAkB,EAElB,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,EAEhB,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,KAAK,aAAa,EAClB,KAAK,aAAa,GACnB,MAAM,aAAa,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -44,4 +44,29 @@ export { formatOutput, detectFormat, renderPrimitive, renderList, renderTable, r
|
|
|
44
44
|
export { resolvePath, listFiles, ensureDir, resolvePhotonPath, listPhotonFiles, ensurePhotonDir, DEFAULT_PHOTON_DIR, } from './path-resolver.js';
|
|
45
45
|
// Types
|
|
46
46
|
export * from './types.js';
|
|
47
|
+
// Generator-based tools with ask/emit pattern
|
|
48
|
+
// See generator.ts for comprehensive documentation
|
|
49
|
+
export {
|
|
50
|
+
// Type guards - check yield direction
|
|
51
|
+
isAskYield, isEmitYield, getAskType, getEmitType,
|
|
52
|
+
// Generator detection
|
|
53
|
+
isAsyncGeneratorFunction, isAsyncGenerator,
|
|
54
|
+
// Executor - runs generators to completion
|
|
55
|
+
executeGenerator,
|
|
56
|
+
// Ask extraction (for REST API schema generation)
|
|
57
|
+
extractAsks,
|
|
58
|
+
// Built-in providers
|
|
59
|
+
createPrefilledProvider, NeedsInputError,
|
|
60
|
+
// Utility
|
|
61
|
+
wrapAsGenerator,
|
|
62
|
+
// Legacy compatibility (deprecated)
|
|
63
|
+
isInputYield, isProgressYield, isStreamYield, isLogYield, extractYields, } from './generator.js';
|
|
64
|
+
// Elicit - Cross-platform user input (legacy, prefer generators)
|
|
65
|
+
export {
|
|
66
|
+
// Simple functions (no imports needed in photon files)
|
|
67
|
+
prompt, confirm,
|
|
68
|
+
// Full elicit with options
|
|
69
|
+
elicit, elicitReadline, elicitNativeDialog,
|
|
70
|
+
// Handler management (for runtimes)
|
|
71
|
+
setPromptHandler, getPromptHandler, setElicitHandler, getElicitHandler, } from './elicit.js';
|
|
47
72
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH,uCAAuC;AACvC,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtC,wBAAwB;AACxB,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAE5D,oBAAoB;AACpB,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAExD,iBAAiB;AACjB,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,eAAe,EACf,UAAU,EACV,WAAW,EACX,UAAU,EACV,UAAU,EACV,SAAS,EACT,WAAW,EACX,gBAAgB,EAChB,YAAY,EACZ,UAAU,EACV,SAAS,EACT,YAAY,EACZ,WAAW,EACX,MAAM,GACP,MAAM,oBAAoB,CAAC;AAE5B,kBAAkB;AAClB,OAAO,EACL,WAAW,EACX,SAAS,EACT,SAAS,EACT,iBAAiB,EACjB,eAAe,EACf,eAAe,EACf,kBAAkB,GAEnB,MAAM,oBAAoB,CAAC;AAE5B,QAAQ;AACR,cAAc,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH,uCAAuC;AACvC,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtC,wBAAwB;AACxB,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAE5D,oBAAoB;AACpB,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAExD,iBAAiB;AACjB,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,eAAe,EACf,UAAU,EACV,WAAW,EACX,UAAU,EACV,UAAU,EACV,SAAS,EACT,WAAW,EACX,gBAAgB,EAChB,YAAY,EACZ,UAAU,EACV,SAAS,EACT,YAAY,EACZ,WAAW,EACX,MAAM,GACP,MAAM,oBAAoB,CAAC;AAE5B,kBAAkB;AAClB,OAAO,EACL,WAAW,EACX,SAAS,EACT,SAAS,EACT,iBAAiB,EACjB,eAAe,EACf,eAAe,EACf,kBAAkB,GAEnB,MAAM,oBAAoB,CAAC;AAE5B,QAAQ;AACR,cAAc,YAAY,CAAC;AAE3B,8CAA8C;AAC9C,mDAAmD;AACnD,OAAO;AACL,sCAAsC;AACtC,UAAU,EACV,WAAW,EACX,UAAU,EACV,WAAW;AAEX,sBAAsB;AACtB,wBAAwB,EACxB,gBAAgB;AAEhB,2CAA2C;AAC3C,gBAAgB;AAEhB,kDAAkD;AAClD,WAAW;AAEX,qBAAqB;AACrB,uBAAuB,EACvB,eAAe;AAEf,UAAU;AACV,eAAe;AA+Bf,oCAAoC;AACpC,YAAY,EACZ,eAAe,EACf,aAAa,EACb,UAAU,EACV,aAAa,GAQd,MAAM,gBAAgB,CAAC;AAExB,iEAAiE;AACjE,OAAO;AACL,uDAAuD;AACvD,MAAM,EACN,OAAO;AACP,2BAA2B;AAC3B,MAAM,EACN,cAAc,EACd,kBAAkB;AAClB,oCAAoC;AACpC,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,GAMjB,MAAM,aAAa,CAAC"}
|
|
@@ -108,5 +108,11 @@ export declare class SchemaExtractor {
|
|
|
108
108
|
* Example: @mimeType text/markdown
|
|
109
109
|
*/
|
|
110
110
|
private extractMimeType;
|
|
111
|
+
/**
|
|
112
|
+
* Extract yield information from JSDoc for generator methods
|
|
113
|
+
* Supports @yields tags with id, type, and description
|
|
114
|
+
* Example: @yields {pairing_code} text Enter the 6-digit code shown on TV
|
|
115
|
+
*/
|
|
116
|
+
private extractYieldsFromJSDoc;
|
|
111
117
|
}
|
|
112
118
|
//# sourceMappingURL=schema-extractor.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema-extractor.d.ts","sourceRoot":"","sources":["../src/schema-extractor.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,YAAY,EAAE,UAAU,
|
|
1
|
+
{"version":3,"file":"schema-extractor.d.ts","sourceRoot":"","sources":["../src/schema-extractor.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,YAAY,EAAE,UAAU,EAA2B,MAAM,YAAY,CAAC;AAElH,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,eAAe,EAAE,CAAC;IACzB,SAAS,EAAE,YAAY,EAAE,CAAC;IAC1B,OAAO,EAAE,UAAU,EAAE,CAAC;CACvB;AAED;;GAEG;AACH,qBAAa,eAAe;IAC1B;;OAEG;IACG,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;IAUnE;;OAEG;IACH,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,iBAAiB;IAgIvD;;OAEG;IACH,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,eAAe,EAAE;IAIpD;;OAEG;IACH,OAAO,CAAC,eAAe;IAqBvB;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAS7B;;;OAGG;IACH,OAAO,CAAC,mBAAmB;IAiC3B;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAyGxB;;;;;OAKG;IACH,OAAO,CAAC,oBAAoB;IA0F5B;;OAEG;IACH,wBAAwB,CAAC,MAAM,EAAE,MAAM,GAAG,gBAAgB,EAAE;IAmD5D;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAuB3B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAqB1B;;;OAGG;IACH,OAAO,CAAC,gBAAgB;IA4BxB;;;;OAIG;IACH,OAAO,CAAC,uBAAuB;IA2G/B;;;;;OAKG;IACH,OAAO,CAAC,gBAAgB;IA0FxB;;OAEG;IACH,OAAO,CAAC,cAAc;IAItB;;OAEG;IACH,OAAO,CAAC,YAAY;IAIpB;;;OAGG;IACH,OAAO,CAAC,gBAAgB;IAKxB;;;;;OAKG;IACH,OAAO,CAAC,aAAa;IAsBrB;;;OAGG;IACH,OAAO,CAAC,eAAe;IAKvB;;;;OAIG;IACH,OAAO,CAAC,sBAAsB;CAiB/B"}
|
package/dist/schema-extractor.js
CHANGED
|
@@ -45,6 +45,8 @@ export class SchemaExtractor {
|
|
|
45
45
|
const processMethod = (member) => {
|
|
46
46
|
const methodName = member.name.getText(sourceFile);
|
|
47
47
|
const jsdoc = this.getJSDocComment(member, sourceFile);
|
|
48
|
+
// Check if this is an async generator method (has asterisk token)
|
|
49
|
+
const isGenerator = member.asteriskToken !== undefined;
|
|
48
50
|
// Extract parameter type information
|
|
49
51
|
const paramsType = this.getFirstParameterType(member, sourceFile);
|
|
50
52
|
if (!paramsType) {
|
|
@@ -100,11 +102,14 @@ export class SchemaExtractor {
|
|
|
100
102
|
// Otherwise, it's a regular tool
|
|
101
103
|
else {
|
|
102
104
|
const outputFormat = this.extractFormat(jsdoc);
|
|
105
|
+
const yields = isGenerator ? this.extractYieldsFromJSDoc(jsdoc) : undefined;
|
|
103
106
|
tools.push({
|
|
104
107
|
name: methodName,
|
|
105
108
|
description,
|
|
106
109
|
inputSchema,
|
|
107
110
|
...(outputFormat ? { outputFormat } : {}),
|
|
111
|
+
...(isGenerator ? { isGenerator: true } : {}),
|
|
112
|
+
...(yields && yields.length > 0 ? { yields } : {}),
|
|
108
113
|
});
|
|
109
114
|
}
|
|
110
115
|
};
|
|
@@ -113,7 +118,7 @@ export class SchemaExtractor {
|
|
|
113
118
|
// Look for class declarations
|
|
114
119
|
if (ts.isClassDeclaration(node)) {
|
|
115
120
|
node.members.forEach((member) => {
|
|
116
|
-
// Look for async methods
|
|
121
|
+
// Look for async methods (including async generators with *)
|
|
117
122
|
if (ts.isMethodDeclaration(member) &&
|
|
118
123
|
member.modifiers?.some(m => m.kind === ts.SyntaxKind.AsyncKeyword)) {
|
|
119
124
|
processMethod(member);
|
|
@@ -736,5 +741,25 @@ export class SchemaExtractor {
|
|
|
736
741
|
const match = jsdocContent.match(/@mimeType\s+([\w\/\-+.]+)/i);
|
|
737
742
|
return match ? match[1].trim() : undefined;
|
|
738
743
|
}
|
|
744
|
+
/**
|
|
745
|
+
* Extract yield information from JSDoc for generator methods
|
|
746
|
+
* Supports @yields tags with id, type, and description
|
|
747
|
+
* Example: @yields {pairing_code} text Enter the 6-digit code shown on TV
|
|
748
|
+
*/
|
|
749
|
+
extractYieldsFromJSDoc(jsdocContent) {
|
|
750
|
+
const yields = [];
|
|
751
|
+
// Match @yields {id} type description
|
|
752
|
+
const yieldRegex = /@yields?\s+\{(\w+)\}\s+(prompt|confirm|select)\s+(.+)/gi;
|
|
753
|
+
let match;
|
|
754
|
+
while ((match = yieldRegex.exec(jsdocContent)) !== null) {
|
|
755
|
+
const [, id, type, description] = match;
|
|
756
|
+
yields.push({
|
|
757
|
+
id,
|
|
758
|
+
type: type.toLowerCase(),
|
|
759
|
+
prompt: description.trim(),
|
|
760
|
+
});
|
|
761
|
+
}
|
|
762
|
+
return yields;
|
|
763
|
+
}
|
|
739
764
|
}
|
|
740
765
|
//# sourceMappingURL=schema-extractor.js.map
|