palmier 1.1.9 → 1.1.11

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.
@@ -17,6 +17,11 @@ When you are done, output exactly one of these markers as the very last line on
17
17
  [PALMIER_TASK_SUCCESS]
18
18
  [PALMIER_TASK_FAILURE]
19
19
 
20
+ On the line right before that marker, in the same final message, print the model you are running as, using the exact model name or ID from your system prompt (skip this line if you do not know it rather than guessing):
21
+ [PALMIER_AGENT_MODEL] <model>
22
+
23
+ Do this at the end of every response, including responses to follow-up messages.
24
+
20
25
  ## Permissions
21
26
 
22
27
  Whenever a tool you are trying to use is denied or you lack the required permissions, print each required permission on its own line to stdout using this exact format:
@@ -3,3 +3,4 @@ export declare function getAgentInstructions(task: ParsedTask): string;
3
3
  export declare const TASK_SUCCESS_MARKER = "[PALMIER_TASK_SUCCESS]";
4
4
  export declare const TASK_FAILURE_MARKER = "[PALMIER_TASK_FAILURE]";
5
5
  export declare const TASK_PERMISSION_PREFIX = "[PALMIER_PERMISSION]";
6
+ export declare const AGENT_MODEL_PREFIX = "[PALMIER_AGENT_MODEL]";
@@ -21,3 +21,4 @@ export function getAgentInstructions(task) {
21
21
  export const TASK_SUCCESS_MARKER = "[PALMIER_TASK_SUCCESS]";
22
22
  export const TASK_FAILURE_MARKER = "[PALMIER_TASK_FAILURE]";
23
23
  export const TASK_PERMISSION_PREFIX = "[PALMIER_PERMISSION]";
24
+ export const AGENT_MODEL_PREFIX = "[PALMIER_AGENT_MODEL]";
@@ -4,5 +4,6 @@ export declare function runCommand(taskId: string): Promise<void>;
4
4
  /** Only links to files that exist count, so example links echoed from the prompt are ignored. */
5
5
  export declare function listLinkedTaskFiles(taskDir: string, runId: string, output: string): string[];
6
6
  export declare function parsePermissions(output: string): RequiredPermission[];
7
+ export declare function parseAgentModel(output: string): string | undefined;
7
8
  /** Falls back to "finished" if no success/failure marker is found. */
8
9
  export declare function parseTaskOutcome(output: string): TaskRunningState;
@@ -3,10 +3,10 @@ import * as path from "path";
3
3
  import { spawnCommand } from "../spawn-command.js";
4
4
  import { loadConfig } from "../config.js";
5
5
  import { connectNats } from "../nats-client.js";
6
- import { parseTaskFile, taskDisplayName, getTaskDir, writeTaskFile, writeTaskStatus, readTaskStatus, appendHistory, createRunDir, appendRunMessage, readRunMessages, getRunDir, beginStreamingMessage } from "../task.js";
6
+ import { parseTaskFile, taskDisplayName, getTaskDir, writeTaskFile, writeTaskStatus, readTaskStatus, appendHistory, createRunDir, appendRunMessage, readRunMessages, getRunDir, beginStreamingMessage, formatAgentModelComment } from "../task.js";
7
7
  import { getAgent } from "../agents/agent.js";
8
8
  import { getPlatform } from "../platform/index.js";
9
- import { TASK_SUCCESS_MARKER, TASK_FAILURE_MARKER, TASK_PERMISSION_PREFIX } from "../agents/shared-prompt.js";
9
+ import { TASK_SUCCESS_MARKER, TASK_FAILURE_MARKER, TASK_PERMISSION_PREFIX, AGENT_MODEL_PREFIX } from "../agents/shared-prompt.js";
10
10
  import { extractFileLinks, resolveTaskFile } from "../task-files.js";
11
11
  import { publishHostEvent } from "../events.js";
12
12
  /**
@@ -22,6 +22,8 @@ async function invokeAgentWithRetries(ctx, invokeTask) {
22
22
  const lineBufs = { stdout: "", stderr: "" };
23
23
  let notifyPending = false;
24
24
  let notifyTimer;
25
+ let agentModelSeen = false;
26
+ let pendingAgentModel;
25
27
  function throttledNotify() {
26
28
  if (notifyPending)
27
29
  return;
@@ -40,15 +42,27 @@ async function invokeAgentWithRetries(ctx, invokeTask) {
40
42
  activeStream = stream;
41
43
  return writer;
42
44
  }
45
+ function flushAgentModel() {
46
+ if (!pendingAgentModel || !writer)
47
+ return;
48
+ writer.write(formatAgentModelComment(pendingAgentModel));
49
+ pendingAgentModel = undefined;
50
+ throttledNotify();
51
+ }
43
52
  function emit(stream, chunk) {
44
53
  lineBufs[stream] += chunk;
45
54
  const lines = lineBufs[stream].split("\n");
46
55
  lineBufs[stream] = lines.pop() ?? "";
56
+ if (stream === "stdout" && !agentModelSeen) {
57
+ pendingAgentModel = parseAgentModel(lines.join("\n"));
58
+ agentModelSeen = !!pendingAgentModel;
59
+ }
47
60
  const filtered = lines.filter((l) => !l.startsWith("[PALMIER"));
48
- if (filtered.length === 0)
49
- return;
50
- ensureWriter(stream).write(filtered.join("\n") + "\n");
51
- throttledNotify();
61
+ if (filtered.length > 0) {
62
+ ensureWriter(stream).write(filtered.join("\n") + "\n");
63
+ throttledNotify();
64
+ }
65
+ flushAgentModel();
52
66
  }
53
67
  const { args, stdin, env: agentEnv, files } = ctx.agent.getTaskRunCommandLine(invokeTask, undefined, ctx.task.frontmatter.yolo_mode ? "yolo" : ctx.transientPermissions);
54
68
  const command = ctx.agent.command;
@@ -384,6 +398,18 @@ export function parsePermissions(output) {
384
398
  }
385
399
  return perms;
386
400
  }
401
+ export function parseAgentModel(output) {
402
+ const regex = new RegExp(`^\\${AGENT_MODEL_PREFIX}[ \\t]+(.+)$`, "gm");
403
+ let match;
404
+ while ((match = regex.exec(output)) !== null) {
405
+ const model = match[1].trim();
406
+ // Skip the "<model>" placeholder echoed from the prompt, and values that would break the run-file comment.
407
+ if (!model || model.startsWith("<") || model.includes("-->") || model.length > 100)
408
+ continue;
409
+ return model;
410
+ }
411
+ return undefined;
412
+ }
387
413
  /** Falls back to "finished" if no success/failure marker is found. */
388
414
  export function parseTaskOutcome(output) {
389
415
  const lastChunk = output.slice(-500);