mirror of
https://github.com/davidkaya/aryx.git
synced 2026-08-26 21:03:58 +02:00
fix: restart idle sidecar on capability refresh
Force-refreshing sidecar capabilities now disposes the idle sidecar process before re-querying capabilities, so Kopaya can pick up backend sidecar changes and refreshed Copilot connection state without a full app restart. Add a small helper and regression tests for the refresh decision. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -496,7 +496,12 @@ export class KopayaAppService extends EventEmitter<AppServiceEvents> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async loadSidecarCapabilities(forceRefresh = false): Promise<SidecarCapabilities> {
|
private async loadSidecarCapabilities(forceRefresh = false): Promise<SidecarCapabilities> {
|
||||||
if (forceRefresh || !this.sidecarCapabilities) {
|
if (forceRefresh) {
|
||||||
|
this.sidecarCapabilities = await this.sidecar.refreshCapabilities();
|
||||||
|
return this.sidecarCapabilities;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.sidecarCapabilities) {
|
||||||
this.sidecarCapabilities = await this.sidecar.describeCapabilities();
|
this.sidecarCapabilities = await this.sidecar.describeCapabilities();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import type {
|
|||||||
} from '@shared/contracts/sidecar';
|
} from '@shared/contracts/sidecar';
|
||||||
import type { ChatMessageRecord } from '@shared/domain/session';
|
import type { ChatMessageRecord } from '@shared/domain/session';
|
||||||
import { createSidecarEnvironment } from '@main/sidecar/sidecarEnvironment';
|
import { createSidecarEnvironment } from '@main/sidecar/sidecarEnvironment';
|
||||||
|
import { shouldRestartSidecarOnCapabilityRefresh } from '@main/sidecar/sidecarRefresh';
|
||||||
import {
|
import {
|
||||||
markRunTurnPendingErrored,
|
markRunTurnPendingErrored,
|
||||||
shouldHandleRunTurnEvent,
|
shouldHandleRunTurnEvent,
|
||||||
@@ -46,6 +47,14 @@ export class SidecarClient {
|
|||||||
return command;
|
return command;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async refreshCapabilities(): Promise<SidecarCapabilities> {
|
||||||
|
if (shouldRestartSidecarOnCapabilityRefresh(this.hasActiveRunTurn())) {
|
||||||
|
await this.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.describeCapabilities();
|
||||||
|
}
|
||||||
|
|
||||||
async validatePattern(pattern: ValidatePatternCommand['pattern']): Promise<unknown> {
|
async validatePattern(pattern: ValidatePatternCommand['pattern']): Promise<unknown> {
|
||||||
return this.dispatch<unknown>({
|
return this.dispatch<unknown>({
|
||||||
type: 'validate-pattern',
|
type: 'validate-pattern',
|
||||||
@@ -71,6 +80,16 @@ export class SidecarClient {
|
|||||||
this.process = undefined;
|
this.process = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hasActiveRunTurn(): boolean {
|
||||||
|
for (const pending of this.pending.values()) {
|
||||||
|
if (pending.kind === 'run-turn') {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
private async ensureProcess(): Promise<ChildProcessWithoutNullStreams> {
|
private async ensureProcess(): Promise<ChildProcessWithoutNullStreams> {
|
||||||
if (this.process && !this.process.killed) {
|
if (this.process && !this.process.killed) {
|
||||||
return this.process;
|
return this.process;
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
export function shouldRestartSidecarOnCapabilityRefresh(hasActiveRunTurn: boolean): boolean {
|
||||||
|
return !hasActiveRunTurn;
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
import { describe, expect, test } from 'bun:test';
|
||||||
|
|
||||||
|
import { shouldRestartSidecarOnCapabilityRefresh } from '@main/sidecar/sidecarRefresh';
|
||||||
|
|
||||||
|
describe('shouldRestartSidecarOnCapabilityRefresh', () => {
|
||||||
|
test('restarts the sidecar when no run-turn is active', () => {
|
||||||
|
expect(shouldRestartSidecarOnCapabilityRefresh(false)).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('keeps the existing sidecar when a run-turn is active', () => {
|
||||||
|
expect(shouldRestartSidecarOnCapabilityRefresh(true)).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user