@f5-sales-demo/xcsh 23.0.2 → 23.0.3
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 +8 -8
- package/src/extensibility/extensions/wrapper.ts +9 -1
- package/src/internal-urls/api-catalog-qmd-index.generated.ts +2 -2
- package/src/internal-urls/build-info.generated.ts +8 -8
- package/src/modes/rpc/rpc-mode.ts +3 -0
- package/src/modes/rpc/rpc-types.ts +4 -0
- package/src/session/agent-session.ts +5 -0
- package/src/session/tool-choice-queue.ts +15 -0
- package/src/web/search/index.ts +27 -10
- package/src/web/search/providers/anthropic.ts +3 -0
- package/src/web/search/types.ts +1 -1
|
@@ -17,17 +17,17 @@ export interface BuildInfo {
|
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
export const BUILD_INFO: BuildInfo = {
|
|
20
|
-
"version": "23.0.
|
|
21
|
-
"commit": "
|
|
22
|
-
"shortCommit": "
|
|
20
|
+
"version": "23.0.3",
|
|
21
|
+
"commit": "a1b667ce0f3621987ad2be76de041c08185614ee",
|
|
22
|
+
"shortCommit": "a1b667c",
|
|
23
23
|
"branch": "main",
|
|
24
|
-
"tag": "v23.0.
|
|
25
|
-
"commitDate": "2026-10-
|
|
26
|
-
"buildDate": "2026-10-
|
|
24
|
+
"tag": "v23.0.3",
|
|
25
|
+
"commitDate": "2026-10-08T19:11:22Z",
|
|
26
|
+
"buildDate": "2026-10-08T19:50:26.569Z",
|
|
27
27
|
"dirty": true,
|
|
28
28
|
"prNumber": "",
|
|
29
29
|
"repoUrl": "https://github.com/f5-sales-demo/xcsh",
|
|
30
30
|
"repoSlug": "f5-sales-demo/xcsh",
|
|
31
|
-
"commitUrl": "https://github.com/f5-sales-demo/xcsh/commit/
|
|
32
|
-
"releaseUrl": "https://github.com/f5-sales-demo/xcsh/releases/tag/v23.0.
|
|
31
|
+
"commitUrl": "https://github.com/f5-sales-demo/xcsh/commit/a1b667ce0f3621987ad2be76de041c08185614ee",
|
|
32
|
+
"releaseUrl": "https://github.com/f5-sales-demo/xcsh/releases/tag/v23.0.3"
|
|
33
33
|
};
|
|
@@ -634,6 +634,9 @@ export async function runRpcMode(session: AgentSession): Promise<never> {
|
|
|
634
634
|
queuedMessageCount: session.queuedMessageCount,
|
|
635
635
|
todoPhases: session.getTodoPhases(),
|
|
636
636
|
systemPrompt: session.systemPrompt,
|
|
637
|
+
registeredToolNames: session.getRegisteredToolNames(),
|
|
638
|
+
activeToolNames: session.getActiveToolNames(),
|
|
639
|
+
toolChoiceState: session.toolChoiceQueue.snapshot(),
|
|
637
640
|
dumpTools: session.agent.state.tools.map(tool => ({
|
|
638
641
|
name: tool.name,
|
|
639
642
|
description: tool.description,
|
|
@@ -136,6 +136,10 @@ export interface RpcSessionState {
|
|
|
136
136
|
todoPhases: TodoPhase[];
|
|
137
137
|
/** For session dump / export (plain-text parity with /dump). */
|
|
138
138
|
systemPrompt?: string;
|
|
139
|
+
/** Read-only execution diagnostics; no credentials, inputs, or callback state. */
|
|
140
|
+
registeredToolNames?: string[];
|
|
141
|
+
activeToolNames?: string[];
|
|
142
|
+
toolChoiceState?: ReturnType<import("../../session/tool-choice-queue").ToolChoiceQueue["snapshot"]>;
|
|
139
143
|
dumpTools?: Array<{ name: string; description: string; parameters: unknown }>;
|
|
140
144
|
}
|
|
141
145
|
|
|
@@ -3149,6 +3149,11 @@ export class AgentSession {
|
|
|
3149
3149
|
return this.agent.state.tools.map(t => t.name);
|
|
3150
3150
|
}
|
|
3151
3151
|
|
|
3152
|
+
/** Complete registry names, including dormant tools, without tool payloads. */
|
|
3153
|
+
getRegisteredToolNames(): string[] {
|
|
3154
|
+
return [...this.#toolRegistry.keys()];
|
|
3155
|
+
}
|
|
3156
|
+
|
|
3152
3157
|
/** Numeric-only prompt/tool/provider-call profile. Raw context is never retained. */
|
|
3153
3158
|
getContextProfile(): ContextProfile {
|
|
3154
3159
|
this.#contextProfileCollector.setPrompt(this.systemPrompt, this.agent.state.tools);
|
|
@@ -206,6 +206,21 @@ export class ToolChoiceQueue {
|
|
|
206
206
|
return label;
|
|
207
207
|
}
|
|
208
208
|
|
|
209
|
+
/** Read-only diagnostics. Never advance an iterator or invoke callbacks. */
|
|
210
|
+
snapshot(): { queuedLabels: string[]; inFlight?: { label: string; choice: ToolChoice } } {
|
|
211
|
+
return {
|
|
212
|
+
queuedLabels: [...this.inspect()],
|
|
213
|
+
...(this.#inFlight
|
|
214
|
+
? {
|
|
215
|
+
inFlight: {
|
|
216
|
+
label: this.#inFlight.directive.label,
|
|
217
|
+
choice: structuredClone(this.#inFlight.yielded),
|
|
218
|
+
},
|
|
219
|
+
}
|
|
220
|
+
: {}),
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
|
|
209
224
|
/** For tests/debug: labels of currently queued directives in order. */
|
|
210
225
|
inspect(): readonly string[] {
|
|
211
226
|
return this.#queue.map(d => d.label);
|
package/src/web/search/index.ts
CHANGED
|
@@ -6,11 +6,12 @@
|
|
|
6
6
|
*
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import
|
|
10
|
-
AgentTool,
|
|
11
|
-
AgentToolContext,
|
|
12
|
-
|
|
13
|
-
|
|
9
|
+
import {
|
|
10
|
+
type AgentTool,
|
|
11
|
+
type AgentToolContext,
|
|
12
|
+
AgentToolError,
|
|
13
|
+
type AgentToolResult,
|
|
14
|
+
type AgentToolUpdateCallback,
|
|
14
15
|
} from "@f5-sales-demo/pi-agent-core";
|
|
15
16
|
import { StringEnum } from "@f5-sales-demo/pi-ai";
|
|
16
17
|
import { prompt } from "@f5-sales-demo/pi-utils";
|
|
@@ -185,13 +186,16 @@ function formatForLLM(response: SearchResponse): string {
|
|
|
185
186
|
async function executeSearch(
|
|
186
187
|
_toolCallId: string,
|
|
187
188
|
params: SearchQueryParams,
|
|
188
|
-
|
|
189
|
+
signal?: AbortSignal,
|
|
190
|
+
): Promise<{ content: Array<{ type: "text"; text: string }>; details: SearchRenderDetails; isError?: boolean }> {
|
|
191
|
+
signal?.throwIfAborted();
|
|
189
192
|
params = { ...params, user_location: normalizeUserLocation(params.user_location) };
|
|
190
193
|
const validation = validateWebSearchParams(params);
|
|
191
194
|
if (!validation.valid) {
|
|
192
195
|
const message = `web_search invalid parameter: ${validation.error}`;
|
|
193
196
|
return {
|
|
194
197
|
content: [{ type: "text" as const, text: `Error: ${message}` }],
|
|
198
|
+
isError: true,
|
|
195
199
|
details: { response: { provider: "none", sources: [] }, error: message },
|
|
196
200
|
};
|
|
197
201
|
}
|
|
@@ -209,6 +213,7 @@ async function executeSearch(
|
|
|
209
213
|
const message = "No web search provider configured.";
|
|
210
214
|
return {
|
|
211
215
|
content: [{ type: "text" as const, text: `Error: ${message}` }],
|
|
216
|
+
isError: true,
|
|
212
217
|
details: { response: { provider: "none", sources: [] }, error: message },
|
|
213
218
|
};
|
|
214
219
|
}
|
|
@@ -221,6 +226,7 @@ async function executeSearch(
|
|
|
221
226
|
try {
|
|
222
227
|
const searchStart = performance.now();
|
|
223
228
|
const response = await provider.search({
|
|
229
|
+
signal,
|
|
224
230
|
query: params.query.replace(/202\d/g, String(new Date().getFullYear())), // LUL
|
|
225
231
|
limit: params.limit,
|
|
226
232
|
recency: params.recency,
|
|
@@ -243,6 +249,11 @@ async function executeSearch(
|
|
|
243
249
|
details: { response },
|
|
244
250
|
};
|
|
245
251
|
} catch (error) {
|
|
252
|
+
if (
|
|
253
|
+
signal?.aborted ||
|
|
254
|
+
(error instanceof Error && (error.name === "AbortError" || error.name === "ToolAbortError"))
|
|
255
|
+
)
|
|
256
|
+
throw error;
|
|
246
257
|
lastError = error;
|
|
247
258
|
}
|
|
248
259
|
}
|
|
@@ -255,6 +266,7 @@ async function executeSearch(
|
|
|
255
266
|
|
|
256
267
|
return {
|
|
257
268
|
content: [{ type: "text" as const, text: `Error: ${message}` }],
|
|
269
|
+
isError: true,
|
|
258
270
|
details: { response: { provider: lastProvider.id, sources: [] }, error: message },
|
|
259
271
|
};
|
|
260
272
|
}
|
|
@@ -264,8 +276,9 @@ async function executeSearch(
|
|
|
264
276
|
*/
|
|
265
277
|
export async function runSearchQuery(
|
|
266
278
|
params: SearchQueryParams,
|
|
267
|
-
|
|
268
|
-
|
|
279
|
+
signal?: AbortSignal,
|
|
280
|
+
): Promise<{ content: Array<{ type: "text"; text: string }>; details: SearchRenderDetails; isError?: boolean }> {
|
|
281
|
+
return executeSearch("cli-web-search", params, signal);
|
|
269
282
|
}
|
|
270
283
|
|
|
271
284
|
/**
|
|
@@ -292,7 +305,9 @@ export class SearchTool implements AgentTool<typeof webSearchSchema, SearchRende
|
|
|
292
305
|
_onUpdate?: AgentToolUpdateCallback<SearchRenderDetails>,
|
|
293
306
|
_context?: AgentToolContext,
|
|
294
307
|
): Promise<AgentToolResult<SearchRenderDetails>> {
|
|
295
|
-
|
|
308
|
+
const result = await executeSearch(_toolCallId, params, _signal);
|
|
309
|
+
if (result.isError) throw new AgentToolError(result.details.error ?? "Web search failed", result);
|
|
310
|
+
return result;
|
|
296
311
|
}
|
|
297
312
|
}
|
|
298
313
|
|
|
@@ -310,7 +325,9 @@ export const webSearchCustomTool: CustomTool<typeof webSearchSchema, SearchRende
|
|
|
310
325
|
_ctx: CustomToolContext,
|
|
311
326
|
_signal?: AbortSignal,
|
|
312
327
|
) {
|
|
313
|
-
|
|
328
|
+
const result = await executeSearch(toolCallId, params, _signal);
|
|
329
|
+
if (result.isError) throw new AgentToolError(result.details.error ?? "Web search failed", result);
|
|
330
|
+
return result;
|
|
314
331
|
},
|
|
315
332
|
|
|
316
333
|
renderCall(args: SearchToolParams, options: RenderResultOptions, theme: Theme) {
|
|
@@ -227,6 +227,9 @@ function parseResponse(response: AnthropicApiResponse): SearchResponse {
|
|
|
227
227
|
searchQueries.push(block.input.query);
|
|
228
228
|
}
|
|
229
229
|
} else if (block.type === "web_search_tool_result" && block.content) {
|
|
230
|
+
if (!Array.isArray(block.content)) {
|
|
231
|
+
throw new SearchProviderError("anthropic", `Anthropic web search failed: ${block.content.error_code}`);
|
|
232
|
+
}
|
|
230
233
|
// Search results
|
|
231
234
|
for (const result of block.content) {
|
|
232
235
|
if (result.type === "web_search_result") {
|
package/src/web/search/types.ts
CHANGED
|
@@ -136,7 +136,7 @@ export interface AnthropicContentBlock {
|
|
|
136
136
|
/** Tool input (for type="server_tool_use") */
|
|
137
137
|
input?: { query: string };
|
|
138
138
|
/** Search results (for type="web_search_tool_result") */
|
|
139
|
-
content?: AnthropicSearchResult[];
|
|
139
|
+
content?: AnthropicSearchResult[] | { type: "web_search_tool_result_error"; error_code: string };
|
|
140
140
|
}
|
|
141
141
|
|
|
142
142
|
export interface AnthropicApiResponse {
|