@alpaca-editor/core 1.0.4132 → 1.0.4134

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.
@@ -77,7 +77,7 @@ const getToolIcon = (toolName: string) => {
77
77
  // Types for tool calls - supporting both AI and Agent formats
78
78
  export type ApprovalInfo = {
79
79
  summary: string;
80
- riskLevel?: 'low' | 'medium' | 'high';
80
+ riskLevel?: "low" | "medium" | "high";
81
81
  };
82
82
 
83
83
  export interface BaseToolCall {
@@ -116,7 +116,6 @@ interface ToolCallDisplayProps {
116
116
  messageId: string;
117
117
  }
118
118
 
119
-
120
119
  // Helper function to normalize tool calls to a common format
121
120
  const normalizeToolCall = (
122
121
  toolCall: BaseToolCall | AgentToolCall,
@@ -308,237 +307,223 @@ export function ToolCallDisplay({
308
307
  const toolResult = toolCall.function?.result;
309
308
  const popoverKey = `${messageId}-${toolIndex}`;
310
309
  const isAgentToolCall = "isCompleted" in originalToolCall;
311
-
310
+
312
311
  // Get approval information to check if tool call is pending approval
313
- const approvalInfo = originalToolCall.requiresApproval || toolCall.requiresApproval;
314
-
312
+ const approvalInfo =
313
+ originalToolCall.requiresApproval || toolCall.requiresApproval;
314
+
315
315
  const isCompleted = isAgentToolCall
316
316
  ? originalToolCall.isCompleted
317
317
  : !!(toolResult || toolCall.function?.error) && !approvalInfo;
318
-
318
+
319
319
  // Use the approval info from the backend
320
320
  const finalApprovalInfo = approvalInfo;
321
-
321
+
322
322
  // Check if this tool call has been approved/rejected (look for status indicators in function name)
323
323
  // The AgentTerminal adds " (approved)" or " (rejected)" or " (pending approval)" to the functionName field
324
- const originalFunctionName = ("functionName" in originalToolCall ? originalToolCall.functionName : toolCall?.function?.name) || '';
325
- const isApproved = originalFunctionName.includes('(approved)');
326
- const isRejected = originalFunctionName.includes('(rejected)');
327
- const isPending = originalFunctionName.includes('(pending approval)');
324
+ const originalFunctionName =
325
+ ("functionName" in originalToolCall
326
+ ? originalToolCall.functionName
327
+ : toolCall?.function?.name) || "";
328
+ const isApproved = originalFunctionName.includes("(approved)");
329
+ const isRejected = originalFunctionName.includes("(rejected)");
330
+ const isPending = originalFunctionName.includes("(pending approval)");
328
331
  // Treat only approved/rejected as final; pending should still show buttons
329
332
  const hasApprovalStatus = isApproved || isRejected;
330
-
331
- console.log("🔍 Approval status check:", {
332
- toolCallId: toolCall.id,
333
- originalFunctionName,
334
- displayName: toolCall?.displayName,
335
- functionName: toolCall?.function?.name,
336
- isApproved,
337
- isRejected,
338
- hasApprovalStatus
339
- });
340
-
341
- // Debug: Check what we're receiving
342
- console.log("🔍 Approval debug:", {
343
- toolIndex,
344
- functionName: toolCall?.function?.name,
345
- originalRequiresApproval: originalToolCall.requiresApproval,
346
- normalizedRequiresApproval: toolCall.requiresApproval,
347
- approvalInfo,
348
- approvalInfoType: typeof approvalInfo,
349
- isCompleted,
350
- hasApprovalStatus,
351
- finalApprovalInfo,
352
- shouldShowApprovalUI: !isCompleted && finalApprovalInfo && !hasApprovalStatus,
353
- toolResult: toolCall.function?.result,
354
- toolError: toolCall.function?.error,
355
- });
356
-
357
- // Debug: Check if agent ID is available
358
- if (finalApprovalInfo) {
359
- console.log("🔍 Agent ID check:", {
360
- currentAgentId: (window as any)?.currentAgentId,
361
- messageId,
362
- toolCallId: toolCall.id,
363
- hasAgentId: !!(window as any)?.currentAgentId,
364
- windowKeys: Object.keys(window).filter(k => k.includes('agent') || k.includes('Agent'))
365
- });
366
- }
367
333
 
334
+ // Debug logging removed for performance
368
335
 
369
336
  return (
370
337
  <div key={toolIndex}>
371
- <Popover
372
- enableIframeClickDetection={false}
373
- open={openPopovers[popoverKey] || false}
374
- onOpenChange={(open) => {
375
- setOpenPopovers((prev) => ({
376
- ...prev,
377
- [popoverKey]: open,
378
- }));
379
- }}
380
- >
381
- <PopoverTrigger asChild>
382
- <div className="flex items-center gap-2 text-xs text-gray-500">
383
- {isCompleted ? (
384
- <div
385
- className={`flex items-center ${toolCall.function?.error ? "text-red-500" : ""}`}
386
- >
387
- {getToolIcon(toolCall?.function?.name || "")}
388
- </div>
389
- ) : finalApprovalInfo && !hasApprovalStatus ? (
390
- <div className="flex items-center text-amber-600">
391
- {getToolIcon(toolCall?.function?.name || "")}
392
- </div>
393
- ) : finished ? (
394
- <div className="flex items-center opacity-50">
395
- {getToolIcon(toolCall?.function?.name || "")}
396
- </div>
397
- ) : (
398
- <Spinner size="xs" />
399
- )}
400
- <div className="inline-flex items-center gap-2">
401
- <span
402
- className={`${toolCall.function?.error ? "text-red-500" : "hover:text-gray-700"} cursor-pointer`}
403
- >
404
- {/* Show clean function name without approval suffix */}
405
- {(originalFunctionName || toolCall?.function?.name || "tool call")
406
- .replace(' (approved)', '')
407
- .replace(' (rejected)', '')
408
- .replace(' (pending approval)', '')}
409
- {toolCall.function?.error && " (error)"}
410
- {finalApprovalInfo && isApproved && (
411
- <span className="ml-2 text-xs text-green-600 font-medium">
412
- ✓ Approved
413
- </span>
414
- )}
415
- {finalApprovalInfo && isRejected && (
416
- <span className="ml-2 text-xs text-red-600 font-medium">
417
- ✗ Rejected
418
- </span>
419
- )}
420
- {finalApprovalInfo && isPending && (
421
- <span className="ml-2 text-xs text-amber-600 font-medium">
422
- ⏸ Pending approval
423
- </span>
424
- )}
425
- </span>
426
- </div>
427
- </div>
428
- </PopoverTrigger>
429
- <PopoverContent
430
- className="w-[450px] p-0"
431
- align="start"
432
- side="bottom"
433
- sideOffset={8}
434
- onMouseDown={(e) => e.stopPropagation()}
435
- onClick={(e) => e.stopPropagation()}
338
+ <Popover
339
+ enableIframeClickDetection={false}
340
+ open={openPopovers[popoverKey] || false}
341
+ onOpenChange={(open) => {
342
+ setOpenPopovers((prev) => ({
343
+ ...prev,
344
+ [popoverKey]: open,
345
+ }));
346
+ }}
436
347
  >
437
- <ToolCallPopover
438
- toolCall={toolCall}
439
- result={toolResult}
440
- onClose={() => {
441
- setOpenPopovers((prev) => ({
442
- ...prev,
443
- [popoverKey]: false,
444
- }));
445
- }}
446
- />
447
- </PopoverContent>
448
- </Popover>
449
- {!isCompleted && finalApprovalInfo && !hasApprovalStatus && (
450
- <div className="border rounded mt-2">
451
- <div className="p-3 border-b bg-amber-50">
452
- <div className="flex items-start gap-2">
453
- <div className={`w-2 h-2 rounded-full mt-1.5 ${
454
- finalApprovalInfo.riskLevel === 'high' ? 'bg-red-500' :
455
- finalApprovalInfo.riskLevel === 'medium' ? 'bg-amber-500' :
456
- 'bg-green-500'
457
- }`} />
458
- <div>
459
- <div className="text-xs font-medium text-gray-900 mb-1">
460
- Action requires approval
348
+ <PopoverTrigger asChild>
349
+ <div className="flex items-center gap-2 text-xs text-gray-500">
350
+ {isCompleted ? (
351
+ <div
352
+ className={`flex items-center ${toolCall.function?.error ? "text-red-500" : ""}`}
353
+ >
354
+ {getToolIcon(toolCall?.function?.name || "")}
355
+ </div>
356
+ ) : finalApprovalInfo && !hasApprovalStatus ? (
357
+ <div className="flex items-center text-amber-600">
358
+ {getToolIcon(toolCall?.function?.name || "")}
461
359
  </div>
462
- <div className="text-xs text-gray-700">
463
- {finalApprovalInfo.summary}
360
+ ) : finished ? (
361
+ <div className="flex items-center opacity-50">
362
+ {getToolIcon(toolCall?.function?.name || "")}
464
363
  </div>
465
- {finalApprovalInfo.riskLevel && (
466
- <div className={`text-xs mt-1 font-medium ${
467
- finalApprovalInfo.riskLevel === 'high' ? 'text-red-600' :
468
- finalApprovalInfo.riskLevel === 'medium' ? 'text-amber-600' :
469
- 'text-green-600'
470
- }`}>
471
- Risk level: {finalApprovalInfo.riskLevel}
364
+ ) : (
365
+ <Spinner size="xs" />
366
+ )}
367
+ <div className="inline-flex items-center gap-2">
368
+ <span
369
+ className={`${toolCall.function?.error ? "text-red-500" : "hover:text-gray-700"} cursor-pointer`}
370
+ >
371
+ {/* Show clean function name without approval suffix */}
372
+ {(
373
+ originalFunctionName ||
374
+ toolCall?.function?.name ||
375
+ "tool call"
376
+ )
377
+ .replace(" (approved)", "")
378
+ .replace(" (rejected)", "")
379
+ .replace(" (pending approval)", "")}
380
+ {toolCall.function?.error && " (error)"}
381
+ {finalApprovalInfo && isApproved && (
382
+ <span className="ml-2 text-xs font-medium text-green-600">
383
+ ✓ Approved
384
+ </span>
385
+ )}
386
+ {finalApprovalInfo && isRejected && (
387
+ <span className="ml-2 text-xs font-medium text-red-600">
388
+ ✗ Rejected
389
+ </span>
390
+ )}
391
+ {finalApprovalInfo && isPending && (
392
+ <span className="ml-2 text-xs font-medium text-amber-600">
393
+ ⏸ Pending approval
394
+ </span>
395
+ )}
396
+ </span>
397
+ </div>
398
+ </div>
399
+ </PopoverTrigger>
400
+ <PopoverContent
401
+ className="w-[450px] p-0"
402
+ align="start"
403
+ side="bottom"
404
+ sideOffset={8}
405
+ onMouseDown={(e) => e.stopPropagation()}
406
+ onClick={(e) => e.stopPropagation()}
407
+ >
408
+ <ToolCallPopover
409
+ toolCall={toolCall}
410
+ result={toolResult}
411
+ onClose={() => {
412
+ setOpenPopovers((prev) => ({
413
+ ...prev,
414
+ [popoverKey]: false,
415
+ }));
416
+ }}
417
+ />
418
+ </PopoverContent>
419
+ </Popover>
420
+ {!isCompleted && finalApprovalInfo && !hasApprovalStatus && (
421
+ <div className="mt-2 rounded border">
422
+ <div className="border-b bg-amber-50 p-3">
423
+ <div className="flex items-start gap-2">
424
+ <div
425
+ className={`mt-1.5 h-2 w-2 rounded-full ${
426
+ finalApprovalInfo.riskLevel === "high"
427
+ ? "bg-red-500"
428
+ : finalApprovalInfo.riskLevel === "medium"
429
+ ? "bg-amber-500"
430
+ : "bg-green-500"
431
+ }`}
432
+ />
433
+ <div>
434
+ <div className="mb-1 text-xs font-medium text-gray-900">
435
+ Action requires approval
436
+ </div>
437
+ <div className="text-xs text-gray-700">
438
+ {finalApprovalInfo.summary}
472
439
  </div>
473
- )}
440
+ {finalApprovalInfo.riskLevel && (
441
+ <div
442
+ className={`mt-1 text-xs font-medium ${
443
+ finalApprovalInfo.riskLevel === "high"
444
+ ? "text-red-600"
445
+ : finalApprovalInfo.riskLevel === "medium"
446
+ ? "text-amber-600"
447
+ : "text-green-600"
448
+ }`}
449
+ >
450
+ Risk level: {finalApprovalInfo.riskLevel}
451
+ </div>
452
+ )}
453
+ </div>
474
454
  </div>
475
455
  </div>
476
- </div>
477
- <div className="flex items-center justify-end gap-2 p-2">
478
- <Button
479
- size="sm"
480
- variant="secondary"
481
- onClick={async () => {
482
- console.log("🚫 Rejecting tool call:", {
483
- agentId: (window as any)?.currentAgentId,
484
- messageId: messageId,
485
- toolCallId: toolCall.id,
486
- });
487
- try {
488
- const result = await rejectToolCall({
456
+ <div className="flex items-center justify-end gap-2 p-2">
457
+ <Button
458
+ size="sm"
459
+ variant="secondary"
460
+ onClick={async () => {
461
+ console.log("🚫 Rejecting tool call:", {
489
462
  agentId: (window as any)?.currentAgentId,
490
463
  messageId: messageId,
491
464
  toolCallId: toolCall.id,
492
465
  });
493
- console.log("✅ Reject successful:", result);
494
- const ev = new CustomEvent('agent:toolApprovalResolved', {
495
- detail: {
466
+ try {
467
+ const result = await rejectToolCall({
468
+ agentId: (window as any)?.currentAgentId,
496
469
  messageId: messageId,
497
470
  toolCallId: toolCall.id,
498
- approved: false,
499
- },
500
- } as any);
501
- window.dispatchEvent(ev);
502
- } catch (error) {
503
- console.error("❌ Reject failed:", error);
504
- }
505
- }}
506
- >
507
- Reject
508
- </Button>
509
- <Button
510
- size="sm"
511
- onClick={async () => {
512
- console.log(" Approving tool call:", {
513
- agentId: (window as any)?.currentAgentId,
514
- messageId: messageId,
515
- toolCallId: toolCall.id,
516
- });
517
- try {
518
- const result = await approveToolCall({
471
+ });
472
+ console.log("✅ Reject successful:", result);
473
+ const ev = new CustomEvent(
474
+ "agent:toolApprovalResolved",
475
+ {
476
+ detail: {
477
+ messageId: messageId,
478
+ toolCallId: toolCall.id,
479
+ approved: false,
480
+ },
481
+ } as any,
482
+ );
483
+ window.dispatchEvent(ev);
484
+ } catch (error) {
485
+ console.error(" Reject failed:", error);
486
+ }
487
+ }}
488
+ >
489
+ Reject
490
+ </Button>
491
+ <Button
492
+ size="sm"
493
+ onClick={async () => {
494
+ console.log("✅ Approving tool call:", {
519
495
  agentId: (window as any)?.currentAgentId,
520
496
  messageId: messageId,
521
497
  toolCallId: toolCall.id,
522
498
  });
523
- console.log("✅ Approve successful:", result);
524
- const ev = new CustomEvent('agent:toolApprovalResolved', {
525
- detail: {
499
+ try {
500
+ const result = await approveToolCall({
501
+ agentId: (window as any)?.currentAgentId,
526
502
  messageId: messageId,
527
503
  toolCallId: toolCall.id,
528
- approved: true,
529
- },
530
- } as any);
531
- window.dispatchEvent(ev);
532
- } catch (error) {
533
- console.error("❌ Approve failed:", error);
534
- }
535
- }}
536
- >
537
- Approve
538
- </Button>
504
+ });
505
+ console.log("✅ Approve successful:", result);
506
+ const ev = new CustomEvent(
507
+ "agent:toolApprovalResolved",
508
+ {
509
+ detail: {
510
+ messageId: messageId,
511
+ toolCallId: toolCall.id,
512
+ approved: true,
513
+ },
514
+ } as any,
515
+ );
516
+ window.dispatchEvent(ev);
517
+ } catch (error) {
518
+ console.error("❌ Approve failed:", error);
519
+ }
520
+ }}
521
+ >
522
+ Approve
523
+ </Button>
524
+ </div>
539
525
  </div>
540
- </div>
541
- )}
526
+ )}
542
527
  </div>
543
528
  );
544
529
  })}
@@ -75,7 +75,7 @@ const ToolbarButtonWrapper: React.FC<{
75
75
  });
76
76
 
77
77
  return (
78
- <ToolbarButton icon={icon} active={isActive} onMouseDown={onMouseDown} />
78
+ <ToolbarButton icon={icon} active={isActive} onMouseDown={onMouseDown} type={`${option.type}-${option.id}`} />
79
79
  );
80
80
  });
81
81
 
@@ -492,7 +492,6 @@ export const ReactSlate = forwardRef<any, ReactSlateProps>((props, ref) => {
492
492
  <div
493
493
  key={`subgroup-${subGroupIndex}`}
494
494
  className="toolbar-button-group"
495
- data-testid="toolbar-button-group"
496
495
  >
497
496
  {subGroup.map((option) => {
498
497
  const optionObj = getOption(option);
@@ -938,26 +937,26 @@ export const ReactSlate = forwardRef<any, ReactSlateProps>((props, ref) => {
938
937
  {!readOnly && showControls && (
939
938
  <div className="mb-4 flex flex-col gap-2">
940
939
  {toolbarStructure.map(([rowIndex, rowGroups], mapIndex) => (
941
- <div
942
- key={`row-${rowIndex}`}
943
- className="toolbar-row"
944
- data-testid={`rte-toolbar-row-${rowGroups[0]?.options?.[0]?.id || 'unknown'}`}
945
- >
946
- {rowGroups.map((group) =>
947
- renderToolbarGroup(group, parseInt(rowIndex)),
948
- )}
949
- {/* Add strip formatting button to the last row */}
950
- {mapIndex === toolbarStructure.length - 1 && (
951
- <div className="toolbar-button-group">
952
- <ToolbarButton
953
- icon="✗"
954
- active={false}
955
- onMouseDown={handleStripFormattingClick}
956
- type={rowGroups[0]?.options?.[0]?.id || 'unknown'}
957
- />
958
- </div>
959
- )}
960
- </div>
940
+ <div
941
+ key={`row-${rowIndex}`}
942
+ className="toolbar-row"
943
+ data-testid={`rte-toolbar-row-${rowGroups[0]?.options?.[0]?.id || 'unknown'}`}
944
+ >
945
+ {rowGroups.map((group) =>
946
+ renderToolbarGroup(group, parseInt(rowIndex)),
947
+ )}
948
+ {/* Add strip formatting button to the last row */}
949
+ {mapIndex === toolbarStructure.length - 1 && (
950
+ <div className="toolbar-button-group">
951
+ <ToolbarButton
952
+ icon="✗"
953
+ active={false}
954
+ onMouseDown={handleStripFormattingClick}
955
+ type="strip-formatting"
956
+ />
957
+ </div>
958
+ )}
959
+ </div>
961
960
  ))}
962
961
  {/* Fallback: if no toolbar structure exists, create a row for strip formatting */}
963
962
  {toolbarStructure.length === 0 && (
@@ -967,7 +966,7 @@ export const ReactSlate = forwardRef<any, ReactSlateProps>((props, ref) => {
967
966
  icon="✗"
968
967
  active={false}
969
968
  onMouseDown={handleStripFormattingClick}
970
- type={"strip-formatting"}
969
+ type="strip-formatting"
971
970
  />
972
971
  </div>
973
972
  </div>
@@ -15,7 +15,7 @@ export const ToolbarButton: React.FC<ToolbarButtonProps> = ({
15
15
  active && "active bg-white",
16
16
  )}
17
17
  onMouseDown={onMouseDown}
18
- data-testid={`toolbar-button-${type || "unknown"}`}
18
+ data-testid={`rte-toolbar-button-${type || "unknown"}`}
19
19
  >
20
20
  {icon}
21
21
  </button>
@@ -14,12 +14,15 @@ export type AiProfile = {
14
14
  id: string;
15
15
  name: string;
16
16
  instructions: string;
17
+ managedTodoInstructions?: string;
17
18
  defaultModelId: string | null; // Guid as string, nullable
18
19
  models: AiModel[]; // Array of model objects with id and name
19
20
  prompts: { prompt: string; title: string }[];
20
21
  errorMessage?: string;
21
22
  // Whether a new agent should be seeded with current item/selection/field
22
23
  includeEditorContextOnCreate?: boolean;
24
+ // When true, the agent should run in managed TODO list mode.
25
+ managedTodoMode?: boolean;
23
26
  // Tools that are allowed when the user switches to "Ask" mode
24
27
  askModeTools?: string[];
25
28
  // Optional cost limit in USD, sourced from profile
package/src/revision.ts CHANGED
@@ -1,2 +1,2 @@
1
- export const version = "1.0.4132";
2
- export const buildDate = "2025-10-01 09:31:16";
1
+ export const version = "1.0.4134";
2
+ export const buildDate = "2025-10-02 00:59:02";