pi-maestro-teammate 2.6.1 → 2.6.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-maestro-teammate",
3
- "version": "2.6.1",
3
+ "version": "2.6.2",
4
4
  "description": "Pi extension — teammate agent dispatch with DAG task graphs, RPC messaging, and compact TUI",
5
5
  "type": "module",
6
6
  "engines": {
@@ -197,6 +197,23 @@ function isReservedAgentName(name: string): boolean {
197
197
  return isBuiltinAgentName(name);
198
198
  }
199
199
 
200
+ function agentDefinitionFingerprint(agent: AgentConfig): string {
201
+ return JSON.stringify([
202
+ agent.name,
203
+ agent.description,
204
+ agent.tools ?? null,
205
+ agent.model ?? null,
206
+ agent.fallbackModels ?? null,
207
+ agent.taskType ?? null,
208
+ agent.thinking ?? null,
209
+ agent.systemPromptMode,
210
+ agent.inheritProjectContext,
211
+ agent.inheritSkills,
212
+ agent.defaultContext ?? null,
213
+ agent.systemPrompt,
214
+ ]);
215
+ }
216
+
200
217
  interface DiscoveryDirs {
201
218
  legacyUserAgentsDir: string;
202
219
  userPiAgentsDir: string;
@@ -394,8 +411,17 @@ export function discoverAgents(
394
411
  }> = [];
395
412
  const mergeAgent = (agent: AgentConfig): void => {
396
413
  // Builtin names are reserved so custom definitions cannot silently replace
397
- // the stable general, exploration, and DAG orchestration roles.
414
+ // the stable general, exploration, and DAG orchestration roles. Package
415
+ // catalogs may carry byte-equivalent builtin mirrors for other consumers;
416
+ // those are duplicates, not attempted overrides.
398
417
  if (agent.source !== "builtin" && isReservedAgentName(agent.name)) {
418
+ const builtin = agentMap.get(agent.name);
419
+ if (
420
+ builtin?.source === "builtin"
421
+ && agentDefinitionFingerprint(builtin) === agentDefinitionFingerprint(agent)
422
+ ) {
423
+ return;
424
+ }
399
425
  rejectedCandidates.push({ name: agent.name, reason: "reserved-builtin", candidate: agent });
400
426
  return;
401
427
  }
@@ -487,7 +487,7 @@ import {
487
487
  type RuntimeReadModelSnapshotV2,
488
488
  } from "../runtime-v2/read-model.ts";
489
489
  import { RuntimeReadModelBrokerBridge } from "../runtime-v2/broker-read-model.ts";
490
- import { formatLocalAgentMessage } from "../shared/routing.ts";
490
+ import { formatLocalAgentMessage, formatNoRestorableRuntimeError } from "../shared/routing.ts";
491
491
  export * from "./teammate-core.ts";
492
492
  import {
493
493
  appendTeammateDepthContext,
@@ -2704,7 +2704,7 @@ export default function registerTeammateExtension(
2704
2704
  const restarted = agent.status === "sleeping" && agent.restart?.(message, provenance) === true;
2705
2705
  if (!restarted) {
2706
2706
  restoreDeferredAgentContext(agent, deferredContext);
2707
- return { delivered: false, error: `Agent "${targetLabel}" has no restorable runtime.` };
2707
+ return { delivered: false, error: formatNoRestorableRuntimeError(targetLabel, agent.status) };
2708
2708
  }
2709
2709
  const restartDelivery = agent.restartDelivery;
2710
2710
  if (restartDelivery) {
@@ -6201,7 +6201,7 @@ export default function registerTeammateExtension(
6201
6201
  const agent = cid ? state.activeRuns.get(cid) : undefined;
6202
6202
  if (agent && !LIVE_AGENT_STATUSES.has(agent.status)) {
6203
6203
  return {
6204
- content: [{ type: "text", text: `Agent "${params.to}" is already ${agent.status} and cannot receive commands.` }],
6204
+ content: [{ type: "text", text: formatNoRestorableRuntimeError(params.to, agent.status) }],
6205
6205
  isError: true,
6206
6206
  details: { delivered: false },
6207
6207
  };
@@ -20,7 +20,11 @@ import type { AgentToolResult } from "@earendil-works/pi-agent-core";
20
20
  import { Check } from "typebox/value";
21
21
  import { isGuiTeammateToolAllowed, registerGuiTool, unregisterGuiTool } from "../shared/gui-registry.ts";
22
22
  import { aggregateAgentRunPhase, projectAgentRuntime } from "../shared/agent-status.ts";
23
- import { formatLocalAgentMessage, resolveAgentCompletionTarget } from "../shared/routing.ts";
23
+ import {
24
+ formatLocalAgentMessage,
25
+ formatNoRestorableRuntimeError,
26
+ resolveAgentCompletionTarget,
27
+ } from "../shared/routing.ts";
24
28
  import { Text, truncateToWidth } from "@earendil-works/pi-tui";
25
29
  import { TeammateParams, TeammateSendParams, TeammateListParams, TeammateWatchParams, TeammateWaitParams, TeammateMonitorParams, ObserveParams, LocalObserveParams } from "./schemas.ts";
26
30
  import {
@@ -3113,7 +3117,7 @@ export async function handleProxyRequest(
3113
3117
  const agent = state.activeRuns.get(cid);
3114
3118
  if (agent && !LIVE_AGENT_STATUSES.has(agent.status)) {
3115
3119
  reply({ type: "teammate_proxy_result", requestId, result: {
3116
- content: [{ type: "text", text: `Agent "${to}" is already ${agent.status} and cannot receive commands.` }],
3120
+ content: [{ type: "text", text: formatNoRestorableRuntimeError(to, agent.status) }],
3117
3121
  isError: true, details: { delivered: false },
3118
3122
  }});
3119
3123
  return;
@@ -3298,7 +3302,7 @@ export async function handleProxyRequest(
3298
3302
  if (!restarted || !agent) {
3299
3303
  if (agent) restoreDeferredAgentContext(agent, deferredContext);
3300
3304
  reply({ type: "teammate_proxy_result", requestId, result: {
3301
- content: [{ type: "text", text: `Agent "${to}" has no restorable runtime.` }],
3305
+ content: [{ type: "text", text: formatNoRestorableRuntimeError(to, agent?.status) }],
3302
3306
  isError: true, details: { delivered: false },
3303
3307
  }});
3304
3308
  return;
@@ -96,3 +96,13 @@ export function formatLocalAgentMessage(input: LocalAgentMessageInput): string {
96
96
  input.message,
97
97
  ].join("\n");
98
98
  }
99
+
100
+ /** Explain why a settled local agent cannot accept another message and how to continue. */
101
+ export function formatNoRestorableRuntimeError(label: string, status?: string): string {
102
+ const state = status === "completed"
103
+ ? "has completed"
104
+ : status
105
+ ? `is ${status}`
106
+ : "is unavailable";
107
+ return `Agent "${label}" ${state} and has no restorable runtime. Dispatch a new teammate and pass the previous agent:// publication via tasks[].briefing.`;
108
+ }
@@ -37,3 +37,5 @@ export interface LocalAgentMessageInput {
37
37
  }
38
38
  /** Canonical model-visible envelope for local agent-to-agent messages. */
39
39
  export declare function formatLocalAgentMessage(input: LocalAgentMessageInput): string;
40
+ /** Explain why a settled local agent cannot accept another message and how to continue. */
41
+ export declare function formatNoRestorableRuntimeError(label: string, status?: string): string;