@femtomc/mu-agent 26.2.43 → 26.2.45

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.
@@ -3,6 +3,7 @@ export { brandingExtension } from "./branding.js";
3
3
  export { eventLogExtension } from "./event-log.js";
4
4
  export { heartbeatsExtension } from "./heartbeats.js";
5
5
  export { messagingSetupExtension } from "./messaging-setup.js";
6
+ export { operatorCommandExtension } from "./operator-command.js";
6
7
  export { orchestrationRunsExtension } from "./orchestration-runs.js";
7
8
  export { orchestrationRunsReadOnlyExtension } from "./orchestration-runs-readonly.js";
8
9
  export { serverToolsExtension, serverToolsReadOnlyExtension } from "./server-tools.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/extensions/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAC/D,OAAO,EAAE,0BAA0B,EAAE,MAAM,yBAAyB,CAAC;AACrE,OAAO,EAAE,kCAAkC,EAAE,MAAM,kCAAkC,CAAC;AACtF,OAAO,EAAE,oBAAoB,EAAE,4BAA4B,EAAE,MAAM,mBAAmB,CAAC;AACvF,OAAO,EAAE,4BAA4B,EAAE,MAAM,4BAA4B,CAAC;AAyB1E;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB,UAE/B,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,UAElC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/extensions/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAC/D,OAAO,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AACjE,OAAO,EAAE,0BAA0B,EAAE,MAAM,yBAAyB,CAAC;AACrE,OAAO,EAAE,kCAAkC,EAAE,MAAM,kCAAkC,CAAC;AACtF,OAAO,EAAE,oBAAoB,EAAE,4BAA4B,EAAE,MAAM,mBAAmB,CAAC;AACvF,OAAO,EAAE,4BAA4B,EAAE,MAAM,4BAA4B,CAAC;AA0B1E;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB,UAE/B,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,UAElC,CAAC"}
@@ -3,6 +3,7 @@ export { brandingExtension } from "./branding.js";
3
3
  export { eventLogExtension } from "./event-log.js";
4
4
  export { heartbeatsExtension } from "./heartbeats.js";
5
5
  export { messagingSetupExtension } from "./messaging-setup.js";
6
+ export { operatorCommandExtension } from "./operator-command.js";
6
7
  export { orchestrationRunsExtension } from "./orchestration-runs.js";
7
8
  export { orchestrationRunsReadOnlyExtension } from "./orchestration-runs-readonly.js";
8
9
  export { serverToolsExtension, serverToolsReadOnlyExtension } from "./server-tools.js";
@@ -22,6 +23,7 @@ const OPERATOR_EXTENSION_MODULE_BASENAMES = [
22
23
  "event-log",
23
24
  "messaging-setup",
24
25
  "orchestration-runs-readonly",
26
+ "operator-command",
25
27
  ];
26
28
  const RUNTIME_EXTENSION = import.meta.url.endsWith(".ts") ? "ts" : "js";
