////////////////////////////////////////////////////////////////////////////////
// Stage 3: Conceptualising ...
////////////////////////////////////////////////////////////////////////////////First, we need to modify the notifyExecutionsUpdatedImmediate function by adding an optional boolean parameter named importantUpdate with a default value of false. We will use this parameter to determine whether or not we need to report the update to the AnalyticsManager.
// Add importantUpdate parameter with a default value of false
async notifyExecutionsUpdatedImmediate(minionTask?: MinionTask, importantUpdate: boolean = false) {
[...]
}
Next, we need to change the call to AnalyticsManager.instance.reportOrUpdateMinionTask(minionTask); by wrapping it with a condition to only execute the call if importantUpdate is set to true.
if (minionTask && importantUpdate) {
AnalyticsManager.instance.reportOrUpdateMinionTask(minionTask);
}
Lastly, we need to update the calls to this function, for example, in the reRunExecution function where it calls this.notifyExecutionsUpdatedImmediate(newExecution);, we should pass true when the update is important.
I hope this helps! Let me know if you need any more assistance or clarification.
////////////////////////////////////////////////////////////////////////////////
// Stage 4: Preparing Changes ...
////////////////////////////////////////////////////////////////////////////////I will modify the notifyExecutionsUpdatedImmediate function by adding an optional boolean parameter named importantUpdate with a default value of false. Then, I will wrap the call to AnalyticsManager.instance.reportOrUpdateMinionTask(minionTask); with a condition to only execute the call if importantUpdate is set to true. Finally, I will update the calls to this function, such as in the reRunExecution function, to pass true when the update is important.
// Create an EventEmitter to handle document updates
private _onDidChangeEmitter = new vscode.EventEmitter();
// Use the getter to expose the onDidChange event using EventEmitter's event property
get onDidChange(): vscode.Event | undefined {
return this._onDidChangeEmitter.event;
}
reportChange(uri: vscode.Uri) {
// Emit the event to notify subscribers of the change in the URI
this._onDidChangeEmitter.fire(uri);
}
if (!oldExecutionMaybe) {
vscode.window.showErrorMessage("No execution found for id", executionId);
throw new Error(`No execution found for id ${executionId}`);
}
let oldExecution = oldExecutionMaybe;
if (!oldExecution.stopped) {
vscode.window.showErrorMessage("Execution is still running", executionId);
return;
}
await oldExecution.run();
this.notifyExecutionsUpdatedImmediate(oldExecution);
if (!oldExecutionMaybe) {
vscode.window.showErrorMessage("No execution found for id", executionId);
throw new Error(`No execution found for id ${executionId}`);
}
let oldExecution = oldExecutionMaybe;
if (!oldExecution.stopped) {
vscode.window.showErrorMessage("Execution is still running", executionId);
return;
}
//remove old execution
this.executions = this.executions.filter((e) => e.id !== executionId);
this.notifyExecutionsUpdatedImmediate(oldExecution);
//after 1 second add a new one
setTimeout(async () => {
let newExecution = await MinionTask.create({
userQuery: newUserQuery || oldExecution.userQuery,
document: await oldExecution.document(),
selection: oldExecution.selection,
selectedText: oldExecution.selectedText,
minionIndex: oldExecution.minionIndex,
onChanged: async (important) => {
if (important) {
this.notifyExecutionsUpdatedImmediate(newExecution);
} else {
this.notifyExecutionsUpdated(newExecution);
}
},
});
const runningExecution = this.getRunningExecution(newExecution.documentURI);
this.executions = [newExecution, ...this.executions.filter((e) => e.id !== executionId)];
// Set the waiting flag if there's a running execution on the same file
if (runningExecution) {
newExecution.shortName = "Queued ...";
newExecution.progress = 0;
newExecution.waiting = true;
} else {
await newExecution.run();
}
this.notifyExecutionsUpdatedImmediate(newExecution);
}, 500);
}
}
////////////////////////////////////////////////////////////////////////////////
// Stage 6: Preparing Changes (retry) ...
////////////////////////////////////////////////////////////////////////////////I will modify the notifyExecutionsUpdatedImmediate function by adding an optional boolean parameter named importantUpdate with a default value of false. Then, I will wrap the call to AnalyticsManager.instance.reportOrUpdateMinionTask(minionTask); with a condition to only execute the call if importantUpdate is set to true. Finally, I will update the calls to this function, such as in the reRunExecution function, to pass true when the update is important.
// Create an EventEmitter to handle document updates
private _onDidChangeEmitter = new vscode.EventEmitter();
// Use the getter to expose the onDidChange event using EventEmitter's event property
get onDidChange(): vscode.Event | undefined {
return this._onDidChangeEmitter.event;
}
reportChange(uri: vscode.Uri) {
// Emit the event to notify subscribers of the change in the URI
this._onDidChangeEmitter.fire(uri);
}
if (!oldExecutionMaybe) {
vscode.window.showErrorMessage("No execution found for id", executionId);
throw new Error(`No execution found for id ${executionId}`);
}
let oldExecution = oldExecutionMaybe;
if (!oldExecution.stopped) {
vscode.window.showErrorMessage("Execution is still running", executionId);
return;
}
await oldExecution.run();
this.notifyExecutionsUpdatedImmediate(oldExecution);
if (!oldExecutionMaybe) {
vscode.window.showErrorMessage("No execution found for id", executionId);
throw new Error(`No execution found for id ${executionId}`);
}
let oldExecution = oldExecutionMaybe;
if (!oldExecution.stopped) {
vscode.window.showErrorMessage("Execution is still running", executionId);
return;
}
//remove old execution
this.executions = this.executions.filter((e) => e.id !== executionId);
this.notifyExecutionsUpdatedImmediate(oldExecution);
//after 1 second add a new one
setTimeout(async () => {
let newExecution = await MinionTask.create({
userQuery: newUserQuery || oldExecution.userQuery,
document: await oldExecution.document(),
selection: oldExecution.selection,
selectedText: oldExecution.selectedText,
minionIndex: oldExecution.minionIndex,
onChanged: async (important) => {
if (important) {
this.notifyExecutionsUpdatedImmediate(newExecution);
} else {
this.notifyExecutionsUpdated(newExecution);
}
},
});
const runningExecution = this.getRunningExecution(newExecution.documentURI);
this.executions = [newExecution, ...this.executions.filter((e) => e.id !== executionId)];
// Set the waiting flag if there's a running execution on the same file
if (runningExecution) {
newExecution.shortName = "Queued ...";
newExecution.progress = 0;
newExecution.waiting = true;
} else {
await newExecution.run();
}
this.notifyExecutionsUpdatedImmediate(newExecution);
}, 500);
File: ExecutionsManager.ts Task: Report this only when it's an important update, otherwise not.
//////////////////////////////////////////////////////////////////////////////// // Stage 2: Understanding ... ////////////////////////////////////////////////////////////////////////////////* LocalChange
Classification: LocalChange
//////////////////////////////////////////////////////////////////////////////// // Stage 3: Conceptualising ... ////////////////////////////////////////////////////////////////////////////////First, we need to modify the
notifyExecutionsUpdatedImmediate
function by adding an optional boolean parameter namedimportantUpdate
with a default value offalse
. We will use this parameter to determine whether or not we need to report the update to theAnalyticsManager
.Next, we need to change the call to
AnalyticsManager.instance.reportOrUpdateMinionTask(minionTask);
by wrapping it with a condition to only execute the call ifimportantUpdate
is set totrue
.Lastly, we need to update the calls to this function, for example, in the
reRunExecution
function where it callsthis.notifyExecutionsUpdatedImmediate(newExecution);
, we should passtrue
when the update is important.I hope this helps! Let me know if you need any more assistance or clarification.
//////////////////////////////////////////////////////////////////////////////// // Stage 4: Preparing Changes ... ////////////////////////////////////////////////////////////////////////////////I will modify the
notifyExecutionsUpdatedImmediate
function by adding an optional boolean parameter namedimportantUpdate
with a default value offalse
. Then, I will wrap the call toAnalyticsManager.instance.reportOrUpdateMinionTask(minionTask);
with a condition to only execute the call ifimportantUpdate
is set totrue
. Finally, I will update the calls to this function, such as in thereRunExecution
function, to passtrue
when the update is important.REPLACE async notifyExecutionsUpdatedImmediate(minionTask?: MinionTask) { WITH async notifyExecutionsUpdatedImmediate(minionTask?: MinionTask, importantUpdate: boolean = false) { END_REPLACE
REPLACE AnalyticsManager.instance.reportOrUpdateMinionTask(minionTask); WITH if (minionTask && importantUpdate) { AnalyticsManager.instance.reportOrUpdateMinionTask(minionTask); } END_REPLACE
REPLACE this.notifyExecutionsUpdatedImmediate(newExecution); WITH this.notifyExecutionsUpdatedImmediate(newExecution, true); END_REPLACE
//////////////////////////////////////////////////////////////////////////////// // Stage 5: Applying Changes ... ////////////////////////////////////////////////////////////////////////////////
Error in applying consolidation: Error: Failed replace
replaceText: async notifyExecutionsUpdatedImmediate(minionTask?: MinionTask) {
originalCode: import { basename } from "path"; import * as vscode from "vscode"; import { MinionTask, SerializedMinionTask } from "./MinionTask"; import { postMessageToWebView } from "./TenMinionsViewProvider"; import { CANCELED_STAGE_NAME, MinionTaskUIInfo } from "./ui/MinionTaskUIInfo"; import { AnalyticsManager } from "./AnalyticsManager";
function extractExecutionIdFromUri(uri: vscode.Uri): string { return uri.path.match(/^minionTaskId\/([a-z\d-]+)/)![1]; }
class LogProvider implements vscode.TextDocumentContentProvider { private executionsManager: ExecutionsManager;
constructor(executionsManager: ExecutionsManager) { this.executionsManager = executionsManager; }
// Create an EventEmitter to handle document updates private _onDidChangeEmitter = new vscode.EventEmitter();
// Use the getter to expose the onDidChange event using EventEmitter's event property get onDidChange(): vscode.Event | undefined {
return this._onDidChangeEmitter.event;
}
reportChange(uri: vscode.Uri) { // Emit the event to notify subscribers of the change in the URI this._onDidChangeEmitter.fire(uri); }
provideTextDocumentContent(uri: vscode.Uri): string { const textKey = extractExecutionIdFromUri(uri); const execution = this.executionsManager.getExecutionById(textKey); const logContent = execution?.logContent || ""; const shortName = execution?.shortName || "Unknown Execution";
} }
export class ExecutionsManager { public static instance: ExecutionsManager;
private executions: MinionTask[] = []; private readonly _context: vscode.ExtensionContext; private _view?: vscode.WebviewView; private _isThrottled = false; private _pendingUpdate = false;
fullContentProvider: vscode.TextDocumentContentProvider; logProvider: LogProvider;
constructor(context: vscode.ExtensionContext) { this._context = context;
}
async saveExecutions() { const serializedExecutions = this.executions.map((execution) => execution.serialize()); await this._context.globalState.update("10minions.executions", serializedExecutions); }
async showDiff(executionId: string) { let minionTask = this.getExecutionById(executionId);
}
async openDocument(executionId: string) { let minionTask = this.getExecutionById(executionId);
}
async openLog(executionId: string) { let minionTask = this.getExecutionById(executionId);
}
updateView(view: vscode.WebviewView) { this._view = view; }
addExecution(execution: MinionTask) { this.executions = [execution, ...this.executions]; }
removeExecution(id: string) { this.executions = this.executions.filter((e) => e.id !== id); }
getExecutionById(executionId: string): MinionTask | undefined { return this.executions.find((e) => e.id === executionId); }
clearExecutions() { this.executions = []; }
public async runMinionOnCurrentSelectionAndEditor(userQuery: string) { const activeEditor = vscode.window.activeTextEditor;
}
acquireMinionIndex(): number { const NUM_TOTAL_ROBOTS = 12; //get all free indices const ALL_FILL_ROBOT_ICONS = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]; const freeIndices = ALL_FILL_ROBOT_ICONS.map((e, i) => i).filter((i) => !this.executions.find((e) => e.minionIndex === i));
}
notifyExecutionsUpdated(minionTask: MinionTask) { if (this._isThrottled) { this._pendingUpdate = true; return; }
}
async forceExecution(executionId: string) { let oldExecutionMaybe = this.executions.find((e) => e.id === executionId);
}
reRunExecution(executionId: any, newUserQuery?: string) { let oldExecutionMaybe = this.executions.find((e) => e.id === executionId);
}
}
notifyExecutionsUpdatedImmediate(minionTask?: MinionTask) { const executionInfo: MinionTaskUIInfo[] = this.executions.map((e) => ({ id: e.id, minionIndex: e.minionIndex, fullContent: e.originalContent, userQuery: e.userQuery, executionStage: e.executionStage, documentName: e.baseName, documentURI: e.documentURI, progress: e.progress, stopped: e.stopped, classification: e.classification, modificationDescription: e.modificationDescription, selectedText: e.selectedText, shortName: e.shortName, waiting: e.waiting, }));
}
stopExecution(executionId: any) { let execution = this.executions.find((e) => e.id === executionId);
}
closeExecution(executionId: any) { let execution = this.executions.find((e) => e.id === executionId);
}
private getRunningExecution(documentURI: string): MinionTask | null { for (const execution of this.executions) { if (execution.documentURI === documentURI && !execution.stopped && !execution.waiting) { return execution; } } return null; }
private async runNextWaitingExecution() { for (const execution of [...this.executions].reverse()) { if (execution.waiting && !execution.stopped) { const runningExecution = this.getRunningExecution(execution.documentURI);
} } //////////////////////////////////////////////////////////////////////////////// // Stage 6: Preparing Changes (retry) ... ////////////////////////////////////////////////////////////////////////////////I will modify the
notifyExecutionsUpdatedImmediate
function by adding an optional boolean parameter namedimportantUpdate
with a default value offalse
. Then, I will wrap the call toAnalyticsManager.instance.reportOrUpdateMinionTask(minionTask);
with a condition to only execute the call ifimportantUpdate
is set totrue
. Finally, I will update the calls to this function, such as in thereRunExecution
function, to passtrue
when the update is important.REPLACE async notifyExecutionsUpdatedImmediate(minionTask?: MinionTask) { [...] if (minionTask) { AnalyticsManager.instance.reportOrUpdateMinionTask(minionTask); } } WITH async notifyExecutionsUpdatedImmediate(minionTask?: MinionTask, importantUpdate: boolean = false) { [...] if (minionTask && importantUpdate) { AnalyticsManager.instance.reportOrUpdateMinionTask(minionTask); } } END_REPLACE
REPLACE this.notifyExecutionsUpdatedImmediate(newExecution); WITH this.notifyExecutionsUpdatedImmediate(newExecution, true); END_REPLACE
//////////////////////////////////////////////////////////////////////////////// // Stage 7: Applying Changes (retry) ... ////////////////////////////////////////////////////////////////////////////////
Error in applying consolidation: Error: Failed replace
replaceText: async notifyExecutionsUpdatedImmediate(minionTask?: MinionTask) { [...] if (minionTask) { AnalyticsManager.instance.reportOrUpdateMinionTask(minionTask); } }
originalCode: import { basename } from "path"; import * as vscode from "vscode"; import { MinionTask, SerializedMinionTask } from "./MinionTask"; import { postMessageToWebView } from "./TenMinionsViewProvider"; import { CANCELED_STAGE_NAME, MinionTaskUIInfo } from "./ui/MinionTaskUIInfo"; import { AnalyticsManager } from "./AnalyticsManager";
function extractExecutionIdFromUri(uri: vscode.Uri): string { return uri.path.match(/^minionTaskId\/([a-z\d-]+)/)![1]; }
class LogProvider implements vscode.TextDocumentContentProvider { private executionsManager: ExecutionsManager;
constructor(executionsManager: ExecutionsManager) { this.executionsManager = executionsManager; }
// Create an EventEmitter to handle document updates private _onDidChangeEmitter = new vscode.EventEmitter();
// Use the getter to expose the onDidChange event using EventEmitter's event property get onDidChange(): vscode.Event | undefined {
return this._onDidChangeEmitter.event;
}
reportChange(uri: vscode.Uri) { // Emit the event to notify subscribers of the change in the URI this._onDidChangeEmitter.fire(uri); }
provideTextDocumentContent(uri: vscode.Uri): string { const textKey = extractExecutionIdFromUri(uri); const execution = this.executionsManager.getExecutionById(textKey); const logContent = execution?.logContent || ""; const shortName = execution?.shortName || "Unknown Execution";
} }
export class ExecutionsManager { public static instance: ExecutionsManager;
private executions: MinionTask[] = []; private readonly _context: vscode.ExtensionContext; private _view?: vscode.WebviewView; private _isThrottled = false; private _pendingUpdate = false;
fullContentProvider: vscode.TextDocumentContentProvider; logProvider: LogProvider;
constructor(context: vscode.ExtensionContext) { this._context = context;
}
async saveExecutions() { const serializedExecutions = this.executions.map((execution) => execution.serialize()); await this._context.globalState.update("10minions.executions", serializedExecutions); }
async showDiff(executionId: string) { let minionTask = this.getExecutionById(executionId);
}
async openDocument(executionId: string) { let minionTask = this.getExecutionById(executionId);
}
async openLog(executionId: string) { let minionTask = this.getExecutionById(executionId);
}
updateView(view: vscode.WebviewView) { this._view = view; }
addExecution(execution: MinionTask) { this.executions = [execution, ...this.executions]; }
removeExecution(id: string) { this.executions = this.executions.filter((e) => e.id !== id); }
getExecutionById(executionId: string): MinionTask | undefined { return this.executions.find((e) => e.id === executionId); }
clearExecutions() { this.executions = []; }
public async runMinionOnCurrentSelectionAndEditor(userQuery: string) { const activeEditor = vscode.window.activeTextEditor;
}
acquireMinionIndex(): number { const NUM_TOTAL_ROBOTS = 12; //get all free indices const ALL_FILL_ROBOT_ICONS = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]; const freeIndices = ALL_FILL_ROBOT_ICONS.map((e, i) => i).filter((i) => !this.executions.find((e) => e.minionIndex === i));
}
notifyExecutionsUpdated(minionTask: MinionTask) { if (this._isThrottled) { this._pendingUpdate = true; return; }
}
async forceExecution(executionId: string) { let oldExecutionMaybe = this.executions.find((e) => e.id === executionId);
}
reRunExecution(executionId: any, newUserQuery?: string) { let oldExecutionMaybe = this.executions.find((e) => e.id === executionId);
}
}
notifyExecutionsUpdatedImmediate(minionTask?: MinionTask) { const executionInfo: MinionTaskUIInfo[] = this.executions.map((e) => ({ id: e.id, minionIndex: e.minionIndex, fullContent: e.originalContent, userQuery: e.userQuery, executionStage: e.executionStage, documentName: e.baseName, documentURI: e.documentURI, progress: e.progress, stopped: e.stopped, classification: e.classification, modificationDescription: e.modificationDescription, selectedText: e.selectedText, shortName: e.shortName, waiting: e.waiting, }));
}
stopExecution(executionId: any) { let execution = this.executions.find((e) => e.id === executionId);
}
closeExecution(executionId: any) { let execution = this.executions.find((e) => e.id === executionId);
}
private getRunningExecution(documentURI: string): MinionTask | null { for (const execution of this.executions) { if (execution.documentURI === documentURI && !execution.stopped && !execution.waiting) { return execution; } } return null; }
private async runNextWaitingExecution() { for (const execution of [...this.executions].reverse()) { if (execution.waiting && !execution.stopped) { const runningExecution = this.getRunningExecution(execution.documentURI);
} } //////////////////////////////////////////////////////////////////////////////// // Stage 8: Applying changes as comment (fall back) ... //////////////////////////////////////////////////////////////////////////////// PLAIN COMMENT FALLBACK //////////////////////////////////////////////////////////////////////////////// // Stage 9: Finishing ... ////////////////////////////////////////////////////////////////////////////////Finished (Execution Time: 00:01:24)