feat: migrate to Letta TS SDK v1 (alpha) (#11)
This commit is contained in:
122
src/cli/App.tsx
122
src/cli/App.tsx
@@ -1,6 +1,11 @@
|
||||
// src/cli/App.tsx
|
||||
|
||||
import { Letta } from "@letta-ai/letta-client";
|
||||
import type { MessageCreate } from "@letta-ai/letta-client/resources/agents/agents";
|
||||
import type {
|
||||
ApprovalCreate,
|
||||
LettaMessageUnion,
|
||||
} from "@letta-ai/letta-client/resources/agents/messages";
|
||||
import type { LlmConfig } from "@letta-ai/letta-client/resources/models/models";
|
||||
import { Box, Static } from "ink";
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
||||
import { getResumeData } from "../agent/check-approval";
|
||||
@@ -105,7 +110,7 @@ export default function App({
|
||||
| "ready";
|
||||
continueSession?: boolean;
|
||||
startupApproval?: ApprovalRequest | null;
|
||||
messageHistory?: Letta.LettaMessageUnion[];
|
||||
messageHistory?: LettaMessageUnion[];
|
||||
tokenStreaming?: boolean;
|
||||
}) {
|
||||
// Whether a stream is in flight (disables input)
|
||||
@@ -132,7 +137,7 @@ export default function App({
|
||||
|
||||
// Model selector state
|
||||
const [modelSelectorOpen, setModelSelectorOpen] = useState(false);
|
||||
const [llmConfig, setLlmConfig] = useState<Letta.LlmConfig | null>(null);
|
||||
const [llmConfig, setLlmConfig] = useState<LlmConfig | null>(null);
|
||||
|
||||
// Token streaming preference (can be toggled at runtime)
|
||||
const [tokenStreamingEnabled, setTokenStreamingEnabled] =
|
||||
@@ -345,9 +350,9 @@ export default function App({
|
||||
const { getClient } = await import("../agent/client");
|
||||
const client = await getClient();
|
||||
const agent = await client.agents.retrieve(agentId);
|
||||
setLlmConfig(agent.llmConfig);
|
||||
setLlmConfig(agent.llm_config);
|
||||
} catch (error) {
|
||||
console.error("Error fetching llmConfig:", error);
|
||||
console.error("Error fetching llm_config:", error);
|
||||
}
|
||||
};
|
||||
fetchConfig();
|
||||
@@ -372,7 +377,7 @@ export default function App({
|
||||
// Core streaming function - iterative loop that processes conversation turns
|
||||
const processConversation = useCallback(
|
||||
async (
|
||||
initialInput: Array<Letta.MessageCreate | Letta.ApprovalCreate>,
|
||||
initialInput: Array<MessageCreate | ApprovalCreate>,
|
||||
): Promise<void> => {
|
||||
let currentInput = initialInput;
|
||||
|
||||
@@ -398,7 +403,7 @@ export default function App({
|
||||
refreshDerived();
|
||||
|
||||
// Case 1: Turn ended normally
|
||||
if (stopReason === Letta.StopReasonType.EndTurn) {
|
||||
if (stopReason === "end_turn") {
|
||||
setStreaming(false);
|
||||
return;
|
||||
}
|
||||
@@ -411,7 +416,7 @@ export default function App({
|
||||
}
|
||||
|
||||
// Case 2: Requires approval
|
||||
if (stopReason === Letta.StopReasonType.RequiresApproval) {
|
||||
if (stopReason === "requires_approval") {
|
||||
if (!approval) {
|
||||
appendError(
|
||||
`Unexpected null approval with stop reason: ${stopReason}`,
|
||||
@@ -453,7 +458,7 @@ export default function App({
|
||||
await processConversation([
|
||||
{
|
||||
type: "approval",
|
||||
approvalRequestId: toolCallId,
|
||||
approval_request_id: toolCallId,
|
||||
approve: false,
|
||||
reason: denyReason,
|
||||
},
|
||||
@@ -479,11 +484,11 @@ export default function App({
|
||||
|
||||
// Update buffers with tool return
|
||||
onChunk(buffersRef.current, {
|
||||
messageType: "tool_return_message",
|
||||
message_type: "tool_return_message",
|
||||
id: "dummy",
|
||||
date: new Date(),
|
||||
toolCallId,
|
||||
toolReturn: toolResult.toolReturn,
|
||||
date: new Date().toISOString(),
|
||||
tool_call_id: toolCallId,
|
||||
tool_return: toolResult.toolReturn,
|
||||
status: toolResult.status,
|
||||
stdout: toolResult.stdout,
|
||||
stderr: toolResult.stderr,
|
||||
@@ -497,8 +502,8 @@ export default function App({
|
||||
approvals: [
|
||||
{
|
||||
type: "tool",
|
||||
toolCallId,
|
||||
toolReturn: toolResult.toolReturn,
|
||||
tool_call_id: toolCallId,
|
||||
tool_return: toolResult.toolReturn,
|
||||
status: toolResult.status,
|
||||
stdout: toolResult.stdout,
|
||||
stderr: toolResult.stderr,
|
||||
@@ -664,6 +669,61 @@ export default function App({
|
||||
return { submitted: true };
|
||||
}
|
||||
|
||||
// Special handling for /clear command - reset conversation
|
||||
if (msg.trim() === "/clear") {
|
||||
const cmdId = uid("cmd");
|
||||
buffersRef.current.byId.set(cmdId, {
|
||||
kind: "command",
|
||||
id: cmdId,
|
||||
input: msg,
|
||||
output: "Clearing conversation...",
|
||||
phase: "running",
|
||||
});
|
||||
buffersRef.current.order.push(cmdId);
|
||||
refreshDerived();
|
||||
|
||||
setCommandRunning(true);
|
||||
|
||||
try {
|
||||
const client = getClient();
|
||||
await client.agents.messages.reset(agentId, {
|
||||
add_default_initial_messages: false,
|
||||
});
|
||||
|
||||
// Clear local buffers and static items
|
||||
// buffersRef.current.byId.clear();
|
||||
// buffersRef.current.order = [];
|
||||
// buffersRef.current.tokenCount = 0;
|
||||
// emittedIdsRef.current.clear();
|
||||
// setStaticItems([]);
|
||||
|
||||
// Update command with success
|
||||
buffersRef.current.byId.set(cmdId, {
|
||||
kind: "command",
|
||||
id: cmdId,
|
||||
input: msg,
|
||||
output: "Conversation cleared",
|
||||
phase: "finished",
|
||||
success: true,
|
||||
});
|
||||
buffersRef.current.order.push(cmdId);
|
||||
refreshDerived();
|
||||
} catch (error) {
|
||||
buffersRef.current.byId.set(cmdId, {
|
||||
kind: "command",
|
||||
id: cmdId,
|
||||
input: msg,
|
||||
output: `Failed: ${error instanceof Error ? error.message : String(error)}`,
|
||||
phase: "finished",
|
||||
success: false,
|
||||
});
|
||||
refreshDerived();
|
||||
} finally {
|
||||
setCommandRunning(false);
|
||||
}
|
||||
return { submitted: true };
|
||||
}
|
||||
|
||||
// Immediately add command to transcript with "running" phase
|
||||
const cmdId = uid("cmd");
|
||||
buffersRef.current.byId.set(cmdId, {
|
||||
@@ -782,8 +842,8 @@ export default function App({
|
||||
// Start the conversation loop
|
||||
await processConversation([
|
||||
{
|
||||
role: Letta.MessageCreateRole.User,
|
||||
content: messageContent as unknown as Letta.MessageCreate["content"],
|
||||
role: "user",
|
||||
content: messageContent as unknown as MessageCreate["content"],
|
||||
},
|
||||
]);
|
||||
|
||||
@@ -817,11 +877,11 @@ export default function App({
|
||||
|
||||
// Update buffers with tool return
|
||||
onChunk(buffersRef.current, {
|
||||
messageType: "tool_return_message",
|
||||
message_type: "tool_return_message",
|
||||
id: "dummy",
|
||||
date: new Date(),
|
||||
toolCallId,
|
||||
toolReturn: toolResult.toolReturn,
|
||||
date: new Date().toISOString(),
|
||||
tool_call_id: toolCallId,
|
||||
tool_return: toolResult.toolReturn,
|
||||
status: toolResult.status,
|
||||
stdout: toolResult.stdout,
|
||||
stderr: toolResult.stderr,
|
||||
@@ -837,8 +897,8 @@ export default function App({
|
||||
approvals: [
|
||||
{
|
||||
type: "tool",
|
||||
toolCallId,
|
||||
toolReturn: toolResult.toolReturn,
|
||||
tool_call_id: toolCallId,
|
||||
tool_return: toolResult.toolReturn,
|
||||
status: toolResult.status,
|
||||
stdout: toolResult.stdout,
|
||||
stderr: toolResult.stderr,
|
||||
@@ -897,7 +957,7 @@ export default function App({
|
||||
await processConversation([
|
||||
{
|
||||
type: "approval",
|
||||
approvalRequestId: toolCallId,
|
||||
approval_request_id: toolCallId,
|
||||
approve: false,
|
||||
reason: reason || "User denied the tool execution",
|
||||
// TODO the above is legacy?
|
||||
@@ -1031,11 +1091,11 @@ export default function App({
|
||||
|
||||
// Update buffers with tool return
|
||||
onChunk(buffersRef.current, {
|
||||
messageType: "tool_return_message",
|
||||
message_type: "tool_return_message",
|
||||
id: "dummy",
|
||||
date: new Date(),
|
||||
toolCallId,
|
||||
toolReturn: toolResult.toolReturn,
|
||||
date: new Date().toISOString(),
|
||||
tool_call_id: toolCallId,
|
||||
tool_return: toolResult.toolReturn,
|
||||
status: toolResult.status,
|
||||
stdout: toolResult.stdout,
|
||||
stderr: toolResult.stderr,
|
||||
@@ -1052,8 +1112,8 @@ export default function App({
|
||||
approvals: [
|
||||
{
|
||||
type: "tool",
|
||||
toolCallId,
|
||||
toolReturn: toolResult.toolReturn,
|
||||
tool_call_id: toolCallId,
|
||||
tool_return: toolResult.toolReturn,
|
||||
status: toolResult.status,
|
||||
stdout: toolResult.stdout,
|
||||
stderr: toolResult.stderr,
|
||||
@@ -1085,7 +1145,7 @@ export default function App({
|
||||
await processConversation([
|
||||
{
|
||||
type: "approval",
|
||||
approvalRequestId: toolCallId,
|
||||
approval_request_id: toolCallId,
|
||||
approve: false,
|
||||
reason:
|
||||
reason ||
|
||||
|
||||
Reference in New Issue
Block a user