Proper proxy support on windows & mac (#6840)
Co-authored-by: Douwe Osinga <douwe@squareup.com>
This commit is contained in:
@@ -26,7 +26,7 @@ schemars = "1.0"
|
|||||||
shellexpand = "3.1.0"
|
shellexpand = "3.1.0"
|
||||||
indoc = "2.0.5"
|
indoc = "2.0.5"
|
||||||
xcap = "=0.4.0"
|
xcap = "=0.4.0"
|
||||||
reqwest = { workspace = true, features = ["json", "rustls-tls-native-roots"], default-features = false }
|
reqwest = { workspace = true, features = ["json", "rustls-tls-native-roots", "system-proxy"], default-features = false }
|
||||||
chrono = { version = "0.4.38", features = ["serde"] }
|
chrono = { version = "0.4.38", features = ["serde"] }
|
||||||
etcetera = { workspace = true }
|
etcetera = { workspace = true }
|
||||||
tempfile = "3.8"
|
tempfile = "3.8"
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ thiserror = "1.0"
|
|||||||
clap = { version = "4.4", features = ["derive"] }
|
clap = { version = "4.4", features = ["derive"] }
|
||||||
serde_yaml = "0.9.34"
|
serde_yaml = "0.9.34"
|
||||||
utoipa = { version = "4.1", features = ["axum_extras", "chrono"] }
|
utoipa = { version = "4.1", features = ["axum_extras", "chrono"] }
|
||||||
reqwest = { workspace = true, features = ["json", "rustls-tls", "blocking", "multipart"], default-features = false }
|
reqwest = { workspace = true, features = ["json", "rustls-tls", "blocking", "multipart", "system-proxy"], default-features = false }
|
||||||
tokio-util = "0.7.15"
|
tokio-util = "0.7.15"
|
||||||
serde_path_to_error = "0.1.20"
|
serde_path_to_error = "0.1.20"
|
||||||
tokio-tungstenite = { version = "0.28.0", features = ["rustls-tls-native-roots"] }
|
tokio-tungstenite = { version = "0.28.0", features = ["rustls-tls-native-roots"] }
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ tokio = { workspace = true }
|
|||||||
reqwest = { workspace = true, features = [
|
reqwest = { workspace = true, features = [
|
||||||
"json",
|
"json",
|
||||||
"rustls-tls-native-roots",
|
"rustls-tls-native-roots",
|
||||||
|
"system-proxy",
|
||||||
], default-features = false }
|
], default-features = false }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
@@ -34,7 +35,7 @@ anyhow = { workspace = true }
|
|||||||
thiserror = "1.0"
|
thiserror = "1.0"
|
||||||
futures = { workspace = true }
|
futures = { workspace = true }
|
||||||
dirs = "5.0"
|
dirs = "5.0"
|
||||||
reqwest = { workspace = true, features = ["rustls-tls-native-roots", "json", "cookies", "gzip", "brotli", "deflate", "zstd", "charset", "http2", "stream", "blocking", "multipart"], default-features = false }
|
reqwest = { workspace = true, features = ["rustls-tls-native-roots", "json", "cookies", "gzip", "brotli", "deflate", "zstd", "charset", "http2", "stream", "blocking", "multipart", "system-proxy"], default-features = false }
|
||||||
tokio = { workspace = true }
|
tokio = { workspace = true }
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
serde_json = { workspace = true }
|
serde_json = { workspace = true }
|
||||||
|
|||||||
@@ -276,9 +276,10 @@ export default function ChatInput({
|
|||||||
? filteredText.replace(/\bsubmit[.,!?;'"\s]*$/i, '').trim()
|
? filteredText.replace(/\bsubmit[.,!?;'"\s]*$/i, '').trim()
|
||||||
: filteredText;
|
: filteredText;
|
||||||
|
|
||||||
const newValue = displayValue.trim() && cleanedText
|
const newValue =
|
||||||
? `${displayValue.trim()} ${cleanedText}`
|
displayValue.trim() && cleanedText
|
||||||
: displayValue.trim() || cleanedText;
|
? `${displayValue.trim()} ${cleanedText}`
|
||||||
|
: displayValue.trim() || cleanedText;
|
||||||
|
|
||||||
setDisplayValue(newValue);
|
setDisplayValue(newValue);
|
||||||
setValue(newValue);
|
setValue(newValue);
|
||||||
@@ -928,7 +929,6 @@ export default function ChatInput({
|
|||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
const handleKeyDown = (evt: React.KeyboardEvent<HTMLTextAreaElement>) => {
|
const handleKeyDown = (evt: React.KeyboardEvent<HTMLTextAreaElement>) => {
|
||||||
if (mentionPopover.isOpen && mentionPopoverRef.current) {
|
if (mentionPopover.isOpen && mentionPopoverRef.current) {
|
||||||
if (evt.key === 'ArrowDown') {
|
if (evt.key === 'ArrowDown') {
|
||||||
@@ -1383,9 +1383,7 @@ export default function ChatInput({
|
|||||||
Listening
|
Listening
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
{isRecording && isTranscribing && (
|
{isRecording && isTranscribing && <span className="text-textSubtle">•</span>}
|
||||||
<span className="text-textSubtle">•</span>
|
|
||||||
)}
|
|
||||||
{isTranscribing && (
|
{isTranscribing && (
|
||||||
<span className="flex items-center gap-1 text-blue-500">
|
<span className="flex items-center gap-1 text-blue-500">
|
||||||
<span className="inline-block w-2 h-2 bg-blue-500 rounded-full animate-pulse" />
|
<span className="inline-block w-2 h-2 bg-blue-500 rounded-full animate-pulse" />
|
||||||
|
|||||||
@@ -85,7 +85,13 @@ export default function McpAppRenderer({
|
|||||||
if (response.data) {
|
if (response.data) {
|
||||||
const content = response.data;
|
const content = response.data;
|
||||||
const meta = content._meta as
|
const meta = content._meta as
|
||||||
| { ui?: { csp?: CspMetadata; permissions?: PermissionsMetadata; prefersBorder?: boolean } }
|
| {
|
||||||
|
ui?: {
|
||||||
|
csp?: CspMetadata;
|
||||||
|
permissions?: PermissionsMetadata;
|
||||||
|
prefersBorder?: boolean;
|
||||||
|
};
|
||||||
|
}
|
||||||
| undefined;
|
| undefined;
|
||||||
|
|
||||||
if (content.text !== cachedHtml) {
|
if (content.text !== cachedHtml) {
|
||||||
|
|||||||
@@ -1,4 +1,8 @@
|
|||||||
export type { CspMetadata, PermissionsMetadata, CallToolResponse as ToolResult } from '../../api/types.gen';
|
export type {
|
||||||
|
CspMetadata,
|
||||||
|
PermissionsMetadata,
|
||||||
|
CallToolResponse as ToolResult,
|
||||||
|
} from '../../api/types.gen';
|
||||||
|
|
||||||
export type ContentBlock =
|
export type ContentBlock =
|
||||||
| { type: 'text'; text: string }
|
| { type: 'text'; text: string }
|
||||||
|
|||||||
@@ -66,8 +66,8 @@ export const LocalModelManager = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const selectModel = async (modelId: string) => {
|
const selectModel = async (modelId: string) => {
|
||||||
await upsert(LOCAL_WHISPER_MODEL_CONFIG_KEY, modelId, false);
|
await upsert(LOCAL_WHISPER_MODEL_CONFIG_KEY, modelId, false);
|
||||||
setSelectedModelId(modelId);
|
setSelectedModelId(modelId);
|
||||||
};
|
};
|
||||||
|
|
||||||
const loadModels = async () => {
|
const loadModels = async () => {
|
||||||
@@ -151,7 +151,10 @@ export const LocalModelManager = () => {
|
|||||||
return (
|
return (
|
||||||
<div className="space-y-3">
|
<div className="space-y-3">
|
||||||
<div className="text-xs text-text-muted mb-2">
|
<div className="text-xs text-text-muted mb-2">
|
||||||
<p>Supports GPU acceleration (CUDA for NVIDIA, Metal for Apple Silicon). GPU features must be enabled at build time for hardware acceleration.</p>
|
<p>
|
||||||
|
Supports GPU acceleration (CUDA for NVIDIA, Metal for Apple Silicon). GPU features must be
|
||||||
|
enabled at build time for hardware acceleration.
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
@@ -184,9 +187,7 @@ export const LocalModelManager = () => {
|
|||||||
<h4 className="text-sm font-medium text-text-default">
|
<h4 className="text-sm font-medium text-text-default">
|
||||||
{capitalize(model.id)}
|
{capitalize(model.id)}
|
||||||
</h4>
|
</h4>
|
||||||
<span className="text-xs text-text-muted">
|
<span className="text-xs text-text-muted">{model.size_mb}MB</span>
|
||||||
{model.size_mb}MB
|
|
||||||
</span>
|
|
||||||
{model.recommended && (
|
{model.recommended && (
|
||||||
<span className="text-xs bg-blue-500 text-white px-2 py-0.5 rounded">
|
<span className="text-xs bg-blue-500 text-white px-2 py-0.5 rounded">
|
||||||
Recommended
|
Recommended
|
||||||
@@ -199,9 +200,7 @@ export const LocalModelManager = () => {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p className="text-xs text-text-muted mt-1">
|
<p className="text-xs text-text-muted mt-1">{model.description}</p>
|
||||||
{model.description}
|
|
||||||
</p>
|
|
||||||
{model.recommended && (
|
{model.recommended && (
|
||||||
<p className="text-xs text-blue-600 mt-1 font-medium">
|
<p className="text-xs text-blue-600 mt-1 font-medium">
|
||||||
Recommended for your hardware
|
Recommended for your hardware
|
||||||
@@ -230,11 +229,7 @@ export const LocalModelManager = () => {
|
|||||||
<div className="text-xs text-text-muted min-w-[60px]">
|
<div className="text-xs text-text-muted min-w-[60px]">
|
||||||
{progress.progress_percent.toFixed(0)}%
|
{progress.progress_percent.toFixed(0)}%
|
||||||
</div>
|
</div>
|
||||||
<Button
|
<Button variant="ghost" size="sm" onClick={() => cancelDownload(model.id)}>
|
||||||
variant="ghost"
|
|
||||||
size="sm"
|
|
||||||
onClick={() => cancelDownload(model.id)}
|
|
||||||
>
|
|
||||||
<X className="w-4 h-4" />
|
<X className="w-4 h-4" />
|
||||||
</Button>
|
</Button>
|
||||||
</>
|
</>
|
||||||
@@ -259,9 +254,7 @@ export const LocalModelManager = () => {
|
|||||||
<span>
|
<span>
|
||||||
{formatBytes(progress.bytes_downloaded)} / {formatBytes(progress.total_bytes)}
|
{formatBytes(progress.bytes_downloaded)} / {formatBytes(progress.total_bytes)}
|
||||||
</span>
|
</span>
|
||||||
{progress.speed_bps && (
|
{progress.speed_bps && <span>{formatBytes(progress.speed_bps)}/s</span>}
|
||||||
<span>{formatBytes(progress.speed_bps)}/s</span>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
@@ -296,9 +289,7 @@ export const LocalModelManager = () => {
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
{models.length === 0 && (
|
{models.length === 0 && (
|
||||||
<div className="text-center py-6 text-text-muted text-sm">
|
<div className="text-center py-6 text-text-muted text-sm">No models available</div>
|
||||||
No models available
|
|
||||||
</div>
|
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user