@flue/client 0.0.28 → 0.0.29

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.
Files changed (2) hide show
  1. package/dist/index.mjs +46 -4
  2. package/package.json +1 -1
package/dist/index.mjs CHANGED
@@ -181,7 +181,6 @@ function buildResultInstructions(schema) {
181
181
  const { $schema: _, ...schemaWithoutMeta } = toJsonSchema(schema, { errorMode: "ignore" });
182
182
  return [
183
183
  "",
184
- "When complete, you MUST output your result between these exact delimiters conforming to this schema:",
185
184
  "```json",
186
185
  JSON.stringify(schemaWithoutMeta, null, 2),
187
186
  "```",
@@ -205,6 +204,20 @@ function buildProxyInstructions(instructions) {
205
204
  return "\n\n" + instructions.join("\n");
206
205
  }
207
206
  /**
207
+ * Build a standalone follow-up prompt that asks the LLM to return its result.
208
+ *
209
+ * Used when the initial response is missing the ---RESULT_START--- /
210
+ * ---RESULT_END--- block. Sent as a second message in the same session so the
211
+ * format instructions are fresh in context.
212
+ */
213
+ function buildResultExtractionPrompt(schema) {
214
+ return [
215
+ "Your task is complete. Now respond with ONLY your final result.",
216
+ "No explanation, no preamble — just the result in the following format, conforming to this schema:",
217
+ buildResultInstructions(schema)
218
+ ].join("\n");
219
+ }
220
+ /**
208
221
  * Build the prompt text for a skill invocation.
209
222
  *
210
223
  * If `name` looks like a file path (contains '/' or ends with '.md'), the
@@ -220,7 +233,10 @@ function buildSkillPrompt(name, args, schema, proxyInstructions) {
220
233
  ];
221
234
  if (args && Object.keys(args).length > 0) parts.push(`\nArguments:\n${JSON.stringify(args, null, 2)}`);
222
235
  if (proxyInstructions && proxyInstructions.length > 0) parts.push(buildProxyInstructions(proxyInstructions));
223
- if (schema) parts.push(buildResultInstructions(schema));
236
+ if (schema) {
237
+ parts.push("When complete, you MUST output your result between these exact delimiters conforming to this schema:");
238
+ parts.push(buildResultInstructions(schema));
239
+ }
224
240
  return parts.join("\n");
225
241
  }
226
242
 
@@ -340,7 +356,30 @@ async function runPrompt(client, workdir, label, prompt, options) {
340
356
  const promptElapsed = ((Date.now() - promptStart) / 1e3).toFixed(1);
341
357
  console.log(`[flue] ${label}: completed (${promptElapsed}s)`);
342
358
  if (!schema) return;
343
- return extractResult(parts, schema, sessionId);
359
+ try {
360
+ return extractResult(parts, schema, sessionId);
361
+ } catch (error) {
362
+ if (!(error instanceof SkillOutputError)) throw error;
363
+ if (!error.message.includes("---RESULT_START---")) throw error;
364
+ console.log(`[flue] ${label}: result extraction failed, sending follow-up prompt to request result`);
365
+ const followUpResult = await client.session.promptAsync({
366
+ path: { id: sessionId },
367
+ query: { directory: workdir },
368
+ body: {
369
+ ...model ? { model } : {},
370
+ parts: [{
371
+ type: "text",
372
+ text: buildResultExtractionPrompt(schema)
373
+ }]
374
+ }
375
+ });
376
+ if (followUpResult.error) {
377
+ if (followUpResult.error instanceof Error) followUpResult.error.cause = error;
378
+ throw followUpResult.error;
379
+ }
380
+ await confirmSessionStarted(client, sessionId, workdir, label);
381
+ return extractResult(await pollUntilIdle(client, sessionId, workdir, label, Date.now(), timeout), schema, sessionId);
382
+ }
344
383
  }
345
384
  /**
346
385
  * Run a named skill: builds the skill prompt from the name + args + schema,
@@ -474,7 +513,10 @@ var FlueClient = class {
474
513
  promptText
475
514
  ];
476
515
  if (this.proxyInstructions.length > 0) parts.push(buildProxyInstructions(this.proxyInstructions));
477
- if (schema) parts.push(buildResultInstructions(schema));
516
+ if (schema) {
517
+ parts.push("When complete, you MUST output your result between these exact delimiters conforming to this schema:");
518
+ parts.push(buildResultInstructions(schema));
519
+ }
478
520
  const fullPrompt = parts.join("\n");
479
521
  const label = `prompt("${promptText.length > 40 ? promptText.slice(0, 40) + "…" : promptText}")`;
480
522
  return runPrompt(this.client, this.workdir, label, fullPrompt, {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flue/client",
3
- "version": "0.0.28",
3
+ "version": "0.0.29",
4
4
  "type": "module",
5
5
  "license": "Apache-2.0",
6
6
  "exports": {