mirror of
https://github.com/eigent-ai/eigent.git
synced 2026-05-29 19:15:39 +00:00
update
This commit is contained in:
parent
a3b45a0c05
commit
77df69b585
5 changed files with 263 additions and 95 deletions
|
|
@ -1,16 +1,29 @@
|
|||
from typing import Any, Dict, List
|
||||
import os
|
||||
|
||||
from app.component.environment import env
|
||||
from app.service.task import Agents
|
||||
from app.utils.listen.toolkit_listen import listen_toolkit
|
||||
from app.utils.toolkit.abstract_toolkit import AbstractToolkit
|
||||
from camel.toolkits import GoogleCalendarToolkit as BaseGoogleCalendarToolkit
|
||||
|
||||
SCOPES = ['https://www.googleapis.com/auth/calendar']
|
||||
|
||||
class GoogleCalendarToolkit(BaseGoogleCalendarToolkit, AbstractToolkit):
|
||||
agent_name: str = Agents.social_medium_agent
|
||||
|
||||
def __init__(self, api_task_id: str, timeout: float | None = None):
|
||||
self.api_task_id = api_task_id
|
||||
self._token_path = (
|
||||
os.environ.get("GOOGLE_CALENDAR_TOKEN_PATH")
|
||||
or os.path.join(
|
||||
os.path.expanduser("~"),
|
||||
".eigent",
|
||||
"tokens",
|
||||
"google_calendar",
|
||||
f"google_calendar_token_{api_task_id}.json",
|
||||
)
|
||||
)
|
||||
super().__init__(timeout)
|
||||
|
||||
@listen_toolkit(BaseGoogleCalendarToolkit.create_event)
|
||||
|
|
@ -24,10 +37,14 @@ class GoogleCalendarToolkit(BaseGoogleCalendarToolkit, AbstractToolkit):
|
|||
attendees_email: List[str] | None = None,
|
||||
timezone: str = "UTC",
|
||||
) -> Dict[str, Any]:
|
||||
return super().create_event(event_title, start_time, end_time, description, location, attendees_email, timezone)
|
||||
return super().create_event(
|
||||
event_title, start_time, end_time, description, location, attendees_email, timezone
|
||||
)
|
||||
|
||||
@listen_toolkit(BaseGoogleCalendarToolkit.get_events)
|
||||
def get_events(self, max_results: int = 10, time_min: str | None = None) -> List[Dict[str, Any]] | Dict[str, Any]:
|
||||
def get_events(
|
||||
self, max_results: int = 10, time_min: str | None = None
|
||||
) -> List[Dict[str, Any]] | Dict[str, Any]:
|
||||
return super().get_events(max_results, time_min)
|
||||
|
||||
@listen_toolkit(BaseGoogleCalendarToolkit.update_event)
|
||||
|
|
@ -41,7 +58,9 @@ class GoogleCalendarToolkit(BaseGoogleCalendarToolkit, AbstractToolkit):
|
|||
location: str | None = None,
|
||||
attendees_email: List[str] | None = None,
|
||||
) -> Dict[str, Any]:
|
||||
return super().update_event(event_id, event_title, start_time, end_time, description, location, attendees_email)
|
||||
return super().update_event(
|
||||
event_id, event_title, start_time, end_time, description, location, attendees_email
|
||||
)
|
||||
|
||||
@listen_toolkit(BaseGoogleCalendarToolkit.delete_event)
|
||||
def delete_event(self, event_id: str) -> str:
|
||||
|
|
@ -57,3 +76,75 @@ class GoogleCalendarToolkit(BaseGoogleCalendarToolkit, AbstractToolkit):
|
|||
return cls(api_task_id).get_tools()
|
||||
else:
|
||||
return []
|
||||
|
||||
def _get_calendar_service(self):
|
||||
from googleapiclient.discovery import build
|
||||
from google.auth.transport.requests import Request
|
||||
|
||||
creds = self._authenticate()
|
||||
|
||||
if creds and creds.expired and creds.refresh_token:
|
||||
creds.refresh(Request())
|
||||
try:
|
||||
os.makedirs(os.path.dirname(self._token_path), exist_ok=True)
|
||||
with open(self._token_path, "w") as f:
|
||||
f.write(creds.to_json())
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
return build("calendar", "v3", credentials=creds)
|
||||
|
||||
def _authenticate(self):
|
||||
from google.oauth2.credentials import Credentials
|
||||
from google_auth_oauthlib.flow import InstalledAppFlow
|
||||
from google.auth.transport.requests import Request
|
||||
|
||||
client_id = os.environ.get("GOOGLE_CLIENT_ID")
|
||||
client_secret = os.environ.get("GOOGLE_CLIENT_SECRET")
|
||||
refresh_token = os.environ.get("GOOGLE_REFRESH_TOKEN")
|
||||
token_uri = os.environ.get("GOOGLE_TOKEN_URI", "https://oauth2.googleapis.com/token")
|
||||
|
||||
creds = None
|
||||
|
||||
try:
|
||||
if os.path.exists(self._token_path):
|
||||
creds = Credentials.from_authorized_user_file(self._token_path, SCOPES)
|
||||
except Exception:
|
||||
creds = None
|
||||
|
||||
if not creds and refresh_token:
|
||||
creds = Credentials(
|
||||
None,
|
||||
refresh_token=refresh_token,
|
||||
token_uri=token_uri,
|
||||
client_id=client_id,
|
||||
client_secret=client_secret,
|
||||
scopes=SCOPES,
|
||||
)
|
||||
|
||||
if not creds:
|
||||
client_config = {
|
||||
"installed": {
|
||||
"client_id": client_id,
|
||||
"client_secret": client_secret,
|
||||
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
|
||||
"token_uri": token_uri,
|
||||
"redirect_uris": ["http://localhost"],
|
||||
}
|
||||
}
|
||||
flow = InstalledAppFlow.from_client_config(client_config, SCOPES)
|
||||
creds = flow.run_local_server(port=0)
|
||||
|
||||
|
||||
if creds and creds.expired and creds.refresh_token:
|
||||
creds.refresh(Request())
|
||||
|
||||
|
||||
try:
|
||||
os.makedirs(os.path.dirname(self._token_path), exist_ok=True)
|
||||
with open(self._token_path, "w") as f:
|
||||
f.write(creds.to_json())
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
return creds
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
import { Button } from "@/components/ui/button";
|
||||
import { TooltipSimple } from "@/components/ui/tooltip";
|
||||
import { CircleAlert } from "lucide-react";
|
||||
import { proxyFetchGet, proxyFetchPost, proxyFetchDelete } from "@/api/http";
|
||||
import { proxyFetchGet, proxyFetchPost, proxyFetchPut, proxyFetchDelete } from "@/api/http";
|
||||
|
||||
import React, { useState, useCallback, useEffect, useRef } from "react";
|
||||
import ellipseIcon from "@/assets/mcp/Ellipse-25.svg";
|
||||
|
|
@ -104,7 +104,21 @@ export default function IntegrationList({
|
|||
config_name: envVarKey,
|
||||
config_value: value,
|
||||
};
|
||||
await proxyFetchPost("/api/configs", configPayload);
|
||||
|
||||
// Check if config already exists
|
||||
const existingConfig = configs.find(
|
||||
(c: any) => c.config_name === envVarKey &&
|
||||
c.config_group?.toLowerCase() === provider.toLowerCase()
|
||||
);
|
||||
|
||||
if (existingConfig) {
|
||||
// Update existing config
|
||||
await proxyFetchPut(`/api/configs/${existingConfig.id}`, configPayload);
|
||||
} else {
|
||||
// Create new config
|
||||
await proxyFetchPost("/api/configs", configPayload);
|
||||
}
|
||||
|
||||
if (window.electronAPI?.envWrite) {
|
||||
await window.electronAPI.envWrite(email, { key: envVarKey, value });
|
||||
}
|
||||
|
|
@ -223,39 +237,55 @@ export default function IntegrationList({
|
|||
return;
|
||||
}
|
||||
|
||||
if (item.key === "Google Calendar") {
|
||||
let mcp = {
|
||||
name: "Google Calendar",
|
||||
key: "Google Calendar",
|
||||
install_command: {
|
||||
env: {} as any,
|
||||
},
|
||||
id: 14,
|
||||
};
|
||||
item.env_vars.map((key) => {
|
||||
mcp.install_command.env[key] = "";
|
||||
});
|
||||
onShowEnvConfig?.(mcp);
|
||||
return;
|
||||
}
|
||||
if (installed[item.key]) return;
|
||||
await item.onInstall();
|
||||
// refresh configs after install to update installed state indicator
|
||||
await fetchInstalled();
|
||||
if (item.key === "Google Calendar") {
|
||||
let mcp = {
|
||||
name: "Google Calendar",
|
||||
key: "Google Calendar",
|
||||
install_command: {
|
||||
env: {} as any,
|
||||
},
|
||||
id: 14,
|
||||
};
|
||||
item.env_vars.map((key) => {
|
||||
mcp.install_command.env[key] = "";
|
||||
});
|
||||
onShowEnvConfig?.(mcp);
|
||||
return;
|
||||
}
|
||||
if (installed[item.key]) return;
|
||||
await item.onInstall();
|
||||
// refresh configs after install to update installed state indicator
|
||||
await fetchInstalled();
|
||||
},
|
||||
[installed]
|
||||
);
|
||||
|
||||
const onConnect = (mcp: any) => {
|
||||
console.log(mcp);
|
||||
Object.keys(mcp.install_command.env).map(async (key) => {
|
||||
await saveEnvAndConfig(mcp.key, key, mcp.install_command.env[key]);
|
||||
});
|
||||
const onConnect = async (mcp: any) => {
|
||||
// Refresh configs first to get latest state
|
||||
await fetchInstalled();
|
||||
|
||||
// Save all environment variables
|
||||
await Promise.all(
|
||||
Object.keys(mcp.install_command.env).map(async (key) => {
|
||||
return saveEnvAndConfig(mcp.key, key, mcp.install_command.env[key]);
|
||||
})
|
||||
);
|
||||
|
||||
fetchInstalled();
|
||||
addOption(mcp, true);
|
||||
onClose();
|
||||
};
|
||||
// After saving env vars, trigger installation/instantiation for Google Calendar
|
||||
if (mcp.key === "Google Calendar") {
|
||||
const calendarItem = items.find(item => item.key === "Google Calendar");
|
||||
if (calendarItem && calendarItem.onInstall) {
|
||||
await calendarItem.onInstall();
|
||||
}
|
||||
}
|
||||
|
||||
await fetchInstalled();
|
||||
// Don't call addOption here for Google Calendar, as it's already called in onInstall
|
||||
if (mcp.key !== "Google Calendar") {
|
||||
addOption(mcp, true);
|
||||
}
|
||||
onClose();
|
||||
};
|
||||
const onClose = () => {
|
||||
setShowEnvConfig(false);
|
||||
setActiveMcp(null);
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import React, {
|
|||
} from "react";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { CircleAlert, Store, X } from "lucide-react";
|
||||
import { proxyFetchGet, proxyFetchPost, fetchPost } from "@/api/http";
|
||||
import { proxyFetchGet, proxyFetchPost, proxyFetchPut, fetchPost } from "@/api/http";
|
||||
import { Input } from "../ui/input";
|
||||
import { Button } from "../ui/button";
|
||||
import githubIcon from "@/assets/github.svg";
|
||||
|
|
@ -210,12 +210,30 @@ const ToolSelect = forwardRef<
|
|||
envVarKey: string,
|
||||
value: string
|
||||
) => {
|
||||
// First fetch current configs to check for existing ones
|
||||
const configsRes = await proxyFetchGet("/api/configs");
|
||||
const configs = Array.isArray(configsRes) ? configsRes : [];
|
||||
|
||||
const configPayload = {
|
||||
config_group: capitalizeFirstLetter(provider),
|
||||
config_name: envVarKey,
|
||||
config_value: value,
|
||||
};
|
||||
await proxyFetchPost("/api/configs", configPayload);
|
||||
|
||||
// Check if config already exists
|
||||
const existingConfig = configs.find(
|
||||
(c: any) => c.config_name === envVarKey &&
|
||||
c.config_group?.toLowerCase() === provider.toLowerCase()
|
||||
);
|
||||
|
||||
if (existingConfig) {
|
||||
// Update existing config
|
||||
await proxyFetchPut(`/api/configs/${existingConfig.id}`, configPayload);
|
||||
} else {
|
||||
// Create new config
|
||||
await proxyFetchPost("/api/configs", configPayload);
|
||||
}
|
||||
|
||||
if (window.electronAPI?.envWrite) {
|
||||
await window.electronAPI.envWrite(email, { key: envVarKey, value });
|
||||
}
|
||||
|
|
@ -233,36 +251,49 @@ const ToolSelect = forwardRef<
|
|||
env[key] = envValue[key]?.value;
|
||||
});
|
||||
activeMcp.install_command.env = env;
|
||||
Object.keys(activeMcp.install_command.env).map(async (key) => {
|
||||
await saveEnvAndConfig(
|
||||
activeMcp.key,
|
||||
key,
|
||||
activeMcp.install_command.env[key]
|
||||
);
|
||||
});
|
||||
|
||||
// Add to selected tools after saving config
|
||||
// Save all env vars and wait for completion
|
||||
console.log("[installMcp] Saving env vars for", activeMcp.key);
|
||||
try {
|
||||
await Promise.all(
|
||||
Object.keys(activeMcp.install_command.env).map(async (key) => {
|
||||
console.log("[installMcp] Saving", key, "=", activeMcp.install_command.env[key]);
|
||||
return saveEnvAndConfig(
|
||||
activeMcp.key,
|
||||
key,
|
||||
activeMcp.install_command.env[key]
|
||||
);
|
||||
})
|
||||
);
|
||||
console.log("[installMcp] All env vars saved successfully");
|
||||
} catch (error) {
|
||||
console.error("[installMcp] Failed to save env vars:", error);
|
||||
// Continue anyway to trigger installation
|
||||
}
|
||||
|
||||
// Trigger instantiation for Google Calendar
|
||||
if (activeMcp.key === "Google Calendar") {
|
||||
const calendarItem = {
|
||||
id: activeMcp.id,
|
||||
key: activeMcp.key,
|
||||
name: activeMcp.name,
|
||||
description: "Google Calendar integration for managing events and schedules",
|
||||
toolkit: "google_calendar_toolkit",
|
||||
isLocal: true
|
||||
};
|
||||
addOption(calendarItem, true);
|
||||
try {
|
||||
const response = await fetchPost("/install/tool/google_calendar");
|
||||
|
||||
if (response.success) {
|
||||
const selectedItem = {
|
||||
id: activeMcp.id,
|
||||
key: activeMcp.key,
|
||||
name: activeMcp.name,
|
||||
description: "Google Calendar integration for managing events and schedules",
|
||||
toolkit: "google_calendar_toolkit",
|
||||
isLocal: true
|
||||
};
|
||||
addOption(selectedItem, true);
|
||||
} else {
|
||||
console.error("Failed to install Google Calendar:", response.error || "Unknown error");
|
||||
}
|
||||
} catch (error: any) {
|
||||
console.error("Failed to install Google Calendar:", error.message);
|
||||
}
|
||||
}
|
||||
return;
|
||||
// async function fetchInstalled() {
|
||||
// try {
|
||||
// const configsRes = await proxyFetchGet("/api/configs");
|
||||
// setConfigs(Array.isArray(configsRes) ? configsRes : []);
|
||||
// } catch (e) {
|
||||
// setConfigs([]);
|
||||
// }
|
||||
// }
|
||||
// fetchInstalled();
|
||||
}
|
||||
setInstalling((prev) => ({ ...prev, [id]: true }));
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ export default function SettingMCP() {
|
|||
proxyFetchGet("/api/config/info").then((res) => {
|
||||
if (res && typeof res === "object") {
|
||||
const baseURL = getProxyBaseURL();
|
||||
const list = Object.entries(res).map(([key, value]: [string, any]) => {
|
||||
const list = Object.entries(res).map(([key, value]: [string, any]) => {
|
||||
let onInstall = null;
|
||||
|
||||
// Special handling for Notion MCP
|
||||
|
|
@ -136,18 +136,12 @@ export default function SettingMCP() {
|
|||
toast.error(error.message || "Failed to install Notion MCP");
|
||||
}
|
||||
};
|
||||
} else if (key.toLowerCase() === 'google calendar') {
|
||||
} else if (key.toLowerCase() === 'google calendar') {
|
||||
onInstall = async () => {
|
||||
try {
|
||||
const response = await fetchPost("/install/tool/google_calendar");
|
||||
if (response.success) {
|
||||
toast.success("Google Calendar installed successfully");
|
||||
// Save to config to mark as installed
|
||||
await proxyFetchPost("/api/configs", {
|
||||
config_group: "Google Calendar",
|
||||
config_name: "GOOGLE_CLIENT_ID",
|
||||
config_value: response.toolkit_name || "GoogleCalendarToolkit",
|
||||
});
|
||||
toast.success("Google Calendar installed successfully");
|
||||
// Refresh the integrations list to show the installed state
|
||||
fetchList();
|
||||
// Force refresh IntegrationList component
|
||||
|
|
@ -181,10 +175,6 @@ export default function SettingMCP() {
|
|||
onInstall,
|
||||
};
|
||||
});
|
||||
console.log("API response:", res);
|
||||
console.log("Generated list:", list);
|
||||
console.log("Essential integrations:", essentialIntegrations);
|
||||
|
||||
setIntegrations(
|
||||
list.filter(
|
||||
(item) => !essentialIntegrations.find((i) => i.key === item.key)
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import { CircleAlert } from "lucide-react";
|
|||
import {
|
||||
proxyFetchGet,
|
||||
proxyFetchPost,
|
||||
proxyFetchPut,
|
||||
proxyFetchDelete,
|
||||
} from "@/api/http";
|
||||
|
||||
|
|
@ -102,7 +103,21 @@ export default function IntegrationList({
|
|||
config_name: envVarKey,
|
||||
config_value: value,
|
||||
};
|
||||
await proxyFetchPost("/api/configs", configPayload);
|
||||
|
||||
// Check if config already exists
|
||||
const existingConfig = configs.find(
|
||||
(c: any) => c.config_name === envVarKey &&
|
||||
c.config_group?.toLowerCase() === provider.toLowerCase()
|
||||
);
|
||||
|
||||
if (existingConfig) {
|
||||
// Update existing config
|
||||
await proxyFetchPut(`/api/configs/${existingConfig.id}`, configPayload);
|
||||
} else {
|
||||
// Create new config
|
||||
await proxyFetchPost("/api/configs", configPayload);
|
||||
}
|
||||
|
||||
if (window.electronAPI?.envWrite) {
|
||||
await window.electronAPI.envWrite(email, { key: envVarKey, value });
|
||||
}
|
||||
|
|
@ -228,38 +243,49 @@ export default function IntegrationList({
|
|||
return;
|
||||
}
|
||||
|
||||
if (item.key === "Google Calendar") {
|
||||
let mcp = {
|
||||
name: "Google Calendar",
|
||||
key: "Google Calendar",
|
||||
install_command: {
|
||||
env: {} as any,
|
||||
},
|
||||
id: 14,
|
||||
};
|
||||
item.env_vars.map((key) => {
|
||||
mcp.install_command.env[key] = "";
|
||||
});
|
||||
setActiveMcp(mcp);
|
||||
setShowEnvConfig(true);
|
||||
return;
|
||||
}
|
||||
if (item.key === "Google Calendar") {
|
||||
let mcp = {
|
||||
name: "Google Calendar",
|
||||
key: "Google Calendar",
|
||||
install_command: {
|
||||
env: {} as any,
|
||||
},
|
||||
id: 14,
|
||||
};
|
||||
item.env_vars.map((key) => {
|
||||
mcp.install_command.env[key] = "";
|
||||
});
|
||||
setActiveMcp(mcp);
|
||||
setShowEnvConfig(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (installed[item.key]) return;
|
||||
await item.onInstall();
|
||||
if (installed[item.key]) return;
|
||||
await item.onInstall();
|
||||
},
|
||||
[installed]
|
||||
);
|
||||
|
||||
const onConnect = async (mcp: any) => {
|
||||
console.log(mcp);
|
||||
// Refresh configs first to get latest state
|
||||
await fetchInstalled();
|
||||
|
||||
// Save all environment variables
|
||||
await Promise.all(
|
||||
Object.keys(mcp.install_command.env).map((key) => {
|
||||
return saveEnvAndConfig(mcp.key, key, mcp.install_command.env[key]);
|
||||
})
|
||||
);
|
||||
|
||||
fetchInstalled();
|
||||
// After saving env vars, trigger installation/instantiation for Google Calendar
|
||||
if (mcp.key === "Google Calendar") {
|
||||
const calendarItem = items.find(item => item.key === "Google Calendar");
|
||||
if (calendarItem && calendarItem.onInstall) {
|
||||
await calendarItem.onInstall();
|
||||
}
|
||||
}
|
||||
|
||||
await fetchInstalled();
|
||||
onClose();
|
||||
};
|
||||
const onClose = () => {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue