1
>
/*---------------------------------------------------------------------------------------------
networkFilterService.ts
2
>
* Copyright (c) Microsoft Corporation. All rights reserved.
3
>
* Licensed under the MIT License. See License.txt in the project root for license information.
4
>
*--------------------------------------------------------------------------------------------*/
5
>
6
>
import { Emitter, Event } from '../../../base/common/event.js';
7
>
import { Disposable } from '../../../base/common/lifecycle.js';
8
>
import { LRUCache } from '../../../base/common/map.js';
9
>
import { URI } from '../../../base/common/uri.js';
10
>
import { localize } from '../../../nls.js';
11
>
import { IConfigurationService } from '../../configuration/common/configuration.js';
12
>
import { createDecorator } from '../../instantiation/common/instantiation.js';
13
>
import { extractDomainFromUri, isDomainAllowed } from './domainMatcher.js';
14
>
import { AgentNetworkDomainSettingId } from './settings.js';
15
>
16
>
export const IAgentNetworkFilterService = createDecorator<IAgentNetworkFilterService>('agentNetworkFilterService');
17
>
18
>
/**
19
>
* Service that filters network requests made by agent tools (fetch tool,
20
>
* integrated browser) based on the configured allowed/denied domain lists.
21
>
*
22
>
* Filtering is active for all callers when the `chat.agent.networkFilter` setting
23
>
* is enabled.
24
>
* When both domain lists are empty, all domains are denied.
25
>
* When a domain appears on the denied list it is always blocked, even if it
26
>
* also matches an entry on the allowed list.
27
>
*/
28
>
export interface IAgentNetworkFilterService {
29
>
readonly _serviceBrand: undefined;
30
>
31
>
/**
32
>
* Extracts the domain from a URI and checks it against the configured
33
>
* allowed/denied domain filter.
34
>
* File URIs and URIs without an authority always pass.
35
>
* @returns `true` if the URI's domain is allowed, `false` if blocked.
36
>
*/
37
>
isUriAllowed(uri: URI): boolean;
38
>
39
>
/**
40
>
* Formats an error message for a blocked URI based on the current filter configuration.
41
>
* @param uri The URI that was blocked.
42
>
* @returns A localized error message explaining that access to the URI is blocked by policy.
43
>
*/
44
>
formatError(uri: URI): string;
45
>
46
>
/**
47
>
* Fires when the filter configuration changes.
48
>
*/
49
>
readonly onDidChange: Event<void>;
50
>
}
51
>
52
>
export class AgentNetworkFilterService extends Disposable implements IAgentNetworkFilterService {
53
>
readonly _serviceBrand: undefined;
54
>
55
>
private networkFilterEnabled = false;
56
>
private allowedPatterns: string[] = [];
57
>
private deniedPatterns: string[] = [];
58
>
private readonly domainCache = new LRUCache<string, boolean>(100);
59
>
60
>
private readonly onDidChangeEmitter = this._register(new Emitter<void>());
61
>
readonly onDidChange = this.onDidChangeEmitter.event;
62
>
63
>
constructor(
64
>
@IConfigurationService private readonly configurationService: IConfigurationService,
65
>
) {
66
>
super();
67
>
this.readConfiguration();
68
>
69
>
this._register(this.configurationService.onDidChangeConfiguration(e => {
70
if (
71
e.affectsConfiguration(AgentNetworkDomainSettingId.NetworkFilter) ||