@f5-sales-demo/xcsh 20.18.1 → 20.19.1
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/CHANGELOG.md +14 -0
- package/package.json +8 -8
- package/src/browser/chat-conformance.json +19 -1
- package/src/browser/chat-handler.ts +7 -9
- package/src/config/model-registry.ts +1 -38
- package/src/config/model-resolver.ts +20 -4
- package/src/config/settings-schema.ts +1 -2
- package/src/internal-urls/build-info.generated.ts +8 -8
- package/src/internal-urls/docs-index.generated.ts +2 -1
- package/src/map/render.ts +314 -0
- package/src/map/tile-cache.ts +130 -0
- package/src/map/types.ts +155 -0
- package/src/media/ingest.ts +51 -0
- package/src/media/publish.ts +48 -0
- package/src/media/tool-result.ts +22 -0
- package/src/media/transport.ts +3 -3
- package/src/media/types.ts +36 -1
- package/src/modes/acp/acp-event-mapper.ts +8 -3
- package/src/modes/controllers/login-model.ts +1 -11
- package/src/modes/controllers/selector-controller.ts +27 -2
- package/src/modes/rpc/rpc-mode.ts +12 -3
- package/src/prompts/tools/render-map.md +13 -0
- package/src/routing/presets.ts +0 -2
- package/src/routing/subscription-profiles.ts +1 -31
- package/src/sandbox/enforce.ts +1 -0
- package/src/tools/display-media-renderer.ts +8 -1
- package/src/tools/display-media.ts +3 -21
- package/src/tools/index.ts +3 -0
- package/src/tools/render-map.ts +247 -0
- package/src/tools/renderers.ts +1 -0
- package/src/web/search/provider.ts +0 -3
- package/src/web/search/types.ts +0 -2
- package/src/web/search/providers/codex.ts +0 -402
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,20 @@
|
|
|
2
2
|
|
|
3
3
|
# Changelog
|
|
4
4
|
|
|
5
|
+
## Unreleased
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- Added provenance-validated, deterministic `render_map` PNG generation with OpenStreetMap tile
|
|
10
|
+
policy compliance, schematic and text fallbacks, and optional atomic PNG/GeoJSON export
|
|
11
|
+
([#3202](https://github.com/f5-sales-demo/xcsh/issues/3202)).
|
|
12
|
+
|
|
13
|
+
### Changed
|
|
14
|
+
|
|
15
|
+
- Unified generated and existing media publication behind the versioned `xcsh.media/v1` result
|
|
16
|
+
contract so TUI, Browser, Office, RPC, and ACP transports no longer identify media by tool name
|
|
17
|
+
([#3202](https://github.com/f5-sales-demo/xcsh/issues/3202)).
|
|
18
|
+
|
|
5
19
|
## [20.6.3] - 2026-08-07
|
|
6
20
|
|
|
7
21
|
### Improved
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@f5-sales-demo/xcsh",
|
|
4
|
-
"version": "20.
|
|
4
|
+
"version": "20.19.1",
|
|
5
5
|
"description": "Coding agent CLI with read, bash, edit, write tools and session management",
|
|
6
6
|
"homepage": "https://github.com/f5-sales-demo/xcsh",
|
|
7
7
|
"author": "Can Boluk",
|
|
@@ -61,13 +61,13 @@
|
|
|
61
61
|
},
|
|
62
62
|
"dependencies": {
|
|
63
63
|
"@agentclientprotocol/sdk": "1.3.0",
|
|
64
|
-
"@f5-sales-demo/pi-agent-core": "20.
|
|
65
|
-
"@f5-sales-demo/pi-ai": "20.
|
|
66
|
-
"@f5-sales-demo/pi-natives": "20.
|
|
67
|
-
"@f5-sales-demo/pi-resource-management": "20.
|
|
68
|
-
"@f5-sales-demo/pi-tui": "20.
|
|
69
|
-
"@f5-sales-demo/pi-utils": "20.
|
|
70
|
-
"@f5-sales-demo/xcsh-stats": "20.
|
|
64
|
+
"@f5-sales-demo/pi-agent-core": "20.19.1",
|
|
65
|
+
"@f5-sales-demo/pi-ai": "20.19.1",
|
|
66
|
+
"@f5-sales-demo/pi-natives": "20.19.1",
|
|
67
|
+
"@f5-sales-demo/pi-resource-management": "20.19.1",
|
|
68
|
+
"@f5-sales-demo/pi-tui": "20.19.1",
|
|
69
|
+
"@f5-sales-demo/pi-utils": "20.19.1",
|
|
70
|
+
"@f5-sales-demo/xcsh-stats": "20.19.1",
|
|
71
71
|
"@mozilla/readability": "^0.6",
|
|
72
72
|
"@sinclair/typebox": "^0.34",
|
|
73
73
|
"@xterm/headless": "^6.0",
|
|
@@ -891,7 +891,8 @@
|
|
|
891
891
|
"const": "tool"
|
|
892
892
|
},
|
|
893
893
|
"source": {
|
|
894
|
-
"
|
|
894
|
+
"type": "string",
|
|
895
|
+
"pattern": "^[a-z][a-z0-9_]{0,63}$"
|
|
895
896
|
}
|
|
896
897
|
}
|
|
897
898
|
},
|
|
@@ -942,6 +943,23 @@
|
|
|
942
943
|
},
|
|
943
944
|
"degradation": {
|
|
944
945
|
"type": "string"
|
|
946
|
+
},
|
|
947
|
+
"filenameHint": {
|
|
948
|
+
"type": "string",
|
|
949
|
+
"minLength": 1,
|
|
950
|
+
"maxLength": 255,
|
|
951
|
+
"pattern": "^[^/\\\\]+$"
|
|
952
|
+
},
|
|
953
|
+
"metadata": {
|
|
954
|
+
"type": "object",
|
|
955
|
+
"maxProperties": 16,
|
|
956
|
+
"propertyNames": {
|
|
957
|
+
"pattern": "^[a-zA-Z0-9_.-]{1,64}$"
|
|
958
|
+
},
|
|
959
|
+
"additionalProperties": {
|
|
960
|
+
"type": "string",
|
|
961
|
+
"maxLength": 512
|
|
962
|
+
}
|
|
945
963
|
}
|
|
946
964
|
}
|
|
947
965
|
}
|
|
@@ -334,15 +334,13 @@ export class ChatHandler {
|
|
|
334
334
|
return;
|
|
335
335
|
}
|
|
336
336
|
if (event.type === "tool_execution_end" && "toolName" in event) {
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
} satisfies ChatMedia);
|
|
345
|
-
}
|
|
337
|
+
const descriptor = extractMediaDescriptorFromToolResult(event.result);
|
|
338
|
+
if (descriptor) {
|
|
339
|
+
this.#server.send({
|
|
340
|
+
type: "chat_media",
|
|
341
|
+
id: chat.id,
|
|
342
|
+
media: projectMediaDescriptorForTransport(descriptor),
|
|
343
|
+
} satisfies ChatMedia);
|
|
346
344
|
}
|
|
347
345
|
// ToolExecutionEndEvent carries `isError` (NOT `error`) — checking the wrong
|
|
348
346
|
// field made this always ok:true, so errored tools rendered ✓ and "failed"
|
|
@@ -16,7 +16,6 @@ import {
|
|
|
16
16
|
type ModelRefreshStrategy,
|
|
17
17
|
type OAuthCredentials,
|
|
18
18
|
type OAuthLoginCallbacks,
|
|
19
|
-
openaiCodexModelManagerOptions,
|
|
20
19
|
PROVIDER_DESCRIPTORS,
|
|
21
20
|
readModelCache,
|
|
22
21
|
registerCustomApi,
|
|
@@ -32,7 +31,7 @@ import { type ConfigError, ConfigFile } from "../config";
|
|
|
32
31
|
import { hasLiteLLMEnv, probeAndUpgradeLiteLLMConfig, startupHealthCheck } from "../config/auto-config";
|
|
33
32
|
import { parseModelString, resolveProviderModelReference } from "../config/model-resolver";
|
|
34
33
|
import { isValidThemeColor, type ThemeColor } from "../modes/theme/theme";
|
|
35
|
-
import type { AuthStorage
|
|
34
|
+
import type { AuthStorage } from "../session/auth-storage";
|
|
36
35
|
import {
|
|
37
36
|
buildCanonicalModelIndex,
|
|
38
37
|
type CanonicalModelIndex,
|
|
@@ -553,31 +552,6 @@ function extractGoogleOAuthToken(value: string | undefined): string | undefined
|
|
|
553
552
|
return value;
|
|
554
553
|
}
|
|
555
554
|
|
|
556
|
-
function getOAuthCredentialsForProvider(authStorage: AuthStorage, provider: string): OAuthCredential[] {
|
|
557
|
-
const providerEntry = authStorage.getAll()[provider];
|
|
558
|
-
if (!providerEntry) {
|
|
559
|
-
return [];
|
|
560
|
-
}
|
|
561
|
-
const entries = Array.isArray(providerEntry) ? providerEntry : [providerEntry];
|
|
562
|
-
return entries.filter((entry): entry is OAuthCredential => entry.type === "oauth");
|
|
563
|
-
}
|
|
564
|
-
|
|
565
|
-
function resolveOAuthAccountIdForAccessToken(
|
|
566
|
-
authStorage: AuthStorage,
|
|
567
|
-
provider: string,
|
|
568
|
-
accessToken: string,
|
|
569
|
-
): string | undefined {
|
|
570
|
-
const oauthCredentials = getOAuthCredentialsForProvider(authStorage, provider);
|
|
571
|
-
const matchingCredential = oauthCredentials.find(credential => credential.access === accessToken);
|
|
572
|
-
if (matchingCredential) {
|
|
573
|
-
return matchingCredential.accountId;
|
|
574
|
-
}
|
|
575
|
-
if (oauthCredentials.length === 1) {
|
|
576
|
-
return oauthCredentials[0].accountId;
|
|
577
|
-
}
|
|
578
|
-
return undefined;
|
|
579
|
-
}
|
|
580
|
-
|
|
581
555
|
function mergeCompat(
|
|
582
556
|
baseCompat: Model<Api>["compat"],
|
|
583
557
|
overrideCompat: ModelOverride["compat"],
|
|
@@ -1416,17 +1390,6 @@ export class ModelRegistry {
|
|
|
1416
1390
|
endpoint: this.getProviderBaseUrl("google-gemini-cli"),
|
|
1417
1391
|
}),
|
|
1418
1392
|
},
|
|
1419
|
-
{
|
|
1420
|
-
providerId: "openai-codex",
|
|
1421
|
-
resolveKey: value => value,
|
|
1422
|
-
createOptions: accessToken => {
|
|
1423
|
-
const accountId = resolveOAuthAccountIdForAccessToken(this.authStorage, "openai-codex", accessToken);
|
|
1424
|
-
return openaiCodexModelManagerOptions({
|
|
1425
|
-
accessToken,
|
|
1426
|
-
accountId,
|
|
1427
|
-
});
|
|
1428
|
-
},
|
|
1429
|
-
},
|
|
1430
1393
|
];
|
|
1431
1394
|
const peekKey = (descriptor: { providerId: string }) => this.#peekApiKeyForProvider(descriptor.providerId);
|
|
1432
1395
|
// Special providers discover entitlement-scoped models through OAuth. Refresh their
|
|
@@ -1049,6 +1049,9 @@ export interface InitialModelResult {
|
|
|
1049
1049
|
fallbackMessage: string | undefined;
|
|
1050
1050
|
}
|
|
1051
1051
|
|
|
1052
|
+
export const UNSUPPORTED_OPENAI_CODEX_RECOVERY =
|
|
1053
|
+
"Saved OpenAI Codex subscription configuration is unsupported in xcsh. Use the official codex CLI for ChatGPT subscription access, set OPENAI_API_KEY for usage-based OpenAI API access in xcsh, select another provider, or remove the disabled legacy credential with /logout openai-codex.";
|
|
1054
|
+
|
|
1052
1055
|
/**
|
|
1053
1056
|
* Find the initial model to use based on priority:
|
|
1054
1057
|
* 1. CLI args (provider + model)
|
|
@@ -1109,7 +1112,8 @@ export async function findInitialModel(options: {
|
|
|
1109
1112
|
}
|
|
1110
1113
|
|
|
1111
1114
|
// 3. Try saved default from settings
|
|
1112
|
-
|
|
1115
|
+
const hasUnsupportedOpenAICodexDefault = defaultProvider === "openai-codex";
|
|
1116
|
+
if (defaultProvider && defaultModelId && !hasUnsupportedOpenAICodexDefault) {
|
|
1113
1117
|
const found = modelRegistry.find(defaultProvider, defaultModelId);
|
|
1114
1118
|
if (found) {
|
|
1115
1119
|
model = found;
|
|
@@ -1127,16 +1131,28 @@ export async function findInitialModel(options: {
|
|
|
1127
1131
|
const defaultId = defaultModelPerProvider[provider];
|
|
1128
1132
|
const match = availableModels.find(m => m.provider === provider && m.id === defaultId);
|
|
1129
1133
|
if (match) {
|
|
1130
|
-
return {
|
|
1134
|
+
return {
|
|
1135
|
+
model: match,
|
|
1136
|
+
thinkingLevel: undefined,
|
|
1137
|
+
fallbackMessage: hasUnsupportedOpenAICodexDefault ? UNSUPPORTED_OPENAI_CODEX_RECOVERY : undefined,
|
|
1138
|
+
};
|
|
1131
1139
|
}
|
|
1132
1140
|
}
|
|
1133
1141
|
|
|
1134
1142
|
// If no default found, use first available
|
|
1135
|
-
return {
|
|
1143
|
+
return {
|
|
1144
|
+
model: availableModels[0],
|
|
1145
|
+
thinkingLevel: undefined,
|
|
1146
|
+
fallbackMessage: hasUnsupportedOpenAICodexDefault ? UNSUPPORTED_OPENAI_CODEX_RECOVERY : undefined,
|
|
1147
|
+
};
|
|
1136
1148
|
}
|
|
1137
1149
|
|
|
1138
1150
|
// 5. No model found
|
|
1139
|
-
return {
|
|
1151
|
+
return {
|
|
1152
|
+
model: undefined,
|
|
1153
|
+
thinkingLevel: undefined,
|
|
1154
|
+
fallbackMessage: hasUnsupportedOpenAICodexDefault ? UNSUPPORTED_OPENAI_CODEX_RECOVERY : undefined,
|
|
1155
|
+
};
|
|
1140
1156
|
}
|
|
1141
1157
|
|
|
1142
1158
|
/**
|
|
@@ -564,7 +564,7 @@ export const SETTINGS_SCHEMA = {
|
|
|
564
564
|
|
|
565
565
|
"routing.profile": {
|
|
566
566
|
type: "enum",
|
|
567
|
-
values: ["none", "google-antigravity"
|
|
567
|
+
values: ["none", "google-antigravity"] as const,
|
|
568
568
|
default: "none",
|
|
569
569
|
ui: {
|
|
570
570
|
tab: "model",
|
|
@@ -1988,7 +1988,6 @@ export const SETTINGS_SCHEMA = {
|
|
|
1988
1988
|
"perplexity",
|
|
1989
1989
|
"anthropic",
|
|
1990
1990
|
"gemini",
|
|
1991
|
-
"codex",
|
|
1992
1991
|
"tavily",
|
|
1993
1992
|
"kagi",
|
|
1994
1993
|
"synthetic",
|
|
@@ -17,17 +17,17 @@ export interface BuildInfo {
|
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
export const BUILD_INFO: BuildInfo = {
|
|
20
|
-
"version": "20.
|
|
21
|
-
"commit": "
|
|
22
|
-
"shortCommit": "
|
|
20
|
+
"version": "20.19.1",
|
|
21
|
+
"commit": "85fec653171dd194403a9444e937285f47f5227b",
|
|
22
|
+
"shortCommit": "85fec65",
|
|
23
23
|
"branch": "main",
|
|
24
|
-
"tag": "v20.
|
|
25
|
-
"commitDate": "2026-08-
|
|
26
|
-
"buildDate": "2026-08-
|
|
24
|
+
"tag": "v20.19.1",
|
|
25
|
+
"commitDate": "2026-08-15T22:14:41Z",
|
|
26
|
+
"buildDate": "2026-08-15T22:42:30.318Z",
|
|
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/v20.
|
|
31
|
+
"commitUrl": "https://github.com/f5-sales-demo/xcsh/commit/85fec653171dd194403a9444e937285f47f5227b",
|
|
32
|
+
"releaseUrl": "https://github.com/f5-sales-demo/xcsh/releases/tag/v20.19.1"
|
|
33
33
|
};
|