shortcutxl 0.3.85 → 0.3.87
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 +12 -12
- package/CHANGELOG.md +10 -3
- package/SECURITY.md +1 -1
- package/dist/app/agent-session-runtime-adapter.d.ts +6 -0
- package/dist/app/agent-session-runtime-adapter.js +20 -2
- package/dist/app/background-agents/durable-memory/coordinator.js +1 -12
- package/dist/app/background-agents/durable-memory/memory-tools.js +8 -43
- package/dist/app/background-agents/shorty/doctor/read-tools.d.ts +5 -0
- package/dist/app/background-agents/shorty/doctor/read-tools.js +6 -0
- package/dist/app/background-agents/shorty/doctor/records.d.ts +17 -0
- package/dist/app/background-agents/shorty/doctor/records.js +69 -0
- package/dist/app/background-agents/shorty/doctor/runtime.d.ts +12 -0
- package/dist/app/background-agents/shorty/doctor/runtime.js +162 -0
- package/dist/app/background-agents/shorty/execution.d.ts +16 -0
- package/dist/app/background-agents/shorty/execution.js +28 -0
- package/dist/app/background-agents/shorty/fix-prompts.d.ts +4 -0
- package/dist/app/background-agents/shorty/fix-prompts.js +15 -0
- package/dist/app/background-agents/shorty/inspector/runtime.d.ts +7 -0
- package/dist/app/background-agents/shorty/inspector/runtime.js +156 -0
- package/dist/app/background-agents/shorty/permission-policy.d.ts +22 -0
- package/dist/app/background-agents/shorty/permission-policy.js +22 -0
- package/dist/app/background-agents/shorty/runtime.d.ts +3 -0
- package/dist/app/background-agents/shorty/runtime.js +42 -0
- package/dist/app/background-agents/shorty/types.d.ts +26 -0
- package/dist/app/background-agents/shorty/types.js +2 -0
- package/dist/app/extensions/slash-commands.js +1 -0
- package/dist/app/local/tools/execute-code/read-only-mode.d.ts +3 -0
- package/dist/app/local/tools/execute-code/read-only-mode.js +12 -0
- package/dist/app/local/tools/execute-code/tool.js +10 -0
- package/dist/app/modes/installation/prompt-windows.js +4 -4
- package/dist/app/permissions/effective-view.d.ts +0 -1
- package/dist/app/permissions/effective-view.js +0 -12
- package/dist/app/providers/shortcut-api-v2-transport.js +1 -0
- package/dist/app/session/forked-agent.d.ts +3 -9
- package/dist/app/session/forked-agent.js +5 -6
- package/dist/app/tools/scoped-file-tools.d.ts +8 -0
- package/dist/app/tools/scoped-file-tools.js +43 -0
- package/dist/cli/platform-api-commands.d.ts +20 -0
- package/dist/cli/platform-api-commands.js +6 -5
- package/dist/cli.js +36867 -35564
- package/dist/config.js +0 -10
- package/dist/constants.d.ts +3 -2
- package/dist/constants.js +3 -4
- package/dist/contracts/agent-api.d.ts +8 -3
- package/dist/contracts/agent-api.js +14 -7
- package/dist/embedded-agent/compose.js +7 -5
- package/dist/embedded-agent/context-review/agent.d.ts +8 -0
- package/dist/embedded-agent/context-review/agent.js +17 -6
- package/dist/embedded-agent/host-runtime-options.js +12 -6
- package/dist/embedded-agent/host-tools/execute-code/contract.js +4 -3
- package/dist/embedded-agent/model-registry.d.ts +2 -0
- package/dist/embedded-agent/model-registry.js +2 -0
- package/dist/embedded-agent/provider-native-request.js +17 -4
- package/dist/embedded-agent/suggestions.d.ts +5 -2
- package/dist/embedded-agent/suggestions.js +46 -26
- package/dist/main-helpers.js +2 -2
- package/dist/main.js +55 -11
- package/dist/model-ids.d.ts +4 -0
- package/dist/model-ids.js +4 -0
- package/dist/rpc/index.d.ts +1 -1
- package/dist/rpc/rpc-host.d.ts +4 -0
- package/dist/rpc/rpc-host.js +35 -0
- package/dist/rpc/rpc-mode.d.ts +1 -1
- package/dist/rpc/rpc-types.d.ts +22 -0
- package/dist/setup.js +13 -7
- package/dist/shell/components/editors/custom-editor.d.ts +2 -0
- package/dist/shell/components/editors/custom-editor.js +7 -0
- package/dist/shell/components/shorty-issues.d.ts +37 -0
- package/dist/shell/components/shorty-issues.js +202 -0
- package/dist/shell/interactive/interactive-mode-options.d.ts +3 -0
- package/dist/shell/interactive/interactive-mode.d.ts +6 -0
- package/dist/shell/interactive/interactive-mode.js +144 -1
- package/dist/shell/sandbox/sandbox-command.js +5 -0
- package/dist/shortcut-model-catalog.js +53 -25
- package/dist/startup/output-workbook.d.ts +29 -0
- package/dist/startup/output-workbook.js +96 -0
- package/dist/startup/runtime-routing.js +6 -2
- package/dist/startup/sync-xll.js +4 -4
- package/dist/startup/terminal-update-flow.d.ts +0 -1
- package/dist/startup/terminal-update-flow.js +0 -3
- package/dist/startup/uninstall.d.ts +30 -1
- package/dist/startup/uninstall.js +91 -45
- package/dist/startup/update-execution.js +7 -19
- package/dist/startup/update-manager.d.ts +0 -4
- package/dist/startup/update-manager.js +6 -28
- package/dist/startup/windows-excel-runtime-upgrade.js +3 -3
- package/native-app/main/chunks/{linux-BbyBJPUK.js → linux-D5vrr6vD.js} +3 -5
- package/native-app/main/chunks/{mac-CEzb62LU.js → mac-C1gONwcL.js} +3 -5
- package/native-app/main/chunks/{setup-worker-protocol-Bk1EVQnX.js → setup-worker-protocol-P3bbcYzl.js} +0 -7
- package/native-app/main/chunks/{shared-Kic2CBJF.js → shared-DpP_I5SO.js} +24 -2
- package/native-app/main/index.js +165 -51
- package/native-app/main/setup-worker.js +17 -15
- package/native-app/package.json +1 -1
- package/native-app/preload/index.cjs +4 -0
- package/native-app/renderer/assets/{index-DttUIDtA.js → index-BRbc7n0z.js} +695 -9
- package/native-app/renderer/assets/{index-CjXWevtW.css → index-Ch24bXR6.css} +471 -1
- package/native-app/renderer/assets/mascot-CsVDHiJB.png +0 -0
- package/native-app/renderer/assets/shortcutagent-DxFsGSkw.png +0 -0
- package/native-app/renderer/index.html +2 -2
- package/package.json +2 -4
- 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.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/dist/app/providers/shortcut-auth-recovery.d.ts +0 -10
- package/dist/app/providers/shortcut-auth-recovery.js +0 -14
- package/dist/sea/bootstrap.d.ts +0 -11
- package/dist/sea/bootstrap.js +0 -17
- package/dist/sea/runtime-assets.d.ts +0 -14
- package/dist/sea/runtime-assets.js +0 -110
- package/dist/sea/smoke.d.ts +0 -3
- package/dist/sea/smoke.js +0 -52
- package/dist/startup/sea-release.d.ts +0 -5
- package/dist/startup/sea-release.js +0 -17
- package/dist/startup/sea-update.d.ts +0 -19
- package/dist/startup/sea-update.js +0 -100
- package/native-app/main/chunks/constants-D1yo8u9C.js +0 -32
- package/native-app/renderer/assets/mascot-Y6byL4Yn.png +0 -3
- package/native-app/renderer/assets/shortcutagent-_zicTsV3.png +0 -3
package/BINARY-INVENTORY.json
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
|
-
"generatedAt": "2026-08-
|
|
3
|
+
"generatedAt": "2026-08-24T23:36:20.445Z",
|
|
4
4
|
"package": "shortcutxl",
|
|
5
5
|
"build": {
|
|
6
6
|
"builder": "github-actions",
|
|
7
7
|
"repository": "lyfegame/shortcut",
|
|
8
|
-
"sourceRef": "refs/heads/
|
|
9
|
-
"sourceCommit": "
|
|
10
|
-
"workflowRef": "lyfegame/shortcut/.github/workflows/release-
|
|
11
|
-
"runId": "
|
|
8
|
+
"sourceRef": "refs/heads/shortcutxl-0.3.87-release",
|
|
9
|
+
"sourceCommit": "932b5d424becf9729dc82c1da5c0d7d4ff8be22c",
|
|
10
|
+
"workflowRef": "lyfegame/shortcut/.github/workflows/release-shortcut-cli-npm-package.yml@refs/heads/shortcutxl-0.3.87-release",
|
|
11
|
+
"runId": "32789945621",
|
|
12
12
|
"runnerOs": "Windows",
|
|
13
13
|
"runnerImage": "win25-vs2026",
|
|
14
14
|
"runnerImageVersion": "20260818.207.1"
|
|
@@ -550,7 +550,7 @@
|
|
|
550
550
|
},
|
|
551
551
|
{
|
|
552
552
|
"path": "xll/python/Scripts/httpx.exe",
|
|
553
|
-
"sha256": "
|
|
553
|
+
"sha256": "0b542e5a9dc832d34f33d5c75e111e16f0d9d0100968e8405409018dbf329879",
|
|
554
554
|
"source": "httpx console launcher installed into embedded Python",
|
|
555
555
|
"version": "see packaged httpx distribution",
|
|
556
556
|
"builtBy": "third-party",
|
|
@@ -558,7 +558,7 @@
|
|
|
558
558
|
},
|
|
559
559
|
{
|
|
560
560
|
"path": "xll/python/Scripts/idna.exe",
|
|
561
|
-
"sha256": "
|
|
561
|
+
"sha256": "d985abffe9723dd6672037af85ec4cbaae6b4d9f452028dc794b4d6d61514e05",
|
|
562
562
|
"source": "Python package console launcher installed into embedded Python",
|
|
563
563
|
"version": "see owning Python package metadata in site-packages",
|
|
564
564
|
"builtBy": "third-party",
|
|
@@ -566,7 +566,7 @@
|
|
|
566
566
|
},
|
|
567
567
|
{
|
|
568
568
|
"path": "xll/python/Scripts/pip.exe",
|
|
569
|
-
"sha256": "
|
|
569
|
+
"sha256": "9c25f44908e9efe1afcad1e73d6de35927703f088e03fb35d764aff719bb6304",
|
|
570
570
|
"source": "pip console launcher installed into embedded Python",
|
|
571
571
|
"version": "see packaged pip distribution",
|
|
572
572
|
"builtBy": "third-party",
|
|
@@ -574,7 +574,7 @@
|
|
|
574
574
|
},
|
|
575
575
|
{
|
|
576
576
|
"path": "xll/python/Scripts/pip3.13.exe",
|
|
577
|
-
"sha256": "
|
|
577
|
+
"sha256": "9c25f44908e9efe1afcad1e73d6de35927703f088e03fb35d764aff719bb6304",
|
|
578
578
|
"source": "pip console launcher installed into embedded Python",
|
|
579
579
|
"version": "see packaged pip distribution",
|
|
580
580
|
"builtBy": "third-party",
|
|
@@ -582,7 +582,7 @@
|
|
|
582
582
|
},
|
|
583
583
|
{
|
|
584
584
|
"path": "xll/python/Scripts/pip3.exe",
|
|
585
|
-
"sha256": "
|
|
585
|
+
"sha256": "9c25f44908e9efe1afcad1e73d6de35927703f088e03fb35d764aff719bb6304",
|
|
586
586
|
"source": "pip console launcher installed into embedded Python",
|
|
587
587
|
"version": "see packaged pip distribution",
|
|
588
588
|
"builtBy": "third-party",
|
|
@@ -590,7 +590,7 @@
|
|
|
590
590
|
},
|
|
591
591
|
{
|
|
592
592
|
"path": "xll/python/Scripts/pywin32_postinstall.exe",
|
|
593
|
-
"sha256": "
|
|
593
|
+
"sha256": "00e246620113fd62b23749e74fa31cfb0dd486327abbff4ebda1fb40ba634b28",
|
|
594
594
|
"source": "Python package console launcher installed into embedded Python",
|
|
595
595
|
"version": "see owning Python package metadata in site-packages",
|
|
596
596
|
"builtBy": "third-party",
|
|
@@ -598,7 +598,7 @@
|
|
|
598
598
|
},
|
|
599
599
|
{
|
|
600
600
|
"path": "xll/python/Scripts/pywin32_testall.exe",
|
|
601
|
-
"sha256": "
|
|
601
|
+
"sha256": "c6b2a8c33794368c0834b9dea8e97cc2c188a32c0d95c286c4cf258317af506a",
|
|
602
602
|
"source": "Python package console launcher installed into embedded Python",
|
|
603
603
|
"version": "see owning Python package metadata in site-packages",
|
|
604
604
|
"builtBy": "third-party",
|
package/CHANGELOG.md
CHANGED
|
@@ -1,13 +1,20 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## [0.3.
|
|
3
|
+
## [0.3.87]
|
|
4
4
|
|
|
5
|
+
- **Shorty reviewers** - Inspector Shorty checks recent workbook changes for issues, while Doctor Shorty reviews your saved memory and personal skills.
|
|
6
|
+
- **More reliable native app startup** - Fixed app bugs and resolved some app stability issues.
|
|
7
|
+
|
|
8
|
+
## [0.3.86]
|
|
9
|
+
|
|
10
|
+
- **Signed Windows installer and updates** - Shortcut now ships as a signed Windows app installer, with versioned installer and updater assets published on [GitHub Releases](https://github.com/lyfegame/shortcutxl-releases/releases).
|
|
11
|
+
- **Clearer installation flow** - Windows setup guidance now describes Shortcut's bundled runtime, includes Office-wide recovery steps, and keeps Excel, Word, and PowerPoint integrations current during first run and upgrades.
|
|
5
12
|
- **Scrollable approval dialogs** - Long approval requests in the native app now remain fully accessible.
|
|
6
13
|
|
|
7
14
|
## [0.3.84]
|
|
8
15
|
|
|
9
|
-
- **
|
|
10
|
-
- **
|
|
16
|
+
- **Work across Excel, Word, and PowerPoint** - On Windows, Shortcut can now discover and work with open Word documents and PowerPoint presentations alongside Excel.
|
|
17
|
+
- **Simpler skill setup and sync** - The native app now finds skills from Claude Code and Codex automatically, and adds a dedicated place to review and sync differences with Shortcut Cloud.
|
|
11
18
|
|
|
12
19
|
## [0.3.83]
|
|
13
20
|
|
package/SECURITY.md
CHANGED
|
@@ -11,7 +11,7 @@ The release workflow retains the exact npm tarball, its SHA-256 checksum, and it
|
|
|
11
11
|
```bash
|
|
12
12
|
cosign verify-blob \
|
|
13
13
|
--bundle shortcutxl-<version>.tgz.sigstore.json \
|
|
14
|
-
--certificate-identity "https://github.com/lyfegame/shortcut/.github/workflows/release-
|
|
14
|
+
--certificate-identity "https://github.com/lyfegame/shortcut/.github/workflows/release-shortcut-cli-npm-package.yml@<source-ref>" \
|
|
15
15
|
--certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
|
|
16
16
|
shortcutxl-<version>.tgz
|
|
17
17
|
```
|
|
@@ -16,6 +16,7 @@ import type { ToolRegistry } from '../contracts/host-tool-registry.js';
|
|
|
16
16
|
import { type ThinkingLevel, type ToolDefinition } from '../core/index.js';
|
|
17
17
|
import type { RuntimePermissionPolicy } from '../core/permission-policy.js';
|
|
18
18
|
import { AgentSession, type FastModeDisabledReason } from './agent-session.js';
|
|
19
|
+
import type { LocalShortyRuntime } from './background-agents/shorty/types.js';
|
|
19
20
|
import type { ResourceLoader } from './resources/resource-loader.js';
|
|
20
21
|
import type { AgentSessionSettingsStore } from './session/session-settings-store.js';
|
|
21
22
|
import type { ProductSessionStore } from './session/session-store-types.js';
|
|
@@ -38,6 +39,10 @@ export interface CreateAgentSessionRuntimeAdapterOptions {
|
|
|
38
39
|
approvalState?: AgentApprovalState;
|
|
39
40
|
budgetLimits?: RuntimeBudgetLimits;
|
|
40
41
|
enableToolSummaries?: boolean;
|
|
42
|
+
/** Enable local Doctor/Inspector background reviews for the interactive CLI. */
|
|
43
|
+
enableShortyReviews?: boolean;
|
|
44
|
+
/** Whether the current workbook backend supports unattended read-only inspection. */
|
|
45
|
+
isInspectorAvailable?: () => boolean;
|
|
41
46
|
fastModeAllowed?: boolean;
|
|
42
47
|
fastModeDisabledReason?: FastModeDisabledReason;
|
|
43
48
|
modeName?: string;
|
|
@@ -58,6 +63,7 @@ export interface CreateAgentSessionRuntimeAdapterOptions {
|
|
|
58
63
|
}
|
|
59
64
|
export interface CreateAgentSessionRuntimeAdapterRuntimeResult {
|
|
60
65
|
runtime: EmbeddedAgentRuntime;
|
|
66
|
+
shortyRuntime: LocalShortyRuntime;
|
|
61
67
|
}
|
|
62
68
|
export interface CreateAgentSessionRuntimeAdapterResult extends CreateAgentSessionRuntimeAdapterRuntimeResult {
|
|
63
69
|
extensionsResult: ReturnType<ResourceLoader['getExtensions']>;
|
|
@@ -17,6 +17,7 @@ import { createPendingHostToolRequests } from '../core/pending-host-tool-request
|
|
|
17
17
|
import { getHostToolTimeoutMs } from '../embedded-agent/host-tools/timeouts.js';
|
|
18
18
|
import { AgentSession, LoginRequiredError } from './agent-session.js';
|
|
19
19
|
import { SessionAutoApproveState } from './approvals/session-auto-approve.js';
|
|
20
|
+
import { createLocalShortyRuntime } from './background-agents/shorty/runtime.js';
|
|
20
21
|
import { convertToLlm } from './messages.js';
|
|
21
22
|
import { findInitialModel } from './providers/model-resolver.js';
|
|
22
23
|
export async function resolveInitialSessionModel(options) {
|
|
@@ -50,7 +51,7 @@ export async function resolveInitialSessionModel(options) {
|
|
|
50
51
|
}
|
|
51
52
|
return { model: resolved.model, modelFallbackMessage };
|
|
52
53
|
}
|
|
53
|
-
function createAgentSessionCore(session, pendingHostToolRequests) {
|
|
54
|
+
function createAgentSessionCore(session, pendingHostToolRequests, shortyRuntime) {
|
|
54
55
|
// AgentSession itself doesn't carry a "the last turn was cancelled" flag —
|
|
55
56
|
// cancellation just leaves the message stream truncated. Track it locally
|
|
56
57
|
// so the next snapshot reflects AgentStopReason.Cancelled. Cleared on
|
|
@@ -67,6 +68,12 @@ function createAgentSessionCore(session, pendingHostToolRequests) {
|
|
|
67
68
|
session.replaceToolsByName(configuration.toolNames);
|
|
68
69
|
session.agent.setSystemPrompt(configuration.systemPrompt);
|
|
69
70
|
},
|
|
71
|
+
async configureReviewBuddy(enabled) {
|
|
72
|
+
shortyRuntime.configureInspector(enabled);
|
|
73
|
+
},
|
|
74
|
+
async runContextReview(input) {
|
|
75
|
+
await shortyRuntime.runDoctor(input.trigger);
|
|
76
|
+
},
|
|
70
77
|
async controlTask(request) {
|
|
71
78
|
return {
|
|
72
79
|
ok: false,
|
|
@@ -79,6 +86,7 @@ function createAgentSessionCore(session, pendingHostToolRequests) {
|
|
|
79
86
|
session.clearGoal();
|
|
80
87
|
},
|
|
81
88
|
dispose() {
|
|
89
|
+
shortyRuntime.dispose();
|
|
82
90
|
session.dispose();
|
|
83
91
|
},
|
|
84
92
|
async getGoal() {
|
|
@@ -112,6 +120,9 @@ function createAgentSessionCore(session, pendingHostToolRequests) {
|
|
|
112
120
|
},
|
|
113
121
|
subscribeSnapshotSource(listener) {
|
|
114
122
|
return session.subscribe(listener);
|
|
123
|
+
},
|
|
124
|
+
subscribeExtraEvents(listener) {
|
|
125
|
+
return shortyRuntime.subscribe(listener);
|
|
115
126
|
}
|
|
116
127
|
}, pendingHostToolRequests);
|
|
117
128
|
}
|
|
@@ -254,9 +265,16 @@ export async function createAgentSessionRuntimeAdapter(options) {
|
|
|
254
265
|
observability: options.observability,
|
|
255
266
|
compactionComplete: completeSimple
|
|
256
267
|
});
|
|
268
|
+
const shortyRuntime = createLocalShortyRuntime({
|
|
269
|
+
enabled: options.enableShortyReviews,
|
|
270
|
+
isInspectorAvailable: options.isInspectorAvailable,
|
|
271
|
+
modelRegistry,
|
|
272
|
+
session
|
|
273
|
+
});
|
|
257
274
|
return {
|
|
258
275
|
session,
|
|
259
|
-
runtime: createAgentSessionCore(session, pendingHostToolRequests),
|
|
276
|
+
runtime: createAgentSessionCore(session, pendingHostToolRequests, shortyRuntime),
|
|
277
|
+
shortyRuntime,
|
|
260
278
|
extensionsResult: resourceLoader.getExtensions(),
|
|
261
279
|
modelFallbackMessage
|
|
262
280
|
};
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { SHORTCUT_LLM_PROXY_URL } from '../../../constants.js';
|
|
2
1
|
import { getActiveUserMessageId } from '../../../core/user-message-id.js';
|
|
3
2
|
import { DURABLE_MEMORY_AGENT_EFFORT, DURABLE_MEMORY_AGENT_MODEL, DURABLE_MEMORY_AGENT_TOOLS, DURABLE_MEMORY_TURN_END_CADENCE } from '../../extensions/durable-memory/constants.js';
|
|
4
3
|
import { buildDurableMemoryPromptFragment } from '../../extensions/durable-memory/retrieval.js';
|
|
@@ -6,7 +5,6 @@ import { emitDurableMemoryStatus } from '../../extensions/durable-memory/status.
|
|
|
6
5
|
import { validateWorkspaceState } from '../../extensions/durable-memory/validator.js';
|
|
7
6
|
import { DurableMemoryWorkspace } from '../../extensions/durable-memory/workspace.js';
|
|
8
7
|
import { deriveModePermissionPolicy } from '../../permissions/policy.js';
|
|
9
|
-
import { createShortcutAuthRecovery } from '../../providers/shortcut-auth-recovery.js';
|
|
10
8
|
import { resolveForkTraceDir } from '../../session/fork-trace-paths.js';
|
|
11
9
|
import { runForkedAgent } from '../../session/forked-agent.js';
|
|
12
10
|
import { durableMemoryAgent } from './memory-agent.js';
|
|
@@ -244,11 +242,6 @@ export class DurableMemoryCoordinator {
|
|
|
244
242
|
const currentModel = ctx.model;
|
|
245
243
|
if (!currentModel)
|
|
246
244
|
return null;
|
|
247
|
-
// `ExtensionContext.modelRegistry` is typed as the neutral
|
|
248
|
-
// `AgentModelRegistry` interface, but every production path hands
|
|
249
|
-
// in the concrete `ModelRegistry` (which exposes `authStorage`).
|
|
250
|
-
// Cast here without a null check — tests mock a minimal registry
|
|
251
|
-
// and `createShortcutAuthRecovery(undefined)` is well-defined.
|
|
252
245
|
const messages = ctx.getMessages();
|
|
253
246
|
const userMessageId = ctx.userMessageId ?? getActiveUserMessageId(messages);
|
|
254
247
|
if (!userMessageId)
|
|
@@ -300,7 +293,6 @@ export class DurableMemoryCoordinator {
|
|
|
300
293
|
if (signal.aborted)
|
|
301
294
|
return;
|
|
302
295
|
const memoryModel = run.modelRegistry.find?.(run.model.provider, DURABLE_MEMORY_AGENT_MODEL) ?? run.model;
|
|
303
|
-
const baseUrl = memoryModel.baseUrl ?? run.model.baseUrl ?? SHORTCUT_LLM_PROXY_URL;
|
|
304
296
|
const apiKey = await run.modelRegistry.getApiKey(memoryModel);
|
|
305
297
|
if (!apiKey)
|
|
306
298
|
return;
|
|
@@ -329,12 +321,9 @@ export class DurableMemoryCoordinator {
|
|
|
329
321
|
messages: run.messages,
|
|
330
322
|
tools,
|
|
331
323
|
model: memoryModel,
|
|
332
|
-
|
|
333
|
-
apiKey,
|
|
324
|
+
modelRegistry: run.modelRegistry,
|
|
334
325
|
continuationRunId: run.continuationRunId,
|
|
335
|
-
getExtraHeaders: () => ({ 'X-Session-Id': run.sessionId }),
|
|
336
326
|
userMessageId: run.userMessageId,
|
|
337
|
-
recoverAuth: createShortcutAuthRecovery(run.modelRegistry.authStorage),
|
|
338
327
|
getToolContext: () => ({ permissionPolicy })
|
|
339
328
|
}, {
|
|
340
329
|
kind: DURABLE_MEMORY_FORK_KIND,
|
|
@@ -1,54 +1,19 @@
|
|
|
1
|
-
import { isAbsolute, relative, resolve, sep } from 'node:path';
|
|
2
1
|
import { createEditTool } from '../../tools/edit.js';
|
|
3
|
-
import {
|
|
4
|
-
import { createReadTool } from '../../tools/read.js';
|
|
2
|
+
import { assertPathWithinAnyRoot, createScopedReadTools, wrapScopedTool } from '../../tools/scoped-file-tools.js';
|
|
5
3
|
import { createWriteTool } from '../../tools/write.js';
|
|
6
|
-
/** True if `targetPath` resolves to `rootDir` or one of its descendants. */
|
|
7
|
-
function isWithinRoot(rootDir, targetPath) {
|
|
8
|
-
const relativePath = relative(resolve(rootDir), resolve(targetPath));
|
|
9
|
-
return (relativePath === '' ||
|
|
10
|
-
(relativePath !== '..' && !relativePath.startsWith(`..${sep}`) && !isAbsolute(relativePath)));
|
|
11
|
-
}
|
|
12
4
|
/** Throw if `inputPath` is outside the durable-memory write root. */
|
|
13
|
-
function assertPathWithinRoot(rootDir, inputPath) {
|
|
14
|
-
|
|
15
|
-
if (!isWithinRoot(rootDir, absolutePath)) {
|
|
16
|
-
throw new Error(`Path is outside durable-memory root: ${inputPath}`);
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
/** Throw if `inputPath` is outside every allowed durable-memory read root. */
|
|
20
|
-
function assertPathWithinAnyRoot(roots, inputPath) {
|
|
21
|
-
const absolutePath = resolve(roots[0], inputPath);
|
|
22
|
-
if (!roots.some((root) => isWithinRoot(root, absolutePath))) {
|
|
23
|
-
throw new Error(`Path is outside durable-memory read roots: ${inputPath}`);
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
/** Attach durable-memory path-policy validation to an underlying file tool. */
|
|
27
|
-
function wrapScopedTool(tool, validate) {
|
|
28
|
-
return {
|
|
29
|
-
...tool,
|
|
30
|
-
execute: async (toolCallId, rawParams, signal, onUpdate, ctx) => {
|
|
31
|
-
validate(rawParams);
|
|
32
|
-
return tool.execute(toolCallId, rawParams, signal, onUpdate, ctx);
|
|
33
|
-
}
|
|
34
|
-
};
|
|
5
|
+
async function assertPathWithinRoot(rootDir, inputPath) {
|
|
6
|
+
await assertPathWithinAnyRoot(rootDir, [rootDir], inputPath, 'durable-memory root', 'write');
|
|
35
7
|
}
|
|
36
8
|
/** Build the path-scoped read/edit/write/grep tool set for the durable-memory agent. */
|
|
37
9
|
export function createDurableMemoryTools(rootDir, options = {}) {
|
|
38
10
|
const readRoots = [rootDir, ...(options.readRoots ?? [])];
|
|
39
|
-
const readTool =
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
const editTool = wrapScopedTool(createEditTool(rootDir), (params) => {
|
|
43
|
-
assertPathWithinRoot(rootDir, params.path);
|
|
44
|
-
});
|
|
45
|
-
const writeTool = wrapScopedTool(createWriteTool(rootDir), (params) => {
|
|
46
|
-
assertPathWithinRoot(rootDir, params.path);
|
|
11
|
+
const [readTool, grepTool] = createScopedReadTools(rootDir, readRoots, 'durable-memory read roots');
|
|
12
|
+
const editTool = wrapScopedTool(createEditTool(rootDir), async (params) => {
|
|
13
|
+
await assertPathWithinRoot(rootDir, params.path);
|
|
47
14
|
});
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
-
assertPathWithinAnyRoot(readRoots, params.path);
|
|
51
|
-
}
|
|
15
|
+
const writeTool = wrapScopedTool(createWriteTool(rootDir), async (params) => {
|
|
16
|
+
await assertPathWithinRoot(rootDir, params.path);
|
|
52
17
|
});
|
|
53
18
|
return [readTool, editTool, writeTool, grepTool];
|
|
54
19
|
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { ToolDefinition } from '../../../../core/core-types.js';
|
|
2
|
+
import type { LocalDoctorPaths } from './records.js';
|
|
3
|
+
/** Build Doctor's read-only tools with access limited to memories and personal skills. */
|
|
4
|
+
export declare function createDoctorReadTools(paths: LocalDoctorPaths): ToolDefinition[];
|
|
5
|
+
//# sourceMappingURL=read-tools.d.ts.map
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { createScopedReadTools } from '../../../tools/scoped-file-tools.js';
|
|
2
|
+
/** Build Doctor's read-only tools with access limited to memories and personal skills. */
|
|
3
|
+
export function createDoctorReadTools(paths) {
|
|
4
|
+
return createScopedReadTools(paths.agentDir, [paths.memoriesDir, paths.personalSkills], 'Doctor read roots');
|
|
5
|
+
}
|
|
6
|
+
//# sourceMappingURL=read-tools.js.map
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type AgentContextReviewRecommendation, type AgentContextReviewUpdatedEvent } from '../../../../contracts/agent-api.js';
|
|
2
|
+
import type { LocalContextReviewDecision } from '../types.js';
|
|
3
|
+
export interface LocalDoctorPaths {
|
|
4
|
+
readonly agentDir: string;
|
|
5
|
+
readonly memoriesDir: string;
|
|
6
|
+
readonly memoryIndex: string;
|
|
7
|
+
readonly personalSkills: string;
|
|
8
|
+
readonly archivedSkills: string;
|
|
9
|
+
readonly reviewRecords: string;
|
|
10
|
+
}
|
|
11
|
+
export declare function resolveLocalDoctorPaths(agentDir?: string): LocalDoctorPaths;
|
|
12
|
+
export declare function createDoctorRecordStore(paths: LocalDoctorPaths, now: () => number): {
|
|
13
|
+
isAutomaticReviewDue(date: Date): boolean;
|
|
14
|
+
markAutomaticAttempt(date: Date): void;
|
|
15
|
+
recordDecision(event: AgentContextReviewUpdatedEvent, action: LocalContextReviewDecision, recommendations?: readonly AgentContextReviewRecommendation[]): void;
|
|
16
|
+
};
|
|
17
|
+
//# sourceMappingURL=records.d.ts.map
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { mkdirSync, readFileSync, renameSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { getAgentDir, getMemoriesDir } from '../../../../config.js';
|
|
4
|
+
import { AgentContextReviewPhase } from '../../../../contracts/agent-api.js';
|
|
5
|
+
const DOCTOR_ATTEMPT_FILE = 'context-review-attempt.json';
|
|
6
|
+
function todayKey(now) {
|
|
7
|
+
const year = now.getFullYear();
|
|
8
|
+
const month = String(now.getMonth() + 1).padStart(2, '0');
|
|
9
|
+
const day = String(now.getDate()).padStart(2, '0');
|
|
10
|
+
return `${year}-${month}-${day}`;
|
|
11
|
+
}
|
|
12
|
+
export function resolveLocalDoctorPaths(agentDir) {
|
|
13
|
+
const resolvedAgentDir = agentDir ?? getAgentDir();
|
|
14
|
+
const memoriesDir = agentDir ? join(agentDir, 'memories') : getMemoriesDir();
|
|
15
|
+
const personalSkills = join(resolvedAgentDir, 'skills');
|
|
16
|
+
return {
|
|
17
|
+
agentDir: resolvedAgentDir,
|
|
18
|
+
memoriesDir,
|
|
19
|
+
memoryIndex: join(memoriesDir, 'MEMORY.md'),
|
|
20
|
+
personalSkills,
|
|
21
|
+
archivedSkills: join(personalSkills, '_archive'),
|
|
22
|
+
reviewRecords: join(memoriesDir, 'context-reviews')
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
export function createDoctorRecordStore(paths, now) {
|
|
26
|
+
const attemptPath = join(paths.agentDir, DOCTOR_ATTEMPT_FILE);
|
|
27
|
+
return {
|
|
28
|
+
isAutomaticReviewDue(date) {
|
|
29
|
+
try {
|
|
30
|
+
const stored = JSON.parse(readFileSync(attemptPath, 'utf8'));
|
|
31
|
+
return stored.date !== todayKey(date);
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
return true;
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
markAutomaticAttempt(date) {
|
|
38
|
+
mkdirSync(paths.agentDir, { recursive: true });
|
|
39
|
+
const tempPath = `${attemptPath}.tmp`;
|
|
40
|
+
writeFileSync(tempPath, `${JSON.stringify({ date: todayKey(date) })}\n`, 'utf8');
|
|
41
|
+
renameSync(tempPath, attemptPath);
|
|
42
|
+
},
|
|
43
|
+
recordDecision(event, action, recommendations = event.recommendations ?? []) {
|
|
44
|
+
if (event.phase !== AgentContextReviewPhase.Completed ||
|
|
45
|
+
!event.createdAt ||
|
|
46
|
+
!event.recordPath ||
|
|
47
|
+
!event.outcome) {
|
|
48
|
+
throw new Error('Only completed Doctor Shorty reviews can be recorded.');
|
|
49
|
+
}
|
|
50
|
+
const fileName = event.recordPath.split('/').at(-1);
|
|
51
|
+
if (!fileName || !fileName.endsWith('.json'))
|
|
52
|
+
throw new Error('Invalid review record path.');
|
|
53
|
+
mkdirSync(paths.reviewRecords, { recursive: true });
|
|
54
|
+
const record = {
|
|
55
|
+
id: event.reviewId,
|
|
56
|
+
created_at: event.createdAt,
|
|
57
|
+
trigger: event.trigger,
|
|
58
|
+
outcome: event.outcome,
|
|
59
|
+
recommendations,
|
|
60
|
+
decision: { action, recorded_at: new Date(now()).toISOString() }
|
|
61
|
+
};
|
|
62
|
+
const target = join(paths.reviewRecords, fileName);
|
|
63
|
+
const tempPath = `${target}.tmp`;
|
|
64
|
+
writeFileSync(tempPath, `${JSON.stringify(record, null, 2)}\n`, 'utf8');
|
|
65
|
+
renameSync(tempPath, target);
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=records.js.map
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type AgentContextReviewTrigger } from '../../../../contracts/agent-api.js';
|
|
2
|
+
import type { CreateLocalShortyRuntimeOptions, LocalShortyEvent } from '../types.js';
|
|
3
|
+
import { createDoctorRecordStore } from './records.js';
|
|
4
|
+
export interface LocalDoctorRuntime {
|
|
5
|
+
configure(enabled: boolean): void;
|
|
6
|
+
run(trigger: AgentContextReviewTrigger): Promise<void>;
|
|
7
|
+
runAutomaticIfDue(now?: Date): Promise<boolean>;
|
|
8
|
+
recordDecision: ReturnType<typeof createDoctorRecordStore>['recordDecision'];
|
|
9
|
+
dispose(): void;
|
|
10
|
+
}
|
|
11
|
+
export declare function createLocalDoctorRuntime(options: CreateLocalShortyRuntimeOptions, emit: (event: LocalShortyEvent) => void): LocalDoctorRuntime;
|
|
12
|
+
//# sourceMappingURL=runtime.d.ts.map
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import { AgentContextReviewPhase, AgentEventKind } from '../../../../contracts/agent-api.js';
|
|
2
|
+
import { buildContextReviewQuery, buildContextReviewRecordPath, buildContextReviewSystemPrompt, contextReviewAgent } from '../../../../embedded-agent/context-review/agent.js';
|
|
3
|
+
import { parseContextReviewResult } from '../../../../embedded-agent/context-review/result.js';
|
|
4
|
+
import { readAgentReviewActivityDescription, upsertAgentReviewActivity } from '../../../../embedded-agent/review/activity.js';
|
|
5
|
+
import { GREP, READ } from '../../../../tool-names.js';
|
|
6
|
+
import { resolveAutomaticLocalShortyModel, runLocalShortyAgent } from '../execution.js';
|
|
7
|
+
import { buildShortyPermissionPolicy } from '../permission-policy.js';
|
|
8
|
+
import { createDoctorReadTools } from './read-tools.js';
|
|
9
|
+
import { createDoctorRecordStore, resolveLocalDoctorPaths } from './records.js';
|
|
10
|
+
const REVIEW_TIMEOUT_MS = contextReviewAgent.timeoutSeconds * 1_000;
|
|
11
|
+
export function createLocalDoctorRuntime(options, emit) {
|
|
12
|
+
const now = options.now ?? Date.now;
|
|
13
|
+
const paths = resolveLocalDoctorPaths(options.agentDir);
|
|
14
|
+
const records = createDoctorRecordStore(paths, now);
|
|
15
|
+
let enabled = options.enabled ?? false;
|
|
16
|
+
let disposed = false;
|
|
17
|
+
let active = null;
|
|
18
|
+
const run = async (trigger, model) => {
|
|
19
|
+
if (disposed || active || (!enabled && trigger === 'automatic'))
|
|
20
|
+
return;
|
|
21
|
+
const reviewId = `context-review-${globalThis.crypto.randomUUID()}`;
|
|
22
|
+
const createdAt = new Date(now()).toISOString();
|
|
23
|
+
const controller = new AbortController();
|
|
24
|
+
active = { reviewId, controller };
|
|
25
|
+
const startedAt = now();
|
|
26
|
+
let activities = [];
|
|
27
|
+
const emitRunningState = () => {
|
|
28
|
+
emit({
|
|
29
|
+
kind: AgentEventKind.ContextReviewUpdated,
|
|
30
|
+
reviewId,
|
|
31
|
+
trigger,
|
|
32
|
+
phase: AgentContextReviewPhase.Started,
|
|
33
|
+
activities
|
|
34
|
+
});
|
|
35
|
+
};
|
|
36
|
+
emitRunningState();
|
|
37
|
+
let timedOut = false;
|
|
38
|
+
const timeout = setTimeout(() => {
|
|
39
|
+
timedOut = true;
|
|
40
|
+
controller.abort();
|
|
41
|
+
}, REVIEW_TIMEOUT_MS);
|
|
42
|
+
try {
|
|
43
|
+
const tools = createDoctorReadTools(paths);
|
|
44
|
+
const permissionPolicy = buildShortyPermissionPolicy([READ, GREP], [paths.memoriesDir, paths.personalSkills]);
|
|
45
|
+
const result = await runLocalShortyAgent({
|
|
46
|
+
model,
|
|
47
|
+
modelRegistry: options.modelRegistry,
|
|
48
|
+
parent: {
|
|
49
|
+
systemPrompt: buildContextReviewSystemPrompt({
|
|
50
|
+
memoryIndex: paths.memoryIndex,
|
|
51
|
+
personalSkills: paths.personalSkills,
|
|
52
|
+
archivedSkills: paths.archivedSkills,
|
|
53
|
+
reviewRecords: paths.reviewRecords
|
|
54
|
+
}, 'read-grep'),
|
|
55
|
+
messages: [],
|
|
56
|
+
tools,
|
|
57
|
+
continuationRunId: reviewId,
|
|
58
|
+
getToolContext: () => ({
|
|
59
|
+
continuationRunId: reviewId,
|
|
60
|
+
permissionPolicy
|
|
61
|
+
})
|
|
62
|
+
},
|
|
63
|
+
controller: {
|
|
64
|
+
kind: 'doctor-shorty',
|
|
65
|
+
instruction: buildContextReviewQuery({ trigger }),
|
|
66
|
+
effortLevel: 'low',
|
|
67
|
+
signal: controller.signal,
|
|
68
|
+
onToolCall: (toolCall) => {
|
|
69
|
+
const description = readAgentReviewActivityDescription(toolCall.arguments ?? {}) ??
|
|
70
|
+
(toolCall.name === GREP
|
|
71
|
+
? 'Searching memory and skills'
|
|
72
|
+
: toolCall.name === READ
|
|
73
|
+
? 'Reading memory and skills'
|
|
74
|
+
: null);
|
|
75
|
+
if (!description || active?.reviewId !== reviewId)
|
|
76
|
+
return;
|
|
77
|
+
activities = upsertAgentReviewActivity(activities, {
|
|
78
|
+
id: toolCall.id,
|
|
79
|
+
description,
|
|
80
|
+
status: 'running'
|
|
81
|
+
});
|
|
82
|
+
emitRunningState();
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
if (active?.reviewId !== reviewId)
|
|
87
|
+
return;
|
|
88
|
+
const parsed = parseContextReviewResult(result.response);
|
|
89
|
+
const recordPath = buildContextReviewRecordPath(new Date(createdAt));
|
|
90
|
+
emit({
|
|
91
|
+
kind: AgentEventKind.ContextReviewUpdated,
|
|
92
|
+
reviewId,
|
|
93
|
+
trigger,
|
|
94
|
+
phase: AgentContextReviewPhase.Completed,
|
|
95
|
+
createdAt,
|
|
96
|
+
recordPath,
|
|
97
|
+
outcome: parsed.outcome,
|
|
98
|
+
recommendations: parsed.recommendations.map((recommendation) => ({
|
|
99
|
+
...recommendation,
|
|
100
|
+
id: `${reviewId}:${recommendation.id}`
|
|
101
|
+
})),
|
|
102
|
+
durationMs: Math.max(0, now() - startedAt)
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
catch (error) {
|
|
106
|
+
if (active?.reviewId !== reviewId)
|
|
107
|
+
return;
|
|
108
|
+
emit({
|
|
109
|
+
kind: AgentEventKind.ContextReviewUpdated,
|
|
110
|
+
reviewId,
|
|
111
|
+
trigger,
|
|
112
|
+
phase: timedOut
|
|
113
|
+
? AgentContextReviewPhase.Failed
|
|
114
|
+
: controller.signal.aborted
|
|
115
|
+
? AgentContextReviewPhase.Cancelled
|
|
116
|
+
: AgentContextReviewPhase.Failed,
|
|
117
|
+
message: timedOut
|
|
118
|
+
? 'Context check timed out.'
|
|
119
|
+
: error instanceof Error
|
|
120
|
+
? error.message
|
|
121
|
+
: String(error),
|
|
122
|
+
durationMs: Math.max(0, now() - startedAt)
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
finally {
|
|
126
|
+
clearTimeout(timeout);
|
|
127
|
+
if (active?.reviewId === reviewId)
|
|
128
|
+
active = null;
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
return {
|
|
132
|
+
configure(nextEnabled) {
|
|
133
|
+
enabled = nextEnabled;
|
|
134
|
+
if (!enabled && active) {
|
|
135
|
+
active.controller.abort();
|
|
136
|
+
active = null;
|
|
137
|
+
}
|
|
138
|
+
},
|
|
139
|
+
run,
|
|
140
|
+
async runAutomaticIfDue(date = new Date()) {
|
|
141
|
+
if (disposed || !enabled || active)
|
|
142
|
+
return false;
|
|
143
|
+
if (!records.isAutomaticReviewDue(date))
|
|
144
|
+
return false;
|
|
145
|
+
const model = resolveAutomaticLocalShortyModel(options.modelRegistry);
|
|
146
|
+
if (!model)
|
|
147
|
+
return false;
|
|
148
|
+
records.markAutomaticAttempt(date);
|
|
149
|
+
await run('automatic', model);
|
|
150
|
+
return true;
|
|
151
|
+
},
|
|
152
|
+
recordDecision: records.recordDecision,
|
|
153
|
+
dispose() {
|
|
154
|
+
if (disposed)
|
|
155
|
+
return;
|
|
156
|
+
disposed = true;
|
|
157
|
+
active?.controller.abort();
|
|
158
|
+
active = null;
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
//# sourceMappingURL=runtime.js.map
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { Model } from '../../../ai/types.js';
|
|
2
|
+
import type { AgentModelRegistry } from '../../../contracts/agent-model.js';
|
|
3
|
+
import { type ForkedAgentControllerOptions, type ForkedAgentParentContext, type ForkedAgentResult } from '../../session/forked-agent.js';
|
|
4
|
+
export interface RunLocalShortyAgentOptions {
|
|
5
|
+
readonly controller: ForkedAgentControllerOptions;
|
|
6
|
+
readonly model?: Model<any>;
|
|
7
|
+
readonly modelRegistry: AgentModelRegistry;
|
|
8
|
+
readonly parent: Omit<ForkedAgentParentContext, 'model' | 'modelRegistry'>;
|
|
9
|
+
}
|
|
10
|
+
/** Resolve the model used by every local Doctor and Inspector run. */
|
|
11
|
+
export declare function resolveLocalShortyModel(modelRegistry: AgentModelRegistry): Model<any> | undefined;
|
|
12
|
+
/** Return Sol only when an automatic review can authenticate without prompting. */
|
|
13
|
+
export declare function resolveAutomaticLocalShortyModel(modelRegistry: AgentModelRegistry): Model<any> | undefined;
|
|
14
|
+
/** Run a local reviewer without leaking credential plumbing into the reviewer. */
|
|
15
|
+
export declare function runLocalShortyAgent(options: RunLocalShortyAgentOptions): Promise<ForkedAgentResult>;
|
|
16
|
+
//# sourceMappingURL=execution.d.ts.map
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { SHORTCUT_MODEL_ID } from '../../../model-ids.js';
|
|
2
|
+
import { runForkedAgent } from '../../session/forked-agent.js';
|
|
3
|
+
/** Resolve the model used by every local Doctor and Inspector run. */
|
|
4
|
+
export function resolveLocalShortyModel(modelRegistry) {
|
|
5
|
+
return modelRegistry.find('shortcut', SHORTCUT_MODEL_ID.Gpt56Sol);
|
|
6
|
+
}
|
|
7
|
+
/** Return Sol only when an automatic review can authenticate without prompting. */
|
|
8
|
+
export function resolveAutomaticLocalShortyModel(modelRegistry) {
|
|
9
|
+
const model = resolveLocalShortyModel(modelRegistry);
|
|
10
|
+
if (!model)
|
|
11
|
+
return undefined;
|
|
12
|
+
const hasCredentials = modelRegistry
|
|
13
|
+
.getAvailable()
|
|
14
|
+
.some((available) => available.provider === model.provider && available.id === model.id);
|
|
15
|
+
return hasCredentials ? model : undefined;
|
|
16
|
+
}
|
|
17
|
+
/** Run a local reviewer without leaking credential plumbing into the reviewer. */
|
|
18
|
+
export async function runLocalShortyAgent(options) {
|
|
19
|
+
const model = options.model ?? resolveLocalShortyModel(options.modelRegistry);
|
|
20
|
+
if (!model)
|
|
21
|
+
throw new Error('The Shortcut Sol review model is not registered.');
|
|
22
|
+
return runForkedAgent({
|
|
23
|
+
...options.parent,
|
|
24
|
+
model,
|
|
25
|
+
modelRegistry: options.modelRegistry
|
|
26
|
+
}, options.controller);
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=execution.js.map
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { AgentContextReviewRecommendation, AgentReviewBuddyFinding } from '../../../contracts/agent-api.js';
|
|
2
|
+
export declare function formatInspectorFixRequest(findings: readonly AgentReviewBuddyFinding[]): string;
|
|
3
|
+
export declare function formatDoctorFixRequest(recommendations: readonly AgentContextReviewRecommendation[]): string;
|
|
4
|
+
//# sourceMappingURL=fix-prompts.d.ts.map
|