@empiricalrun/test-gen 0.57.2 → 0.59.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +69 -0
- package/dist/actions/index.d.ts.map +1 -1
- package/dist/actions/skill.js +2 -2
- package/dist/actions/utils/index.js +2 -3
- package/dist/agent/browsing/index.js +1 -2
- package/dist/agent/browsing/run.d.ts +3 -1
- package/dist/agent/browsing/run.d.ts.map +1 -1
- package/dist/agent/browsing/run.js +24 -27
- package/dist/agent/browsing/utils.d.ts +1 -14
- package/dist/agent/browsing/utils.d.ts.map +1 -1
- package/dist/agent/browsing/utils.js +10 -67
- package/dist/agent/chat/agent-loop.d.ts +6 -3
- package/dist/agent/chat/agent-loop.d.ts.map +1 -1
- package/dist/agent/chat/agent-loop.js +43 -27
- package/dist/agent/chat/exports.d.ts +7 -8
- package/dist/agent/chat/exports.d.ts.map +1 -1
- package/dist/agent/chat/exports.js +14 -34
- package/dist/agent/chat/index.d.ts +1 -1
- package/dist/agent/chat/index.d.ts.map +1 -1
- package/dist/agent/chat/index.js +20 -10
- package/dist/agent/chat/models.d.ts +6 -0
- package/dist/agent/chat/models.d.ts.map +1 -0
- package/dist/agent/chat/models.js +37 -0
- package/dist/agent/chat/prompt.d.ts +2 -1
- package/dist/agent/chat/prompt.d.ts.map +1 -1
- package/dist/agent/chat/prompt.js +40 -12
- package/dist/agent/chat/repo.d.ts +2 -1
- package/dist/agent/chat/repo.d.ts.map +1 -1
- package/dist/agent/chat/repo.js +32 -36
- package/dist/agent/chat/state.d.ts +15 -7
- package/dist/agent/chat/state.d.ts.map +1 -1
- package/dist/agent/chat/state.js +95 -32
- package/dist/agent/chat/types.d.ts +0 -1
- package/dist/agent/chat/types.d.ts.map +1 -1
- package/dist/agent/codegen/create-test-block.js +1 -2
- package/dist/agent/codegen/fix-ts-errors.js +1 -2
- package/dist/agent/codegen/generate-code-apply-changes.js +2 -3
- package/dist/agent/codegen/lexical-scoped-vars.js +1 -2
- package/dist/agent/codegen/repo-edit.js +2 -3
- package/dist/agent/codegen/run.js +2 -3
- package/dist/agent/codegen/skills-retriever.d.ts +3 -3
- package/dist/agent/codegen/skills-retriever.d.ts.map +1 -1
- package/dist/agent/codegen/skills-retriever.js +2 -2
- package/dist/agent/codegen/test-update-feedback.js +1 -2
- package/dist/agent/codegen/update-flow.js +4 -5
- package/dist/agent/codegen/use-skill.js +1 -2
- package/dist/agent/codegen/utils.js +9 -10
- package/dist/agent/cua/computer.js +3 -4
- package/dist/agent/cua/index.js +2 -3
- package/dist/agent/cua/model.js +1 -2
- package/dist/agent/diagnosis-agent/index.js +2 -3
- package/dist/agent/diagnosis-agent/strict-mode-violation.js +1 -2
- package/dist/agent/enrich-prompt/index.d.ts +1 -1
- package/dist/agent/enrich-prompt/index.d.ts.map +1 -1
- package/dist/agent/enrich-prompt/utils.js +1 -2
- package/dist/agent/infer-agent/index.js +1 -2
- package/dist/agent/master/action-tool-calls.js +3 -3
- package/dist/agent/master/browser-tests/index.spec.js +6 -6
- package/dist/agent/master/element-annotation.js +2 -3
- package/dist/agent/master/execute-browser-action.d.ts +1 -1
- package/dist/agent/master/execute-browser-action.d.ts.map +1 -1
- package/dist/agent/master/execute-browser-action.js +1 -2
- package/dist/agent/master/execute-skill-action.js +1 -2
- package/dist/agent/master/icon-descriptor/index.js +6 -7
- package/dist/agent/master/icon-descriptor/normalize-svg.js +1 -2
- package/dist/agent/master/next-action.js +1 -2
- package/dist/agent/master/planner.d.ts.map +1 -1
- package/dist/agent/master/planner.js +1 -2
- package/dist/agent/master/run.js +3 -3
- package/dist/agent/master/scroller.js +1 -2
- package/dist/agent/master/with-hints.d.ts +1 -1
- package/dist/agent/master/with-hints.d.ts.map +1 -1
- package/dist/agent/planner/run-time-planner.d.ts.map +1 -1
- package/dist/agent/planner/run-time-planner.js +1 -2
- package/dist/agent/planner/run.js +1 -2
- package/dist/bin/index.js +4 -0
- package/dist/bin/logger/index.js +2 -2
- package/dist/bin/utils/context.js +5 -6
- package/dist/bin/utils/fs/index.d.ts.map +1 -1
- package/dist/bin/utils/fs/index.js +4 -5
- package/dist/bin/utils/index.d.ts +1 -0
- package/dist/bin/utils/index.d.ts.map +1 -1
- package/dist/bin/utils/index.js +2 -3
- package/dist/bin/utils/platform/web/index.d.ts.map +1 -1
- package/dist/bin/utils/platform/web/index.js +21 -21
- package/dist/bin/utils/scenarios/index.js +3 -4
- package/dist/constants/index.js +1 -1
- package/dist/file/server.js +2 -2
- package/dist/human-in-the-loop/cli.js +1 -2
- package/dist/human-in-the-loop/ipc.js +2 -3
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -2
- package/dist/prompts/lib/ts-transformer.js +17 -7
- package/dist/reporter/index.js +3 -3
- package/dist/reporter/lib.js +1 -1
- package/dist/session/index.js +6 -7
- package/dist/test-build/index.js +3 -4
- package/dist/tool-call-service/index.d.ts +3 -3
- package/dist/tool-call-service/index.d.ts.map +1 -1
- package/dist/tool-call-service/index.js +51 -71
- package/dist/tool-call-service/utils.d.ts +10 -0
- package/dist/tool-call-service/utils.d.ts.map +1 -0
- package/dist/tool-call-service/utils.js +23 -0
- package/dist/tools/commit-and-create-pr.js +2 -2
- package/dist/tools/download-build.d.ts +9 -0
- package/dist/tools/download-build.d.ts.map +1 -1
- package/dist/tools/download-build.js +5 -4
- package/dist/tools/grep/ripgrep/index.js +2 -3
- package/dist/tools/grep/ripgrep/types.d.ts +0 -2
- package/dist/tools/grep/ripgrep/types.d.ts.map +1 -1
- package/dist/tools/str_replace_editor.js +3 -3
- package/dist/tools/test-gen-browser.d.ts.map +1 -1
- package/dist/tools/test-gen-browser.js +8 -13
- package/dist/tools/test-run-fetcher/index.js +2 -2
- package/dist/tools/test-run.d.ts.map +1 -1
- package/dist/tools/test-run.js +8 -13
- package/dist/tools/utils/index.js +2 -3
- package/dist/types/index.d.ts +8 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/uploader/index.js +6 -6
- package/dist/uploader/utils.d.ts.map +1 -1
- package/dist/uploader/utils.js +2 -2
- package/dist/utils/checkpoint.d.ts.map +1 -1
- package/dist/utils/checkpoint.js +4 -3
- package/dist/utils/env.js +1 -2
- package/dist/utils/exec.d.ts +2 -2
- package/dist/utils/exec.d.ts.map +1 -1
- package/dist/utils/exec.js +7 -6
- package/dist/utils/file-tree.d.ts +3 -0
- package/dist/utils/file-tree.d.ts.map +1 -0
- package/dist/utils/file-tree.js +42 -0
- package/dist/utils/file.js +1 -2
- package/dist/utils/git.js +7 -8
- package/dist/utils/html.d.ts.map +1 -1
- package/dist/utils/pw-test.js +1 -2
- package/dist/utils/repo-tree.d.ts +2 -1
- package/dist/utils/repo-tree.d.ts.map +1 -1
- package/dist/utils/repo-tree.js +62 -53
- package/dist/utils/slug.d.ts.map +1 -1
- package/dist/utils/slug.js +1 -1
- package/dist/utils/string.js +1 -2
- package/package.json +5 -5
- package/tsconfig.tsbuildinfo +1 -0
- package/dist/agent/chat/model.d.ts +0 -4
- package/dist/agent/chat/model.d.ts.map +0 -1
- package/dist/agent/chat/model.js +0 -17
|
@@ -1,38 +1,18 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
-
if (mod && mod.__esModule) return mod;
|
|
20
|
-
var result = {};
|
|
21
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
-
__setModuleDefault(result, mod);
|
|
23
|
-
return result;
|
|
24
|
-
};
|
|
25
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
-
exports.
|
|
3
|
+
exports.SUPPORTED_CHAT_MODELS = exports.migrateChatState = exports.LATEST_CHAT_STATE_VERSION = exports.getLatestDownloadBuildUrl = exports.defaultModel = exports.createChatStateForMessages = exports.createChatState = exports.createChatModel = exports.chatStateFromModel = exports.chatAgentLoop = exports.CHAT_STATE_VERSIONS_MIGRATIONS_MAP = void 0;
|
|
4
|
+
const chat_1 = require("@empiricalrun/llm/chat");
|
|
5
|
+
Object.defineProperty(exports, "createChatModel", { enumerable: true, get: function () { return chat_1.createChatModel; } });
|
|
27
6
|
const agent_loop_1 = require("./agent-loop");
|
|
28
7
|
Object.defineProperty(exports, "chatAgentLoop", { enumerable: true, get: function () { return agent_loop_1.chatAgentLoop; } });
|
|
29
|
-
const
|
|
30
|
-
Object.defineProperty(exports, "
|
|
31
|
-
|
|
32
|
-
const
|
|
33
|
-
exports.
|
|
34
|
-
exports.
|
|
35
|
-
exports.
|
|
36
|
-
exports.
|
|
37
|
-
exports.
|
|
38
|
-
exports.
|
|
8
|
+
const models_1 = require("./models");
|
|
9
|
+
Object.defineProperty(exports, "defaultModel", { enumerable: true, get: function () { return models_1.defaultModel; } });
|
|
10
|
+
Object.defineProperty(exports, "SUPPORTED_CHAT_MODELS", { enumerable: true, get: function () { return models_1.SUPPORTED_CHAT_MODELS; } });
|
|
11
|
+
const state_1 = require("./state");
|
|
12
|
+
Object.defineProperty(exports, "CHAT_STATE_VERSIONS_MIGRATIONS_MAP", { enumerable: true, get: function () { return state_1.CHAT_STATE_VERSIONS_MIGRATIONS_MAP; } });
|
|
13
|
+
Object.defineProperty(exports, "chatStateFromModel", { enumerable: true, get: function () { return state_1.chatStateFromModel; } });
|
|
14
|
+
Object.defineProperty(exports, "createChatState", { enumerable: true, get: function () { return state_1.createChatState; } });
|
|
15
|
+
Object.defineProperty(exports, "createChatStateForMessages", { enumerable: true, get: function () { return state_1.createChatStateForMessages; } });
|
|
16
|
+
Object.defineProperty(exports, "getLatestDownloadBuildUrl", { enumerable: true, get: function () { return state_1.getLatestDownloadBuildUrl; } });
|
|
17
|
+
Object.defineProperty(exports, "LATEST_CHAT_STATE_VERSION", { enumerable: true, get: function () { return state_1.LATEST_CHAT_STATE_VERSION; } });
|
|
18
|
+
Object.defineProperty(exports, "migrateChatState", { enumerable: true, get: function () { return state_1.migrateChatState; } });
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { SupportedChatModels } from "
|
|
1
|
+
import { SupportedChatModels } from "@empiricalrun/llm/chat";
|
|
2
2
|
export declare function runChatAgentForCLI({ useDiskForChatState, selectedModel, initialPromptContent, }: {
|
|
3
3
|
selectedModel: SupportedChatModels;
|
|
4
4
|
useDiskForChatState: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/agent/chat/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/agent/chat/index.ts"],"names":[],"mappings":"AACA,OAAO,EAGL,mBAAmB,EACpB,MAAM,wBAAwB,CAAC;AAmChC,wBAAsB,kBAAkB,CAAC,EACvC,mBAAmB,EACnB,aAAa,EACb,oBAAoB,GACrB,EAAE;IACD,aAAa,EAAE,mBAAmB,CAAC;IACnC,mBAAmB,EAAE,OAAO,CAAC;IAC7B,oBAAoB,EAAE,MAAM,GAAG,SAAS,CAAC;CAC1C,iBAiGA;AAuBD,wBAAsB,wBAAwB,CAAC,EAC7C,aAAa,EACb,aAAa,GACd,EAAE;IACD,aAAa,EAAE,mBAAmB,CAAC;IACnC,aAAa,EAAE,MAAM,CAAC;CACvB,iBAsDA"}
|
package/dist/agent/chat/index.js
CHANGED
|
@@ -1,21 +1,24 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.runChatAgentForCLI = runChatAgentForCLI;
|
|
4
|
+
exports.runChatAgentForDashboard = runChatAgentForDashboard;
|
|
4
5
|
const llm_1 = require("@empiricalrun/llm");
|
|
6
|
+
const chat_1 = require("@empiricalrun/llm/chat");
|
|
5
7
|
const picocolors_1 = require("picocolors");
|
|
6
8
|
const human_in_the_loop_1 = require("../../human-in-the-loop");
|
|
7
9
|
const tool_call_service_1 = require("../../tool-call-service");
|
|
10
|
+
const file_tree_1 = require("../../utils/file-tree");
|
|
8
11
|
const git_1 = require("../../utils/git");
|
|
9
12
|
const agent_loop_1 = require("./agent-loop");
|
|
10
|
-
const model_1 = require("./model");
|
|
11
13
|
const state_1 = require("./state");
|
|
14
|
+
const DASHBOARD_DOMAIN = process.env.DASHBOARD_DOMAIN || "https://dash.empirical.run";
|
|
12
15
|
function stopCriteria(userPrompt) {
|
|
13
16
|
return userPrompt?.toLowerCase() === "stop";
|
|
14
17
|
}
|
|
15
18
|
function concludeAgent(chatModel, useDiskForChatState, selectedModel) {
|
|
16
19
|
console.log(`\n${(0, picocolors_1.gray)("Usage summary -> " + chatModel.getUsageSummary())}`);
|
|
17
20
|
if (useDiskForChatState) {
|
|
18
|
-
(0, state_1.saveToDisk)(chatModel.messages, selectedModel);
|
|
21
|
+
(0, state_1.saveToDisk)(chatModel.messages, selectedModel, chatModel.askUserForInput);
|
|
19
22
|
}
|
|
20
23
|
}
|
|
21
24
|
async function runChatAgentForCLI({ useDiskForChatState, selectedModel, initialPromptContent, }) {
|
|
@@ -28,7 +31,7 @@ async function runChatAgentForCLI({ useDiskForChatState, selectedModel, initialP
|
|
|
28
31
|
const branchName = `branch-${randomId}`;
|
|
29
32
|
await (0, git_1.checkoutBranch)(branchName);
|
|
30
33
|
let messagesLoadedFromDisk = chatState?.messages || [];
|
|
31
|
-
let chatModel = (0,
|
|
34
|
+
let chatModel = (0, chat_1.createChatModel)(messagesLoadedFromDisk, selectedModel);
|
|
32
35
|
if (initialPromptContent && chatModel.messages.length === 0) {
|
|
33
36
|
chatModel.pushUserMessage(initialPromptContent);
|
|
34
37
|
chatModel.askUserForInput = false;
|
|
@@ -52,7 +55,7 @@ async function runChatAgentForCLI({ useDiskForChatState, selectedModel, initialP
|
|
|
52
55
|
let userPrompt;
|
|
53
56
|
let reporterFunc = async (chatState, latest) => {
|
|
54
57
|
if (useDiskForChatState) {
|
|
55
|
-
(0, state_1.saveToDisk)(chatState.messages, selectedModel);
|
|
58
|
+
(0, state_1.saveToDisk)(chatState.messages, selectedModel, chatState.askUserForInput);
|
|
56
59
|
}
|
|
57
60
|
if (latest) {
|
|
58
61
|
console.log(`${(0, picocolors_1.blue)(latest.role)}: ${latest.textMessage}`);
|
|
@@ -89,12 +92,15 @@ async function runChatAgentForCLI({ useDiskForChatState, selectedModel, initialP
|
|
|
89
92
|
else {
|
|
90
93
|
// TODO: Should we pass a loader function? That would allow us to show a spinner
|
|
91
94
|
const toolCallService = new tool_call_service_1.ToolCallService(null, selectedModel, branchName);
|
|
95
|
+
const fileInfo = await (0, file_tree_1.getFileInfoFromFS)(process.cwd());
|
|
92
96
|
await (0, agent_loop_1.chatAgentLoop)({
|
|
93
97
|
chatModel,
|
|
94
98
|
selectedModel,
|
|
95
99
|
reporter: reporterFunc,
|
|
96
100
|
trace,
|
|
97
101
|
toolCallService,
|
|
102
|
+
fileInfo,
|
|
103
|
+
isToolExecutionRemote: false,
|
|
98
104
|
});
|
|
99
105
|
}
|
|
100
106
|
}
|
|
@@ -107,8 +113,6 @@ async function runChatAgentForCLI({ useDiskForChatState, selectedModel, initialP
|
|
|
107
113
|
const usageSummary = chatModel.getUsageSummary();
|
|
108
114
|
console.log(`\n${(0, picocolors_1.gray)("Usage summary -> " + usageSummary)}`);
|
|
109
115
|
}
|
|
110
|
-
exports.runChatAgentForCLI = runChatAgentForCLI;
|
|
111
|
-
const DASHBOARD_DOMAIN = process.env.DASHBOARD_DOMAIN || "https://dash.empirical.run";
|
|
112
116
|
async function getChatSessionFromDashboard(chatSessionId) {
|
|
113
117
|
const response = await fetch(`${DASHBOARD_DOMAIN}/api/chat-sessions/${chatSessionId}`, {
|
|
114
118
|
headers: {
|
|
@@ -124,7 +128,11 @@ async function getChatSessionFromDashboard(chatSessionId) {
|
|
|
124
128
|
}
|
|
125
129
|
async function runChatAgentForDashboard({ chatSessionId, selectedModel, }) {
|
|
126
130
|
const chatSession = await getChatSessionFromDashboard(chatSessionId);
|
|
127
|
-
|
|
131
|
+
let chatState = chatSession.chat_state;
|
|
132
|
+
// If not already canonical, migrate to canonical format
|
|
133
|
+
if (!chatState.version || chatState.version !== state_1.LATEST_CHAT_STATE_VERSION) {
|
|
134
|
+
chatState = (0, state_1.migrateChatState)(chatState);
|
|
135
|
+
}
|
|
128
136
|
const branchName = chatSession.branch_name;
|
|
129
137
|
const trace = llm_1.langfuseInstance?.trace({
|
|
130
138
|
id: chatSession.langfuse_trace_id,
|
|
@@ -137,7 +145,7 @@ async function runChatAgentForDashboard({ chatSessionId, selectedModel, }) {
|
|
|
137
145
|
});
|
|
138
146
|
const toolCallService = new tool_call_service_1.ToolCallService(chatSessionId, selectedModel, branchName);
|
|
139
147
|
await (0, git_1.checkoutBranch)(branchName);
|
|
140
|
-
let chatModel = (0,
|
|
148
|
+
let chatModel = (0, chat_1.createChatModel)(chatState.messages, selectedModel);
|
|
141
149
|
let reporterFunc = async (chatState, latest) => {
|
|
142
150
|
const response = await fetch(`${DASHBOARD_DOMAIN}/api/chat-sessions/${chatSessionId}`, {
|
|
143
151
|
method: "PATCH",
|
|
@@ -153,12 +161,14 @@ async function runChatAgentForDashboard({ chatSessionId, selectedModel, }) {
|
|
|
153
161
|
const data = await response.json();
|
|
154
162
|
console.log(`Patch request sent for chat session: ${JSON.stringify(data)}`);
|
|
155
163
|
};
|
|
164
|
+
const fileInfo = await (0, file_tree_1.getFileInfoFromFS)(process.cwd());
|
|
156
165
|
await (0, agent_loop_1.chatAgentLoop)({
|
|
157
166
|
chatModel,
|
|
158
167
|
selectedModel,
|
|
159
168
|
reporter: reporterFunc,
|
|
160
169
|
trace,
|
|
161
170
|
toolCallService,
|
|
171
|
+
fileInfo,
|
|
172
|
+
isToolExecutionRemote: false,
|
|
162
173
|
});
|
|
163
174
|
}
|
|
164
|
-
exports.runChatAgentForDashboard = runChatAgentForDashboard;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { ModelInfo } from "@empiricalrun/shared-types";
|
|
2
|
+
export declare const SUPPORTED_CHAT_MODELS: readonly ModelInfo[];
|
|
3
|
+
export type SupportedChatModels = (typeof SUPPORTED_CHAT_MODELS)[number]["id"];
|
|
4
|
+
export declare const defaultModel: SupportedChatModels;
|
|
5
|
+
export declare const modelLabels: Record<SupportedChatModels, string>;
|
|
6
|
+
//# sourceMappingURL=models.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"models.d.ts","sourceRoot":"","sources":["../../../src/agent/chat/models.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAE5D,eAAO,MAAM,qBAAqB,EAAE,SAAS,SAAS,EAqB5C,CAAC;AAEX,MAAM,MAAM,mBAAmB,GAAG,CAAC,OAAO,qBAAqB,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC;AAW/E,eAAO,MAAM,YAAY,EAAE,mBAA6C,CAAC;AAEzE,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,mBAAmB,EAAE,MAAM,CAOzD,CAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.modelLabels = exports.defaultModel = exports.SUPPORTED_CHAT_MODELS = void 0;
|
|
4
|
+
exports.SUPPORTED_CHAT_MODELS = [
|
|
5
|
+
{
|
|
6
|
+
id: "gemini-2.5-pro-preview-03-25",
|
|
7
|
+
label: "Gemini 2.5 Pro",
|
|
8
|
+
provider: "google",
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
id: "o4-mini-2025-04-16",
|
|
12
|
+
label: "OpenAI O4 Mini",
|
|
13
|
+
provider: "openai",
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
id: "claude-3-7-sonnet-20250219",
|
|
17
|
+
label: "Claude 3.7 Sonnet",
|
|
18
|
+
provider: "claude",
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
id: "claude-3-5-sonnet-20241022",
|
|
22
|
+
label: "Claude 3.5 Sonnet",
|
|
23
|
+
provider: "claude",
|
|
24
|
+
},
|
|
25
|
+
];
|
|
26
|
+
const DEFAULT_CHAT_MODEL_ID = "gemini-2.5-pro-preview-03-25";
|
|
27
|
+
function getDefaultChatModelId() {
|
|
28
|
+
if (!exports.SUPPORTED_CHAT_MODELS.some((m) => m.id === DEFAULT_CHAT_MODEL_ID)) {
|
|
29
|
+
throw new Error("Default chat model is not in SUPPORTED_CHAT_MODELS");
|
|
30
|
+
}
|
|
31
|
+
return DEFAULT_CHAT_MODEL_ID;
|
|
32
|
+
}
|
|
33
|
+
exports.defaultModel = getDefaultChatModelId();
|
|
34
|
+
exports.modelLabels = exports.SUPPORTED_CHAT_MODELS.reduce((acc, model) => ({
|
|
35
|
+
...acc,
|
|
36
|
+
[model.id]: model.label,
|
|
37
|
+
}), {});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../../../src/agent/chat/prompt.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../../../src/agent/chat/prompt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAGvC,wBAAsB,iBAAiB,CAAC,QAAQ,EAAE,QAAQ,mBAiGzD"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.buildSystemPrompt =
|
|
3
|
+
exports.buildSystemPrompt = buildSystemPrompt;
|
|
4
4
|
const repo_1 = require("./repo");
|
|
5
|
-
async function buildSystemPrompt() {
|
|
6
|
-
const repoContext = await (0, repo_1.
|
|
5
|
+
async function buildSystemPrompt(fileInfo) {
|
|
6
|
+
const repoContext = await (0, repo_1.getRepoInfoPrompt)(fileInfo);
|
|
7
7
|
return `
|
|
8
8
|
You are a helpful assistant that can answer questions and help with tasks related to writing
|
|
9
9
|
and maintaining Playwright tests.
|
|
@@ -52,23 +52,51 @@ The position of the comment is important: the browser agent will look for this c
|
|
|
52
52
|
the actual code to click on the login button. If you are fixing a failing test, your comment should be
|
|
53
53
|
around the failing line of code, so that it can be replaced/modified.
|
|
54
54
|
|
|
55
|
-
#
|
|
55
|
+
# Proactiveness
|
|
56
|
+
|
|
57
|
+
1. You are allowed to be proactive, but ONLY for read-only tool calls: like searching for content, reading files, fetching data from tools, and
|
|
58
|
+
running Playwright tests.
|
|
59
|
+
2. For any read-write tool calls (e.g. modifying any file), you should share your plan and get the user's approval before proceeding.
|
|
60
|
+
|
|
61
|
+
# Rules to follow
|
|
56
62
|
|
|
57
63
|
You must follow these rules while adding new tests or modifying existing tests. There can be exceptions to these rules, but
|
|
58
64
|
ONLY when explicitly asked for by the user.
|
|
59
65
|
|
|
60
|
-
1.
|
|
61
|
-
2.
|
|
62
|
-
3.
|
|
63
|
-
4.
|
|
66
|
+
1. You can't delete some steps from the test to make it pass. The test needs to accomplish its objective (which is to validate a particular user scenario)
|
|
67
|
+
2. Do not add any conditional logic or try catch blocks in a test. A good test deterministically tests a user scenario
|
|
68
|
+
3. Trust Playwright's ability to auto-wait while taking actions on elements. For example, do not add checks on locator.isVisible() before clicking on it: Playwright already does this
|
|
69
|
+
4. Do not add waitForTimeout or waitForLoadState in a test. Playwright will automatically wait for the page to load.
|
|
70
|
+
5. Try/catch blocks are a code smell for tests: you should not use them.
|
|
71
|
+
6. Do not use then() or catch() syntax in a test. Use async/await only
|
|
64
72
|
|
|
65
|
-
|
|
73
|
+
There are few exceptions to these rules. BEFORE applying any of the following exceptions, you MUST share your plan with the user and get their approval.
|
|
74
|
+
|
|
75
|
+
## Exceptions for conditional logic
|
|
76
|
+
|
|
77
|
+
There are few exceptions where you can add conditional logic to a test. If the application UI reveals some UI elements on certain conditions, we can add conditional logic.
|
|
66
78
|
|
|
67
|
-
|
|
68
|
-
|
|
79
|
+
For example, a form view shows a "Save" button only when the form is dirty. In this case, we will have to check if the "Save" button is visible before clicking on it. To do this,
|
|
80
|
+
follow this pattern:
|
|
81
|
+
|
|
82
|
+
\`\`\`
|
|
83
|
+
const saveButton = page.getByRole('button', { name: 'Save' });
|
|
84
|
+
if (await saveButton.isVisible()) {
|
|
85
|
+
await saveButton.click();
|
|
86
|
+
}
|
|
87
|
+
\`\`\`
|
|
88
|
+
|
|
89
|
+
Note that locator.isVisible() DOES NOT wait for the element to be visible. If the element in question shows up after a delay, we have no option but to add a waitForTimeout.
|
|
90
|
+
|
|
91
|
+
\`\`\`
|
|
92
|
+
const saveButton = page.getByRole('button', { name: 'Save' });
|
|
93
|
+
await page.waitForTimeout(100); // Wait for the element to be visible -- only if necessary.
|
|
94
|
+
if (await saveButton.isVisible()) {
|
|
95
|
+
await saveButton.click();
|
|
96
|
+
}
|
|
97
|
+
\`\`\`
|
|
69
98
|
|
|
70
99
|
# Repo context
|
|
71
100
|
${repoContext}
|
|
72
101
|
`;
|
|
73
102
|
}
|
|
74
|
-
exports.buildSystemPrompt = buildSystemPrompt;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"repo.d.ts","sourceRoot":"","sources":["../../../src/agent/chat/repo.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"repo.d.ts","sourceRoot":"","sources":["../../../src/agent/chat/repo.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAwCvC,wBAAsB,iBAAiB,CAAC,SAAS,EAAE,QAAQ,mBAyC1D"}
|
package/dist/agent/chat/repo.js
CHANGED
|
@@ -3,28 +3,28 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.
|
|
7
|
-
const fs_1 = __importDefault(require("fs"));
|
|
6
|
+
exports.getRepoInfoPrompt = getRepoInfoPrompt;
|
|
8
7
|
const path_1 = __importDefault(require("path"));
|
|
9
8
|
const repo_tree_1 = require("../../utils/repo-tree");
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
const dir = path_1.default.join(process.cwd(), ".empiricalrun");
|
|
13
|
-
if (!fs_1.default.existsSync(dir)) {
|
|
9
|
+
async function getAllMarkdownFiles(directory) {
|
|
10
|
+
if (!directory.isDirectory) {
|
|
14
11
|
return [];
|
|
15
12
|
}
|
|
16
|
-
const files =
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
13
|
+
const files = directory.children.find((child) => child.isDirectory && child.path === ".empiricalrun")?.children;
|
|
14
|
+
if (!files) {
|
|
15
|
+
return [];
|
|
16
|
+
}
|
|
17
|
+
return Promise.all(files
|
|
18
|
+
.filter((file) => file.isFile && file.path.endsWith(".md"))
|
|
19
|
+
.map(async (file) => {
|
|
20
20
|
return {
|
|
21
|
-
name: file,
|
|
22
|
-
content:
|
|
21
|
+
name: path_1.default.basename(file.path),
|
|
22
|
+
content: await file.getContent(),
|
|
23
23
|
};
|
|
24
|
-
});
|
|
24
|
+
}));
|
|
25
25
|
}
|
|
26
|
-
async function knowledgeContext() {
|
|
27
|
-
const mdFiles = await getAllMarkdownFiles();
|
|
26
|
+
async function knowledgeContext(directory) {
|
|
27
|
+
const mdFiles = await getAllMarkdownFiles(directory);
|
|
28
28
|
const knowledge = mdFiles.map((file) => {
|
|
29
29
|
return `
|
|
30
30
|
<knowledge_file>
|
|
@@ -37,35 +37,32 @@ async function knowledgeContext() {
|
|
|
37
37
|
});
|
|
38
38
|
return knowledge.join("\n");
|
|
39
39
|
}
|
|
40
|
-
async function
|
|
40
|
+
async function getRepoInfoPrompt(directory) {
|
|
41
41
|
let REPO_CONTEXT_PROMPT = `
|
|
42
42
|
You are running as a CLI tool inside the directory of the repo that has Playwright tests.
|
|
43
43
|
|
|
44
44
|
Here is the repo directory structure:
|
|
45
45
|
|
|
46
|
-
${(0, repo_tree_1.generateAsciiTree)(
|
|
46
|
+
${(0, repo_tree_1.generateAsciiTree)(directory)}
|
|
47
47
|
|
|
48
48
|
While specifying paths to files, use relative paths from the current working directory. For example:
|
|
49
49
|
- Correct path: "tests/lesson.spec.ts"
|
|
50
|
-
- Incorrect path: "/repo/tests/lesson.spec.ts" or "${
|
|
50
|
+
- Incorrect path: "/repo/tests/lesson.spec.ts" or "${directory.name}/tests/lesson.spec.ts"
|
|
51
51
|
`;
|
|
52
|
-
try {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
## Playwright configuration
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
console.warn("Failed to read playwright config", error);
|
|
67
|
-
}
|
|
68
|
-
const knowledge = await knowledgeContext();
|
|
52
|
+
// try {
|
|
53
|
+
// const playwrightConfig = await readPlaywrightConfig(process.cwd());
|
|
54
|
+
// const validProjectNames = await getValidProjectNames(playwrightConfig);
|
|
55
|
+
// if (validProjectNames.length > 0) {
|
|
56
|
+
// REPO_CONTEXT_PROMPT += `
|
|
57
|
+
// ## Playwright configuration
|
|
58
|
+
// This repo is configured with these Playwright projects (in the playwright.config.ts file):
|
|
59
|
+
// ${validProjectNames.map((name) => `- ${name}`).join("\n")}
|
|
60
|
+
// `;
|
|
61
|
+
// }
|
|
62
|
+
// } catch (error) {
|
|
63
|
+
// console.warn("Failed to read playwright config", error);
|
|
64
|
+
// }
|
|
65
|
+
const knowledge = await knowledgeContext(directory);
|
|
69
66
|
if (knowledge.length > 0) {
|
|
70
67
|
REPO_CONTEXT_PROMPT += `
|
|
71
68
|
## Repo-specific knowledge
|
|
@@ -78,4 +75,3 @@ ${knowledge}
|
|
|
78
75
|
}
|
|
79
76
|
return REPO_CONTEXT_PROMPT;
|
|
80
77
|
}
|
|
81
|
-
exports.getRepoContext = getRepoContext;
|
|
@@ -1,15 +1,23 @@
|
|
|
1
|
-
import { IChatModel } from "@empiricalrun/llm/chat";
|
|
2
|
-
import {
|
|
3
|
-
export declare const
|
|
1
|
+
import { IChatModel, SupportedChatModels } from "@empiricalrun/llm/chat";
|
|
2
|
+
import { CanonicalMessage, ChatState } from "@empiricalrun/shared-types";
|
|
3
|
+
export declare const CHAT_STATE_VERSIONS_MIGRATIONS_MAP: Record<string, (state: any) => any>;
|
|
4
|
+
export declare const LATEST_CHAT_STATE_VERSION = "0.1";
|
|
4
5
|
export declare const CHAT_STATE_PATH: string;
|
|
5
6
|
export type ChatStateOnDisk<T> = {
|
|
6
7
|
version: string;
|
|
7
8
|
model: SupportedChatModels;
|
|
8
9
|
messages: T[];
|
|
10
|
+
askUserForInput: boolean;
|
|
9
11
|
};
|
|
10
|
-
export declare function createChatState(userPrompt: string, existingState: ChatStateOnDisk<any> | undefined, selectedModel: SupportedChatModels): ChatStateOnDisk<unknown>;
|
|
11
|
-
export declare function createChatStateForMessages<T>(messages: any, selectedModel: SupportedChatModels): ChatStateOnDisk<T>;
|
|
12
|
+
export declare function createChatState(userPrompt: string | undefined, existingState: ChatStateOnDisk<any> | undefined, selectedModel: SupportedChatModels): ChatStateOnDisk<unknown>;
|
|
13
|
+
export declare function createChatStateForMessages<T>(messages: any, selectedModel: SupportedChatModels, askUserForInput: boolean): ChatStateOnDisk<T>;
|
|
12
14
|
export declare function chatStateFromModel<T>(chatModel: IChatModel<T>, selectedModel: SupportedChatModels): ChatStateOnDisk<unknown>;
|
|
13
|
-
export declare function loadChatState
|
|
14
|
-
|
|
15
|
+
export declare function loadChatState(): ChatState | undefined;
|
|
16
|
+
/**
|
|
17
|
+
* Migrates a chat state object from an old version to the latest version.
|
|
18
|
+
* Add migration logic for each version as needed.
|
|
19
|
+
*/
|
|
20
|
+
export declare function migrateChatState<T = any>(oldState: any): ChatStateOnDisk<T>;
|
|
21
|
+
export declare function saveToDisk<T>(messages: Array<T>, selectedModel: SupportedChatModels, askUserForInput: boolean): void;
|
|
22
|
+
export declare function getLatestDownloadBuildUrl(messages: CanonicalMessage[]): string | null;
|
|
15
23
|
//# sourceMappingURL=state.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../../src/agent/chat/state.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../../src/agent/chat/state.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,UAAU,EACV,mBAAmB,EACpB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AA+BzE,eAAO,MAAM,kCAAkC,EAAE,MAAM,CACrD,MAAM,EACN,CAAC,KAAK,EAAE,GAAG,KAAK,GAAG,CAIpB,CAAC;AAEF,eAAO,MAAM,yBAAyB,QAAQ,CAAC;AAE/C,eAAO,MAAM,eAAe,QAI3B,CAAC;AAEF,MAAM,MAAM,eAAe,CAAC,CAAC,IAAI;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,mBAAmB,CAAC;IAC3B,QAAQ,EAAE,CAAC,EAAE,CAAC;IACd,eAAe,EAAE,OAAO,CAAC;CAC1B,CAAC;AAEF,wBAAgB,eAAe,CAC7B,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,aAAa,EAAE,eAAe,CAAC,GAAG,CAAC,GAAG,SAAS,EAC/C,aAAa,EAAE,mBAAmB,4BAYnC;AAED,wBAAgB,0BAA0B,CAAC,CAAC,EAC1C,QAAQ,EAAE,GAAG,EACb,aAAa,EAAE,mBAAmB,EAClC,eAAe,EAAE,OAAO,GACvB,eAAe,CAAC,CAAC,CAAC,CAQpB;AAED,wBAAgB,kBAAkB,CAAC,CAAC,EAClC,SAAS,EAAE,UAAU,CAAC,CAAC,CAAC,EACxB,aAAa,EAAE,mBAAmB,4BAOnC;AAED,wBAAgB,aAAa,IAAI,SAAS,GAAG,SAAS,CAarD;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,GAAG,GAAG,EAAE,QAAQ,EAAE,GAAG,GAAG,eAAe,CAAC,CAAC,CAAC,CAqB3E;AAED,wBAAgB,UAAU,CAAC,CAAC,EAC1B,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,EAClB,aAAa,EAAE,mBAAmB,EAClC,eAAe,EAAE,OAAO,QAezB;AAED,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,gBAAgB,EAAE,GAC3B,MAAM,GAAG,IAAI,CAqBf"}
|
package/dist/agent/chat/state.js
CHANGED
|
@@ -3,64 +3,127 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.
|
|
6
|
+
exports.CHAT_STATE_PATH = exports.LATEST_CHAT_STATE_VERSION = exports.CHAT_STATE_VERSIONS_MIGRATIONS_MAP = void 0;
|
|
7
|
+
exports.createChatState = createChatState;
|
|
8
|
+
exports.createChatStateForMessages = createChatStateForMessages;
|
|
9
|
+
exports.chatStateFromModel = chatStateFromModel;
|
|
10
|
+
exports.loadChatState = loadChatState;
|
|
11
|
+
exports.migrateChatState = migrateChatState;
|
|
12
|
+
exports.saveToDisk = saveToDisk;
|
|
13
|
+
exports.getLatestDownloadBuildUrl = getLatestDownloadBuildUrl;
|
|
14
|
+
const chat_1 = require("@empiricalrun/llm/chat");
|
|
7
15
|
const fs_1 = __importDefault(require("fs"));
|
|
8
16
|
const path_1 = __importDefault(require("path"));
|
|
9
|
-
|
|
10
|
-
|
|
17
|
+
// Migration wrapper for v20250327.1 -> v0.1 chat state versions
|
|
18
|
+
// v20250327.1 was model-specific, but v0.1 is canonical
|
|
19
|
+
function migrateToV01(oldState) {
|
|
20
|
+
if (oldState.model &&
|
|
21
|
+
typeof oldState.model === "string" &&
|
|
22
|
+
Array.isArray(oldState.messages)) {
|
|
23
|
+
const provider = (0, chat_1.getProviderForModel)(oldState.model);
|
|
24
|
+
if (provider === "google") {
|
|
25
|
+
return {
|
|
26
|
+
...oldState,
|
|
27
|
+
version: "0.1",
|
|
28
|
+
messages: oldState.messages.map(chat_1.geminiToCanonical),
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
throw new Error(`Unsupported state for migration with model: ${oldState.model} and version: ${oldState.version}`);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
// If not Gemini or not matching, return the old state
|
|
36
|
+
return oldState;
|
|
37
|
+
}
|
|
38
|
+
exports.CHAT_STATE_VERSIONS_MIGRATIONS_MAP = {
|
|
39
|
+
"20250327.1": migrateToV01,
|
|
40
|
+
"0.1": (state) => state,
|
|
41
|
+
};
|
|
42
|
+
exports.LATEST_CHAT_STATE_VERSION = "0.1";
|
|
11
43
|
exports.CHAT_STATE_PATH = path_1.default.join(process.cwd(), ".empiricalrun", "last-chat.json");
|
|
12
44
|
function createChatState(userPrompt, existingState, selectedModel) {
|
|
13
45
|
const messages = existingState?.messages || [];
|
|
14
|
-
const chatModel = (0,
|
|
15
|
-
|
|
16
|
-
|
|
46
|
+
const chatModel = (0, chat_1.createChatModel)(messages, selectedModel);
|
|
47
|
+
if (userPrompt) {
|
|
48
|
+
chatModel.pushUserMessage(userPrompt);
|
|
49
|
+
}
|
|
50
|
+
return createChatStateForMessages(chatModel.messages, selectedModel, chatModel.askUserForInput);
|
|
17
51
|
}
|
|
18
|
-
|
|
19
|
-
function createChatStateForMessages(messages, selectedModel) {
|
|
52
|
+
function createChatStateForMessages(messages, selectedModel, askUserForInput) {
|
|
20
53
|
// TODO: Add better types for messages
|
|
21
54
|
return {
|
|
22
|
-
version: exports.
|
|
55
|
+
version: exports.LATEST_CHAT_STATE_VERSION,
|
|
23
56
|
model: selectedModel,
|
|
24
57
|
messages: messages,
|
|
58
|
+
askUserForInput: askUserForInput,
|
|
25
59
|
};
|
|
26
60
|
}
|
|
27
|
-
exports.createChatStateForMessages = createChatStateForMessages;
|
|
28
61
|
function chatStateFromModel(chatModel, selectedModel) {
|
|
29
|
-
return createChatStateForMessages(chatModel.messages, selectedModel);
|
|
62
|
+
return createChatStateForMessages(chatModel.messages, selectedModel, chatModel.askUserForInput);
|
|
30
63
|
}
|
|
31
|
-
exports.chatStateFromModel = chatStateFromModel;
|
|
32
64
|
function loadChatState() {
|
|
33
65
|
if (!fs_1.default.existsSync(exports.CHAT_STATE_PATH)) {
|
|
34
66
|
return undefined;
|
|
35
67
|
}
|
|
36
68
|
const raw = fs_1.default.readFileSync(exports.CHAT_STATE_PATH, "utf8");
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
69
|
+
let state = JSON.parse(raw);
|
|
70
|
+
// Always migrate to the latest version after loading
|
|
71
|
+
const migratedState = migrateChatState(state);
|
|
72
|
+
// Only save if migration actually changed the state
|
|
73
|
+
if (JSON.stringify(state) !== JSON.stringify(migratedState)) {
|
|
74
|
+
fs_1.default.writeFileSync(exports.CHAT_STATE_PATH, JSON.stringify(migratedState, null, 2));
|
|
40
75
|
}
|
|
41
|
-
return
|
|
76
|
+
return migratedState;
|
|
42
77
|
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
78
|
+
/**
|
|
79
|
+
* Migrates a chat state object from an old version to the latest version.
|
|
80
|
+
* Add migration logic for each version as needed.
|
|
81
|
+
*/
|
|
82
|
+
function migrateChatState(oldState) {
|
|
83
|
+
if (!oldState || Object.keys(oldState).length === 0) {
|
|
84
|
+
return oldState;
|
|
85
|
+
}
|
|
86
|
+
if (!oldState.version) {
|
|
87
|
+
throw new Error("No version found in chat state");
|
|
88
|
+
}
|
|
89
|
+
if (!exports.CHAT_STATE_VERSIONS_MIGRATIONS_MAP[oldState.version]) {
|
|
90
|
+
throw new Error(`No migration function found for version: ${oldState.version}`);
|
|
91
|
+
}
|
|
92
|
+
if (oldState.version === exports.LATEST_CHAT_STATE_VERSION) {
|
|
93
|
+
return oldState;
|
|
94
|
+
}
|
|
95
|
+
const migrateFn = exports.CHAT_STATE_VERSIONS_MIGRATIONS_MAP[oldState.version];
|
|
96
|
+
const migrated = migrateFn(oldState);
|
|
97
|
+
return {
|
|
98
|
+
version: exports.LATEST_CHAT_STATE_VERSION,
|
|
99
|
+
...migrated,
|
|
50
100
|
};
|
|
101
|
+
}
|
|
102
|
+
function saveToDisk(messages, selectedModel, askUserForInput) {
|
|
103
|
+
const statePath = exports.CHAT_STATE_PATH;
|
|
51
104
|
// Ensure directory exists before trying to read/write
|
|
52
105
|
const dirname = path_1.default.dirname(statePath);
|
|
53
106
|
if (!fs_1.default.existsSync(dirname)) {
|
|
54
107
|
fs_1.default.mkdirSync(dirname, { recursive: true });
|
|
55
108
|
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
}
|
|
59
|
-
const newState = {
|
|
60
|
-
...existingState,
|
|
61
|
-
messages: messages,
|
|
62
|
-
model: selectedModel,
|
|
63
|
-
};
|
|
109
|
+
// Use the helper to build the new state
|
|
110
|
+
const newState = createChatStateForMessages(messages, selectedModel, askUserForInput);
|
|
64
111
|
fs_1.default.writeFileSync(statePath, JSON.stringify(newState, null, 2));
|
|
65
112
|
}
|
|
66
|
-
|
|
113
|
+
function getLatestDownloadBuildUrl(messages) {
|
|
114
|
+
const toolCallMessage = messages
|
|
115
|
+
.sort((a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime())
|
|
116
|
+
.find((p) => p.parts.find((p) => {
|
|
117
|
+
if ("toolCall" in p) {
|
|
118
|
+
return p.toolCall?.name === "downloadBuild";
|
|
119
|
+
}
|
|
120
|
+
return false;
|
|
121
|
+
}));
|
|
122
|
+
if (!toolCallMessage)
|
|
123
|
+
return null;
|
|
124
|
+
const toolCallPart = toolCallMessage.parts.find((p) => "toolCall" in p && p.toolCall?.name === "downloadBuild");
|
|
125
|
+
if (!toolCallPart || !("toolCall" in toolCallPart))
|
|
126
|
+
return null;
|
|
127
|
+
const input = toolCallPart.toolCall.input;
|
|
128
|
+
return input.buildUrl;
|
|
129
|
+
}
|