shortcutxl 0.3.75 → 0.3.76
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/BINARY-INVENTORY.json +9 -9
- package/CHANGELOG.md +4 -0
- package/dist/ai/models.d.ts +1 -1
- package/dist/ai/models.js +2 -2
- package/dist/ai/providers/anthropic.js +4 -4
- package/dist/ai/providers/google-shared.d.ts +2 -0
- package/dist/ai/providers/google-shared.js +6 -0
- package/dist/ai/providers/google-vertex.js +3 -9
- package/dist/ai/providers/google.js +3 -9
- package/dist/ai/providers/provider-error-normalization.js +47 -20
- package/dist/app/agent-session.js +2 -0
- package/dist/app/providers/model-resolver.js +4 -4
- package/dist/app/session/run-agent-observability.d.ts +2 -0
- package/dist/app/session/run-agent-observability.js +1 -0
- package/dist/app/session/session-models.js +2 -2
- package/dist/app/subagents/defaults.d.ts +1 -1
- package/dist/app/subagents/defaults.js +1 -4
- package/dist/app/tools/cron.js +3 -2
- package/dist/app/tools/llm-analysis.js +9 -4
- package/dist/app/tools/refresh-context.js +1 -1
- package/dist/app/tools/take-screenshot.js +2 -1
- package/dist/app/tools/task/task.js +1 -1
- package/dist/cli/list-models.js +2 -1
- package/dist/cli.js +1542 -1385
- package/dist/contracts/agent-failure.d.ts +4 -0
- package/dist/contracts/agent-failure.js +2 -0
- package/dist/contracts/model-call.d.ts +4 -1
- package/dist/contracts/model-stream.d.ts +29 -1
- package/dist/contracts/model-stream.js +86 -0
- package/dist/core/agent-loop.js +2 -5
- package/dist/core/error-classification.js +35 -30
- package/dist/core/prompts/agent-guidelines.d.ts +1 -1
- package/dist/core/prompts/agent-guidelines.js +1 -1
- package/dist/core/run-failure.js +38 -6
- package/dist/core/session/session-error-recovery.js +8 -3
- package/dist/embedded-agent/anthropic-messages-transport.js +60 -140
- package/dist/embedded-agent/google-vertex-transport.js +14 -81
- package/dist/embedded-agent/host-tools/execute-code/raw-sdk-patterns.json +1 -3
- package/dist/embedded-agent/host-tools/sandbox-llm/contract.d.ts +2 -0
- package/dist/embedded-agent/host-tools/sandbox-llm/contract.js +10 -3
- package/dist/embedded-agent/host-tools/sandbox-llm/index.d.ts +1 -1
- package/dist/embedded-agent/host-tools/sandbox-llm/index.js +1 -1
- package/dist/embedded-agent/host-tools/take-screenshot/contract.d.ts +2 -0
- package/dist/embedded-agent/host-tools/take-screenshot/contract.js +5 -2
- package/dist/embedded-agent/host-tools/take-screenshot/index.d.ts +1 -1
- package/dist/embedded-agent/host-tools/take-screenshot/index.js +1 -1
- package/dist/embedded-agent/host-tools/task/contract.d.ts +3 -6
- package/dist/embedded-agent/host-tools/task/contract.js +5 -8
- package/dist/embedded-agent/model-registry.d.ts +1 -0
- package/dist/embedded-agent/model-registry.js +1 -0
- package/dist/embedded-agent/openai-completions-transport.js +4 -70
- package/dist/embedded-agent/openai-responses-transport.js +4 -70
- package/dist/embedded-agent/provider-fast-mode.js +6 -1
- package/dist/embedded-agent/stream.js +7 -6
- package/dist/embedded-agent/transport-errors.d.ts +25 -0
- package/dist/embedded-agent/transport-errors.js +107 -0
- package/dist/embedded-agent/worker-bridge/host-client.js +17 -2
- package/dist/main.js +8 -4
- package/dist/model-ids.d.ts +4 -0
- package/dist/model-ids.js +7 -1
- package/dist/rpc/rpc-types.d.ts +1 -2
- package/dist/shell/theme/theme-schema.json +1 -1
- package/dist/shell/tools/presentation/registry.js +2 -1
- package/dist/shell/tools/presentation/renderers/task.d.ts +2 -2
- package/dist/shell/tools/presentation/renderers/task.js +2 -2
- package/dist/shortcut-model-catalog.js +27 -0
- package/native-app/package.json +1 -1
- package/package.json +3 -3
- package/user-docs/dist/shortcutxl-docs.pdf +0 -0
- package/xll/ShortcutXL.xll +0 -0
- package/xll/python/Lib/site-packages/certifi/__init__.py +1 -1
- package/xll/python/Lib/site-packages/certifi/cacert.pem +125 -29
- package/xll/python/Lib/site-packages/certifi/tests/__init__.py +0 -0
- package/xll/python/Lib/site-packages/certifi/tests/test_certify.py +18 -0
- package/xll/python/Lib/site-packages/{certifi-2026.6.17.dist-info → certifi-2026.7.22.dist-info}/METADATA +1 -1
- package/xll/python/Lib/site-packages/certifi-2026.7.22.dist-info/RECORD +18 -0
- package/xll/python/Lib/site-packages/{certifi-2026.6.17.dist-info → certifi-2026.7.22.dist-info}/WHEEL +1 -1
- package/xll/python/Lib/site-packages/httpx-0.28.1.dist-info/RECORD +1 -1
- package/xll/python/Lib/site-packages/idna-3.18.dist-info/RECORD +1 -1
- package/xll/python/Lib/site-packages/pip-26.1.2.dist-info/RECORD +3 -3
- package/xll/python/Lib/site-packages/pywin32-311.dist-info/RECORD +2 -2
- package/xll/python/Scripts/httpx.exe +0 -0
- package/xll/python/Scripts/idna.exe +0 -0
- package/xll/python/Scripts/pip.exe +0 -0
- package/xll/python/Scripts/pip3.13.exe +0 -0
- package/xll/python/Scripts/pip3.exe +0 -0
- package/xll/python/Scripts/pywin32_postinstall.exe +0 -0
- package/xll/python/Scripts/pywin32_testall.exe +0 -0
- package/xll/python/Lib/site-packages/certifi-2026.6.17.dist-info/RECORD +0 -14
- /package/xll/python/Lib/site-packages/{certifi-2026.6.17.dist-info → certifi-2026.7.22.dist-info}/INSTALLER +0 -0
- /package/xll/python/Lib/site-packages/{certifi-2026.6.17.dist-info → certifi-2026.7.22.dist-info}/licenses/LICENSE +0 -0
- /package/xll/python/Lib/site-packages/{certifi-2026.6.17.dist-info → certifi-2026.7.22.dist-info}/top_level.txt +0 -0
package/BINARY-INVENTORY.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
|
-
"generatedAt": "2026-07-
|
|
3
|
+
"generatedAt": "2026-07-27T04:35:44.825Z",
|
|
4
4
|
"package": "shortcutxl",
|
|
5
5
|
"binaryExtensions": [
|
|
6
6
|
".dll",
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"files": [
|
|
12
12
|
{
|
|
13
13
|
"path": "xll/ShortcutXL.xll",
|
|
14
|
-
"sha256": "
|
|
14
|
+
"sha256": "f0d06082d5296e5737b9e4416a62942d22afd1780c27c84304bb5b11b0ba1c8a",
|
|
15
15
|
"source": "ShortcutXL native XLL build",
|
|
16
16
|
"version": "package",
|
|
17
17
|
"builtBy": "shortcut",
|
|
@@ -523,7 +523,7 @@
|
|
|
523
523
|
},
|
|
524
524
|
{
|
|
525
525
|
"path": "xll/python/Scripts/httpx.exe",
|
|
526
|
-
"sha256": "
|
|
526
|
+
"sha256": "27001c85dbe85fa448ba575c9b41295349f72b8bcfe2e0805748bebe8ccc9888",
|
|
527
527
|
"source": "httpx console launcher installed into embedded Python",
|
|
528
528
|
"version": "see packaged httpx distribution",
|
|
529
529
|
"builtBy": "third-party",
|
|
@@ -531,7 +531,7 @@
|
|
|
531
531
|
},
|
|
532
532
|
{
|
|
533
533
|
"path": "xll/python/Scripts/idna.exe",
|
|
534
|
-
"sha256": "
|
|
534
|
+
"sha256": "9f01a7efccc9917f3ed7e7a41b950b8734be8c844db5a6b78014188ddb2255da",
|
|
535
535
|
"source": "Python package console launcher installed into embedded Python",
|
|
536
536
|
"version": "see owning Python package metadata in site-packages",
|
|
537
537
|
"builtBy": "third-party",
|
|
@@ -539,7 +539,7 @@
|
|
|
539
539
|
},
|
|
540
540
|
{
|
|
541
541
|
"path": "xll/python/Scripts/pip.exe",
|
|
542
|
-
"sha256": "
|
|
542
|
+
"sha256": "8296d812e172cc359b23905d4a424185e80a9ab470770c8a247fb033b0c12554",
|
|
543
543
|
"source": "pip console launcher installed into embedded Python",
|
|
544
544
|
"version": "see packaged pip distribution",
|
|
545
545
|
"builtBy": "third-party",
|
|
@@ -547,7 +547,7 @@
|
|
|
547
547
|
},
|
|
548
548
|
{
|
|
549
549
|
"path": "xll/python/Scripts/pip3.13.exe",
|
|
550
|
-
"sha256": "
|
|
550
|
+
"sha256": "8296d812e172cc359b23905d4a424185e80a9ab470770c8a247fb033b0c12554",
|
|
551
551
|
"source": "pip console launcher installed into embedded Python",
|
|
552
552
|
"version": "see packaged pip distribution",
|
|
553
553
|
"builtBy": "third-party",
|
|
@@ -555,7 +555,7 @@
|
|
|
555
555
|
},
|
|
556
556
|
{
|
|
557
557
|
"path": "xll/python/Scripts/pip3.exe",
|
|
558
|
-
"sha256": "
|
|
558
|
+
"sha256": "8296d812e172cc359b23905d4a424185e80a9ab470770c8a247fb033b0c12554",
|
|
559
559
|
"source": "pip console launcher installed into embedded Python",
|
|
560
560
|
"version": "see packaged pip distribution",
|
|
561
561
|
"builtBy": "third-party",
|
|
@@ -563,7 +563,7 @@
|
|
|
563
563
|
},
|
|
564
564
|
{
|
|
565
565
|
"path": "xll/python/Scripts/pywin32_postinstall.exe",
|
|
566
|
-
"sha256": "
|
|
566
|
+
"sha256": "72dfdcd5711cf7093921eb0da7c196f308b5a75471a124039401eed472b87547",
|
|
567
567
|
"source": "Python package console launcher installed into embedded Python",
|
|
568
568
|
"version": "see owning Python package metadata in site-packages",
|
|
569
569
|
"builtBy": "third-party",
|
|
@@ -571,7 +571,7 @@
|
|
|
571
571
|
},
|
|
572
572
|
{
|
|
573
573
|
"path": "xll/python/Scripts/pywin32_testall.exe",
|
|
574
|
-
"sha256": "
|
|
574
|
+
"sha256": "8201c25e4d02041af95225057a08873831cb343767d1660cab9bc0891da1114b",
|
|
575
575
|
"source": "Python package console launcher installed into embedded Python",
|
|
576
576
|
"version": "see owning Python package metadata in site-packages",
|
|
577
577
|
"builtBy": "third-party",
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.3.76]
|
|
4
|
+
|
|
5
|
+
- **Claude Opus 5** - Claude Opus 5 is now available as ShortcutXL's high-accuracy Opus option.
|
|
6
|
+
|
|
3
7
|
## [0.3.75]
|
|
4
8
|
|
|
5
9
|
- **Native desktop app** - Run `shortcut app` for a multi-session desktop experience with tools, approvals, subagents, attachments, skills, themes, and account controls.
|
package/dist/ai/models.d.ts
CHANGED
|
@@ -12,7 +12,7 @@ export declare function calculateCost<TApi extends Api>(model: Model<TApi>, usag
|
|
|
12
12
|
*
|
|
13
13
|
* Supported today:
|
|
14
14
|
* - Shortcut's current and legacy OpenAI reasoning models
|
|
15
|
-
* - Anthropic Messages API Opus
|
|
15
|
+
* - Anthropic Messages API Opus models (xhigh maps to adaptive effort "max")
|
|
16
16
|
*/
|
|
17
17
|
export declare function supportsXhigh<TApi extends Api>(model: Model<TApi>): boolean;
|
|
18
18
|
/**
|
package/dist/ai/models.js
CHANGED
|
@@ -37,7 +37,7 @@ export function calculateCost(model, usage) {
|
|
|
37
37
|
*
|
|
38
38
|
* Supported today:
|
|
39
39
|
* - Shortcut's current and legacy OpenAI reasoning models
|
|
40
|
-
* - Anthropic Messages API Opus
|
|
40
|
+
* - Anthropic Messages API Opus models (xhigh maps to adaptive effort "max")
|
|
41
41
|
*/
|
|
42
42
|
export function supportsXhigh(model) {
|
|
43
43
|
const modelId = model.id.startsWith('openai/') ? model.id.slice('openai/'.length) : model.id;
|
|
@@ -45,7 +45,7 @@ export function supportsXhigh(model) {
|
|
|
45
45
|
return true;
|
|
46
46
|
}
|
|
47
47
|
if (model.api === 'anthropic-messages') {
|
|
48
|
-
return model.id.
|
|
48
|
+
return model.id.toLowerCase().includes('opus');
|
|
49
49
|
}
|
|
50
50
|
return false;
|
|
51
51
|
}
|
|
@@ -379,7 +379,7 @@ export const streamAnthropic = (model, context, options) => {
|
|
|
379
379
|
* tolerated. These are the only Claude Opus/Sonnet/Fable models still served;
|
|
380
380
|
* older budget-based models have been retired.
|
|
381
381
|
*/
|
|
382
|
-
const ADAPTIVE_THINKING_MODELS = ['opus-4-8', 'sonnet-5', 'fable-5'];
|
|
382
|
+
const ADAPTIVE_THINKING_MODELS = ['opus-5', 'opus-4-8', 'sonnet-5', 'fable-5'];
|
|
383
383
|
/** Check if a model uses adaptive thinking. */
|
|
384
384
|
function supportsAdaptiveThinking(modelId) {
|
|
385
385
|
const normalized = modelId.toLowerCase();
|
|
@@ -419,8 +419,8 @@ export const streamSimpleAnthropic = (model, context, options) => {
|
|
|
419
419
|
thinkingEnabled: false
|
|
420
420
|
});
|
|
421
421
|
}
|
|
422
|
-
//
|
|
423
|
-
//
|
|
422
|
+
// Current served Claude models use adaptive thinking with an effort level.
|
|
423
|
+
// Older models use budget-based thinking.
|
|
424
424
|
if (supportsAdaptiveThinking(model.id)) {
|
|
425
425
|
const effort = mapThinkingLevelToEffort(options.reasoning, model.id);
|
|
426
426
|
return streamAnthropic(model, context, {
|
|
@@ -488,7 +488,7 @@ function buildParams(model, context, options) {
|
|
|
488
488
|
if (context.tools) {
|
|
489
489
|
params.tools = convertTools(context.tools);
|
|
490
490
|
}
|
|
491
|
-
// Configure
|
|
491
|
+
// Configure adaptive thinking for current models or budget-based thinking for older models.
|
|
492
492
|
if (options?.thinkingEnabled && model.reasoning) {
|
|
493
493
|
if (supportsAdaptiveThinking(model.id)) {
|
|
494
494
|
// Adaptive thinking: Claude decides when and how much to think
|
|
@@ -38,6 +38,8 @@ export declare function retainThoughtSignature(existing: string | undefined, inc
|
|
|
38
38
|
* Models via Google APIs that require explicit tool call IDs in function calls/responses.
|
|
39
39
|
*/
|
|
40
40
|
export declare function requiresToolCallId(modelId: string): boolean;
|
|
41
|
+
export declare function isGemini3FlashModelId(modelId: string): boolean;
|
|
42
|
+
export declare function isGemini3ProModelId(modelId: string): boolean;
|
|
41
43
|
/**
|
|
42
44
|
* Convert internal messages to Gemini Content[] format.
|
|
43
45
|
*/
|
|
@@ -57,6 +57,12 @@ function resolveThoughtSignature(isSameProviderAndModel, signature) {
|
|
|
57
57
|
export function requiresToolCallId(modelId) {
|
|
58
58
|
return modelId.startsWith('claude-') || modelId.startsWith('gpt-oss-');
|
|
59
59
|
}
|
|
60
|
+
export function isGemini3FlashModelId(modelId) {
|
|
61
|
+
return /^gemini-3(?:\.\d+)?-flash(?:-|$)/.test(modelId);
|
|
62
|
+
}
|
|
63
|
+
export function isGemini3ProModelId(modelId) {
|
|
64
|
+
return /^gemini-3(?:\.\d+)?-pro(?:-|$)/.test(modelId);
|
|
65
|
+
}
|
|
60
66
|
/**
|
|
61
67
|
* Convert internal messages to Gemini Content[] format.
|
|
62
68
|
*/
|
|
@@ -2,7 +2,7 @@ import { GoogleGenAI, ThinkingLevel } from '@google/genai';
|
|
|
2
2
|
import { calculateCost } from '../models.js';
|
|
3
3
|
import { AssistantMessageEventStream } from '../utils/event-stream.js';
|
|
4
4
|
import { sanitizeSurrogates } from '../utils/sanitize-unicode.js';
|
|
5
|
-
import { convertMessages, convertTools, isThinkingPart, mapStopReason, mapToolChoice, retainThoughtSignature } from './google-shared.js';
|
|
5
|
+
import { convertMessages, convertTools, isGemini3FlashModelId, isGemini3ProModelId, isThinkingPart, mapStopReason, mapToolChoice, retainThoughtSignature } from './google-shared.js';
|
|
6
6
|
import { buildBaseOptions, clampReasoning } from './simple-options.js';
|
|
7
7
|
const API_VERSION = 'v1';
|
|
8
8
|
const THINKING_LEVEL_MAP = {
|
|
@@ -235,7 +235,7 @@ export const streamSimpleGoogleVertex = (model, context, options) => {
|
|
|
235
235
|
}
|
|
236
236
|
const effort = clampReasoning(options.reasoning);
|
|
237
237
|
const geminiModel = model;
|
|
238
|
-
if (
|
|
238
|
+
if (isGemini3ProModelId(geminiModel.id) || isGemini3FlashModelId(geminiModel.id)) {
|
|
239
239
|
return streamGoogleVertex(model, context, {
|
|
240
240
|
...base,
|
|
241
241
|
thinking: {
|
|
@@ -327,14 +327,8 @@ function buildParams(model, context, options = {}) {
|
|
|
327
327
|
};
|
|
328
328
|
return params;
|
|
329
329
|
}
|
|
330
|
-
function isGemini3ProModel(model) {
|
|
331
|
-
return model.id.includes('3-pro');
|
|
332
|
-
}
|
|
333
|
-
function isGemini3FlashModel(model) {
|
|
334
|
-
return model.id.includes('3-flash');
|
|
335
|
-
}
|
|
336
330
|
function getGemini3ThinkingLevel(effort, model) {
|
|
337
|
-
if (
|
|
331
|
+
if (isGemini3ProModelId(model.id)) {
|
|
338
332
|
switch (effort) {
|
|
339
333
|
case 'minimal':
|
|
340
334
|
case 'low':
|
|
@@ -3,7 +3,7 @@ import { getEnvApiKey } from '../env-api-keys.js';
|
|
|
3
3
|
import { calculateCost } from '../models.js';
|
|
4
4
|
import { AssistantMessageEventStream } from '../utils/event-stream.js';
|
|
5
5
|
import { sanitizeSurrogates } from '../utils/sanitize-unicode.js';
|
|
6
|
-
import { convertMessages, convertTools, isThinkingPart, mapStopReason, mapToolChoice, retainThoughtSignature } from './google-shared.js';
|
|
6
|
+
import { convertMessages, convertTools, isGemini3FlashModelId, isGemini3ProModelId, isThinkingPart, mapStopReason, mapToolChoice, retainThoughtSignature } from './google-shared.js';
|
|
7
7
|
import { buildBaseOptions, clampReasoning } from './simple-options.js';
|
|
8
8
|
// Counter for generating unique tool call IDs
|
|
9
9
|
let toolCallCounter = 0;
|
|
@@ -232,7 +232,7 @@ export const streamSimpleGoogle = (model, context, options) => {
|
|
|
232
232
|
}
|
|
233
233
|
const effort = clampReasoning(options.reasoning);
|
|
234
234
|
const googleModel = model;
|
|
235
|
-
if (
|
|
235
|
+
if (isGemini3ProModelId(googleModel.id) || isGemini3FlashModelId(googleModel.id)) {
|
|
236
236
|
return streamGoogle(model, context, {
|
|
237
237
|
...base,
|
|
238
238
|
thinking: {
|
|
@@ -311,14 +311,8 @@ function buildParams(model, context, options = {}) {
|
|
|
311
311
|
};
|
|
312
312
|
return params;
|
|
313
313
|
}
|
|
314
|
-
function isGemini3ProModel(model) {
|
|
315
|
-
return model.id.includes('3-pro');
|
|
316
|
-
}
|
|
317
|
-
function isGemini3FlashModel(model) {
|
|
318
|
-
return model.id.includes('3-flash');
|
|
319
|
-
}
|
|
320
314
|
function getGemini3ThinkingLevel(effort, model) {
|
|
321
|
-
if (
|
|
315
|
+
if (isGemini3ProModelId(model.id)) {
|
|
322
316
|
switch (effort) {
|
|
323
317
|
case 'minimal':
|
|
324
318
|
case 'low':
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { APIConnectionError as AnthropicAPIConnectionError } from '@anthropic-ai/sdk';
|
|
2
|
+
import { APIConnectionError as OpenAIAPIConnectionError } from 'openai';
|
|
3
|
+
import { applyModelAccessDeniedErrorDetails, LLMErrorMetadataHeaders, modelStreamErrorDetailsFromThrown, networkErrorDetails, parseStreamErrorPayload, providerErrorDetailsFromRawType, safeModelStreamErrorMessage, ShortcutXLModelStreamFetchStage } from '../../contracts/model-stream.js';
|
|
2
4
|
import { isContextOverflowErrorMessage } from '../utils/overflow.js';
|
|
3
5
|
function getErrorMessage(error) {
|
|
4
6
|
return error instanceof Error ? error.message : (JSON.stringify(error) ?? String(error));
|
|
@@ -22,32 +24,57 @@ function apiV2PayloadFromHeaders(headers) {
|
|
|
22
24
|
};
|
|
23
25
|
return Object.values(payload).some((value) => value !== undefined) ? payload : undefined;
|
|
24
26
|
}
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
/**
|
|
28
|
+
* Classify an SDK-thrown error from what the provider itself reported.
|
|
29
|
+
* Anthropic's `APIError` carries the error type as `.type` (in-stream error
|
|
30
|
+
* events) or `.error.error.type`; OpenAI's as `.error.type` / `.code`. SDK
|
|
31
|
+
* connection failures (fetch rejected before an HTTP response) classify as
|
|
32
|
+
* network errors.
|
|
33
|
+
*/
|
|
34
|
+
function sdkErrorDetails(error) {
|
|
35
|
+
if (error instanceof AnthropicAPIConnectionError || error instanceof OpenAIAPIConnectionError) {
|
|
36
|
+
return networkErrorDetails(ShortcutXLModelStreamFetchStage.BeforeResponse);
|
|
37
|
+
}
|
|
38
|
+
const candidates = [
|
|
39
|
+
error.type,
|
|
40
|
+
error.error?.error?.type,
|
|
41
|
+
error.error?.type,
|
|
42
|
+
error.code,
|
|
43
|
+
error.error?.code
|
|
44
|
+
];
|
|
45
|
+
for (const raw of candidates) {
|
|
46
|
+
if (typeof raw !== 'string')
|
|
47
|
+
continue;
|
|
48
|
+
const details = providerErrorDetailsFromRawType(raw);
|
|
49
|
+
if (details)
|
|
50
|
+
return details;
|
|
51
|
+
}
|
|
52
|
+
return undefined;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Build normalized details for an SDK-thrown error by merging what the
|
|
56
|
+
* provider reported on the error itself with the api-v2 gateway's metadata
|
|
57
|
+
* headers. Header values win: the gateway sets `X-LLM-Provider-Error-Type`
|
|
58
|
+
* deliberately on HTTP failures, and a real HTTP `status` beats the synthetic
|
|
59
|
+
* one the raw-type mapping supplies.
|
|
60
|
+
*/
|
|
61
|
+
function normalizedSdkErrorDetails(error, rawMessage) {
|
|
29
62
|
const status = typeof error.status === 'number' ? error.status : undefined;
|
|
30
|
-
const
|
|
31
|
-
|
|
63
|
+
const classified = sdkErrorDetails(error);
|
|
64
|
+
const headerDetails = parseStreamErrorPayload(apiV2PayloadFromHeaders(error.headers), status);
|
|
65
|
+
if (!classified && !headerDetails)
|
|
32
66
|
return undefined;
|
|
33
|
-
const
|
|
67
|
+
const merged = { ...classified, ...headerDetails };
|
|
68
|
+
const accessAware = applyModelAccessDeniedErrorDetails(merged, rawMessage);
|
|
34
69
|
if (isContextOverflowErrorMessage(rawMessage)) {
|
|
35
|
-
return { ...
|
|
70
|
+
return { ...accessAware, code: 'context_overflow' };
|
|
36
71
|
}
|
|
37
|
-
return
|
|
38
|
-
}
|
|
39
|
-
function streamDetailsFromError(error) {
|
|
40
|
-
const detailsError = error;
|
|
41
|
-
if (isShortcutXLModelStreamErrorDetails(detailsError.details))
|
|
42
|
-
return detailsError.details;
|
|
43
|
-
if (isShortcutXLModelStreamErrorDetails(detailsError.errorDetails))
|
|
44
|
-
return detailsError.errorDetails;
|
|
45
|
-
return undefined;
|
|
72
|
+
return accessAware;
|
|
46
73
|
}
|
|
47
74
|
export function applyNormalizedProviderError(output, error) {
|
|
48
75
|
const rawMessage = getErrorMessage(error);
|
|
49
|
-
const details =
|
|
50
|
-
|
|
76
|
+
const details = modelStreamErrorDetailsFromThrown(error) ??
|
|
77
|
+
normalizedSdkErrorDetails(error, rawMessage);
|
|
51
78
|
if (!details) {
|
|
52
79
|
output.errorMessage = rawMessage;
|
|
53
80
|
return { usedStructuredDetails: false };
|
|
@@ -371,6 +371,7 @@ export class AgentSession {
|
|
|
371
371
|
charCount: deliveredContent.charCount,
|
|
372
372
|
imageCount: deliveredContent.imageCount,
|
|
373
373
|
conversationId,
|
|
374
|
+
modelName: this.agent.state.model?.id,
|
|
374
375
|
userMessageId
|
|
375
376
|
})),
|
|
376
377
|
conversationId,
|
|
@@ -979,6 +980,7 @@ export class AgentSession {
|
|
|
979
980
|
imageCount: currentImages?.length ?? 0,
|
|
980
981
|
conversationId: this.sessionManager.getSessionId(),
|
|
981
982
|
workbookDetails,
|
|
983
|
+
modelName: this.agent.state.model?.id,
|
|
982
984
|
userMessageId
|
|
983
985
|
});
|
|
984
986
|
this._pendingImmediateRunAgentMetadata = promptMetadata;
|
|
@@ -37,13 +37,13 @@ export function resolveExactModelRef(availableModels, requested) {
|
|
|
37
37
|
/** Default model IDs for each provider with a preferred initial model. */
|
|
38
38
|
export const defaultModelPerProvider = {
|
|
39
39
|
[SHORTCUT_PROVIDER_ID]: SHORTCUT_OPENAI_MODEL_ID,
|
|
40
|
-
anthropic: SHORTCUT_MODEL_ID.
|
|
40
|
+
anthropic: SHORTCUT_MODEL_ID.ClaudeOpus5,
|
|
41
41
|
openai: SHORTCUT_OPENAI_MODEL_ID,
|
|
42
42
|
'azure-openai-responses': SHORTCUT_OPENAI_MODEL_ID,
|
|
43
43
|
google: 'gemini-2.5-pro',
|
|
44
44
|
'google-vertex': 'gemini-3-pro-preview',
|
|
45
45
|
openrouter: `openai/${SHORTCUT_OPENAI_MODEL_ID}`,
|
|
46
|
-
'vercel-ai-gateway': 'anthropic/claude-opus-
|
|
46
|
+
'vercel-ai-gateway': 'anthropic/claude-opus-5',
|
|
47
47
|
xai: 'grok-4-fast-non-reasoning',
|
|
48
48
|
groq: 'openai/gpt-oss-120b',
|
|
49
49
|
cerebras: 'zai-glm-4.6',
|
|
@@ -51,7 +51,7 @@ export const defaultModelPerProvider = {
|
|
|
51
51
|
minimax: 'MiniMax-M2.1',
|
|
52
52
|
'minimax-cn': 'MiniMax-M2.1',
|
|
53
53
|
huggingface: 'moonshotai/Kimi-K2.5',
|
|
54
|
-
opencode: SHORTCUT_MODEL_ID.
|
|
54
|
+
opencode: SHORTCUT_MODEL_ID.ClaudeOpus5,
|
|
55
55
|
'kimi-coding': 'kimi-k2-thinking'
|
|
56
56
|
};
|
|
57
57
|
function getDefaultModelCandidatesForProvider(provider) {
|
|
@@ -59,7 +59,7 @@ function getDefaultModelCandidatesForProvider(provider) {
|
|
|
59
59
|
return [
|
|
60
60
|
SHORTCUT_OPENAI_MODEL_ID,
|
|
61
61
|
SHORTCUT_MODEL_ID.ClaudeFable5,
|
|
62
|
-
SHORTCUT_MODEL_ID.
|
|
62
|
+
SHORTCUT_MODEL_ID.ClaudeOpus5
|
|
63
63
|
];
|
|
64
64
|
}
|
|
65
65
|
return [defaultModelPerProvider[provider]].filter((modelId) => !!modelId);
|
|
@@ -8,6 +8,7 @@ export type RunAgentMetadata = {
|
|
|
8
8
|
has_workbook_context: boolean;
|
|
9
9
|
workbook_count: number;
|
|
10
10
|
workbook_scope_mode: string | undefined;
|
|
11
|
+
modelName?: string;
|
|
11
12
|
user_message_id?: string;
|
|
12
13
|
turnId?: string;
|
|
13
14
|
};
|
|
@@ -31,6 +32,7 @@ export declare function buildRunAgentMetadata(options: {
|
|
|
31
32
|
workbooks?: string[];
|
|
32
33
|
scopeMode?: string;
|
|
33
34
|
};
|
|
35
|
+
modelName?: string;
|
|
34
36
|
userMessageId?: string;
|
|
35
37
|
}): RunAgentMetadata;
|
|
36
38
|
export declare function emitRunAgent(observability: RunAgentObservability | undefined, metadata: RunAgentMetadata): void;
|
|
@@ -33,6 +33,7 @@ export function buildRunAgentMetadata(options) {
|
|
|
33
33
|
has_workbook_context: Boolean(options.workbookDetails),
|
|
34
34
|
workbook_count: options.workbookDetails?.workbooks?.length ?? 0,
|
|
35
35
|
workbook_scope_mode: options.workbookDetails?.scopeMode,
|
|
36
|
+
...(options.modelName ? { modelName: options.modelName } : {}),
|
|
36
37
|
...(options.userMessageId
|
|
37
38
|
? { user_message_id: options.userMessageId, turnId: options.userMessageId }
|
|
38
39
|
: {})
|
|
@@ -25,12 +25,12 @@ export const THINKING_LEVELS_WITH_XHIGH = [
|
|
|
25
25
|
const INTERACTIVE_MODELS_PER_PROVIDER = {
|
|
26
26
|
shortcut: new Set([
|
|
27
27
|
SHORTCUT_MODEL_ID.ClaudeFable5,
|
|
28
|
-
SHORTCUT_MODEL_ID.
|
|
28
|
+
SHORTCUT_MODEL_ID.ClaudeOpus5,
|
|
29
29
|
SHORTCUT_OPENAI_MODEL_ID,
|
|
30
30
|
SHORTCUT_MODEL_ID.Glm52Fireworks,
|
|
31
31
|
SHORTCUT_MODEL_ID.Hosted
|
|
32
32
|
]),
|
|
33
|
-
anthropic: new Set([SHORTCUT_MODEL_ID.
|
|
33
|
+
anthropic: new Set([SHORTCUT_MODEL_ID.ClaudeOpus5]),
|
|
34
34
|
openai: new Set([SHORTCUT_OPENAI_MODEL_ID])
|
|
35
35
|
};
|
|
36
36
|
// ============================================================================
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export declare const DEFAULT_SUBAGENT_MODEL: "shortcut/gpt-5.6-sol";
|
|
2
2
|
export declare const DEFAULT_SUBAGENT_TIMEOUT_SECONDS: number;
|
|
3
|
-
export declare const TASK_MODEL_CHOICES: readonly ["shortcut/gpt-5.6-sol", "shortcut/claude-opus-
|
|
3
|
+
export declare const TASK_MODEL_CHOICES: readonly ["shortcut/gpt-5.6-sol", "shortcut/claude-opus-5"];
|
|
4
4
|
//# sourceMappingURL=defaults.d.ts.map
|
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
import { SHORTCUT_MODEL_REF, SHORTCUT_OPENAI_MODEL_REF } from '../../model-ids.js';
|
|
2
2
|
export const DEFAULT_SUBAGENT_MODEL = SHORTCUT_OPENAI_MODEL_REF;
|
|
3
3
|
export const DEFAULT_SUBAGENT_TIMEOUT_SECONDS = 30 * 60;
|
|
4
|
-
export const TASK_MODEL_CHOICES = [
|
|
5
|
-
DEFAULT_SUBAGENT_MODEL,
|
|
6
|
-
SHORTCUT_MODEL_REF.ClaudeOpus48
|
|
7
|
-
];
|
|
4
|
+
export const TASK_MODEL_CHOICES = [DEFAULT_SUBAGENT_MODEL, SHORTCUT_MODEL_REF.ClaudeOpus5];
|
|
8
5
|
//# sourceMappingURL=defaults.js.map
|
package/dist/app/tools/cron.js
CHANGED
|
@@ -32,12 +32,13 @@ const ScheduleSchema = Type.Union([
|
|
|
32
32
|
}))
|
|
33
33
|
})
|
|
34
34
|
]);
|
|
35
|
+
const MODEL_OVERRIDE_DESCRIPTION = `Model override, for example "${SHORTCUT_MODEL_REF.ClaudeOpus5}" for Opus.`;
|
|
35
36
|
const JobInputSchema = Type.Object({
|
|
36
37
|
name: Type.String({ description: 'Short name for the job' }),
|
|
37
38
|
schedule: ScheduleSchema,
|
|
38
39
|
payload: Type.Object({
|
|
39
40
|
message: Type.String({ description: 'The prompt/instruction for the agent to execute' }),
|
|
40
|
-
model: Type.Optional(Type.String({ description:
|
|
41
|
+
model: Type.Optional(Type.String({ description: MODEL_OVERRIDE_DESCRIPTION }))
|
|
41
42
|
}),
|
|
42
43
|
enabled: Type.Optional(Type.Boolean({ description: 'Whether the job is enabled (default: true)' })),
|
|
43
44
|
description: Type.Optional(Type.String({ description: 'Longer description of what the job does' }))
|
|
@@ -49,7 +50,7 @@ const PatchSchema = Type.Object({
|
|
|
49
50
|
schedule: Type.Optional(ScheduleSchema),
|
|
50
51
|
payload: Type.Optional(Type.Object({
|
|
51
52
|
message: Type.Optional(Type.String()),
|
|
52
|
-
model: Type.Optional(Type.String())
|
|
53
|
+
model: Type.Optional(Type.String({ description: MODEL_OVERRIDE_DESCRIPTION }))
|
|
53
54
|
}))
|
|
54
55
|
});
|
|
55
56
|
const schema = Type.Object({
|
|
@@ -8,6 +8,7 @@ import { Type } from '@sinclair/typebox';
|
|
|
8
8
|
import { mkdir, readdir, readFile, stat, unlink, writeFile } from 'fs/promises';
|
|
9
9
|
import { basename, extname, join } from 'path';
|
|
10
10
|
import { getAgentTempDir } from '../../config.js';
|
|
11
|
+
import { SHORTCUT_MODEL_ID } from '../../model-ids.js';
|
|
11
12
|
import { LLM_ANALYSIS } from '../../tool-names.js';
|
|
12
13
|
import { mapShortcutLlmProxyError } from '../providers/shortcut-llm-proxy-client.js';
|
|
13
14
|
const TOOL_NAME = LLM_ANALYSIS;
|
|
@@ -53,10 +54,12 @@ const TEXT_EXTENSIONS = new Set([
|
|
|
53
54
|
'.bas'
|
|
54
55
|
]);
|
|
55
56
|
const MODELS = {
|
|
56
|
-
|
|
57
|
+
[SHORTCUT_MODEL_ID.Gemini3Flash]: SHORTCUT_MODEL_ID.Gemini3Flash,
|
|
58
|
+
[SHORTCUT_MODEL_ID.Gemini35FlashLite]: SHORTCUT_MODEL_ID.Gemini35FlashLite,
|
|
59
|
+
[SHORTCUT_MODEL_ID.Gemini36Flash]: SHORTCUT_MODEL_ID.Gemini36Flash,
|
|
57
60
|
'claude-haiku-4-5-20251001': 'claude-haiku-4-5-20251001'
|
|
58
61
|
};
|
|
59
|
-
const DEFAULT_MODEL =
|
|
62
|
+
const DEFAULT_MODEL = SHORTCUT_MODEL_ID.Gemini3Flash;
|
|
60
63
|
const SYSTEM_PROMPT = `You are a document extraction assistant.
|
|
61
64
|
|
|
62
65
|
Extraction rules:
|
|
@@ -76,7 +79,9 @@ Supported text types: ${[...TEXT_EXTENSIONS].join(', ')}
|
|
|
76
79
|
Also supports: .pdf
|
|
77
80
|
|
|
78
81
|
MODEL SELECTION:
|
|
79
|
-
- "
|
|
82
|
+
- "${SHORTCUT_MODEL_ID.Gemini3Flash}" (default): Current production model for careful extraction, tables, and images
|
|
83
|
+
- "${SHORTCUT_MODEL_ID.Gemini35FlashLite}": Fast, cost-efficient document parsing and structured extraction
|
|
84
|
+
- "${SHORTCUT_MODEL_ID.Gemini36Flash}": Complex visual and multimodal reasoning
|
|
80
85
|
- "claude-haiku-4-5-20251001": Quick scanning, structure discovery
|
|
81
86
|
|
|
82
87
|
FOR EXTRACTION TASKS:
|
|
@@ -97,7 +102,7 @@ const schema = Type.Object({
|
|
|
97
102
|
description: 'The question/instruction for the LLM about the file content.'
|
|
98
103
|
}),
|
|
99
104
|
model: Type.Optional(Type.String({
|
|
100
|
-
description: `Model to use: '${DEFAULT_MODEL}' (default,
|
|
105
|
+
description: `Model to use: '${DEFAULT_MODEL}' (default), '${SHORTCUT_MODEL_ID.Gemini35FlashLite}' (fast, cost-efficient extraction), '${SHORTCUT_MODEL_ID.Gemini36Flash}' (complex visual reasoning), or 'claude-haiku-4-5-20251001' (fallback/verifier)`
|
|
101
106
|
})),
|
|
102
107
|
output_filename: Type.Optional(Type.String({
|
|
103
108
|
description: "Optional output filename (e.g., 'analysis.md'). Auto-generated if omitted."
|
|
@@ -20,7 +20,7 @@ const schema = Type.Object({
|
|
|
20
20
|
description: 'Progress folder for autonomous continuation. When autonomous mode is active, pass this explicitly so the runtime can inject it into the next-session prompt.'
|
|
21
21
|
})),
|
|
22
22
|
model: Type.Optional(Type.String({
|
|
23
|
-
description: `Optional model override for the next session.
|
|
23
|
+
description: `Optional model override for the next session. Set model to "${SHORTCUT_MODEL_REF.ClaudeOpus5}" to use Opus.`
|
|
24
24
|
})),
|
|
25
25
|
thinkingLevel: Type.Optional(thinkingLevelSchema)
|
|
26
26
|
});
|
|
@@ -17,10 +17,11 @@
|
|
|
17
17
|
*/
|
|
18
18
|
import { Type } from '@sinclair/typebox';
|
|
19
19
|
import { TAKE_SCREENSHOT_SYSTEM_PROMPT, TAKE_SCREENSHOT_TOOL_DESCRIPTION } from '../../core/prompts/take-screenshot.js';
|
|
20
|
+
import { SHORTCUT_MODEL_ID } from '../../model-ids.js';
|
|
20
21
|
import { TAKE_SCREENSHOT } from '../../tool-names.js';
|
|
21
22
|
import { mapShortcutLlmProxyError } from '../providers/shortcut-llm-proxy-client.js';
|
|
22
23
|
const TOOL_NAME = TAKE_SCREENSHOT;
|
|
23
|
-
const DEFAULT_VISION_MODEL =
|
|
24
|
+
const DEFAULT_VISION_MODEL = SHORTCUT_MODEL_ID.Gemini3Flash;
|
|
24
25
|
const SCREENSHOT_LLM_MAX_TOKENS = 16384;
|
|
25
26
|
const SCREENSHOT_LLM_TIMEOUT_MS = 120_000;
|
|
26
27
|
// ---------------------------------------------------------------------------
|
|
@@ -153,7 +153,7 @@ function buildSchema(excludeSubagents) {
|
|
|
153
153
|
description: 'Full sandbox path to a .txt file containing the complete subagent prompt. Prefer this for long prompts, repeated/batched tasks, or many parallel agents using similar guidance; generate the files programmatically, then launch the tasks concurrently with these paths.'
|
|
154
154
|
})),
|
|
155
155
|
model: Type.Optional(StringEnum(TASK_MODEL_CHOICES, {
|
|
156
|
-
description: `${SHORTCUT_OPENAI_MODEL_REF}
|
|
156
|
+
description: `${SHORTCUT_OPENAI_MODEL_REF} is the default and fastest option. Set model to "${SHORTCUT_MODEL_REF.ClaudeOpus5}" for the Opus option with higher accuracy and stronger formatting when extra latency is acceptable.`
|
|
157
157
|
})),
|
|
158
158
|
run_in_background: Type.Optional(Type.Boolean({
|
|
159
159
|
description: RUN_IN_BACKGROUND_DESCRIPTION
|
package/dist/cli/list-models.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* List available models with optional fuzzy search
|
|
3
3
|
*/
|
|
4
|
+
import { filterInteractiveSelectableModels } from '../app/session/session-models.js';
|
|
4
5
|
import { fuzzyFilter } from '../tui/index.js';
|
|
5
6
|
/**
|
|
6
7
|
* Format a number as human-readable (e.g., 200000 -> "200K", 1000000 -> "1M")
|
|
@@ -20,7 +21,7 @@ function formatTokenCount(count) {
|
|
|
20
21
|
* List available models, optionally filtered by search pattern
|
|
21
22
|
*/
|
|
22
23
|
export async function listModels(modelRegistry, searchPattern) {
|
|
23
|
-
const models = modelRegistry.getAvailable();
|
|
24
|
+
const models = filterInteractiveSelectableModels(modelRegistry.getAvailable());
|
|
24
25
|
if (models.length === 0) {
|
|
25
26
|
console.log('No models available. Set API keys in environment variables.');
|
|
26
27
|
return;
|