@letta-ai/letta-code 0.12.0 → 0.12.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/letta.js +279 -37
- package/package.json +1 -1
package/letta.js
CHANGED
|
@@ -3237,7 +3237,7 @@ var package_default;
|
|
|
3237
3237
|
var init_package = __esm(() => {
|
|
3238
3238
|
package_default = {
|
|
3239
3239
|
name: "@letta-ai/letta-code",
|
|
3240
|
-
version: "0.12.
|
|
3240
|
+
version: "0.12.1",
|
|
3241
3241
|
description: "Letta Code is a CLI tool for interacting with stateful Letta agents from the terminal.",
|
|
3242
3242
|
type: "module",
|
|
3243
3243
|
bin: {
|
|
@@ -29951,6 +29951,10 @@ var init_WelcomeScreen = __esm(async () => {
|
|
|
29951
29951
|
});
|
|
29952
29952
|
|
|
29953
29953
|
// src/permissions/readOnlyShell.ts
|
|
29954
|
+
function isReadOnlySkillScript(scriptPath) {
|
|
29955
|
+
const normalized = scriptPath.replace(/\\/g, "/");
|
|
29956
|
+
return BUNDLED_READ_ONLY_SCRIPTS.some((pattern) => normalized.endsWith(pattern));
|
|
29957
|
+
}
|
|
29954
29958
|
function isReadOnlyShellCommand(command) {
|
|
29955
29959
|
if (!command) {
|
|
29956
29960
|
return false;
|
|
@@ -30018,6 +30022,13 @@ function isSafeSegment(segment) {
|
|
|
30018
30022
|
if (command === "sort") {
|
|
30019
30023
|
return !/\s-o\b/.test(segment);
|
|
30020
30024
|
}
|
|
30025
|
+
if (command === "npx" && tokens[1] === "tsx") {
|
|
30026
|
+
const scriptPath = tokens[2];
|
|
30027
|
+
if (scriptPath && isReadOnlySkillScript(scriptPath)) {
|
|
30028
|
+
return true;
|
|
30029
|
+
}
|
|
30030
|
+
return false;
|
|
30031
|
+
}
|
|
30021
30032
|
return false;
|
|
30022
30033
|
}
|
|
30023
30034
|
return true;
|
|
@@ -30050,7 +30061,7 @@ function extractDashCArgument(tokens) {
|
|
|
30050
30061
|
}
|
|
30051
30062
|
return;
|
|
30052
30063
|
}
|
|
30053
|
-
var ALWAYS_SAFE_COMMANDS, SAFE_GIT_SUBCOMMANDS, DANGEROUS_OPERATOR_PATTERN;
|
|
30064
|
+
var ALWAYS_SAFE_COMMANDS, SAFE_GIT_SUBCOMMANDS, BUNDLED_READ_ONLY_SCRIPTS, DANGEROUS_OPERATOR_PATTERN;
|
|
30054
30065
|
var init_readOnlyShell = __esm(() => {
|
|
30055
30066
|
ALWAYS_SAFE_COMMANDS = new Set([
|
|
30056
30067
|
"cat",
|
|
@@ -30113,6 +30124,12 @@ var init_readOnlyShell = __esm(() => {
|
|
|
30113
30124
|
"tag",
|
|
30114
30125
|
"remote"
|
|
30115
30126
|
]);
|
|
30127
|
+
BUNDLED_READ_ONLY_SCRIPTS = [
|
|
30128
|
+
"/skills/searching-messages/scripts/search-messages.ts",
|
|
30129
|
+
"/skills/searching-messages/scripts/get-messages.ts",
|
|
30130
|
+
"/skills/builtin/searching-messages/scripts/search-messages.ts",
|
|
30131
|
+
"/skills/builtin/searching-messages/scripts/get-messages.ts"
|
|
30132
|
+
];
|
|
30116
30133
|
DANGEROUS_OPERATOR_PATTERN = /(>>|>|\$\(|`)/;
|
|
30117
30134
|
});
|
|
30118
30135
|
|
|
@@ -31629,6 +31646,46 @@ Remember: You're planning, not implementing. Don't make changes, just create a r
|
|
|
31629
31646
|
`;
|
|
31630
31647
|
var init_plan = () => {};
|
|
31631
31648
|
|
|
31649
|
+
// src/agent/subagents/builtin/recall.md
|
|
31650
|
+
var recall_default = `---
|
|
31651
|
+
name: recall
|
|
31652
|
+
description: Search conversation history to recall past discussions, decisions, and context
|
|
31653
|
+
tools: Skill, Bash, Read, BashOutput
|
|
31654
|
+
model: haiku
|
|
31655
|
+
memoryBlocks: human, persona
|
|
31656
|
+
mode: stateless
|
|
31657
|
+
---
|
|
31658
|
+
|
|
31659
|
+
You are a subagent launched via the Task tool to search conversation history. You run autonomously and return a single final report when done. You CANNOT ask questions mid-execution.
|
|
31660
|
+
|
|
31661
|
+
## Instructions
|
|
31662
|
+
|
|
31663
|
+
### Step 1: Load the searching-messages skill
|
|
31664
|
+
\`\`\`
|
|
31665
|
+
Skill({ command: "load", skills: ["searching-messages"] })
|
|
31666
|
+
\`\`\`
|
|
31667
|
+
|
|
31668
|
+
The skill content will appear in your loaded_skills block with script paths and search strategies.
|
|
31669
|
+
|
|
31670
|
+
### Step 2: Search the parent agent's history
|
|
31671
|
+
|
|
31672
|
+
**CRITICAL - Two rules:**
|
|
31673
|
+
|
|
31674
|
+
1. **DO NOT use \`conversation_search\`** - That tool only searches YOUR history (empty). You MUST use the Bash scripts from the skill.
|
|
31675
|
+
|
|
31676
|
+
2. **ALWAYS add \`--agent-id $LETTA_PARENT_AGENT_ID\`** - This searches the parent agent's history. The only exception is \`--all-agents\` searches.
|
|
31677
|
+
|
|
31678
|
+
Follow the strategies documented in the loaded skill.
|
|
31679
|
+
|
|
31680
|
+
## Output Format
|
|
31681
|
+
|
|
31682
|
+
1. **Direct answer** - What the user asked about
|
|
31683
|
+
2. **Key findings** - Relevant quotes or summaries from past conversations
|
|
31684
|
+
3. **When discussed** - Timestamps of relevant discussions
|
|
31685
|
+
4. **Outcome/Decision** - What was decided or concluded (if applicable)
|
|
31686
|
+
`;
|
|
31687
|
+
var init_recall = () => {};
|
|
31688
|
+
|
|
31632
31689
|
// src/agent/subagents/index.ts
|
|
31633
31690
|
var exports_subagents = {};
|
|
31634
31691
|
__export(exports_subagents, {
|
|
@@ -31793,7 +31850,13 @@ var init_subagents = __esm(() => {
|
|
|
31793
31850
|
init_explore();
|
|
31794
31851
|
init_general_purpose();
|
|
31795
31852
|
init_plan();
|
|
31796
|
-
|
|
31853
|
+
init_recall();
|
|
31854
|
+
BUILTIN_SOURCES = [
|
|
31855
|
+
explore_default,
|
|
31856
|
+
general_purpose_default,
|
|
31857
|
+
plan_default,
|
|
31858
|
+
recall_default
|
|
31859
|
+
];
|
|
31797
31860
|
GLOBAL_AGENTS_DIR = join3(process.env.HOME || process.env.USERPROFILE || "~", ".letta/agents");
|
|
31798
31861
|
VALID_MEMORY_BLOCKS = new Set(MEMORY_BLOCK_LABELS);
|
|
31799
31862
|
cache3 = {
|
|
@@ -43281,11 +43344,16 @@ async function executeSubagent(type, config, model, userPrompt, baseURL, subagen
|
|
|
43281
43344
|
try {
|
|
43282
43345
|
const cliArgs = buildSubagentArgs(type, config, model, userPrompt);
|
|
43283
43346
|
const lettaCmd = process.env.LETTA_CODE_BIN || "letta";
|
|
43347
|
+
let parentAgentId;
|
|
43348
|
+
try {
|
|
43349
|
+
parentAgentId = getCurrentAgentId();
|
|
43350
|
+
} catch {}
|
|
43284
43351
|
const proc2 = spawn3(lettaCmd, cliArgs, {
|
|
43285
43352
|
cwd: process.cwd(),
|
|
43286
43353
|
env: {
|
|
43287
43354
|
...process.env,
|
|
43288
|
-
LETTA_CODE_AGENT_ROLE: "subagent"
|
|
43355
|
+
LETTA_CODE_AGENT_ROLE: "subagent",
|
|
43356
|
+
...parentAgentId && { LETTA_PARENT_AGENT_ID: parentAgentId }
|
|
43289
43357
|
}
|
|
43290
43358
|
});
|
|
43291
43359
|
let wasAborted = false;
|
|
@@ -45644,7 +45712,13 @@ var init_subagents2 = __esm(() => {
|
|
|
45644
45712
|
init_explore();
|
|
45645
45713
|
init_general_purpose();
|
|
45646
45714
|
init_plan();
|
|
45647
|
-
|
|
45715
|
+
init_recall();
|
|
45716
|
+
BUILTIN_SOURCES2 = [
|
|
45717
|
+
explore_default,
|
|
45718
|
+
general_purpose_default,
|
|
45719
|
+
plan_default,
|
|
45720
|
+
recall_default
|
|
45721
|
+
];
|
|
45648
45722
|
GLOBAL_AGENTS_DIR2 = join10(process.env.HOME || process.env.USERPROFILE || "~", ".letta/agents");
|
|
45649
45723
|
VALID_MEMORY_BLOCKS2 = new Set(MEMORY_BLOCK_LABELS);
|
|
45650
45724
|
cache4 = {
|
|
@@ -48326,7 +48400,9 @@ var init_checker = __esm(() => {
|
|
|
48326
48400
|
"explore",
|
|
48327
48401
|
"Explore",
|
|
48328
48402
|
"plan",
|
|
48329
|
-
"Plan"
|
|
48403
|
+
"Plan",
|
|
48404
|
+
"recall",
|
|
48405
|
+
"Recall"
|
|
48330
48406
|
]);
|
|
48331
48407
|
});
|
|
48332
48408
|
|
|
@@ -49510,7 +49586,7 @@ var init_create = __esm(async () => {
|
|
|
49510
49586
|
});
|
|
49511
49587
|
|
|
49512
49588
|
// src/agent/message.ts
|
|
49513
|
-
async function sendMessageStream(agentId, messages, opts = { streamTokens: true, background: true }) {
|
|
49589
|
+
async function sendMessageStream(agentId, messages, opts = { streamTokens: true, background: true }, requestOptions = { maxRetries: 0 }) {
|
|
49514
49590
|
const client = await getClient2();
|
|
49515
49591
|
return client.agents.messages.create(agentId, {
|
|
49516
49592
|
messages,
|
|
@@ -49518,7 +49594,7 @@ async function sendMessageStream(agentId, messages, opts = { streamTokens: true,
|
|
|
49518
49594
|
stream_tokens: opts.streamTokens ?? true,
|
|
49519
49595
|
background: opts.background ?? true,
|
|
49520
49596
|
client_tools: getClientToolsFromRegistry()
|
|
49521
|
-
});
|
|
49597
|
+
}, requestOptions);
|
|
49522
49598
|
}
|
|
49523
49599
|
var init_message = __esm(async () => {
|
|
49524
49600
|
await __promiseAll([
|
|
@@ -49636,8 +49712,10 @@ function markCurrentLineAsFinished(b) {
|
|
|
49636
49712
|
markAsFinished(b, b.lastOtid);
|
|
49637
49713
|
} else {}
|
|
49638
49714
|
}
|
|
49639
|
-
function markIncompleteToolsAsCancelled(b) {
|
|
49640
|
-
|
|
49715
|
+
function markIncompleteToolsAsCancelled(b, setInterruptedFlag = true) {
|
|
49716
|
+
if (setInterruptedFlag) {
|
|
49717
|
+
b.interrupted = true;
|
|
49718
|
+
}
|
|
49641
49719
|
let anyToolsCancelled = false;
|
|
49642
49720
|
for (const [id, line] of b.byId.entries()) {
|
|
49643
49721
|
if (line.kind === "tool_call" && line.phase !== "finished") {
|
|
@@ -50032,6 +50110,10 @@ async function drainStream(stream2, buffers, refresh, abortSignal, onFirstMessag
|
|
|
50032
50110
|
queueMicrotask(refresh);
|
|
50033
50111
|
break;
|
|
50034
50112
|
}
|
|
50113
|
+
const errObj = chunk.error;
|
|
50114
|
+
if (errObj?.detail?.includes("No tool call is currently awaiting approval")) {
|
|
50115
|
+
continue;
|
|
50116
|
+
}
|
|
50035
50117
|
onChunk(buffers, chunk);
|
|
50036
50118
|
queueMicrotask(refresh);
|
|
50037
50119
|
if (chunk.message_type === "stop_reason") {
|
|
@@ -50113,7 +50195,7 @@ async function drainStreamWithResume(stream2, buffers, refresh, abortSignal, onF
|
|
|
50113
50195
|
const resumeStream = await client.runs.messages.stream(result.lastRunId, {
|
|
50114
50196
|
starting_after: result.lastSeqId,
|
|
50115
50197
|
batch_size: 1000
|
|
50116
|
-
});
|
|
50198
|
+
}, { maxRetries: 0 });
|
|
50117
50199
|
const resumeResult = await drainStream(resumeStream, buffers, refresh, abortSignal);
|
|
50118
50200
|
result = resumeResult;
|
|
50119
50201
|
} catch (_e) {
|
|
@@ -70528,6 +70610,7 @@ function App2({
|
|
|
70528
70610
|
}, [agentId]);
|
|
70529
70611
|
const [streaming, setStreaming, streamingRef] = useSyncedState(false);
|
|
70530
70612
|
const processingConversationRef = import_react76.useRef(0);
|
|
70613
|
+
const conversationGenerationRef = import_react76.useRef(0);
|
|
70531
70614
|
const [interruptRequested, setInterruptRequested] = import_react76.useState(false);
|
|
70532
70615
|
const [commandRunning, setCommandRunning, commandRunningRef] = useSyncedState(false);
|
|
70533
70616
|
const [profileConfirmPending, setProfileConfirmPending] = import_react76.useState(null);
|
|
@@ -70917,6 +71000,10 @@ function App2({
|
|
|
70917
71000
|
const processConversation = import_react76.useCallback(async (initialInput, options) => {
|
|
70918
71001
|
const currentInput = [...initialInput];
|
|
70919
71002
|
const allowReentry = options?.allowReentry ?? false;
|
|
71003
|
+
const myGeneration = options?.submissionGeneration ?? conversationGenerationRef.current;
|
|
71004
|
+
if (myGeneration !== conversationGenerationRef.current) {
|
|
71005
|
+
return;
|
|
71006
|
+
}
|
|
70920
71007
|
if (processingConversationRef.current > 0 && !allowReentry) {
|
|
70921
71008
|
return;
|
|
70922
71009
|
}
|
|
@@ -70930,20 +71017,29 @@ function App2({
|
|
|
70930
71017
|
userCancelledRef.current = false;
|
|
70931
71018
|
return;
|
|
70932
71019
|
}
|
|
71020
|
+
if (myGeneration !== conversationGenerationRef.current) {
|
|
71021
|
+
return;
|
|
71022
|
+
}
|
|
70933
71023
|
setStreaming(true);
|
|
70934
71024
|
abortControllerRef.current = new AbortController;
|
|
70935
|
-
markIncompleteToolsAsCancelled(buffersRef.current);
|
|
71025
|
+
markIncompleteToolsAsCancelled(buffersRef.current, false);
|
|
70936
71026
|
buffersRef.current.interrupted = false;
|
|
70937
71027
|
clearCompletedSubagents();
|
|
70938
71028
|
while (true) {
|
|
70939
71029
|
const signal = abortControllerRef.current?.signal;
|
|
70940
71030
|
if (signal?.aborted) {
|
|
70941
|
-
|
|
71031
|
+
const isStaleAtAbort = myGeneration !== conversationGenerationRef.current;
|
|
71032
|
+
if (!isStaleAtAbort) {
|
|
71033
|
+
setStreaming(false);
|
|
71034
|
+
}
|
|
70942
71035
|
return;
|
|
70943
71036
|
}
|
|
70944
71037
|
const stream2 = await sendMessageStream(agentIdRef.current, currentInput);
|
|
70945
71038
|
if (signal?.aborted) {
|
|
70946
|
-
|
|
71039
|
+
const isStaleAtAbort = myGeneration !== conversationGenerationRef.current;
|
|
71040
|
+
if (!isStaleAtAbort) {
|
|
71041
|
+
setStreaming(false);
|
|
71042
|
+
}
|
|
70947
71043
|
return;
|
|
70948
71044
|
}
|
|
70949
71045
|
const syncAgentState = async () => {
|
|
@@ -70987,6 +71083,10 @@ function App2({
|
|
|
70987
71083
|
const wasInterrupted = !!buffersRef.current.interrupted;
|
|
70988
71084
|
const wasAborted = !!signal?.aborted;
|
|
70989
71085
|
let stopReasonToHandle = wasAborted ? "cancelled" : stopReason;
|
|
71086
|
+
const isStaleAfterDrain = myGeneration !== conversationGenerationRef.current;
|
|
71087
|
+
if (isStaleAfterDrain) {
|
|
71088
|
+
return;
|
|
71089
|
+
}
|
|
70990
71090
|
if (!wasInterrupted) {
|
|
70991
71091
|
refreshDerived();
|
|
70992
71092
|
}
|
|
@@ -71306,7 +71406,8 @@ function App2({
|
|
|
71306
71406
|
sendDesktopNotification();
|
|
71307
71407
|
return;
|
|
71308
71408
|
}
|
|
71309
|
-
const
|
|
71409
|
+
const hasApprovalInPayload = currentInput.some((item) => item?.type === "approval");
|
|
71410
|
+
const isApprovalOnlyPayload = hasApprovalInPayload && currentInput.length === 1;
|
|
71310
71411
|
let latestErrorText = null;
|
|
71311
71412
|
for (let i = buffersRef.current.order.length - 1;i >= 0; i -= 1) {
|
|
71312
71413
|
const id = buffersRef.current.order[i];
|
|
@@ -71321,7 +71422,7 @@ function App2({
|
|
|
71321
71422
|
const detailFromRun = await fetchRunErrorDetail(lastRunId);
|
|
71322
71423
|
const desyncDetected = isApprovalStateDesyncError(detailFromRun) || isApprovalStateDesyncError(latestErrorText);
|
|
71323
71424
|
const lastFailureMessage = latestErrorText || detailFromRun || null;
|
|
71324
|
-
if (
|
|
71425
|
+
if (hasApprovalInPayload && desyncDetected) {
|
|
71325
71426
|
if (llmApiErrorRetriesRef.current < LLM_API_ERROR_MAX_RETRIES2) {
|
|
71326
71427
|
llmApiErrorRetriesRef.current += 1;
|
|
71327
71428
|
const statusId = uid4("status");
|
|
@@ -71334,7 +71435,16 @@ function App2({
|
|
|
71334
71435
|
});
|
|
71335
71436
|
buffersRef.current.order.push(statusId);
|
|
71336
71437
|
refreshDerived();
|
|
71337
|
-
|
|
71438
|
+
if (isApprovalOnlyPayload) {
|
|
71439
|
+
currentInput.splice(0, currentInput.length, buildApprovalRecoveryMessage());
|
|
71440
|
+
} else {
|
|
71441
|
+
const messageItems = currentInput.filter((item) => item?.type !== "approval");
|
|
71442
|
+
if (messageItems.length > 0) {
|
|
71443
|
+
currentInput.splice(0, currentInput.length, ...messageItems);
|
|
71444
|
+
} else {
|
|
71445
|
+
currentInput.splice(0, currentInput.length, buildApprovalRecoveryMessage());
|
|
71446
|
+
}
|
|
71447
|
+
}
|
|
71338
71448
|
buffersRef.current.byId.delete(statusId);
|
|
71339
71449
|
buffersRef.current.order = buffersRef.current.order.filter((id) => id !== statusId);
|
|
71340
71450
|
refreshDerived();
|
|
@@ -71451,8 +71561,11 @@ function App2({
|
|
|
71451
71561
|
sendDesktopNotification();
|
|
71452
71562
|
refreshDerived();
|
|
71453
71563
|
} finally {
|
|
71564
|
+
const isStale = myGeneration !== conversationGenerationRef.current;
|
|
71454
71565
|
abortControllerRef.current = null;
|
|
71455
|
-
|
|
71566
|
+
if (!isStale) {
|
|
71567
|
+
processingConversationRef.current = Math.max(0, processingConversationRef.current - 1);
|
|
71568
|
+
}
|
|
71456
71569
|
}
|
|
71457
71570
|
}, [
|
|
71458
71571
|
appendError,
|
|
@@ -71495,8 +71608,9 @@ function App2({
|
|
|
71495
71608
|
}, 50);
|
|
71496
71609
|
return;
|
|
71497
71610
|
}
|
|
71498
|
-
if (!streaming || interruptRequested)
|
|
71611
|
+
if (!streaming || interruptRequested) {
|
|
71499
71612
|
return;
|
|
71613
|
+
}
|
|
71500
71614
|
if (waitingForQueueCancelRef.current) {
|
|
71501
71615
|
setRestoreQueueOnCancel(true);
|
|
71502
71616
|
}
|
|
@@ -71509,11 +71623,22 @@ function App2({
|
|
|
71509
71623
|
abortControllerRef.current = null;
|
|
71510
71624
|
}
|
|
71511
71625
|
userCancelledRef.current = true;
|
|
71626
|
+
conversationGenerationRef.current += 1;
|
|
71627
|
+
processingConversationRef.current = 0;
|
|
71512
71628
|
setStreaming(false);
|
|
71513
71629
|
if (!toolsCancelled) {
|
|
71514
71630
|
appendError(INTERRUPT_MESSAGE, true);
|
|
71515
71631
|
}
|
|
71516
71632
|
refreshDerived();
|
|
71633
|
+
if (pendingApprovals.length > 0) {
|
|
71634
|
+
const denialResults = pendingApprovals.map((approval) => ({
|
|
71635
|
+
type: "approval",
|
|
71636
|
+
tool_call_id: approval.toolCallId,
|
|
71637
|
+
approve: false,
|
|
71638
|
+
reason: "User interrupted the stream"
|
|
71639
|
+
}));
|
|
71640
|
+
setQueuedApprovalResults(denialResults);
|
|
71641
|
+
}
|
|
71517
71642
|
setPendingApprovals([]);
|
|
71518
71643
|
setApprovalContexts([]);
|
|
71519
71644
|
setApprovalResults([]);
|
|
@@ -71546,7 +71671,8 @@ function App2({
|
|
|
71546
71671
|
appendError,
|
|
71547
71672
|
isExecutingTool,
|
|
71548
71673
|
refreshDerived,
|
|
71549
|
-
setStreaming
|
|
71674
|
+
setStreaming,
|
|
71675
|
+
pendingApprovals
|
|
71550
71676
|
]);
|
|
71551
71677
|
const processConversationRef = import_react76.useRef(processConversation);
|
|
71552
71678
|
import_react76.useEffect(() => {
|
|
@@ -71761,6 +71887,96 @@ function App2({
|
|
|
71761
71887
|
}
|
|
71762
71888
|
refreshDerived();
|
|
71763
71889
|
}, [refreshDerived]);
|
|
71890
|
+
const checkPendingApprovalsForSlashCommand = import_react76.useCallback(async () => {
|
|
71891
|
+
if (!CHECK_PENDING_APPROVALS_BEFORE_SEND) {
|
|
71892
|
+
return { blocked: false };
|
|
71893
|
+
}
|
|
71894
|
+
try {
|
|
71895
|
+
const client = await getClient2();
|
|
71896
|
+
const agent = await client.agents.retrieve(agentId);
|
|
71897
|
+
const { pendingApprovals: existingApprovals } = await getResumeData2(client, agent);
|
|
71898
|
+
if (!existingApprovals || existingApprovals.length === 0) {
|
|
71899
|
+
return { blocked: false };
|
|
71900
|
+
}
|
|
71901
|
+
const approvalResults2 = await Promise.all(existingApprovals.map(async (approvalItem) => {
|
|
71902
|
+
if (!approvalItem.toolName) {
|
|
71903
|
+
return {
|
|
71904
|
+
approval: approvalItem,
|
|
71905
|
+
permission: {
|
|
71906
|
+
decision: "deny",
|
|
71907
|
+
reason: "Tool call incomplete - missing name"
|
|
71908
|
+
},
|
|
71909
|
+
context: null
|
|
71910
|
+
};
|
|
71911
|
+
}
|
|
71912
|
+
const parsedArgs = safeJsonParseOr(approvalItem.toolArgs, {});
|
|
71913
|
+
const permission = await checkToolPermission(approvalItem.toolName, parsedArgs);
|
|
71914
|
+
const context3 = await analyzeToolApproval(approvalItem.toolName, parsedArgs);
|
|
71915
|
+
return { approval: approvalItem, permission, context: context3 };
|
|
71916
|
+
}));
|
|
71917
|
+
const needsUserInput = [];
|
|
71918
|
+
const autoAllowed = [];
|
|
71919
|
+
const autoDenied = [];
|
|
71920
|
+
for (const ac of approvalResults2) {
|
|
71921
|
+
const { approval, permission } = ac;
|
|
71922
|
+
let decision = permission.decision;
|
|
71923
|
+
if (alwaysRequiresUserInput(approval.toolName) && decision === "allow") {
|
|
71924
|
+
decision = "ask";
|
|
71925
|
+
}
|
|
71926
|
+
if (decision === "ask") {
|
|
71927
|
+
needsUserInput.push(ac);
|
|
71928
|
+
} else if (decision === "deny") {
|
|
71929
|
+
autoDenied.push(ac);
|
|
71930
|
+
} else {
|
|
71931
|
+
autoAllowed.push(ac);
|
|
71932
|
+
}
|
|
71933
|
+
}
|
|
71934
|
+
if (needsUserInput.length > 0) {
|
|
71935
|
+
setPendingApprovals(needsUserInput.map((ac) => ac.approval));
|
|
71936
|
+
setApprovalContexts(needsUserInput.map((ac) => ac.context).filter((ctx) => ctx !== null));
|
|
71937
|
+
return { blocked: true };
|
|
71938
|
+
}
|
|
71939
|
+
const allResults = [];
|
|
71940
|
+
if (autoAllowed.length > 0) {
|
|
71941
|
+
const autoAllowedResults = await executeAutoAllowedTools(autoAllowed, (chunk) => onChunk(buffersRef.current, chunk));
|
|
71942
|
+
allResults.push(...autoAllowedResults.map((ar) => ({
|
|
71943
|
+
type: "tool",
|
|
71944
|
+
tool_call_id: ar.toolCallId,
|
|
71945
|
+
tool_return: ar.result.toolReturn,
|
|
71946
|
+
status: ar.result.status,
|
|
71947
|
+
stdout: ar.result.stdout,
|
|
71948
|
+
stderr: ar.result.stderr
|
|
71949
|
+
})));
|
|
71950
|
+
}
|
|
71951
|
+
for (const ac of autoDenied) {
|
|
71952
|
+
const reason = ac.permission.reason || "Permission denied";
|
|
71953
|
+
onChunk(buffersRef.current, {
|
|
71954
|
+
message_type: "tool_return_message",
|
|
71955
|
+
id: "dummy",
|
|
71956
|
+
date: new Date().toISOString(),
|
|
71957
|
+
tool_call_id: ac.approval.toolCallId,
|
|
71958
|
+
tool_return: `Error: request to call tool denied. User reason: ${reason}`,
|
|
71959
|
+
status: "error",
|
|
71960
|
+
stdout: null,
|
|
71961
|
+
stderr: null
|
|
71962
|
+
});
|
|
71963
|
+
allResults.push({
|
|
71964
|
+
type: "approval",
|
|
71965
|
+
tool_call_id: ac.approval.toolCallId,
|
|
71966
|
+
approve: false,
|
|
71967
|
+
reason
|
|
71968
|
+
});
|
|
71969
|
+
}
|
|
71970
|
+
if (allResults.length > 0) {
|
|
71971
|
+
await processConversation([
|
|
71972
|
+
{ type: "approval", approvals: allResults }
|
|
71973
|
+
]);
|
|
71974
|
+
}
|
|
71975
|
+
return { blocked: false };
|
|
71976
|
+
} catch {
|
|
71977
|
+
return { blocked: false };
|
|
71978
|
+
}
|
|
71979
|
+
}, [agentId, processConversation]);
|
|
71764
71980
|
const onSubmit = import_react76.useCallback(async (message) => {
|
|
71765
71981
|
const msg = message?.trim() ?? "";
|
|
71766
71982
|
if (profileConfirmPending && !msg) {
|
|
@@ -71789,6 +72005,7 @@ function App2({
|
|
|
71789
72005
|
}
|
|
71790
72006
|
if (!msg)
|
|
71791
72007
|
return { submitted: false };
|
|
72008
|
+
const submissionGeneration = conversationGenerationRef.current;
|
|
71792
72009
|
telemetry2.trackUserInput(msg, "user", currentModelId || "unknown");
|
|
71793
72010
|
if (pendingApprovals.length > 0) {
|
|
71794
72011
|
return { submitted: false };
|
|
@@ -71801,6 +72018,9 @@ function App2({
|
|
|
71801
72018
|
if (!isSlashCommand && streamingRef.current && !waitingForQueueCancelRef.current) {
|
|
71802
72019
|
waitingForQueueCancelRef.current = true;
|
|
71803
72020
|
queueSnapshotRef.current = [...newQueue];
|
|
72021
|
+
if (toolAbortControllerRef.current) {
|
|
72022
|
+
toolAbortControllerRef.current.abort();
|
|
72023
|
+
}
|
|
71804
72024
|
getClient2().then((client) => client.agents.messages.cancel(agentId)).then(() => {}).catch(() => {
|
|
71805
72025
|
waitingForQueueCancelRef.current = false;
|
|
71806
72026
|
});
|
|
@@ -72479,6 +72699,10 @@ Press Enter to continue, or type anything to cancel.`, false, "running");
|
|
|
72479
72699
|
return { submitted: true };
|
|
72480
72700
|
}
|
|
72481
72701
|
if (trimmed.startsWith("/skill")) {
|
|
72702
|
+
const approvalCheck = await checkPendingApprovalsForSlashCommand();
|
|
72703
|
+
if (approvalCheck.blocked) {
|
|
72704
|
+
return { submitted: false };
|
|
72705
|
+
}
|
|
72482
72706
|
const cmdId2 = uid4("cmd");
|
|
72483
72707
|
const [, ...rest] = trimmed.split(/\s+/);
|
|
72484
72708
|
const description = rest.join(" ").trim();
|
|
@@ -72537,6 +72761,10 @@ ${SKILL_CREATOR_PROMPT3}${userDescriptionLine}
|
|
|
72537
72761
|
return { submitted: true };
|
|
72538
72762
|
}
|
|
72539
72763
|
if (trimmed.startsWith("/remember")) {
|
|
72764
|
+
const approvalCheck = await checkPendingApprovalsForSlashCommand();
|
|
72765
|
+
if (approvalCheck.blocked) {
|
|
72766
|
+
return { submitted: false };
|
|
72767
|
+
}
|
|
72540
72768
|
const cmdId2 = uid4("cmd");
|
|
72541
72769
|
const [, ...rest] = trimmed.split(/\s+/);
|
|
72542
72770
|
const userText = rest.join(" ").trim();
|
|
@@ -72593,6 +72821,10 @@ The user did not specify what to remember. Look at the recent conversation conte
|
|
|
72593
72821
|
return { submitted: true };
|
|
72594
72822
|
}
|
|
72595
72823
|
if (trimmed === "/init") {
|
|
72824
|
+
const approvalCheck = await checkPendingApprovalsForSlashCommand();
|
|
72825
|
+
if (approvalCheck.blocked) {
|
|
72826
|
+
return { submitted: false };
|
|
72827
|
+
}
|
|
72596
72828
|
const cmdId2 = uid4("cmd");
|
|
72597
72829
|
buffersRef.current.byId.set(cmdId2, {
|
|
72598
72830
|
kind: "command",
|
|
@@ -72709,6 +72941,10 @@ ${gitContext}
|
|
|
72709
72941
|
const commandName = trimmed.split(/\s+/)[0]?.slice(1) || "";
|
|
72710
72942
|
const matchedCustom = await findCustomCommand2(commandName);
|
|
72711
72943
|
if (matchedCustom) {
|
|
72944
|
+
const approvalCheck = await checkPendingApprovalsForSlashCommand();
|
|
72945
|
+
if (approvalCheck.blocked) {
|
|
72946
|
+
return { submitted: false };
|
|
72947
|
+
}
|
|
72712
72948
|
const cmdId2 = uid4("cmd");
|
|
72713
72949
|
const args = trimmed.slice(`/${matchedCustom.id}`.length).trim();
|
|
72714
72950
|
let prompt = substituteArguments2(matchedCustom.content, args);
|
|
@@ -73108,7 +73344,7 @@ DO NOT respond to these messages or otherwise consider them in your response unl
|
|
|
73108
73344
|
role: "user",
|
|
73109
73345
|
content: messageContent
|
|
73110
73346
|
});
|
|
73111
|
-
await processConversation(initialInput);
|
|
73347
|
+
await processConversation(initialInput, { submissionGeneration });
|
|
73112
73348
|
clearPlaceholdersInText(msg);
|
|
73113
73349
|
return { submitted: true };
|
|
73114
73350
|
}, [
|
|
@@ -73230,6 +73466,8 @@ DO NOT respond to these messages or otherwise consider them in your response unl
|
|
|
73230
73466
|
setQueuedApprovalResults(allResults);
|
|
73231
73467
|
}
|
|
73232
73468
|
setStreaming(false);
|
|
73469
|
+
waitingForQueueCancelRef.current = false;
|
|
73470
|
+
queueSnapshotRef.current = [];
|
|
73233
73471
|
} else {
|
|
73234
73472
|
await processConversation([
|
|
73235
73473
|
{
|
|
@@ -74001,7 +74239,6 @@ Plan file path: ${planFilePath}`;
|
|
|
74001
74239
|
]);
|
|
74002
74240
|
return /* @__PURE__ */ jsx_dev_runtime56.jsxDEV(Box_default, {
|
|
74003
74241
|
flexDirection: "column",
|
|
74004
|
-
gap: 1,
|
|
74005
74242
|
children: [
|
|
74006
74243
|
/* @__PURE__ */ jsx_dev_runtime56.jsxDEV(Static, {
|
|
74007
74244
|
items: staticItems,
|
|
@@ -74047,7 +74284,6 @@ Plan file path: ${planFilePath}`;
|
|
|
74047
74284
|
}, staticRenderEpoch, false, undefined, this),
|
|
74048
74285
|
/* @__PURE__ */ jsx_dev_runtime56.jsxDEV(Box_default, {
|
|
74049
74286
|
flexDirection: "column",
|
|
74050
|
-
gap: 1,
|
|
74051
74287
|
children: [
|
|
74052
74288
|
loadingState !== "ready" && /* @__PURE__ */ jsx_dev_runtime56.jsxDEV(WelcomeScreen, {
|
|
74053
74289
|
loadingState,
|
|
@@ -74242,7 +74478,7 @@ Plan file path: ${planFilePath}`;
|
|
|
74242
74478
|
]
|
|
74243
74479
|
}, undefined, true, undefined, this),
|
|
74244
74480
|
/* @__PURE__ */ jsx_dev_runtime56.jsxDEV(Box_default, {
|
|
74245
|
-
marginTop:
|
|
74481
|
+
marginTop: 1,
|
|
74246
74482
|
children: /* @__PURE__ */ jsx_dev_runtime56.jsxDEV(Input, {
|
|
74247
74483
|
visible: !showExitStats && pendingApprovals.length === 0 && !anySelectorOpen,
|
|
74248
74484
|
streaming: streaming && !abortControllerRef.current?.signal.aborted,
|
|
@@ -77556,13 +77792,19 @@ Error: ${message}`);
|
|
|
77556
77792
|
try {
|
|
77557
77793
|
await client.agents.retrieve(localProjectSettings.lastAgent);
|
|
77558
77794
|
resumingAgentId = localProjectSettings.lastAgent;
|
|
77559
|
-
} catch {
|
|
77795
|
+
} catch {
|
|
77796
|
+
setLoadingState("selecting_global");
|
|
77797
|
+
return;
|
|
77798
|
+
}
|
|
77560
77799
|
}
|
|
77561
77800
|
if (!resumingAgentId && continueSession && settings.lastAgent) {
|
|
77562
77801
|
try {
|
|
77563
77802
|
await client.agents.retrieve(settings.lastAgent);
|
|
77564
77803
|
resumingAgentId = settings.lastAgent;
|
|
77565
|
-
} catch {
|
|
77804
|
+
} catch {
|
|
77805
|
+
setLoadingState("selecting_global");
|
|
77806
|
+
return;
|
|
77807
|
+
}
|
|
77566
77808
|
}
|
|
77567
77809
|
if (!resumingAgentId && selectedGlobalAgentId) {
|
|
77568
77810
|
try {
|
|
@@ -77617,22 +77859,22 @@ Error: ${message}`);
|
|
|
77617
77859
|
agent = result.agent;
|
|
77618
77860
|
setAgentProvenance(result.provenance);
|
|
77619
77861
|
}
|
|
77620
|
-
if (!agent) {
|
|
77621
|
-
|
|
77622
|
-
|
|
77623
|
-
|
|
77624
|
-
|
|
77625
|
-
|
|
77626
|
-
|
|
77627
|
-
console.error(`Project agent ${localProjectSettings.lastAgent} not found (error: ${JSON.stringify(error)}), creating new one...`);
|
|
77628
|
-
}
|
|
77862
|
+
if (!agent && resumingAgentId) {
|
|
77863
|
+
try {
|
|
77864
|
+
agent = await client.agents.retrieve(resumingAgentId);
|
|
77865
|
+
} catch (error) {
|
|
77866
|
+
console.error(`Agent ${resumingAgentId} not found (error: ${JSON.stringify(error)})`);
|
|
77867
|
+
setLoadingState("selecting_global");
|
|
77868
|
+
return;
|
|
77629
77869
|
}
|
|
77630
77870
|
}
|
|
77631
77871
|
if (!agent && continueSession && settings.lastAgent) {
|
|
77632
77872
|
try {
|
|
77633
77873
|
agent = await client.agents.retrieve(settings.lastAgent);
|
|
77634
77874
|
} catch (error) {
|
|
77635
|
-
console.error(`Previous agent ${settings.lastAgent} not found (error: ${JSON.stringify(error)})
|
|
77875
|
+
console.error(`Previous agent ${settings.lastAgent} not found (error: ${JSON.stringify(error)})`);
|
|
77876
|
+
setLoadingState("selecting_global");
|
|
77877
|
+
return;
|
|
77636
77878
|
}
|
|
77637
77879
|
}
|
|
77638
77880
|
if (!agent) {
|
|
@@ -77795,4 +78037,4 @@ Error during initialization: ${message}`);
|
|
|
77795
78037
|
}
|
|
77796
78038
|
main();
|
|
77797
78039
|
|
|
77798
|
-
//# debugId=
|
|
78040
|
+
//# debugId=D2E37E4C34BABD1E64756E2164756E21
|