@mystilleef/pi-subagent 0.10.2 → 0.11.0

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.
@@ -79,6 +79,47 @@ function redactSensitiveDebugMessages(messages: unknown): unknown {
79
79
  return messages.map(redactSensitiveDebugValue);
80
80
  }
81
81
 
82
+ function sanitizeProgressObject(
83
+ progress: SingleResult["progress"],
84
+ _includeDebugMessages: boolean,
85
+ ): StreamingProgress | undefined {
86
+ if (!progress) return undefined;
87
+ const {
88
+ activityText,
89
+ activeToolActivity,
90
+ lastToolPreview,
91
+ toolResultCompleted,
92
+ ...progBase
93
+ } = progress;
94
+ return {
95
+ toolCalls: progBase.toolCalls.map((tc) => ({
96
+ id: tc.id,
97
+ preview: tc.preview,
98
+ })),
99
+ ...(activityText !== undefined && { activityText }),
100
+ ...(activeToolActivity !== undefined && { activeToolActivity }),
101
+ ...(lastToolPreview !== undefined && { lastToolPreview }),
102
+ ...(toolResultCompleted !== undefined && { toolResultCompleted }),
103
+ };
104
+ }
105
+
106
+ function sanitizeTerminationObject(
107
+ termination: TerminationMetadata | undefined,
108
+ includeMessages: boolean,
109
+ includeDebugMessages: boolean,
110
+ ): TerminationMetadata | undefined {
111
+ if (!includeMessages || !includeDebugMessages || !termination)
112
+ return undefined;
113
+ const { cancelReason, terminationSignal, fallbackCause, ...termBase } =
114
+ termination;
115
+ return {
116
+ ...termBase,
117
+ ...(cancelReason !== undefined && { cancelReason }),
118
+ ...(terminationSignal !== undefined && { terminationSignal }),
119
+ ...(fallbackCause !== undefined && { fallbackCause }),
120
+ };
121
+ }
122
+
82
123
  export function sanitizeResultDetails(
83
124
  result: SingleResult,
84
125
  includeDebugMessages: boolean,
@@ -88,37 +129,6 @@ export function sanitizeResultDetails(
88
129
  includeDebugMessages && (options?.includeMessages ?? true);
89
130
  const { messages, termination, progress, stderr, usage, ...core } = result;
90
131
  const { contextWindowTokens, ...usageBase } = usage;
91
- let progressValue: StreamingProgress | undefined;
92
- if (progress) {
93
- const {
94
- activityText,
95
- activeToolActivity,
96
- lastToolPreview,
97
- toolResultCompleted,
98
- ...progBase
99
- } = progress;
100
- progressValue = {
101
- toolCalls: progBase.toolCalls.map((tc) => ({
102
- id: tc.id,
103
- preview: tc.preview,
104
- })),
105
- ...(activityText !== undefined && { activityText }),
106
- ...(activeToolActivity !== undefined && { activeToolActivity }),
107
- ...(lastToolPreview !== undefined && { lastToolPreview }),
108
- ...(toolResultCompleted !== undefined && { toolResultCompleted }),
109
- };
110
- }
111
- let terminationValue: TerminationMetadata | undefined;
112
- if (includeMessages && includeDebugMessages && termination) {
113
- const { cancelReason, terminationSignal, fallbackCause, ...termBase } =
114
- termination;
115
- terminationValue = {
116
- ...termBase,
117
- ...(cancelReason !== undefined && { cancelReason }),
118
- ...(terminationSignal !== undefined && { terminationSignal }),
119
- ...(fallbackCause !== undefined && { fallbackCause }),
120
- };
121
- }
122
132
  const sanitized: SingleResult = {
123
133
  ...core,
124
134
  stderr: includeDebugMessages ? stderr : "",
@@ -127,6 +137,7 @@ export function sanitizeResultDetails(
127
137
  ...(contextWindowTokens !== undefined && { contextWindowTokens }),
128
138
  },
129
139
  };
140
+ const progressValue = sanitizeProgressObject(progress, includeDebugMessages);
130
141
  if (progressValue !== undefined) sanitized.progress = progressValue;
131
142
  if (includeMessages) {
132
143
  sanitized.messages = options?.recentMessages
@@ -135,6 +146,11 @@ export function sanitizeResultDetails(
135
146
  ? [...messages]
136
147
  : undefined;
137
148
  }
149
+ const terminationValue = sanitizeTerminationObject(
150
+ termination,
151
+ includeMessages,
152
+ includeDebugMessages,
153
+ );
138
154
  if (terminationValue !== undefined) sanitized.termination = terminationValue;
139
155
  return sanitized;
140
156
  }
@@ -224,19 +240,12 @@ export function patchProgressFromDetails(
224
240
  patchProgressState(requestId, patch);
225
241
  }
226
242
 
227
- function getSubagentText(result: SubagentToolResult): string {
228
- return (result.content[0] as { text?: string })?.text ?? "";
229
- }
230
-
231
- export function getResultDisplayText(result: SubagentToolResult): string {
232
- return (
233
- getLatestResult(result.details)?.finalOutput ?? getSubagentText(result)
234
- );
235
- }
236
-
237
243
  export function getFeedbackSummaryText(result: SubagentToolResult): string {
238
- const rawFinalOutput = getLatestResult(result.details)?.finalOutput;
239
- if (rawFinalOutput?.trim())
240
- return summarizeFeedbackUiFinalOutput(rawFinalOutput);
241
- return getSubagentText(result).trim() || "(no output)";
244
+ const latestResult = getLatestResult(result.details);
245
+ const rawFinalOutput = latestResult?.finalOutput ?? "";
246
+ const outcome = latestResult?.outcome;
247
+ if (!outcome?.trim() && !rawFinalOutput.trim()) {
248
+ return "(no output)";
249
+ }
250
+ return summarizeFeedbackUiFinalOutput(rawFinalOutput, outcome);
242
251
  }
@@ -0,0 +1,56 @@
1
+ export interface SamplingParams {
2
+ temperature?: number | undefined;
3
+ topP?: number | undefined;
4
+ }
5
+
6
+ export function isValidSamplingValue(value: unknown): value is number {
7
+ return (
8
+ typeof value === "number" &&
9
+ Number.isFinite(value) &&
10
+ value >= 0.0 &&
11
+ value <= 1.0
12
+ );
13
+ }
14
+
15
+ /**
16
+ * Parses a JSON-encoded sampling parameters string.
17
+ * Returns undefined for missing, malformed, or wholly invalid values.
18
+ */
19
+ export function parseSamplingParams(
20
+ envVal?: string,
21
+ ): SamplingParams | undefined {
22
+ if (!envVal) return undefined;
23
+ try {
24
+ const parsed = JSON.parse(envVal);
25
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
26
+ return undefined;
27
+ const { temperature: rawTemperature, topP: rawTopP } = parsed as Record<
28
+ string,
29
+ unknown
30
+ >;
31
+ const result: SamplingParams = {};
32
+ if (isValidSamplingValue(rawTemperature))
33
+ result.temperature = rawTemperature;
34
+ if (isValidSamplingValue(rawTopP)) result.topP = rawTopP;
35
+ if (result.temperature !== undefined || result.topP !== undefined)
36
+ return result;
37
+ } catch {
38
+ /* malformed env value: run without sampling overrides */
39
+ }
40
+ return undefined;
41
+ }
42
+
43
+ /**
44
+ * Serializes sampling parameters into a JSON string for environment passing.
45
+ * Returns undefined when no valid parameters are present.
46
+ */
47
+ export function serializeSamplingParams(
48
+ params: SamplingParams,
49
+ ): string | undefined {
50
+ if (params.temperature === undefined && params.topP === undefined)
51
+ return undefined;
52
+ const config: SamplingParams = {};
53
+ if (params.temperature !== undefined) config.temperature = params.temperature;
54
+ if (params.topP !== undefined) config.topP = params.topP;
55
+ return JSON.stringify(config);
56
+ }
@@ -52,6 +52,7 @@ export interface SingleResult {
52
52
  messages?: Message[] | undefined;
53
53
  termination?: TerminationMetadata | undefined;
54
54
  thinkingWarning?: string | undefined;
55
+ outcome?: string | undefined;
55
56
  }
56
57
 
57
58
  export interface SubagentDetails {
@@ -230,6 +230,15 @@ export function findLastAssistantTextMessage(messages: Message[]): number {
230
230
  return -1;
231
231
  }
232
232
 
233
+ export function extractFinalOutputFromMessages(messages: Message[]): string {
234
+ const lastAsstIdx = findLastAssistantTextMessage(messages);
235
+ if (lastAsstIdx < 0) return "";
236
+ const content = messages[lastAsstIdx]?.content;
237
+ if (!Array.isArray(content)) return "";
238
+ const lastText = content.findLast((p) => p.type === "text");
239
+ return lastText?.type === "text" ? (lastText.text ?? "") : "";
240
+ }
241
+
233
242
  export function detectMessageError(messages: Message[]): boolean {
234
243
  const lastAssistantIdx = findLastAssistantTextMessage(messages);
235
244
  const from = lastAssistantIdx >= 0 ? lastAssistantIdx + 1 : 0;
@@ -241,6 +250,7 @@ export function detectMessageError(messages: Message[]): boolean {
241
250
  }
242
251
 
243
252
  export function hasSubagentFailed(result: SingleResult): boolean {
253
+ if (result.outcome?.trim()) return false;
244
254
  return (
245
255
  result.exitCode !== 0 ||
246
256
  result.stopReason === "error" ||