Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
c2757b9
Show send-button spinner immediately on Omni chat submit (#331224)
Copilot Aug 17, 2026
5547d97
agentHost: sync provider enablement through root config
vritant24 Aug 17, 2026
45b7c7d
Browser: CDP proxy correctness fixes (#331085)
kycutler Aug 17, 2026
03ec394
Fix duplicate floating window when adding context in omni chat (#331353)
Copilot Aug 17, 2026
702b3b0
fix: memory leak in markersTable (#327885)
SimonSiefke Aug 17, 2026
e7ed830
Add BYOK enablement trace logs
Copilot Aug 17, 2026
33ca494
sessions: register a tunnel host service on web (#331362)
connor4312 Aug 17, 2026
83dfbdd
chat: experiment hook to test Luna for dictation LLM cleanup (#331338)
meganrogge Aug 17, 2026
f32dfe1
agentHost: defer provider registration until root-config sync
Copilot Aug 17, 2026
9538e85
Match omni chat Add Context (+) glyph size to the send button, fix st…
Copilot Aug 17, 2026
0a70859
Allow sandboxed access to terminal output files (#331313)
dileepyavan Aug 17, 2026
74704a7
agentHost: limit root config sync to BYOK
vritant24 Aug 17, 2026
de6c4a7
agentHost: address session discovery review feedback (#331332)
benibenj Aug 17, 2026
d97d405
Enforce Agent Host starter experiment typing
Copilot Aug 17, 2026
7752a44
agentHost: explain experiment sync typing
vritant24 Aug 17, 2026
9c4f6ba
agentHost: simplify experiment sync constraint
vritant24 Aug 17, 2026
4a4c778
fix aquarium not showing (#331380)
justschen Aug 17, 2026
7db491a
Improve dictation cleanup reliability (#331241)
meganrogge Aug 17, 2026
1f5b9a4
update chat footer details (#331308)
justschen Aug 17, 2026
d483f80
MCP: Preserve Launch Working Directories Across Hosts (#330223)
dmitrivMS Aug 18, 2026
cf9be84
Refactor browser sharing status into main process (#331382)
kycutler Aug 18, 2026
9d9b1b2
agentHost: Report billed AI credits per turn (#330931)
benibenj Aug 18, 2026
04ecfa2
Improve chat sticky scroll UX and fix accessibility issues (#331387)
osortega Aug 18, 2026
d000184
Merge branch 'main' into agents/add-logs-tests-byok-models-issue
vritant24 Aug 18, 2026
537fabc
Clarify quick chat row presentation (#331377)
benvillalobos Aug 18, 2026
68481a1
Show/hide multi-root session folder picker for agent-host sessions (#…
DonJayamanne Aug 18, 2026
086005b
agentHost: address BYOK experiment sync feedback
vritant24 Aug 18, 2026
c492da7
Changes for sandbox toggle in copilot harness (#330978)
dileepyavan Aug 18, 2026
399cc59
agentHost: Distinguish automatic chat renames (#331378)
sandy081 Aug 18, 2026
c077835
Merge pull request #331383 from microsoft/copilot/add-trace-logs-byok…
vritant24 Aug 18, 2026
8ba0422
Confirm before discarding edited chat requests (#330748)
Copilot Aug 18, 2026
2c0f00a
Flatten markdown headings in omni bar routing badge preview (#331222)
Copilot Aug 18, 2026
030d5ac
Merge origin/main into agents/add-logs-tests-byok-models-issue
vritant24 Aug 18, 2026
d9a8a27
Share one model-selection policy between Workbench chat and the Agent…
lramos15 Aug 18, 2026
4079c68
agentHost: log BYOK enablement decisions
vritant24 Aug 18, 2026
d5a0b0c
agentHost: trace BYOK enablement decisions
vritant24 Aug 18, 2026
c03489f
Merge branch 'main' into agents/add-logs-tests-byok-models-issue
vritant24 Aug 18, 2026
62d7680
Refactor hook scanning logic and improve folder picker decision handl…
DonJayamanne Aug 18, 2026
4279af5
agentHost: clarify BYOK environment override
vritant24 Aug 18, 2026
436b699
Merge branch 'agents/add-logs-tests-byok-models-issue' of https://git…
vritant24 Aug 18, 2026
c178d46
Chat: Use mouse Back to return to agent sessions (#331126)
dmitrivMS Aug 18, 2026
7fee815
Merge pull request #331372 from microsoft/agents/add-logs-tests-byok-…
vritant24 Aug 18, 2026
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
1 change: 1 addition & 0 deletions build/lib/stylelint/vscode-known-variables.json
Original file line number Diff line number Diff line change
Expand Up @@ -1179,6 +1179,7 @@
"--slide-from-x",
"--slide-from-y",
"--omni-icon-column",
"--omni-input-editor-background",
"--omni-rail",
"--omni-row-gap",
"--vg-w1",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -944,26 +944,20 @@ export class CopilotCLISession extends DisposableStore implements ICopilotCLISes
this._permissionLevel = level;
}

/**
* Whether the session was configured with the sandbox enabled. The sandbox
* only actually applies to requests that run with default permissions — see
* {@link _applyEffectiveSandboxConfig}.
*/
/** Whether the session was configured with the sandbox enabled. */
private get _sandboxEnabled(): boolean {
return !!this._sandboxConfig?.enabled;
}

/**
* Apply the sandbox policy for the request that is about to be sent. The
* sandbox enable setting only applies under default permissions; the sandbox
* is explicitly disabled when the request runs with bypass approvals
* (autopilot / autoApprove) or when no sandbox is configured for the
* session. Pushing `{ enabled: false }` (rather than skipping the update)
* ensures the SDK never retains a stale or auto-discovered sandbox.
* configured sandbox is independent of the permission level. Pushing
* `{ enabled: false }` when no sandbox is configured ensures the SDK never
* retains a stale or auto-discovered sandbox.
*/
private _applyEffectiveSandboxConfig(bypassApprovals: boolean): void {
private _applyEffectiveSandboxConfig(): void {
const base = this._sandboxConfig;
const sandboxConfig = (base?.enabled && !bypassApprovals) ? base : { enabled: false };
const sandboxConfig = base?.enabled ? base : { enabled: false };
try {
this._sdkSession.updateOptions({ sandboxConfig });
} catch (error) {
Expand Down Expand Up @@ -1889,12 +1883,7 @@ export class CopilotCLISession extends DisposableStore implements ICopilotCLISes
} else {
this._sdkSession.currentMode = 'interactive';
}
// The sandbox only applies under default permissions — disable it for
// this request when running in a bypass-approvals mode.
const bypassApprovals = remoteMode
? remoteMode === 'autopilot'
: this._permissionLevel === 'autopilot' || this._permissionLevel === 'autoApprove';
this._applyEffectiveSandboxConfig(bypassApprovals);
this._applyEffectiveSandboxConfig();
const sendOptions: SendOptions = { prompt: input.prompt ?? '', attachments, agentMode: this._sdkSession.currentMode };
if (steering) {
sendOptions.mode = 'immediate';
Expand Down Expand Up @@ -1932,9 +1921,7 @@ export class CopilotCLISession extends DisposableStore implements ICopilotCLISes
} else {
this._sdkSession.currentMode = 'interactive';
}
// The sandbox only applies under default permissions — disable it when
// fleet runs in autopilot (a bypass-approvals mode).
this._applyEffectiveSandboxConfig(this._permissionLevel === 'autopilot');
this._applyEffectiveSandboxConfig();
const result = await this._sdkSession.fleet.start({ prompt });
if (!result.started) {
this.logService.info('[CopilotCLISession] Fleet mode not started');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -927,15 +927,15 @@ describe('CopilotCLISession', () => {
expect(sdkSession.lastSandboxConfig).toEqual({ enabled: true, userPolicy: { filesystem: {}, network: { allowOutbound: false } } });
});

it('disables the sandbox for a request running with bypass approvals', async () => {
it('applies the configured sandbox for a request running with bypass approvals', async () => {
for (const level of ['autopilot', 'autoApprove'] as const) {
sdkSession = new MockSdkSession();
const session = await createSession({ sandboxEnabled: true });
session.setPermissionLevel(level);
session.attachStream(new MockChatResponseStream());
await session.handleRequest({ id: '', toolInvocationToken: undefined as never }, { prompt: 'Run' }, [], undefined, authInfo, CancellationToken.None);

expect(sdkSession.lastSandboxConfig, level).toEqual({ enabled: false });
expect(sdkSession.lastSandboxConfig, level).toEqual({ enabled: true, userPolicy: { filesystem: {}, network: { allowOutbound: false } } });
}
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,8 @@ function buildConfigurationSchema(endpoint: IChatEndpoint, autoTiersEnabled: boo
return { configurationSchema: { properties } };
}

const utilityAliasFamilies: readonly ChatEndpointFamily[] = ['copilot-utility-small', 'copilot-utility'];
const DICTATION_CLEANUP_LUNA_ALIAS = 'copilot-dictation-cleanup-luna';
const utilityAliasFamilies: readonly ChatEndpointFamily[] = ['copilot-utility-small', 'copilot-utility', DICTATION_CLEANUP_LUNA_ALIAS];

/**
* Builds the {@link vscode.LanguageModelChatInformation} entry that publishes a
Expand Down Expand Up @@ -295,6 +296,9 @@ export class LanguageModelAccess extends Disposable implements IExtensionContrib
// honored while routing goes through `POST /auto`.
this._onDidChange.fire();
}));
void this._refreshUtilityOverrides().catch(err => {
this._logService.warn(`[LanguageModelAccess] Failed to pre-resolve internal model aliases: ${err}`);
});
}

private async _provideLanguageModelChatInfo(options: { silent: boolean }, token: vscode.CancellationToken): Promise<vscode.LanguageModelChatInformation[]> {
Expand Down Expand Up @@ -541,6 +545,9 @@ export class LanguageModelAccess extends Disposable implements IExtensionContrib
progress: vscode.Progress<vscode.LanguageModelResponsePart2>,
token: vscode.CancellationToken
): Promise<void> {
if (model.id === DICTATION_CLEANUP_LUNA_ALIAS && options.requestInitiator !== 'core') {
throw new Error(`Model ${model.id} is only available to VS Code core.`);
}
let endpoint = await this._getEndpointForModel(model, buildAutoRoutingContext(messages, options));
if (!endpoint) {
throw new Error(`Endpoint not found for model ${model.id}`);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -434,6 +434,101 @@ suite('LanguageModelAccess model info', () => {
await extensionContext.globalState.update(baseCountCacheKey, undefined);
}
});

test('publishes a core-only Luna alias for dictation cleanup without publishing hidden models directly', async () => {
const makeHiddenEndpoint = (model: string): IChatEndpoint => ({
model,
name: model,
family: model,
version: '1',
modelProvider: 'copilot',
modelMaxPromptTokens: 128_000,
maxOutputTokens: 4_096,
supportsToolCalls: true,
supportsVision: false,
supportsPrediction: false,
showInModelPicker: false,
isFallback: false,
tokenizer: TokenizerType.O200K,
urlOrRequestMetadata: '',
} as unknown as IChatEndpoint);
const lunaEndpoint = makeHiddenEndpoint('gpt-5.6-luna');
const otherEndpoint = makeHiddenEndpoint('some-hidden-model');
const copilotToken = new CopilotToken(createTestExtendedTokenInfo({ token: 'token', username: 'fake', copilot_plan: 'unknown' }));
const testingServiceCollection = createExtensionTestingServices();
testingServiceCollection.define(ICopilotTokenManager, {
_serviceBrand: undefined,
onDidCopilotTokenRefresh: Event.None,
getCopilotToken: async () => copilotToken,
resetCopilotToken: () => { },
} as unknown as ICopilotTokenManager);
testingServiceCollection.define(IAutomodeService, {
_serviceBrand: undefined,
resolveAutoModeEndpoint: async () => lunaEndpoint,
resolveAutoModePickerEndpoint: async () => lunaEndpoint,
getAutoPickerMetadata: () => ({ discountRange: { low: 0, high: 0 } }),
areAutoModeTiersSupported: () => false,
onDidChangeAutoModeTierSupport: Event.None,
consumeLastRoutingDecision: () => undefined,
invalidateRouterCache: () => { },
} as unknown as IAutomodeService);
testingServiceCollection.define(IEndpointProvider, {
_serviceBrand: undefined,
onDidModelsRefresh: Event.None,
getAllCompletionModels: async () => [],
getAllChatEndpoints: async () => [lunaEndpoint, otherEndpoint],
getChatEndpoint: async () => lunaEndpoint,
getEmbeddingsEndpoint: async () => { throw new Error('Not implemented in test'); },
} as unknown as IEndpointProvider);
const accessor = testingServiceCollection.createTestingAccessor();
const extensionContext = accessor.get(IVSCodeExtensionContext);
const version = accessor.get(IEnvService).getVersion();
await extensionContext.globalState.update('lmBaseCount/gpt-5.6-luna', { extensionVersion: version, baseCount: 0 });
await extensionContext.globalState.update('lmBaseCount/some-hidden-model', { extensionVersion: version, baseCount: 0 });
const languageModelAccess = accessor.get(IInstantiationService).createInstance(LanguageModelAccess);
try {
const testAccess = languageModelAccess as unknown as {
_refreshUtilityOverrides(): Promise<void>;
_provideLanguageModelChatInfo(options: { silent: boolean }, token: vscode.CancellationToken): Promise<vscode.LanguageModelChatInformation[]>;
_provideLanguageModelChatResponse(
model: vscode.LanguageModelChatInformation,
messages: vscode.LanguageModelChatMessage[],
options: vscode.ProvideLanguageModelChatResponseOptions,
progress: vscode.Progress<vscode.LanguageModelResponsePart2>,
token: vscode.CancellationToken,
): Promise<void>;
};
await testAccess._refreshUtilityOverrides();
const modelInfo = await raceTimeout(testAccess._provideLanguageModelChatInfo({ silent: true }, CancellationToken.None), 2_000);
assert.ok(modelInfo, 'provideLanguageModelChatInfo did not resolve');
const dictationAlias = modelInfo.find(m => m.id === 'copilot-dictation-cleanup-luna');
assert.deepStrictEqual({
dictationAliasPublished: Boolean(dictationAlias),
dictationAliasUserSelectable: dictationAlias?.isUserSelectable,
lunaPublishedDirectly: modelInfo.some(m => m.id === 'gpt-5.6-luna'),
otherPublished: modelInfo.some(m => m.id === 'some-hidden-model'),
}, {
dictationAliasPublished: true,
dictationAliasUserSelectable: false,
lunaPublishedDirectly: false,
otherPublished: false,
});
await assert.rejects(
testAccess._provideLanguageModelChatResponse(
dictationAlias!,
[],
{ requestInitiator: 'publisher.extension' } as vscode.ProvideLanguageModelChatResponseOptions,
{ report: () => { } },
CancellationToken.None,
),
/only available to VS Code core/,
);
} finally {
languageModelAccess.dispose();
await extensionContext.globalState.update('lmBaseCount/gpt-5.6-luna', undefined);
await extensionContext.globalState.update('lmBaseCount/some-hidden-model', undefined);
}
});
});

suite('buildUtilityAliasModelInfo', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,14 +162,17 @@ export class ProductionEndpointProvider extends Disposable implements IEndpointP

/**
* Resolves a chat endpoint from a family string. The internal utility
* families (`copilot-utility` / `copilot-utility-small`) are routed through
* their dedicated resolvers; any other value is treated as a CAPI model
* family (e.g. `gemini-3-flash`, `gpt-5-mini`) and resolved directly. This
* lets callers such as the execution and search subagents honor their
* `*.model` override settings rather than silently falling back to the
* parent model.
* aliases are routed through their dedicated resolvers; any other value is
* treated as a CAPI model family (e.g. `gemini-3-flash`, `gpt-5-mini`) and
* resolved directly. This lets callers such as the execution and search
* subagents honor their `*.model` override settings rather than silently
* falling back to the parent model.
*/
private async _resolveFamily(family: string): Promise<IChatEndpoint> {
if (family === 'copilot-dictation-cleanup-luna') {
const modelMetadata = await this._modelFetcher.getChatModelFromCapiFamily('gpt-5.6-luna');
return this.getOrCreateChatEndpointInstance(modelMetadata);
}
if (family === 'copilot-utility' || family === 'copilot-utility-small') {
return this._resolveUtilityFamily(family);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -180,14 +180,13 @@ export function isCompletionModelInformation(model: IModelAPIResponse): model is
return model.capabilities.type === 'completion';
}

export type ChatEndpointFamily = 'copilot-utility' | 'copilot-utility-small';
export type ChatEndpointFamily = 'copilot-utility' | 'copilot-utility-small' | 'copilot-dictation-cleanup-luna';

/**
* A model family accepted by {@link IEndpointProvider.getChatEndpoint}: either
* an internal utility alias ({@link ChatEndpointFamily}) or any CAPI model
* family id (e.g. `gemini-3-flash`, `gpt-5-mini`). The utility literals are
* kept for editor autocomplete while still allowing arbitrary CAPI family
* strings.
* an internal model alias ({@link ChatEndpointFamily}) or any CAPI model family
* id (e.g. `gemini-3-flash`, `gpt-5-mini`). The internal literals are kept for
* editor autocomplete while still allowing arbitrary CAPI family strings.
*/
export type ChatModelFamily = ChatEndpointFamily | (string & {});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,8 @@ const CAPTURED_DOMAINS = ['Browser', 'Target'];
out[key] = replaceId('session', value as string);
} else if (key === 'browserContextId') {
out[key] = replaceId('context', value as string);
} else if (key === 'vscodeBrowserViewId') {
out[key] = replaceId('browser-view', value as string);
} else if (key === 'title' && obj['type'] === 'browser') {
out[key] = '<browser-title>';
} else if ((key === 'title' || key === 'url') && (value === '' || value === 'about:blank')) {
Expand Down Expand Up @@ -274,22 +276,22 @@ const CAPTURED_DOMAINS = ['Browser', 'Target'];
{ direction: 'recv', method: 'Target.attachedToTarget', params: { sessionId: '<session-0>', targetInfo: { targetId: '<target-0>', type: 'browser', title: '<browser-title>', url: '<blank>', attached: true, canAccessOpener: false }, waitingForDebugger: false } },
{ direction: 'resp', method: 'Target.attachToBrowserTarget', result: { sessionId: '<session-0>' } },
{ direction: 'send', method: 'Target.setDiscoverTargets', params: { discover: true }, sessionId: '<session-0>' },
{ direction: 'recv', method: 'Target.targetCreated', params: { targetInfo: { attached: false, browserContextId: '<context-0>', canAccessOpener: false, targetId: '<target-1>', title: '<blank>', type: 'page', url: '<blank>' } }, sessionId: '<session-0>' },
{ direction: 'recv', method: 'Target.targetCreated', params: { targetInfo: { attached: false, browserContextId: '<context-0>', canAccessOpener: false, targetId: '<target-1>', title: '<blank>', type: 'page', url: '<blank>', vscodeBrowserViewId: '<browser-view-0>' } }, sessionId: '<session-0>' },
{ direction: 'resp', method: 'Target.setDiscoverTargets', result: {} },
{ direction: 'send', method: 'Target.attachToTarget', params: { targetId: '<target-1>', flatten: true }, sessionId: '<session-0>' },
{ direction: 'recv', method: 'Target.targetInfoChanged', params: { targetInfo: { attached: false, browserContextId: '<context-0>', canAccessOpener: false, targetId: '<target-1>', title: '<blank>', type: 'page', url: '<blank>' } }, sessionId: '<session-0>' },
{ direction: 'recv', method: 'Target.attachedToTarget', params: { sessionId: '<session-1>', targetInfo: { attached: true, browserContextId: '<context-0>', canAccessOpener: false, targetId: '<target-1>', title: '<blank>', type: 'page', url: '<blank>' }, waitingForDebugger: false }, sessionId: '<session-0>' },
{ direction: 'recv', method: 'Target.targetInfoChanged', params: { targetInfo: { attached: false, browserContextId: '<context-0>', canAccessOpener: false, targetId: '<target-1>', title: '<blank>', type: 'page', url: '<blank>', vscodeBrowserViewId: '<browser-view-0>' } }, sessionId: '<session-0>' },
{ direction: 'recv', method: 'Target.attachedToTarget', params: { sessionId: '<session-1>', targetInfo: { attached: true, browserContextId: '<context-0>', canAccessOpener: false, targetId: '<target-1>', title: '<blank>', type: 'page', url: '<blank>', vscodeBrowserViewId: '<browser-view-0>' }, waitingForDebugger: false }, sessionId: '<session-0>' },
{ direction: 'resp', method: 'Target.attachToTarget', result: { sessionId: '<session-1>' } },
{ direction: 'send', method: 'Target.setAutoAttach', params: { autoAttach: true, waitForDebuggerOnStart: true, flatten: true }, sessionId: '<session-1>' },
{ direction: 'resp', method: 'Target.setAutoAttach', result: {} },
{ direction: 'recv', method: 'Target.targetCreated', params: { targetInfo: { attached: false, browserContextId: '<context-0>', canAccessOpener: false, targetId: '<target-2>', title: '<omitted>/worker.js', type: 'worker', url: '<omitted>/worker.js' } }, sessionId: '<session-0>' },
{ direction: 'recv', method: 'Target.targetInfoChanged', params: { targetInfo: { attached: false, browserContextId: '<context-0>', canAccessOpener: false, targetId: '<target-2>', title: '<omitted>/worker.js', type: 'worker', url: '<omitted>/worker.js' } }, sessionId: '<session-0>' },
{ direction: 'recv', method: 'Target.attachedToTarget', params: { sessionId: '<session-2>', targetInfo: { attached: true, browserContextId: '<context-0>', canAccessOpener: false, targetId: '<target-2>', title: '<omitted>/worker.js', type: 'worker', url: '<omitted>/worker.js' }, waitingForDebugger: true }, sessionId: '<session-1>' },
{ direction: 'recv', method: 'Target.targetCreated', params: { targetInfo: { attached: false, browserContextId: '<context-0>', canAccessOpener: false, targetId: '<target-2>', title: '<omitted>/worker.js', type: 'worker', url: '<omitted>/worker.js', vscodeBrowserViewId: '<browser-view-0>' } }, sessionId: '<session-0>' },
{ direction: 'recv', method: 'Target.targetInfoChanged', params: { targetInfo: { attached: false, browserContextId: '<context-0>', canAccessOpener: false, targetId: '<target-2>', title: '<omitted>/worker.js', type: 'worker', url: '<omitted>/worker.js', vscodeBrowserViewId: '<browser-view-0>' } }, sessionId: '<session-0>' },
{ direction: 'recv', method: 'Target.attachedToTarget', params: { sessionId: '<session-2>', targetInfo: { attached: true, browserContextId: '<context-0>', canAccessOpener: false, targetId: '<target-2>', title: '<omitted>/worker.js', type: 'worker', url: '<omitted>/worker.js', vscodeBrowserViewId: '<browser-view-0>' }, waitingForDebugger: true }, sessionId: '<session-1>' },
{ direction: 'send', method: 'Target.closeTarget', params: { targetId: '<target-1>' }, sessionId: '<session-0>' },
{ direction: 'recv', method: 'Target.targetInfoChanged', params: { targetInfo: { attached: false, browserContextId: '<context-0>', canAccessOpener: false, targetId: '<target-1>', title: '<blank>', type: 'page', url: '<blank>' } }, sessionId: '<session-0>' },
{ direction: 'recv', method: 'Target.targetInfoChanged', params: { targetInfo: { attached: false, browserContextId: '<context-0>', canAccessOpener: false, targetId: '<target-1>', title: '<blank>', type: 'page', url: '<blank>', vscodeBrowserViewId: '<browser-view-0>' } }, sessionId: '<session-0>' },
{ direction: 'recv', method: 'Target.detachedFromTarget', params: { sessionId: '<session-1>', targetId: '<target-1>' }, sessionId: '<session-0>' },
{ direction: 'recv', method: 'Target.targetDestroyed', params: { targetId: '<target-1>' }, sessionId: '<session-0>' },
{ direction: 'recv', method: 'Target.targetInfoChanged', params: { targetInfo: { attached: false, browserContextId: '<context-0>', canAccessOpener: false, targetId: '<target-2>', title: '<omitted>/worker.js', type: 'worker', url: '<omitted>/worker.js' } }, sessionId: '<session-0>' },
{ direction: 'recv', method: 'Target.targetInfoChanged', params: { targetInfo: { attached: false, browserContextId: '<context-0>', canAccessOpener: false, targetId: '<target-2>', title: '<omitted>/worker.js', type: 'worker', url: '<omitted>/worker.js', vscodeBrowserViewId: '<browser-view-0>' } }, sessionId: '<session-0>' },
{ direction: 'recv', method: 'Target.detachedFromTarget', params: { sessionId: '<session-2>', targetId: '<target-2>' }, sessionId: '<session-1>' },
{ direction: 'resp', method: 'Target.closeTarget', result: { success: true } },
];
Expand Down
Loading
Loading