mirror of
https://github.com/instructkr/claw-code.git
synced 2026-04-03 15:34:49 +08:00
fix: minor compatibility adjustments for server crate integration
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
use crate::error::ApiError;
|
use crate::error::ApiError;
|
||||||
use crate::providers::claw_provider::{self, ClawApiClient, AuthSource};
|
use crate::providers::claw_provider::{self, AuthSource, ClawApiClient};
|
||||||
use crate::providers::openai_compat::{self, OpenAiCompatClient, OpenAiCompatConfig};
|
use crate::providers::openai_compat::{self, OpenAiCompatClient, OpenAiCompatConfig};
|
||||||
use crate::providers::{self, Provider, ProviderKind};
|
use crate::providers::{self, Provider, ProviderKind};
|
||||||
use crate::types::{MessageRequest, MessageResponse, StreamEvent};
|
use crate::types::{MessageRequest, MessageResponse, StreamEvent};
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ pub use client::{
|
|||||||
resolve_startup_auth_source, MessageStream, OAuthTokenSet, ProviderClient,
|
resolve_startup_auth_source, MessageStream, OAuthTokenSet, ProviderClient,
|
||||||
};
|
};
|
||||||
pub use error::ApiError;
|
pub use error::ApiError;
|
||||||
pub use providers::claw_provider::{ClawApiClient, ClawApiClient as ApiClient, AuthSource};
|
pub use providers::claw_provider::{AuthSource, ClawApiClient, ClawApiClient as ApiClient};
|
||||||
pub use providers::openai_compat::{OpenAiCompatClient, OpenAiCompatConfig};
|
pub use providers::openai_compat::{OpenAiCompatClient, OpenAiCompatConfig};
|
||||||
pub use providers::{
|
pub use providers::{
|
||||||
detect_provider_kind, max_tokens_for_model, resolve_model_alias, ProviderKind,
|
detect_provider_kind, max_tokens_for_model, resolve_model_alias, ProviderKind,
|
||||||
|
|||||||
@@ -652,7 +652,7 @@ mod tests {
|
|||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
now_unix_timestamp, oauth_token_is_expired, resolve_saved_oauth_token,
|
now_unix_timestamp, oauth_token_is_expired, resolve_saved_oauth_token,
|
||||||
resolve_startup_auth_source, ClawApiClient, AuthSource, OAuthTokenSet,
|
resolve_startup_auth_source, AuthSource, ClawApiClient, OAuthTokenSet,
|
||||||
};
|
};
|
||||||
use crate::types::{ContentBlockDelta, MessageRequest};
|
use crate::types::{ContentBlockDelta, MessageRequest};
|
||||||
|
|
||||||
|
|||||||
@@ -290,8 +290,7 @@ async fn live_stream_smoke_test() {
|
|||||||
let client = ApiClient::from_env().expect("ANTHROPIC_API_KEY must be set");
|
let client = ApiClient::from_env().expect("ANTHROPIC_API_KEY must be set");
|
||||||
let mut stream = client
|
let mut stream = client
|
||||||
.stream_message(&MessageRequest {
|
.stream_message(&MessageRequest {
|
||||||
model: std::env::var("CLAW_MODEL")
|
model: std::env::var("CLAW_MODEL").unwrap_or_else(|_| "claude-sonnet-4-6".to_string()),
|
||||||
.unwrap_or_else(|_| "claude-sonnet-4-6".to_string()),
|
|
||||||
max_tokens: 32,
|
max_tokens: 32,
|
||||||
messages: vec![InputMessage::user_text(
|
messages: vec![InputMessage::user_text(
|
||||||
"Reply with exactly: hello from rust",
|
"Reply with exactly: hello from rust",
|
||||||
|
|||||||
@@ -386,8 +386,7 @@ mod tests {
|
|||||||
let root = temp_dir();
|
let root = temp_dir();
|
||||||
fs::create_dir_all(&root).expect("create root");
|
fs::create_dir_all(&root).expect("create root");
|
||||||
fs::write(root.join("CLAW.md"), "custom guidance\n").expect("write existing claw md");
|
fs::write(root.join("CLAW.md"), "custom guidance\n").expect("write existing claw md");
|
||||||
fs::write(root.join(".gitignore"), ".claw/settings.local.json\n")
|
fs::write(root.join(".gitignore"), ".claw/settings.local.json\n").expect("write gitignore");
|
||||||
.expect("write gitignore");
|
|
||||||
|
|
||||||
let first = initialize_repo(&root).expect("first init should succeed");
|
let first = initialize_repo(&root).expect("first init should succeed");
|
||||||
assert!(first
|
assert!(first
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ use std::thread;
|
|||||||
use std::time::{Duration, Instant, SystemTime, UNIX_EPOCH};
|
use std::time::{Duration, Instant, SystemTime, UNIX_EPOCH};
|
||||||
|
|
||||||
use api::{
|
use api::{
|
||||||
resolve_startup_auth_source, ClawApiClient, AuthSource, ContentBlockDelta, InputContentBlock,
|
resolve_startup_auth_source, AuthSource, ClawApiClient, ContentBlockDelta, InputContentBlock,
|
||||||
InputMessage, MessageRequest, MessageResponse, OutputContentBlock,
|
InputMessage, MessageRequest, MessageResponse, OutputContentBlock,
|
||||||
StreamEvent as ApiStreamEvent, ToolChoice, ToolDefinition, ToolResultContentBlock,
|
StreamEvent as ApiStreamEvent, ToolChoice, ToolDefinition, ToolResultContentBlock,
|
||||||
};
|
};
|
||||||
@@ -2037,8 +2037,7 @@ fn render_memory_report() -> Result<String, Box<dyn std::error::Error>> {
|
|||||||
if project_context.instruction_files.is_empty() {
|
if project_context.instruction_files.is_empty() {
|
||||||
lines.push("Discovered files".to_string());
|
lines.push("Discovered files".to_string());
|
||||||
lines.push(
|
lines.push(
|
||||||
" No CLAW instruction files discovered in the current directory ancestry."
|
" No CLAW instruction files discovered in the current directory ancestry.".to_string(),
|
||||||
.to_string(),
|
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
lines.push("Discovered files".to_string());
|
lines.push("Discovered files".to_string());
|
||||||
@@ -2790,7 +2789,8 @@ fn build_runtime(
|
|||||||
allowed_tools: Option<AllowedToolSet>,
|
allowed_tools: Option<AllowedToolSet>,
|
||||||
permission_mode: PermissionMode,
|
permission_mode: PermissionMode,
|
||||||
progress_reporter: Option<InternalPromptProgressReporter>,
|
progress_reporter: Option<InternalPromptProgressReporter>,
|
||||||
) -> Result<ConversationRuntime<DefaultRuntimeClient, CliToolExecutor>, Box<dyn std::error::Error>> {
|
) -> Result<ConversationRuntime<DefaultRuntimeClient, CliToolExecutor>, Box<dyn std::error::Error>>
|
||||||
|
{
|
||||||
let (feature_config, tool_registry) = build_runtime_plugin_state()?;
|
let (feature_config, tool_registry) = build_runtime_plugin_state()?;
|
||||||
Ok(ConversationRuntime::new_with_features(
|
Ok(ConversationRuntime::new_with_features(
|
||||||
session,
|
session,
|
||||||
|
|||||||
@@ -24,8 +24,8 @@ pub use compact::{
|
|||||||
get_compact_continuation_message, should_compact, CompactionConfig, CompactionResult,
|
get_compact_continuation_message, should_compact, CompactionConfig, CompactionResult,
|
||||||
};
|
};
|
||||||
pub use config::{
|
pub use config::{
|
||||||
ConfigEntry, ConfigError, ConfigLoader, ConfigSource, McpManagedProxyServerConfig,
|
ConfigEntry, ConfigError, ConfigLoader, ConfigSource, McpConfigCollection,
|
||||||
McpConfigCollection, McpOAuthConfig, McpRemoteServerConfig, McpSdkServerConfig,
|
McpManagedProxyServerConfig, McpOAuthConfig, McpRemoteServerConfig, McpSdkServerConfig,
|
||||||
McpServerConfig, McpStdioServerConfig, McpTransport, McpWebSocketServerConfig, OAuthConfig,
|
McpServerConfig, McpStdioServerConfig, McpTransport, McpWebSocketServerConfig, OAuthConfig,
|
||||||
ResolvedPermissionMode, RuntimeConfig, RuntimeFeatureConfig, RuntimeHookConfig,
|
ResolvedPermissionMode, RuntimeConfig, RuntimeFeatureConfig, RuntimeHookConfig,
|
||||||
RuntimePluginConfig, ScopedMcpServerConfig, CLAW_SETTINGS_SCHEMA_NAME,
|
RuntimePluginConfig, ScopedMcpServerConfig, CLAW_SETTINGS_SCHEMA_NAME,
|
||||||
@@ -45,7 +45,7 @@ pub use mcp::{
|
|||||||
scoped_mcp_config_hash, unwrap_ccr_proxy_url,
|
scoped_mcp_config_hash, unwrap_ccr_proxy_url,
|
||||||
};
|
};
|
||||||
pub use mcp_client::{
|
pub use mcp_client::{
|
||||||
McpManagedProxyTransport, McpClientAuth, McpClientBootstrap, McpClientTransport,
|
McpClientAuth, McpClientBootstrap, McpClientTransport, McpManagedProxyTransport,
|
||||||
McpRemoteTransport, McpSdkTransport, McpStdioTransport,
|
McpRemoteTransport, McpSdkTransport, McpStdioTransport,
|
||||||
};
|
};
|
||||||
pub use mcp_stdio::{
|
pub use mcp_stdio::{
|
||||||
|
|||||||
@@ -97,12 +97,10 @@ impl McpClientTransport {
|
|||||||
McpServerConfig::Sdk(config) => Self::Sdk(McpSdkTransport {
|
McpServerConfig::Sdk(config) => Self::Sdk(McpSdkTransport {
|
||||||
name: config.name.clone(),
|
name: config.name.clone(),
|
||||||
}),
|
}),
|
||||||
McpServerConfig::ManagedProxy(config) => {
|
McpServerConfig::ManagedProxy(config) => Self::ManagedProxy(McpManagedProxyTransport {
|
||||||
Self::ManagedProxy(McpManagedProxyTransport {
|
url: config.url.clone(),
|
||||||
url: config.url.clone(),
|
id: config.id.clone(),
|
||||||
id: config.id.clone(),
|
}),
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1163,8 +1163,12 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn cleanup_script(script_path: &Path) {
|
fn cleanup_script(script_path: &Path) {
|
||||||
fs::remove_file(script_path).expect("cleanup script");
|
if let Err(error) = fs::remove_file(script_path) {
|
||||||
fs::remove_dir_all(script_path.parent().expect("script parent")).expect("cleanup dir");
|
assert_eq!(error.kind(), std::io::ErrorKind::NotFound, "cleanup script");
|
||||||
|
}
|
||||||
|
if let Err(error) = fs::remove_dir_all(script_path.parent().expect("script parent")) {
|
||||||
|
assert_eq!(error.kind(), std::io::ErrorKind::NotFound, "cleanup dir");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn manager_server_config(
|
fn manager_server_config(
|
||||||
|
|||||||
@@ -3,10 +3,13 @@ use std::fmt::{Display, Formatter};
|
|||||||
use std::fs;
|
use std::fs;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::json::{JsonError, JsonValue};
|
use crate::json::{JsonError, JsonValue};
|
||||||
use crate::usage::TokenUsage;
|
use crate::usage::TokenUsage;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
|
||||||
|
#[serde(rename_all = "snake_case")]
|
||||||
pub enum MessageRole {
|
pub enum MessageRole {
|
||||||
System,
|
System,
|
||||||
User,
|
User,
|
||||||
@@ -14,7 +17,8 @@ pub enum MessageRole {
|
|||||||
Tool,
|
Tool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
|
||||||
|
#[serde(tag = "type", rename_all = "snake_case")]
|
||||||
pub enum ContentBlock {
|
pub enum ContentBlock {
|
||||||
Text {
|
Text {
|
||||||
text: String,
|
text: String,
|
||||||
@@ -32,14 +36,14 @@ pub enum ContentBlock {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
|
||||||
pub struct ConversationMessage {
|
pub struct ConversationMessage {
|
||||||
pub role: MessageRole,
|
pub role: MessageRole,
|
||||||
pub blocks: Vec<ContentBlock>,
|
pub blocks: Vec<ContentBlock>,
|
||||||
pub usage: Option<TokenUsage>,
|
pub usage: Option<TokenUsage>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
|
||||||
pub struct Session {
|
pub struct Session {
|
||||||
pub version: u32,
|
pub version: u32,
|
||||||
pub messages: Vec<ConversationMessage>,
|
pub messages: Vec<ConversationMessage>,
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
use crate::session::Session;
|
use crate::session::Session;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
const DEFAULT_INPUT_COST_PER_MILLION: f64 = 15.0;
|
const DEFAULT_INPUT_COST_PER_MILLION: f64 = 15.0;
|
||||||
const DEFAULT_OUTPUT_COST_PER_MILLION: f64 = 75.0;
|
const DEFAULT_OUTPUT_COST_PER_MILLION: f64 = 75.0;
|
||||||
@@ -25,7 +26,7 @@ impl ModelPricing {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, Serialize, Deserialize, Default, PartialEq, Eq)]
|
||||||
pub struct TokenUsage {
|
pub struct TokenUsage {
|
||||||
pub input_tokens: u32,
|
pub input_tokens: u32,
|
||||||
pub output_tokens: u32,
|
pub output_tokens: u32,
|
||||||
|
|||||||
@@ -91,7 +91,10 @@ impl GlobalToolRegistry {
|
|||||||
Ok(Self { plugin_tools })
|
Ok(Self { plugin_tools })
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn normalize_allowed_tools(&self, values: &[String]) -> Result<Option<BTreeSet<String>>, String> {
|
pub fn normalize_allowed_tools(
|
||||||
|
&self,
|
||||||
|
values: &[String],
|
||||||
|
) -> Result<Option<BTreeSet<String>>, String> {
|
||||||
if values.is_empty() {
|
if values.is_empty() {
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
}
|
}
|
||||||
@@ -100,7 +103,11 @@ impl GlobalToolRegistry {
|
|||||||
let canonical_names = builtin_specs
|
let canonical_names = builtin_specs
|
||||||
.iter()
|
.iter()
|
||||||
.map(|spec| spec.name.to_string())
|
.map(|spec| spec.name.to_string())
|
||||||
.chain(self.plugin_tools.iter().map(|tool| tool.definition().name.clone()))
|
.chain(
|
||||||
|
self.plugin_tools
|
||||||
|
.iter()
|
||||||
|
.map(|tool| tool.definition().name.clone()),
|
||||||
|
)
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
let mut name_map = canonical_names
|
let mut name_map = canonical_names
|
||||||
.iter()
|
.iter()
|
||||||
@@ -151,7 +158,8 @@ impl GlobalToolRegistry {
|
|||||||
.plugin_tools
|
.plugin_tools
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|tool| {
|
.filter(|tool| {
|
||||||
allowed_tools.is_none_or(|allowed| allowed.contains(tool.definition().name.as_str()))
|
allowed_tools
|
||||||
|
.is_none_or(|allowed| allowed.contains(tool.definition().name.as_str()))
|
||||||
})
|
})
|
||||||
.map(|tool| ToolDefinition {
|
.map(|tool| ToolDefinition {
|
||||||
name: tool.definition().name.clone(),
|
name: tool.definition().name.clone(),
|
||||||
@@ -174,7 +182,8 @@ impl GlobalToolRegistry {
|
|||||||
.plugin_tools
|
.plugin_tools
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|tool| {
|
.filter(|tool| {
|
||||||
allowed_tools.is_none_or(|allowed| allowed.contains(tool.definition().name.as_str()))
|
allowed_tools
|
||||||
|
.is_none_or(|allowed| allowed.contains(tool.definition().name.as_str()))
|
||||||
})
|
})
|
||||||
.map(|tool| {
|
.map(|tool| {
|
||||||
(
|
(
|
||||||
|
|||||||
Reference in New Issue
Block a user