feat(headless): accept sender id via --from-agent
This commit is contained in:
@@ -41,6 +41,7 @@ import { formatErrorDetails } from "./cli/helpers/errorFormatter";
|
||||
import { safeJsonParseOr } from "./cli/helpers/safeJsonParse";
|
||||
import { drainStreamWithResume } from "./cli/helpers/stream";
|
||||
import { StreamProcessor } from "./cli/helpers/streamProcessor";
|
||||
import { SYSTEM_REMINDER_CLOSE, SYSTEM_REMINDER_OPEN } from "./constants";
|
||||
import { settingsManager } from "./settings-manager";
|
||||
import { checkToolPermission } from "./tools/manager";
|
||||
import type {
|
||||
@@ -105,6 +106,7 @@ export async function handleHeadlessCommand(
|
||||
"output-format": { type: "string" },
|
||||
"input-format": { type: "string" },
|
||||
"include-partial-messages": { type: "boolean" },
|
||||
"from-agent": { type: "string" },
|
||||
// Additional flags from index.ts that need to be filtered out
|
||||
help: { type: "boolean", short: "h" },
|
||||
version: { type: "boolean", short: "v" },
|
||||
@@ -209,7 +211,8 @@ export async function handleHeadlessCommand(
|
||||
}
|
||||
|
||||
// --new: Create a new conversation (for concurrent sessions)
|
||||
const forceNewConversation = (values.new as boolean | undefined) ?? false;
|
||||
let forceNewConversation = (values.new as boolean | undefined) ?? false;
|
||||
const fromAgentId = values["from-agent"] as string | undefined;
|
||||
|
||||
// Resolve agent (same logic as interactive mode)
|
||||
let agent: AgentState | null = null;
|
||||
@@ -262,6 +265,26 @@ export async function handleHeadlessCommand(
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
if (fromAgentId) {
|
||||
if (!specifiedAgentId && !specifiedConversationId) {
|
||||
console.error(
|
||||
"Error: --from-agent requires --agent <id> or --conversation <id>.",
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
if (shouldContinue) {
|
||||
console.error("Error: --from-agent cannot be used with --continue");
|
||||
process.exit(1);
|
||||
}
|
||||
if (forceNew) {
|
||||
console.error("Error: --from-agent cannot be used with --new-agent");
|
||||
process.exit(1);
|
||||
}
|
||||
if (!specifiedConversationId && !forceNewConversation) {
|
||||
forceNewConversation = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Validate --conversation flag (mutually exclusive with agent-selection flags)
|
||||
// Exception: --conv default requires --agent
|
||||
if (specifiedConversationId && specifiedConversationId !== "default") {
|
||||
@@ -988,6 +1011,19 @@ export async function handleHeadlessCommand(
|
||||
const { hasLoadedSkills } = await import("./agent/context");
|
||||
let messageContent = "";
|
||||
|
||||
if (fromAgentId) {
|
||||
const senderAgentId = fromAgentId;
|
||||
const senderAgent = await client.agents.retrieve(senderAgentId);
|
||||
const systemReminder = `${SYSTEM_REMINDER_OPEN}
|
||||
This message is from "${senderAgent.name}" (agent ID: ${senderAgentId}), an agent currently running inside the Letta Code CLI (docs.letta.com/letta-code).
|
||||
The sender will only see the final message you generate (not tool calls or reasoning).
|
||||
If you need to share detailed information, include it in your response text.
|
||||
${SYSTEM_REMINDER_CLOSE}
|
||||
|
||||
`;
|
||||
messageContent += systemReminder;
|
||||
}
|
||||
|
||||
// Add plan mode reminder if in plan mode (highest priority)
|
||||
if (permissionMode.getMode() === "plan") {
|
||||
const { PLAN_MODE_REMINDER } = await import("./agent/promptAssets");
|
||||
|
||||
@@ -76,6 +76,7 @@ OPTIONS
|
||||
When set, reads JSON messages from stdin for bidirectional communication
|
||||
--include-partial-messages
|
||||
Emit stream_event wrappers for each chunk (stream-json only)
|
||||
--from-agent <id> Inject agent-to-agent system reminder (headless mode)
|
||||
--skills <path> Custom path to skills directory (default: .skills in current directory)
|
||||
--sleeptime Enable sleeptime memory management (only for new agents)
|
||||
--from-af <path> Create agent from an AgentFile (.af) template
|
||||
@@ -435,6 +436,7 @@ async function main(): Promise<void> {
|
||||
"output-format": { type: "string" },
|
||||
"input-format": { type: "string" },
|
||||
"include-partial-messages": { type: "boolean" },
|
||||
"from-agent": { type: "string" },
|
||||
skills: { type: "string" },
|
||||
sleeptime: { type: "boolean" },
|
||||
"from-af": { type: "string" },
|
||||
|
||||
@@ -58,27 +58,26 @@ letta messages search --query "topic" --all-agents
|
||||
```
|
||||
Results include `agent_id` for each matching message.
|
||||
|
||||
## CLI Usage
|
||||
## CLI Usage (agent-to-agent)
|
||||
|
||||
### Starting a New Conversation
|
||||
|
||||
```bash
|
||||
letta messages start-conversation --agent <id> --message "<text>"
|
||||
letta -p --from-agent $LETTA_AGENT_ID --agent <id> "message text"
|
||||
```
|
||||
|
||||
**Arguments:**
|
||||
| Arg | Required | Description |
|
||||
|-----|----------|-------------|
|
||||
| `--agent <id>` | Yes | Target agent ID to message |
|
||||
| `--agent-id <id>` | No | Alias for `--agent` |
|
||||
| `--message <text>` | Yes | Message to send |
|
||||
| `--timeout <ms>` | No | Max wait time in ms (default: 120000) |
|
||||
| `--from-agent <id>` | Yes | Sender agent ID (injects agent-to-agent system reminder) |
|
||||
| `"message text"` | Yes | Message body (positional after flags) |
|
||||
|
||||
**Example:**
|
||||
```bash
|
||||
letta messages start-conversation \
|
||||
letta -p --from-agent $LETTA_AGENT_ID \
|
||||
--agent agent-abc123 \
|
||||
--message "What do you know about the authentication system?"
|
||||
"What do you know about the authentication system?"
|
||||
```
|
||||
|
||||
**Response:**
|
||||
@@ -94,21 +93,21 @@ letta messages start-conversation \
|
||||
### Continuing a Conversation
|
||||
|
||||
```bash
|
||||
letta messages continue-conversation --conversation-id <id> --message "<text>"
|
||||
letta -p --from-agent $LETTA_AGENT_ID --conversation <id> "message text"
|
||||
```
|
||||
|
||||
**Arguments:**
|
||||
| Arg | Required | Description |
|
||||
|-----|----------|-------------|
|
||||
| `--conversation-id <id>` | Yes | Existing conversation ID |
|
||||
| `--message <text>` | Yes | Follow-up message to send |
|
||||
| `--timeout <ms>` | No | Max wait time in ms (default: 120000) |
|
||||
| `--conversation <id>` | Yes | Existing conversation ID |
|
||||
| `--from-agent <id>` | Yes | Sender agent ID (injects agent-to-agent system reminder) |
|
||||
| `"message text"` | Yes | Follow-up message (positional after flags) |
|
||||
|
||||
**Example:**
|
||||
```bash
|
||||
letta messages continue-conversation \
|
||||
--conversation-id conversation-xyz789 \
|
||||
--message "Can you explain more about the token refresh flow?"
|
||||
letta -p --from-agent $LETTA_AGENT_ID \
|
||||
--conversation conversation-xyz789 \
|
||||
"Can you explain more about the token refresh flow?"
|
||||
```
|
||||
|
||||
## Understanding the Response
|
||||
|
||||
Reference in New Issue
Block a user