refactor: remove link and unlink (#233)
This commit is contained in:
107
src/cli/App.tsx
107
src/cli/App.tsx
@@ -19,7 +19,6 @@ import { getClient } from "../agent/client";
|
||||
import { setCurrentAgentId } from "../agent/context";
|
||||
import type { AgentProvenance } from "../agent/create";
|
||||
import { sendMessageStream } from "../agent/message";
|
||||
import { linkToolsToAgent, unlinkToolsFromAgent } from "../agent/modify";
|
||||
import { SessionStats } from "../agent/stats";
|
||||
import type { ApprovalContext } from "../permissions/analyzer";
|
||||
import { permissionMode } from "../permissions/mode";
|
||||
@@ -265,8 +264,7 @@ export default function App({
|
||||
loadingState?:
|
||||
| "assembling"
|
||||
| "upserting"
|
||||
| "linking"
|
||||
| "unlinking"
|
||||
| "updating_tools"
|
||||
| "importing"
|
||||
| "initializing"
|
||||
| "checking"
|
||||
@@ -382,7 +380,13 @@ export default function App({
|
||||
string | null
|
||||
>("default");
|
||||
const [currentToolset, setCurrentToolset] = useState<
|
||||
"codex" | "codex_snake" | "default" | "gemini" | "gemini_snake" | null
|
||||
| "codex"
|
||||
| "codex_snake"
|
||||
| "default"
|
||||
| "gemini"
|
||||
| "gemini_snake"
|
||||
| "none"
|
||||
| null
|
||||
>(null);
|
||||
const [llmConfig, setLlmConfig] = useState<LlmConfig | null>(null);
|
||||
const [agentName, setAgentName] = useState<string | null>(null);
|
||||
@@ -1763,94 +1767,6 @@ export default function App({
|
||||
return { submitted: true };
|
||||
}
|
||||
|
||||
// Special handling for /link command - attach Letta Code tools
|
||||
if (msg.trim() === "/link") {
|
||||
const cmdId = uid("cmd");
|
||||
buffersRef.current.byId.set(cmdId, {
|
||||
kind: "command",
|
||||
id: cmdId,
|
||||
input: msg,
|
||||
output: "Attaching Letta Code tools to agent...",
|
||||
phase: "running",
|
||||
});
|
||||
buffersRef.current.order.push(cmdId);
|
||||
refreshDerived();
|
||||
|
||||
setCommandRunning(true);
|
||||
|
||||
try {
|
||||
const result = await linkToolsToAgent(agentId);
|
||||
|
||||
buffersRef.current.byId.set(cmdId, {
|
||||
kind: "command",
|
||||
id: cmdId,
|
||||
input: msg,
|
||||
output: result.message,
|
||||
phase: "finished",
|
||||
success: result.success,
|
||||
});
|
||||
refreshDerived();
|
||||
} catch (error) {
|
||||
const errorDetails = formatErrorDetails(error, agentId);
|
||||
buffersRef.current.byId.set(cmdId, {
|
||||
kind: "command",
|
||||
id: cmdId,
|
||||
input: msg,
|
||||
output: `Failed: ${errorDetails}`,
|
||||
phase: "finished",
|
||||
success: false,
|
||||
});
|
||||
refreshDerived();
|
||||
} finally {
|
||||
setCommandRunning(false);
|
||||
}
|
||||
return { submitted: true };
|
||||
}
|
||||
|
||||
// Special handling for /unlink command - remove Letta Code tools
|
||||
if (msg.trim() === "/unlink") {
|
||||
const cmdId = uid("cmd");
|
||||
buffersRef.current.byId.set(cmdId, {
|
||||
kind: "command",
|
||||
id: cmdId,
|
||||
input: msg,
|
||||
output: "Removing Letta Code tools from agent...",
|
||||
phase: "running",
|
||||
});
|
||||
buffersRef.current.order.push(cmdId);
|
||||
refreshDerived();
|
||||
|
||||
setCommandRunning(true);
|
||||
|
||||
try {
|
||||
const result = await unlinkToolsFromAgent(agentId);
|
||||
|
||||
buffersRef.current.byId.set(cmdId, {
|
||||
kind: "command",
|
||||
id: cmdId,
|
||||
input: msg,
|
||||
output: result.message,
|
||||
phase: "finished",
|
||||
success: result.success,
|
||||
});
|
||||
refreshDerived();
|
||||
} catch (error) {
|
||||
const errorDetails = formatErrorDetails(error, agentId);
|
||||
buffersRef.current.byId.set(cmdId, {
|
||||
kind: "command",
|
||||
id: cmdId,
|
||||
input: msg,
|
||||
output: `Failed: ${errorDetails}`,
|
||||
phase: "finished",
|
||||
success: false,
|
||||
});
|
||||
refreshDerived();
|
||||
} finally {
|
||||
setCommandRunning(false);
|
||||
}
|
||||
return { submitted: true };
|
||||
}
|
||||
|
||||
// Special handling for /rename command - rename the agent
|
||||
if (msg.trim().startsWith("/rename")) {
|
||||
const parts = msg.trim().split(/\s+/);
|
||||
@@ -3094,7 +3010,8 @@ ${recentCommits}
|
||||
| "codex_snake"
|
||||
| "default"
|
||||
| "gemini"
|
||||
| "gemini_snake" = isOpenAIModel(selectedModel.handle ?? "")
|
||||
| "gemini_snake"
|
||||
| "none" = isOpenAIModel(selectedModel.handle ?? "")
|
||||
? "codex"
|
||||
: isGeminiModel(selectedModel.handle ?? "")
|
||||
? "gemini"
|
||||
@@ -3106,6 +3023,7 @@ ${recentCommits}
|
||||
| "default"
|
||||
| "gemini"
|
||||
| "gemini_snake"
|
||||
| "none"
|
||||
| null = null;
|
||||
if (currentToolset !== targetToolset) {
|
||||
const { switchToolsetForModel } = await import("../tools/toolset");
|
||||
@@ -3248,7 +3166,8 @@ ${recentCommits}
|
||||
| "codex_snake"
|
||||
| "default"
|
||||
| "gemini"
|
||||
| "gemini_snake",
|
||||
| "gemini_snake"
|
||||
| "none",
|
||||
) => {
|
||||
setToolsetSelectorOpen(false);
|
||||
|
||||
|
||||
@@ -45,20 +45,6 @@ export const commands: Record<string, Command> = {
|
||||
return "Clearing credentials...";
|
||||
},
|
||||
},
|
||||
"/link": {
|
||||
desc: "Attach Letta Code tools to current agent",
|
||||
handler: () => {
|
||||
// Handled specially in App.tsx to access agent ID and client
|
||||
return "Attaching tools...";
|
||||
},
|
||||
},
|
||||
"/unlink": {
|
||||
desc: "Remove Letta Code tools from current agent",
|
||||
handler: () => {
|
||||
// Handled specially in App.tsx to access agent ID and client
|
||||
return "Removing tools...";
|
||||
},
|
||||
},
|
||||
"/rename": {
|
||||
desc: "Rename the current agent",
|
||||
handler: () => {
|
||||
@@ -74,7 +60,7 @@ export const commands: Record<string, Command> = {
|
||||
},
|
||||
},
|
||||
"/toolset": {
|
||||
desc: "Switch toolset",
|
||||
desc: "Switch toolset (replaces /link and /unlink)",
|
||||
handler: () => {
|
||||
// Handled specially in App.tsx to access agent ID and client
|
||||
return "Opening toolset selector...";
|
||||
|
||||
@@ -8,7 +8,8 @@ type ToolsetId =
|
||||
| "codex_snake"
|
||||
| "default"
|
||||
| "gemini"
|
||||
| "gemini_snake";
|
||||
| "gemini_snake"
|
||||
| "none";
|
||||
|
||||
interface ToolsetOption {
|
||||
id: ToolsetId;
|
||||
@@ -99,6 +100,13 @@ const toolsets: ToolsetOption[] = [
|
||||
"read_many_files",
|
||||
],
|
||||
},
|
||||
{
|
||||
id: "none",
|
||||
label: "None (Disable Tools)",
|
||||
description: "Remove all Letta Code tools from the agent",
|
||||
tools: [],
|
||||
isFeatured: true,
|
||||
},
|
||||
];
|
||||
|
||||
interface ToolsetSelectorProps {
|
||||
|
||||
@@ -48,8 +48,7 @@ function getAuthMethod(): "url" | "api-key" | "oauth" {
|
||||
type LoadingState =
|
||||
| "assembling"
|
||||
| "upserting"
|
||||
| "linking"
|
||||
| "unlinking"
|
||||
| "updating_tools"
|
||||
| "importing"
|
||||
| "initializing"
|
||||
| "checking"
|
||||
@@ -207,10 +206,8 @@ function getLoadingMessage(
|
||||
return "Assembling tools...";
|
||||
case "upserting":
|
||||
return "Upserting tools...";
|
||||
case "linking":
|
||||
return "Attaching tools...";
|
||||
case "unlinking":
|
||||
return "Removing tools...";
|
||||
case "updating_tools":
|
||||
return "Updating tools...";
|
||||
case "importing":
|
||||
return "Importing agent...";
|
||||
case "checking":
|
||||
|
||||
@@ -421,6 +421,7 @@ async function main() {
|
||||
const shouldLink = values.link as boolean | undefined;
|
||||
const shouldUnlink = values.unlink as boolean | undefined;
|
||||
|
||||
// Validate --link/--unlink flags require --agent
|
||||
// Validate --link/--unlink flags require --agent
|
||||
if (shouldLink || shouldUnlink) {
|
||||
if (!specifiedAgentId) {
|
||||
@@ -481,8 +482,7 @@ async function main() {
|
||||
| "selecting"
|
||||
| "assembling"
|
||||
| "upserting"
|
||||
| "linking"
|
||||
| "unlinking"
|
||||
| "updating_tools"
|
||||
| "importing"
|
||||
| "initializing"
|
||||
| "checking"
|
||||
@@ -591,7 +591,7 @@ async function main() {
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
setLoadingState(shouldLink ? "linking" : "unlinking");
|
||||
setLoadingState("updating_tools");
|
||||
const { linkToolsToAgent, unlinkToolsFromAgent } = await import(
|
||||
"./agent/modify"
|
||||
);
|
||||
|
||||
@@ -30,7 +30,8 @@ export type ToolsetName =
|
||||
| "codex_snake"
|
||||
| "default"
|
||||
| "gemini"
|
||||
| "gemini_snake";
|
||||
| "gemini_snake"
|
||||
| "none";
|
||||
|
||||
// Server-side/base tools that should stay attached regardless of Letta toolset
|
||||
export const BASE_TOOL_NAMES = ["memory", "web_search"];
|
||||
@@ -130,7 +131,10 @@ export async function forceToolsetSwitch(
|
||||
clearTools();
|
||||
|
||||
// Load the appropriate toolset
|
||||
if (toolsetName === "codex") {
|
||||
if (toolsetName === "none") {
|
||||
// Just clear tools
|
||||
clearTools();
|
||||
} else if (toolsetName === "codex") {
|
||||
await loadSpecificTools([...CODEX_TOOLS]);
|
||||
} else if (toolsetName === "codex_snake") {
|
||||
await loadTools("openai/gpt-4");
|
||||
@@ -146,9 +150,11 @@ export async function forceToolsetSwitch(
|
||||
const client = await getClient();
|
||||
await upsertToolsToServer(client);
|
||||
|
||||
// Remove old Letta tools and add new ones
|
||||
// Remove old Letta tools and add new ones (or just remove if none)
|
||||
await unlinkToolsFromAgent(agentId);
|
||||
await linkToolsToAgent(agentId);
|
||||
if (toolsetName !== "none") {
|
||||
await linkToolsToAgent(agentId);
|
||||
}
|
||||
|
||||
// Ensure base memory tool uses memory_apply_patch instead of legacy memory
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user