27
29
  function resolveBundledExtensionPath(moduleBasename) {
@@ -0,0 +1,14 @@
1
+ /**
2
+ * mu_command — Operator mutation tool.
3
+ *
4
+ * Registered only in operator sessions. The LLM calls this tool with a
5
+ * structured command proposal instead of emitting fragile text directives.
6
+ * The tool itself does nothing except confirm receipt — the actual command
7
+ * is captured by the PiMessagingOperatorBackend subscriber on
8
+ * tool_execution_start and routed through the existing broker/audit pipeline.
9
+ */
10
+ import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
11
+ export declare const MU_COMMAND_TOOL_NAME = "mu_command";
12
+ export declare function operatorCommandExtension(pi: ExtensionAPI): void;
13
+ export default operatorCommandExtension;
14
+ //# sourceMappingURL=operator-command.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"operator-command.d.ts","sourceRoot":"","sources":["../../src/extensions/operator-command.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAGlE,eAAO,MAAM,oBAAoB,eAAe,CAAC;AAEjD,wBAAgB,wBAAwB,CAAC,EAAE,EAAE,YAAY,QAuCxD;AAED,eAAe,wBAAwB,CAAC"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * mu_command — Operator mutation tool.
3
+ *
4
+ * Registered only in operator sessions. The LLM calls this tool with a
5
+ * structured command proposal instead of emitting fragile text directives.
6
+ * The tool itself does nothing except confirm receipt — the actual command
7
+ * is captured by the PiMessagingOperatorBackend subscriber on
8
+ * tool_execution_start and routed through the existing broker/audit pipeline.
9
+ */
10
+ import { StringEnum } from "@mariozechner/pi-ai";
11
+ import { Type } from "@sinclair/typebox";
12
+ export const MU_COMMAND_TOOL_NAME = "mu_command";
13
+ export function operatorCommandExtension(pi) {
14
+ const CommandParams = Type.Object({
15
+ kind: StringEnum([
16
+ "status",
17
+ "ready",
18
+ "issue_list",
19
+ "issue_get",
20
+ "forum_read",
21
+ "run_list",
22
+ "run_status",
23
+ "run_start",
24
+ "run_resume",
25
+ "run_interrupt",
26
+ ]),
27
+ prompt: Type.Optional(Type.String({ description: "Prompt for run_start" })),
28
+ issue_id: Type.Optional(Type.String({ description: "Issue ID for issue_get" })),
29
+ topic: Type.Optional(Type.String({ description: "Topic for forum_read" })),
30
+ limit: Type.Optional(Type.Number({ description: "Limit for forum_read / run_resume" })),
31
+ root_issue_id: Type.Optional(Type.String({ description: "Root issue ID for run_status / run_resume / run_interrupt" })),
32
+ max_steps: Type.Optional(Type.Number({ description: "Max steps for run_start / run_resume" })),
33
+ });
34
+ pi.registerTool({
35
+ name: MU_COMMAND_TOOL_NAME,
36
+ label: "Command",
37
+ description: [
38
+ "Propose an approved mu command for execution.",
39
+ "This is the ONLY way to trigger mutations (starting runs, resuming runs, interrupting runs).",
40
+ "Read-only queries (status, issue_list, etc.) can also be proposed here.",
41
+ "The command will be validated and executed through the control-plane pipeline.",
42
+ ].join(" "),
43
+ parameters: CommandParams,
44
+ async execute(_toolCallId, params) {
45
+ return {
46
+ content: [{ type: "text", text: `Command proposal accepted: ${params.kind}` }],
47
+ details: { kind: params.kind },
48
+ };
49
+ },
50
+ });
51
+ }
52
+ export default operatorCommandExtension;
@@ -1 +1 @@
1
- {"version":3,"file":"operator.d.ts","sourceRoot":"","sources":["../src/operator.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAmB,KAAK,mBAAmB,EAAE,KAAK,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjG,OAAO,EAAE,8BAA8B,EAAE,MAAM,sBAAsB,CAAC;AAEtE,MAAM,MAAM,gCAAgC,GAAG;IAC9C,OAAO,EAAE,MAAM,CAAC;IAChB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,uBAAuB,EAAE,MAAM,CAAC;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC,CAAC;AAEF,MAAM,MAAM,gCAAgC,GAAG;IAC9C,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,KAAK,eAAe,GAAG,gCAAgC,CAAC;AACxD,KAAK,eAAe,GAAG,gCAAgC,CAAC;AAIxD,eAAO,MAAM,6BAA6B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2BA6BxC,CAAC;AACH,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,6BAA6B,CAAC,CAAC;AAEpF,eAAO,MAAM,+BAA+B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2BAG1C,CAAC;AACH,MAAM,MAAM,yBAAyB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,+BAA+B,CAAC,CAAC;AAOxF,MAAM,MAAM,wBAAwB,GAAG;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,eAAe,CAAC;IACzB,OAAO,EAAE,eAAe,CAAC;CACzB,CAAC;AAEF,MAAM,WAAW,wBAAwB;IACxC,OAAO,CAAC,KAAK,EAAE,wBAAwB,GAAG,OAAO,CAAC,yBAAyB,CAAC,CAAC;IAC7E,OAAO,CAAC,IAAI,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACjC;AAED,MAAM,MAAM,gBAAgB,GACzB;IACA,IAAI,EAAE,UAAU,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,cAAc,EAAE,MAAM,CAAC;CACtB,GACD;IACA,IAAI,EAAE,SAAS,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,cAAc,EAAE,MAAM,CAAC;CACtB,GACD;IACA,IAAI,EAAE,QAAQ,CAAC;IACf,MAAM,EACH,mBAAmB,GACnB,4BAA4B,GAC5B,yBAAyB,GACzB,iBAAiB,GACjB,mBAAmB,GACnB,sBAAsB,GACtB,uBAAuB,CAAC;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,cAAc,EAAE,MAAM,CAAC;CACtB,CAAC;AAEL,MAAM,MAAM,yBAAyB,GAAG;IACvC,eAAe,CAAC,EAAE,sBAAsB,CAAC;IACzC,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC7B,CAAC;AAaF,qBAAa,qBAAqB;;gBAId,IAAI,GAAE,yBAA8B;IAKhD,OAAO,CAAC,IAAI,EAAE;QAAE,QAAQ,EAAE,uBAAuB,CAAC;QAAC,OAAO,EAAE,eAAe,CAAA;KAAE,GACjF;QACA,IAAI,EAAE,UAAU,CAAC;QACjB,WAAW,EAAE,MAAM,CAAC;KACnB,GACD;QACA,IAAI,EAAE,QAAQ,CAAC;QACf,MAAM,EACH,4BAA4B,GAC5B,iBAAiB,GACjB,mBAAmB,GACnB,sBAAsB,GACtB,uBAAuB,CAAC;QAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;KAChB;CAsGJ;AAED,MAAM,MAAM,4BAA4B,GAAG;IAC1C,OAAO,EAAE,wBAAwB,CAAC;IAClC,MAAM,CAAC,EAAE,qBAAqB,CAAC;IAC/B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,eAAe,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,gBAAgB,CAAC,EAAE,MAAM,MAAM,CAAC;IAChC,aAAa,CAAC,EAAE,MAAM,MAAM,CAAC;CAC7B,CAAC;AAsBF,qBAAa,wBAAwB;;gBASjB,IAAI,EAAE,4BAA4B;IAoBxC,aAAa,CAAC,IAAI,EAAE;QAAE,OAAO,EAAE,eAAe,CAAC;QAAC,OAAO,EAAE,eAAe,CAAA;KAAE,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAgFtG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAIlC;AAED,MAAM,MAAM,8BAA8B,GAAG;IAC5C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,mBAAmB,KAAK,OAAO,CAAC,SAAS,CAAC,CAAC;IACnE,KAAK,CAAC,EAAE,MAAM,MAAM,CAAC;IACrB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,CAAC;CACrB,CAAC;AAEF,OAAO,EAAE,8BAA8B,EAAE,CAAC;AAgJ1C,qBAAa,0BAA2B,YAAW,wBAAwB;;gBAcvD,IAAI,GAAE,8BAAmC;IA4H/C,OAAO,CAAC,KAAK,EAAE,wBAAwB,GAAG,OAAO,CAAC,yBAAyB,CAAC;IA2GlF,OAAO,IAAI,IAAI;CAKtB"}
1
+ {"version":3,"file":"operator.d.ts","sourceRoot":"","sources":["../src/operator.ts"],"names":[],"mappings":"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"}
package/dist/operator.js CHANGED
@@ -39,10 +39,6 @@ export const OperatorBackendTurnResultSchema = z.discriminatedUnion("kind", [
39
39
  z.object({ kind: z.literal("respond"), message: z.string().trim().min(1).max(2000) }),
40
40
  z.object({ kind: z.literal("command"), command: OperatorApprovedCommandSchema }),
41
41
  ]);
42
- const OperatorDecisionEnvelopeSchema = z.discriminatedUnion("kind", [
43
- z.object({ kind: z.literal("respond"), message: z.string().trim().min(1).max(2000) }),
44
- z.object({ kind: z.literal("command"), command: OperatorApprovedCommandSchema }),
45
- ]);
46
42
  function splitPromptIntoTokens(prompt) {
47
43
  return prompt
48
44
  .split(/\s+/)
@@ -279,107 +275,7 @@ export class MessagingOperatorRuntime {
279
275
  }
280
276
  }
281
277
  export { DEFAULT_OPERATOR_SYSTEM_PROMPT };
282
- const OPERATOR_COMMAND_PREFIX = "MU_COMMAND:";
283
- const OPERATOR_DECISION_PREFIX = "MU_DECISION:";
284
- function stripOperatorDirectiveLines(text) {
285
- return text
286
- .split(/\r?\n/)
287
- .filter((line) => {
288
- const trimmed = line.trim();
289
- return !(trimmed.startsWith(OPERATOR_COMMAND_PREFIX) || trimmed.startsWith(OPERATOR_DECISION_PREFIX));
290
- })
291
- .join("\n")
292
- .trim();
293
- }
294
- function parseOperatorDirective(text) {
295
- const whole = text.trim();
296
- if (whole.startsWith("{") && whole.endsWith("}")) {
297
- try {
298
- const parsed = JSON.parse(whole);
299
- const envelope = OperatorDecisionEnvelopeSchema.safeParse(parsed);
300
- if (envelope.success) {
301
- return envelope.data.kind === "command"
302
- ? { kind: "command", command: envelope.data.command }
303
- : { kind: "respond", message: envelope.data.message };
304
- }
305
- const legacy = OperatorApprovedCommandSchema.safeParse(parsed);
306
- if (legacy.success) {
307
- return { kind: "command", command: legacy.data };
308
- }
309
- }
310
- catch {
311
- // fall through to line-based directives / plain text fallback.
312
- }
313
- }
314
- const lines = text.split(/\r?\n/);
315
- for (const line of lines) {
316
- const trimmed = line.trim();
317
- if (trimmed.startsWith(OPERATOR_DECISION_PREFIX)) {
318
- const payloadText = trimmed.slice(OPERATOR_DECISION_PREFIX.length).trim();
319
- if (payloadText.length === 0) {
320
- return {
321
- kind: "invalid",
322
- reason: "operator_decision_directive_missing_payload",
323
- fallbackMessage: stripOperatorDirectiveLines(text),
324
- };
325
- }
326
- let parsed;
327
- try {
328
- parsed = JSON.parse(payloadText);
329
- }
330
- catch (err) {
331
- return {
332
- kind: "invalid",
333
- reason: `operator_decision_directive_invalid_json: ${err instanceof Error ? err.message : String(err)}`,
334
- fallbackMessage: stripOperatorDirectiveLines(text),
335
- };
336
- }
337
- const envelope = OperatorDecisionEnvelopeSchema.safeParse(parsed);
338
- if (!envelope.success) {
339
- return {
340
- kind: "invalid",
341
- reason: `operator_decision_directive_invalid_payload: ${envelope.error.message}`,
342
- fallbackMessage: stripOperatorDirectiveLines(text),
343
- };
344
- }
345
- return envelope.data.kind === "command"
346
- ? { kind: "command", command: envelope.data.command }
347
- : { kind: "respond", message: envelope.data.message };
348
- }
349
- if (!trimmed.startsWith(OPERATOR_COMMAND_PREFIX)) {
350
- continue;
351
- }
352
- const payloadText = trimmed.slice(OPERATOR_COMMAND_PREFIX.length).trim();
353
- if (payloadText.length === 0) {
354
- return {
355
- kind: "invalid",
356
- reason: "operator_command_directive_missing_payload",
357
- fallbackMessage: stripOperatorDirectiveLines(text),
358
- };
359
- }
360
- let parsed;
361
- try {
362
- parsed = JSON.parse(payloadText);
363
- }
364
- catch (err) {
365
- return {
366
- kind: "invalid",
367
- reason: `operator_command_directive_invalid_json: ${err instanceof Error ? err.message : String(err)}`,
368
- fallbackMessage: stripOperatorDirectiveLines(text),
369
- };
370
- }
371
- const command = OperatorApprovedCommandSchema.safeParse(parsed);
372
- if (!command.success) {
373
- return {
374
- kind: "invalid",
375
- reason: `operator_command_directive_invalid_payload: ${command.error.message}`,
376
- fallbackMessage: stripOperatorDirectiveLines(text),
377
- };
378
- }
379
- return { kind: "command", command: command.data };
380
- }
381
- return { kind: "none" };
382
- }
278
+ const MU_COMMAND_TOOL_NAME = "mu_command";
383
279
  function buildOperatorPrompt(input) {
384
280
  return [
385
281
  `[Messaging context]`,
@@ -516,7 +412,9 @@ export class PiMessagingOperatorBackend {
516
412
  const sessionRecord = await this.#resolveSession(input.sessionId, input.inbound.repo_root);
517
413
  const session = sessionRecord.session;
518
414
  let assistantText = "";
415
+ let capturedCommand = null;
519
416
  const unsub = session.subscribe((event) => {
417
+ // Capture assistant text for fallback responses.
520
418
  if (event?.type === "message_end" && event?.message?.role === "assistant") {
521
419
  const msg = event.message;
522
420
  if (typeof msg.text === "string") {
@@ -536,6 +434,13 @@ export class PiMessagingOperatorBackend {
536
434
  assistantText = parts.join("\n");
537
435
  }
538
436
  }
437
+ // Capture mu_command tool calls — structured command proposals.
438
+ if (event?.type === "tool_execution_start" && event?.toolName === MU_COMMAND_TOOL_NAME) {
439
+ const parsed = OperatorApprovedCommandSchema.safeParse(event.args);
440
+ if (parsed.success) {
441
+ capturedCommand = parsed.data;
442
+ }
443
+ }
539
444
  });
540
445
  const timeoutPromise = new Promise((_, reject) => {
541
446
  setTimeout(() => reject(new Error("pi operator timeout")), this.#timeoutMs);
@@ -558,6 +463,16 @@ export class PiMessagingOperatorBackend {
558
463
  unsub();
559
464
  sessionRecord.lastUsedAtMs = Math.trunc(this.#nowMs());
560
465
  }
466
+ // If the operator called mu_command, use the captured structured command.
467
+ if (capturedCommand) {
468
+ await this.#auditTurn(input, {
469
+ outcome: "command",
470
+ command: capturedCommand,
471
+ messagePreview: assistantText,
472
+ });
473
+ return { kind: "command", command: capturedCommand };
474
+ }
475
+ // Otherwise treat the assistant text as a plain response.
561
476
  const message = assistantText.trim();
562
477
  if (!message) {
563
478
  await this.#auditTurn(input, {
@@ -566,57 +481,12 @@ export class PiMessagingOperatorBackend {
566
481
  });
567
482
  throw new Error("operator_empty_response");
568
483
  }
569
- const parsed = parseOperatorDirective(message);
570
- switch (parsed.kind) {
571
- case "command":
572
- await this.#auditTurn(input, {
573
- outcome: "command",
574
- command: parsed.command,
575
- messagePreview: message,
576
- });
577
- return {
578
- kind: "command",
579
- command: parsed.command,
580
- };
581
- case "respond": {
582
- const responseMessage = parsed.message.trim().slice(0, 2000);
583
- if (!SAFE_RESPONSE_RE.test(responseMessage)) {
584
- const fallback = buildOperatorFailureFallbackMessage("operator_invalid_response_payload");
585
- await this.#auditTurn(input, {
586
- outcome: "invalid_directive",
587
- reason: "operator_invalid_response_payload",
588
- messagePreview: message,
589
- });
590
- return { kind: "respond", message: fallback };
591
- }
592
- await this.#auditTurn(input, {
593
- outcome: "respond",
594
- messagePreview: responseMessage,
595
- });
596
- return { kind: "respond", message: responseMessage };
597
- }
598
- case "invalid": {
599
- const fallbackMessage = parsed.fallbackMessage.trim();
600
- const responseMessage = fallbackMessage.length > 0
601
- ? fallbackMessage.slice(0, 2000)
602
- : buildOperatorFailureFallbackMessage("operator_invalid_command_directive");
603
- await this.#auditTurn(input, {
604
- outcome: "invalid_directive",
605
- reason: parsed.reason,
606
- messagePreview: message,
607
- });
608
- return { kind: "respond", message: responseMessage };
609
- }
610
- case "none":
611
- default: {
612
- const responseMessage = message.slice(0, 2000);
613
- await this.#auditTurn(input, {
614
- outcome: "respond",
615
- messagePreview: responseMessage,
616
- });
617
- return { kind: "respond", message: responseMessage };
618
- }
619
- }
484
+ const responseMessage = message.slice(0, 2000);
485
+ await this.#auditTurn(input, {
486
+ outcome: "respond",
487
+ messagePreview: responseMessage,
488
+ });
489
+ return { kind: "respond", message: responseMessage };
620
490
  }
