@juicesharp/rpiv-advisor 1.0.15 → 1.0.17

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/advisor.ts +19 -1
  2. package/package.json +1 -1
package/advisor.ts CHANGED
@@ -61,6 +61,7 @@ const CHECKMARK = " ✓";
61
61
  // Messages (static)
62
62
  const MSG_ADVISOR_DISABLED = "Advisor disabled";
63
63
  const MSG_REQUIRES_INTERACTIVE = "/advisor requires interactive mode";
64
+ const MSG_ADVISOR_NUDGE = "Please advise on the executor's situation above.";
64
65
 
65
66
  // Errors (static)
66
67
  const ERR_NO_MODEL = "No advisor model is configured. The user can enable one with the /advisor command.";
@@ -206,6 +207,23 @@ export function stripInflightAdvisorCall(messages: Message[]): Message[] {
206
207
  return [...messages.slice(0, -1), { ...last, content: filtered }];
207
208
  }
208
209
 
210
+ // Some providers (recent Anthropic Claude models) reject payloads ending on an
211
+ // assistant turn ("This model does not support assistant message prefill. The
212
+ // conversation must end with a user message."). After stripInflightAdvisorCall
213
+ // the tail can be assistant (e.g. the executor wrote thinking text before
214
+ // calling advisor). Append a minimal user-role nudge to guarantee user-tail.
215
+ export function ensureUserTailForAdvisor(messages: Message[]): Message[] {
216
+ if (messages.length === 0) return messages;
217
+ const last = messages[messages.length - 1];
218
+ if (last.role !== "assistant") return messages;
219
+ const nudge: Message = {
220
+ role: "user",
221
+ content: [{ type: "text", text: MSG_ADVISOR_NUDGE }],
222
+ timestamp: Date.now(),
223
+ };
224
+ return [...messages, nudge];
225
+ }
226
+
209
227
  // Returns `undefined` when the registry is empty (no extensions loaded) so
210
228
  // callers can skip prepending an empty block that would still cost a cache unit.
211
229
  export function getInventoryMessage(tools: ToolInfo[]): Message | undefined {
@@ -337,7 +355,7 @@ async function executeAdvisor(
337
355
  const agentMessages = branch
338
356
  .filter((e): e is SessionEntry & { type: "message" } => e.type === "message")
339
357
  .map((e) => e.message);
340
- const branchMessages = stripInflightAdvisorCall(convertToLlm(agentMessages));
358
+ const branchMessages = ensureUserTailForAdvisor(stripInflightAdvisorCall(convertToLlm(agentMessages)));
341
359
  const inventoryMessage = getInventoryMessage(pi.getAllTools());
342
360
  const messages: Message[] = inventoryMessage ? [inventoryMessage, ...branchMessages] : branchMessages;
343
361
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@juicesharp/rpiv-advisor",
3
- "version": "1.0.15",
3
+ "version": "1.0.17",
4
4
  "description": "Pi extension: lets the model ask a stronger reviewer model for a second opinion before it acts",
5
5
  "keywords": [
6
6
  "pi-package",