Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@ class PeriodicAiCheckService(private val project: Project, private val cs: Corou
"dev.nx.console.last_ai_check_notification_timestamp"
private const val LAST_AI_CONFIGURE_NOTIFICATION_TIMESTAMP_KEY =
"dev.nx.console.last_ai_configure_notification_timestamp"
private const val ONE_MINUTE_MS = 60 * 1000L
private const val ONE_HOUR_MS = 60 * 60 * 1000L
private const val ONE_DAY_MS = 24 * 60 * 60 * 1000L
private const val THREE_MINUTES_MS = 3 * 60 * 1000L
private const val THREE_HOURS_MS = 3 * 60 * 60 * 1000L
private const val TWELVE_HOURS_MS = 12 * 60 * 60 * 1000L
private const val ONE_WEEK_MS = 7 * 24 * 60 * 60 * 1000L
}

Expand All @@ -46,11 +46,11 @@ class PeriodicAiCheckService(private val project: Project, private val cs: Corou

checkJob =
cs.launch {
delay(ONE_MINUTE_MS)
delay(THREE_MINUTES_MS)
runAiAgentCheck()

while (isActive) {
delay(ONE_HOUR_MS)
delay(THREE_HOURS_MS)
runAiAgentCheck()
}
}
Expand All @@ -68,13 +68,6 @@ class PeriodicAiCheckService(private val project: Project, private val cs: Corou

val now = System.currentTimeMillis()

val lastUpdateNotificationTimestamp =
PropertiesComponent.getInstance(project)
.getLong(LAST_AI_CHECK_NOTIFICATION_TIMESTAMP_KEY, 0)
if (now - lastUpdateNotificationTimestamp < ONE_DAY_MS) {
return
}

try {
val workspaceRoot = project.basePath ?: "."

Expand All @@ -98,6 +91,13 @@ class PeriodicAiCheckService(private val project: Project, private val cs: Corou
val output = withContext(Dispatchers.IO) { ExecUtil.execAndGetOutput(checkCommand) }

if (output.stdout.contains("The following AI agents are out of date")) {
val lastUpdateNotificationTimestamp =
PropertiesComponent.getInstance(project)
.getLong(LAST_AI_CHECK_NOTIFICATION_TIMESTAMP_KEY, 0)
if (now - lastUpdateNotificationTimestamp < TWELVE_HOURS_MS) {
return
}

PropertiesComponent.getInstance(project)
.setValue(LAST_AI_CHECK_NOTIFICATION_TIMESTAMP_KEY, now.toString())

Expand Down
47 changes: 15 additions & 32 deletions libs/vscode/mcp/src/lib/periodic-ai-check.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,18 +64,18 @@ let checkTimer: NodeJS.Timeout | undefined;
let intervalTimer: NodeJS.Timeout | undefined;

export function setupPeriodicAiCheck(context: ExtensionContext) {
// Run first check after 1 minute
// Run first check after 3 minutes
checkTimer = setTimeout(() => {
runAiAgentCheck();

// Then check every hour
// Then check every 3 hours
intervalTimer = setInterval(
() => {
runAiAgentCheck();
},
60 * 60 * 1000,
3 * 60 * 60 * 1000,
);
}, 60 * 1000);
}, 3 * 60 * 1000);

context.subscriptions.push(
new Disposable(() => {
Expand Down Expand Up @@ -144,25 +144,12 @@ async function constructCommand(flags: string, forceNpx = false) {
// there are older versions of nx that have this outdated config
// 'yarn' isn't actually a dlx command it's only for local packages
if (dlx === 'yarn' || dlx === 'npx' || dlx === undefined) {
dlx = 'npx -y --ignore-scripts';
dlx = `npx -y --ignore-scripts ${cacheParam}`;
}

return `${forceNpx ? `npx -y ${cacheParam} --ignore-scripts` : dlx} nx@latest configure-ai-agents ${flags}`.trim();
}

async function getNxLatestVersion(): Promise<string | undefined> {
try {
const result = await promisify(exec)('npm view nx@latest version', {
encoding: 'utf-8',
timeout: 10000,
});
return result.stdout.trim();
} catch (e) {
vscodeLogger.log(`Failed to get nx@latest version: ${e}`);
return undefined;
}
}

async function doRunAiAgentCheck(
workspacePath: string,
forceNpx = false,
Expand Down Expand Up @@ -369,16 +356,6 @@ async function runAiAgentCheck() {

const now = Date.now();

const lastUpdateNotificationTimestamp =
WorkspaceConfigurationStore.instance.get(
'lastAiCheckNotificationTimestamp',
0,
);
const gap = 12 * 60 * 60 * 1000;
if (now - lastUpdateNotificationTimestamp < gap) {
return;
}

const workspacePath = getWorkspacePath();
if (!workspacePath) {
return;
Expand Down Expand Up @@ -438,6 +415,16 @@ async function runAiAgentCheck() {
}
}

const lastUpdateNotificationTimestamp =
WorkspaceConfigurationStore.instance.get(
'lastAiCheckNotificationTimestamp',
0,
);
const gap = 12 * 60 * 60 * 1000;
if (now - lastUpdateNotificationTimestamp < gap) {
return;
}

WorkspaceConfigurationStore.instance.set(
'lastAiCheckNotificationTimestamp',
now,
Expand Down Expand Up @@ -490,10 +477,6 @@ async function runAiAgentCheck() {
}
}
getTelemetry().logUsage('ai.configure-agents-check-end');
WorkspaceConfigurationStore.instance.set(
'lastAiCheckNotificationTimestamp',
now,
);

// If we get here, the update check passed (no updates needed)
// Now check if we should prompt for configuration
Expand Down
Loading