621
491
  dispose() {
622
492
  for (const sessionId of [...this.#sessions.keys()]) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@femtomc/mu-agent",
3
- "version": "26.2.43",
3
+ "version": "26.2.45",
4
4
  "description": "Shared agent runtime for mu chat, orchestration roles, and serve extensions.",
5
5
  "keywords": [
6
6
  "mu",
@@ -23,7 +23,7 @@
23
23
  "prompts/**"
24
24
  ],
25
25
  "dependencies": {
26
- "@femtomc/mu-core": "26.2.43",
26
+ "@femtomc/mu-core": "26.2.45",
27
27
  "@mariozechner/pi-agent-core": "^0.52.12",
28
28
  "@mariozechner/pi-ai": "^0.52.12",
29
29
  "@mariozechner/pi-coding-agent": "^0.52.12",
@@ -1,16 +1,19 @@
1
- # Mu Operator
2
-
3
- You are mu, the operator assistant for the mu orchestration platform.
4
-
5
- ## Mission
1
+ You are an operator: you help users interact with and utilize all the capabilities that mu has to offer.
6
2
 
3
+ Mission:
4
+ - Free flowing discussion with users about their interests.
5
+ - Help users with any coding tasks they ask you to handle directly.
7
6
  - Help users inspect repository/control-plane state.
8
7
  - Help users choose safe next actions.
9
- - When needed, propose approved operator commands.
8
+ - When needed, propose approved commands using the mu_command tool.
10
9
 
11
- ## Tools
10
+ Available tools:
11
+ - read: Read file contents
12
+ - bash: Execute bash commands
13
+ - edit: Make surgical edits to files
14
+ - write: Create or overwrite files
12
15
 
13
- Use available read/diagnostic tools:
16
+ You also have access to specialized read/diagnostic tools:
14
17
  - `mu_status`
15
18
  - `mu_control_plane`
16
19
  - `mu_issues`
@@ -21,17 +24,16 @@ Use available read/diagnostic tools:
21
24
  - `mu_heartbeats`
22
25
  - `mu_messaging_setup`
23
26
 
24
- ## Hard Constraints
25
-
26
- - Never perform mutations directly through tools in operator mode.
27
- - Mutating actions must flow through approved command proposals.
28
- - If a command is needed, output exactly one line prefixed with `MU_DECISION:` and compact JSON.
29
-
30
- ## Output Contract
31
-
32
- Command envelope example:
27
+ Hard Constraints:
28
+ - Never perform mutations directly through read/write tools.
29
+ - Mutating actions must flow through the `mu_command` tool.
30
+ - Use the `mu_command` tool to propose commands. It accepts structured parameters — do NOT emit raw JSON directives in your text output.
33
31
 
34
- `MU_DECISION: {"kind":"command","command":{"kind":"run_start","prompt":"ship release"}}`
32
+ mu_command tool usage:
33
+ - Call `mu_command` with `kind` set to the command type and relevant parameters.
34
+ - Example: `mu_command({ kind: "run_start", prompt: "ship release" })`
35
+ - Example: `mu_command({ kind: "status" })`
36
+ - Example: `mu_command({ kind: "issue_get", issue_id: "mu-abc123" })`
35
37
 
36
38
  Allowed command kinds:
37
39
  - `status`
@@ -47,4 +49,3 @@ Allowed command kinds:
47
49
 
48
50
  For normal answers:
49
51
  - Respond in plain text (no directive prefix).
50
- - Be concise, practical, and actionable.
@@ -1,15 +1,12 @@
1
- # Mu Orchestrator
1
+ You are an orchestrator: you help by engaging in planning and review as part of the orchestration engine within mu.
2
2
 
3
- You are mu's orchestrator: the hierarchical planner for the issue DAG.
4
-
5
- ## Mission
6
-
7
- - Decompose assigned issues into executable worker issues.
3
+ Mission:
4
+ - Read and think carefully about the issue assigned to you. Use mu's CLI to explore related issues, and the forum for relevant conversation.
5
+ - Decompose your assigned issue into executable worker issues, or further orchestrator issues if multi-layer decomposition is appropriate.
8
6
  - Define ordering via dependencies.
9
7
  - Move planning state forward by closing expanded planning nodes.
10
8
 
11
- ## Hard Constraints
12
-
9
+ Hard Constraints:
13
10
  1. You MUST NOT execute work directly. No code changes, no file edits, no git commits.
14
11
  2. You MUST decompose the assigned issue into worker child issues.
15
12
  3. You MUST close your assigned issue with `mu issues close <id> --outcome expanded`.
@@ -18,8 +15,7 @@ You are mu's orchestrator: the hierarchical planner for the issue DAG.
18
15
 
19
16
  If the task looks atomic, create exactly one worker child issue rather than doing the work yourself.
20
17
 
21
- ## Workflow
22
-
18
+ Workflow:
23
19
  1. Inspect context:
24
20
  - `mu issues get <id>`
25
21
  - `mu forum read issue:<id> --limit 20`
@@ -31,9 +27,8 @@ If the task looks atomic, create exactly one worker child issue rather than doin
31
27
  4. Close yourself:
32
28
  - `mu issues close <id> --outcome expanded`
33
29
 
34
- ## Guardrails
35
-
30
+ Guardrails:
36
31
  - The only valid orchestrator close outcome is `expanded`.
37
32
  - Never close with `success`, `failure`, `needs_work`, or `skipped`.
38
33
  - Keep plans small, explicit, and testable.
39
- - Be concise.
34
+ - Plans should include proposed evidence for successful completion.
package/prompts/worker.md CHANGED
@@ -1,20 +1,21 @@
1
- # Mu Worker
2
-
3
- You are mu's worker. You execute exactly one atomic issue end-to-end.
4
-
5
- ## Mission
1
+ You are a worker. You execute exactly one atomic issue end-to-end.
6
2
 
3
+ Mission:
7
4
  - Implement the work described in your assigned issue.
8
5
  - Keep scope tight to the issue specification.
9
6
  - Verify outcomes and close with a terminal result.
10
7
 
11
- ## Hard Constraints
8
+ Available tools:
9
+ - read: Read file contents
10
+ - bash: Execute bash commands
11
+ - edit: Make surgical edits to files
12
+ - write: Create or overwrite files
12
13
 
14
+ Hard Constraints:
13
15
  - Do NOT create child issues — that is the orchestrator's job.
14
16
  - If the issue is too large/unclear, close with `--outcome needs_work` and explain what is missing.
15
17
 
16
- ## Workflow
17
-
18
+ Workflow:
18
19
  1. Inspect:
19
20
  - `mu issues get <id>`
20
21
  - `mu forum read issue:<id> --limit 20`
@@ -27,8 +28,7 @@ You are mu's worker. You execute exactly one atomic issue end-to-end.
27
28
  5. Log key notes:
28
29
  - `mu forum post issue:<id> -m "..." --author worker`
29
30
 
30
- ## Guardrails
31
-
31
+ Guardrails:
32
32
  - Prefer concrete evidence over claims (test output, build output, repro checks).
33
33
  - Report what changed and why.
34
34
  - Be concise.