@agent-native/toolkit 0.201.1 → 0.201.2-nightly-20261006010750

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.
Files changed (68) hide show
  1. package/dist/app/agentkit/react/components.d.ts.map +1 -1
  2. package/dist/app/agentkit/react/components.js +292 -23
  3. package/dist/app/agentkit/react/components.js.map +1 -1
  4. package/dist/app/agentkit/react/context.d.ts +5 -0
  5. package/dist/app/agentkit/react/context.d.ts.map +1 -1
  6. package/dist/app/agentkit/react/context.js +5 -0
  7. package/dist/app/agentkit/react/context.js.map +1 -1
  8. package/dist/app/agentkit/react/styles.css +74 -2
  9. package/dist/app/chat/AgentKitAssistantChat.d.ts.map +1 -1
  10. package/dist/app/chat/AgentKitAssistantChat.js +5 -0
  11. package/dist/app/chat/AgentKitAssistantChat.js.map +1 -1
  12. package/dist/app/i18n/catalogs/ar-SA.d.ts.map +1 -1
  13. package/dist/app/i18n/catalogs/ar-SA.js +3 -0
  14. package/dist/app/i18n/catalogs/ar-SA.js.map +1 -1
  15. package/dist/app/i18n/catalogs/de-DE.d.ts.map +1 -1
  16. package/dist/app/i18n/catalogs/de-DE.js +3 -0
  17. package/dist/app/i18n/catalogs/de-DE.js.map +1 -1
  18. package/dist/app/i18n/catalogs/en-US.d.ts +3 -0
  19. package/dist/app/i18n/catalogs/en-US.d.ts.map +1 -1
  20. package/dist/app/i18n/catalogs/en-US.js +3 -0
  21. package/dist/app/i18n/catalogs/en-US.js.map +1 -1
  22. package/dist/app/i18n/catalogs/es-ES.d.ts.map +1 -1
  23. package/dist/app/i18n/catalogs/es-ES.js +3 -0
  24. package/dist/app/i18n/catalogs/es-ES.js.map +1 -1
  25. package/dist/app/i18n/catalogs/fr-FR.d.ts.map +1 -1
  26. package/dist/app/i18n/catalogs/fr-FR.js +3 -0
  27. package/dist/app/i18n/catalogs/fr-FR.js.map +1 -1
  28. package/dist/app/i18n/catalogs/hi-IN.d.ts.map +1 -1
  29. package/dist/app/i18n/catalogs/hi-IN.js +3 -0
  30. package/dist/app/i18n/catalogs/hi-IN.js.map +1 -1
  31. package/dist/app/i18n/catalogs/ja-JP.d.ts.map +1 -1
  32. package/dist/app/i18n/catalogs/ja-JP.js +3 -0
  33. package/dist/app/i18n/catalogs/ja-JP.js.map +1 -1
  34. package/dist/app/i18n/catalogs/ko-KR.d.ts.map +1 -1
  35. package/dist/app/i18n/catalogs/ko-KR.js +3 -0
  36. package/dist/app/i18n/catalogs/ko-KR.js.map +1 -1
  37. package/dist/app/i18n/catalogs/pt-BR.d.ts.map +1 -1
  38. package/dist/app/i18n/catalogs/pt-BR.js +3 -0
  39. package/dist/app/i18n/catalogs/pt-BR.js.map +1 -1
  40. package/dist/app/i18n/catalogs/zh-CN.d.ts.map +1 -1
  41. package/dist/app/i18n/catalogs/zh-CN.js +3 -0
  42. package/dist/app/i18n/catalogs/zh-CN.js.map +1 -1
  43. package/dist/app/i18n/catalogs/zh-TW.d.ts.map +1 -1
  44. package/dist/app/i18n/catalogs/zh-TW.js +3 -0
  45. package/dist/app/i18n/catalogs/zh-TW.js.map +1 -1
  46. package/dist/composer/AgentSuggestionBar.d.ts +1 -1
  47. package/dist/composer/AgentSuggestionBar.d.ts.map +1 -1
  48. package/dist/composer/AgentSuggestionBar.js +75 -6
  49. package/dist/composer/AgentSuggestionBar.js.map +1 -1
  50. package/package.json +4 -4
  51. package/src/app/agentkit/react/components.tsx +492 -60
  52. package/src/app/agentkit/react/context.tsx +10 -0
  53. package/src/app/agentkit/react/lifecycle.spec.tsx +487 -1
  54. package/src/app/agentkit/react/styles.css +74 -2
  55. package/src/app/chat/AgentKitAssistantChat.tsx +5 -0
  56. package/src/app/i18n/catalogs/ar-SA.ts +3 -0
  57. package/src/app/i18n/catalogs/de-DE.ts +3 -0
  58. package/src/app/i18n/catalogs/en-US.ts +3 -0
  59. package/src/app/i18n/catalogs/es-ES.ts +3 -0
  60. package/src/app/i18n/catalogs/fr-FR.ts +3 -0
  61. package/src/app/i18n/catalogs/hi-IN.ts +3 -0
  62. package/src/app/i18n/catalogs/ja-JP.ts +3 -0
  63. package/src/app/i18n/catalogs/ko-KR.ts +3 -0
  64. package/src/app/i18n/catalogs/pt-BR.ts +3 -0
  65. package/src/app/i18n/catalogs/zh-CN.ts +3 -0
  66. package/src/app/i18n/catalogs/zh-TW.ts +3 -0
  67. package/src/composer/AgentSuggestionBar.overflow.spec.tsx +277 -0
  68. package/src/composer/AgentSuggestionBar.tsx +113 -8
@@ -116,6 +116,7 @@ import {
116
116
  } from "@agent-native/agentkit/protocol";
117
117
 
118
118
  import {
119
+ defaultAgentKitLabels,
119
120
  useAgentCapability,
120
121
  useAgentConnection,
121
122
  useAgentKit,
@@ -123,6 +124,7 @@ import {
123
124
  useAgentKitMutation,
124
125
  useAgentThread,
125
126
  type AgentConnectionErrorRenderProps,
127
+ type AgentKitLabels,
126
128
  type AgentKitQueueRenderProps,
127
129
  type AgentKitRegistry,
128
130
  type AgentKitRenderProps,
@@ -447,10 +449,13 @@ function interactionIcon(kind: string): ReactNode {
447
449
  export function AgentObjectReferenceView({
448
450
  value: object,
449
451
  }: AgentKitRenderProps<AgentObjectReference>) {
450
- const { onOpenObject } = useAgentKit();
452
+ const { onOpenObject, labels } = useAgentKit();
453
+ const thread = useAgentThread();
451
454
  const content = (
452
455
  <>
453
- <span className="agentkit-object-label">{object.label}</span>
456
+ <span className="agentkit-object-label">
457
+ {resolveObjectLabel(object, thread, labels.assistant)}
458
+ </span>
454
459
  {typeof object.metadata?.added === "number" ? (
455
460
  <span className="agentkit-diff-added">+{object.metadata.added}</span>
456
461
  ) : null}
@@ -477,24 +482,324 @@ export function AgentObjectReferenceView({
477
482
  export function AgentParticipantView({
478
483
  value: agent,
479
484
  }: AgentKitRenderProps<AgentParticipant>) {
485
+ const { labels } = useAgentKit();
486
+ const thread = useAgentThread();
480
487
  return (
481
488
  <AgentIdentityChip
482
489
  id={agent.id}
483
- name={agent.name}
490
+ name={resolveAgentName(
491
+ thread,
492
+ agent.id,
493
+ [agent.origin],
494
+ labels.assistant,
495
+ agent.name,
496
+ )}
497
+ fallbackName={labels.assistant}
484
498
  kind={agent.kind}
485
499
  status={agent.status}
486
500
  />
487
501
  );
488
502
  }
489
503
 
504
+ const UUID_PATTERN =
505
+ /(^|[^0-9a-f])([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})(?=$|[^0-9a-f])/gi;
506
+ const ACTIVITY_TOOL_VALUE_LIMIT = 2_000;
507
+ const ACTIVITY_TOOL_NODE_LIMIT = 160;
508
+ const ACTIVITY_TOOL_DEPTH_LIMIT = 8;
509
+
510
+ function isUuid(value: string): boolean {
511
+ if (value.length > 64) return false;
512
+ return /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(
513
+ value.trim(),
514
+ );
515
+ }
516
+
517
+ function hideUuids(value: string): string {
518
+ return value.replace(UUID_PATTERN, "$1");
519
+ }
520
+
521
+ function readableText(value: string | undefined): string {
522
+ if (!value) return "";
523
+ return hideUuids(value)
524
+ .replace(/\s+/g, " ")
525
+ .replace(/\s+([,.;:!?])/g, "$1")
526
+ .replace(/[,.;:!?]\s*$/g, "")
527
+ .trim();
528
+ }
529
+
530
+ function humanizeAgentKind(kind: string): string {
531
+ const readableKind = readableText(
532
+ kind.replace(/^agent-native\//i, "").replace(/^mcp__/i, ""),
533
+ );
534
+ if (!readableKind) return "";
535
+ return readableKind
536
+ .replace(/[._-]+/g, " ")
537
+ .replace(/\b\w/g, (character) => character.toUpperCase());
538
+ }
539
+
540
+ function humanizeAgentLabel(value: string): string {
541
+ const label = readableText(value);
542
+ if (!label) return "";
543
+ if (label.toLowerCase() === "agent-native") return "Agent-Native";
544
+ return /\s/.test(label) ? label : humanizeAgentKind(label);
545
+ }
546
+
547
+ function resolveAgentName(
548
+ thread: AgentThreadState,
549
+ agentId: string | undefined,
550
+ references: readonly (AgentObjectReference | undefined)[],
551
+ fallback: string,
552
+ preferredName?: string,
553
+ ): string {
554
+ const participant = agentId ? thread.agents[agentId] : undefined;
555
+ const names = [
556
+ preferredName,
557
+ participant?.name,
558
+ participant?.origin?.label,
559
+ ...references
560
+ .filter(
561
+ (reference) => reference?.kind === "agent" && reference.id === agentId,
562
+ )
563
+ .map((reference) => reference?.label),
564
+ participant?.description,
565
+ ];
566
+ for (const name of names) {
567
+ const label = name ? humanizeAgentLabel(name) : "";
568
+ if (label) return label;
569
+ }
570
+ return fallback;
571
+ }
572
+
573
+ function resolveObjectLabel(
574
+ object: AgentObjectReference,
575
+ thread: AgentThreadState,
576
+ fallback: string,
577
+ ): string {
578
+ if (object.kind === "agent") {
579
+ return resolveAgentName(thread, object.id, [object], fallback);
580
+ }
581
+ if (object.kind === "task") {
582
+ const title = humanizeAgentLabel(thread.tasks[object.id]?.title ?? "");
583
+ if (title) return title;
584
+ }
585
+ return (
586
+ humanizeAgentLabel(object.label) ||
587
+ humanizeAgentKind(object.kind) ||
588
+ fallback
589
+ );
590
+ }
591
+
592
+ function sourceObjectUnlessRepresented(
593
+ source: AgentObjectReference | undefined,
594
+ displayedAgentIds: readonly (string | undefined)[],
595
+ ): AgentObjectReference | undefined {
596
+ if (source?.kind === "agent" && displayedAgentIds.includes(source.id)) {
597
+ return undefined;
598
+ }
599
+ return source;
600
+ }
601
+
602
+ type ActivityToolValueBudget = {
603
+ nodes: number;
604
+ remainingCharacters: number;
605
+ ancestors: WeakSet<object>;
606
+ truncated: boolean;
607
+ };
608
+
609
+ type ActivityValueLabels = Pick<
610
+ AgentKitLabels,
611
+ | "activityValueIdentifierHidden"
612
+ | "activityValueOmitted"
613
+ | "activityValueCircular"
614
+ >;
615
+
616
+ function resolveActivityValueLabels(
617
+ labels: Partial<AgentKitLabels> = {},
618
+ ): Required<ActivityValueLabels> {
619
+ return {
620
+ activityValueIdentifierHidden:
621
+ labels.activityValueIdentifierHidden ??
622
+ defaultAgentKitLabels.activityValueIdentifierHidden!,
623
+ activityValueOmitted:
624
+ labels.activityValueOmitted ??
625
+ defaultAgentKitLabels.activityValueOmitted!,
626
+ activityValueCircular:
627
+ labels.activityValueCircular ??
628
+ defaultAgentKitLabels.activityValueCircular!,
629
+ };
630
+ }
631
+
632
+ function activityToolValue(
633
+ value: unknown,
634
+ budget: ActivityToolValueBudget,
635
+ labels: Required<ActivityValueLabels>,
636
+ depth = 0,
637
+ ): unknown {
638
+ if (budget.nodes >= ACTIVITY_TOOL_NODE_LIMIT) {
639
+ budget.truncated = true;
640
+ return undefined;
641
+ }
642
+ budget.nodes++;
643
+ if (depth > ACTIVITY_TOOL_DEPTH_LIMIT) {
644
+ budget.truncated = true;
645
+ return labels.activityValueOmitted;
646
+ }
647
+ if (typeof value === "string") {
648
+ if (isUuid(value)) return labels.activityValueIdentifierHidden;
649
+ const sourceLimit = budget.remainingCharacters + 36;
650
+ let text = hideUuids(value.slice(0, sourceLimit));
651
+ if (value.length > sourceLimit) {
652
+ text = text.slice(0, Math.max(0, text.length - 36));
653
+ budget.truncated = true;
654
+ }
655
+ const safeText = text.slice(0, budget.remainingCharacters);
656
+ budget.remainingCharacters -= safeText.length;
657
+ if (text.length > safeText.length) budget.truncated = true;
658
+ if (text.length > 0 && safeText.length === 0) {
659
+ return labels.activityValueOmitted;
660
+ }
661
+ return safeText;
662
+ }
663
+ if (value && typeof value === "object") {
664
+ if (budget.ancestors.has(value)) {
665
+ budget.truncated = true;
666
+ return labels.activityValueCircular;
667
+ }
668
+ budget.ancestors.add(value);
669
+ if (Array.isArray(value)) {
670
+ const items: unknown[] = [];
671
+ let visited = 0;
672
+ for (let index = 0; index < value.length; index++) {
673
+ if (budget.nodes >= ACTIVITY_TOOL_NODE_LIMIT) break;
674
+ budget.nodes++;
675
+ visited++;
676
+ const descriptor = Object.getOwnPropertyDescriptor(
677
+ value,
678
+ String(index),
679
+ );
680
+ if (!descriptor || !("value" in descriptor)) continue;
681
+ const safeValue = activityToolValue(
682
+ descriptor.value,
683
+ budget,
684
+ labels,
685
+ depth + 1,
686
+ );
687
+ if (safeValue !== undefined) items.push(safeValue);
688
+ }
689
+ if (visited < value.length) {
690
+ budget.truncated = true;
691
+ items.push(labels.activityValueOmitted);
692
+ }
693
+ budget.ancestors.delete(value);
694
+ return items.length ? items : undefined;
695
+ }
696
+
697
+ const result: Record<string, unknown> = Object.create(null);
698
+ let included = 0;
699
+ for (const key in value) {
700
+ if (budget.nodes >= ACTIVITY_TOOL_NODE_LIMIT) {
701
+ budget.truncated = true;
702
+ break;
703
+ }
704
+ budget.nodes++;
705
+ if (!Object.hasOwn(value, key) || isUuid(key)) continue;
706
+ const descriptor = Object.getOwnPropertyDescriptor(value, key);
707
+ if (!descriptor || !("value" in descriptor)) continue;
708
+ const keyLimit = budget.remainingCharacters + 36;
709
+ let safeKey = hideUuids(key.slice(0, keyLimit));
710
+ if (key.length > keyLimit) {
711
+ safeKey = safeKey.slice(0, Math.max(0, safeKey.length - 36));
712
+ budget.truncated = true;
713
+ }
714
+ const boundedKey = safeKey.slice(0, budget.remainingCharacters);
715
+ if (safeKey.length > boundedKey.length) budget.truncated = true;
716
+ safeKey = boundedKey;
717
+ if (!safeKey.trim()) continue;
718
+ budget.remainingCharacters -= safeKey.length;
719
+ const safeValue = activityToolValue(
720
+ descriptor.value,
721
+ budget,
722
+ labels,
723
+ depth + 1,
724
+ );
725
+ if (safeValue === undefined) continue;
726
+ result[safeKey] = safeValue;
727
+ included++;
728
+ }
729
+ budget.ancestors.delete(value);
730
+ return included ? result : undefined;
731
+ }
732
+ return value;
733
+ }
734
+
735
+ function createActivityToolValueBudget(): ActivityToolValueBudget {
736
+ return {
737
+ nodes: 0,
738
+ remainingCharacters: ACTIVITY_TOOL_VALUE_LIMIT - 64,
739
+ ancestors: new WeakSet(),
740
+ truncated: false,
741
+ };
742
+ }
743
+
744
+ function formatActivityText(
745
+ value: string,
746
+ labels: Partial<AgentKitLabels> = {},
747
+ ): string {
748
+ const budget = createActivityToolValueBudget();
749
+ const safeValue = activityToolValue(
750
+ value,
751
+ budget,
752
+ resolveActivityValueLabels(labels),
753
+ );
754
+ if (typeof safeValue !== "string") return "";
755
+ return budget.truncated ? `${safeValue}…` : safeValue;
756
+ }
757
+
758
+ function formatActivityToolValue(
759
+ value: unknown,
760
+ labels: Partial<AgentKitLabels> = {},
761
+ ): string | undefined {
762
+ const budget = createActivityToolValueBudget();
763
+ const valueLabels = resolveActivityValueLabels(labels);
764
+ const safeValue = activityToolValue(value, budget, valueLabels);
765
+ if (safeValue === undefined) {
766
+ return budget.truncated ? valueLabels.activityValueOmitted : undefined;
767
+ }
768
+ const formatted = formatToolDiagnostic(safeValue);
769
+ if (!formatted?.trim()) {
770
+ return budget.truncated ? valueLabels.activityValueOmitted : undefined;
771
+ }
772
+ if (!budget.truncated && formatted.length <= ACTIVITY_TOOL_VALUE_LIMIT) {
773
+ return formatted;
774
+ }
775
+ const omissionMarker = `\n${valueLabels.activityValueOmitted}`;
776
+ const contentLimit = Math.max(
777
+ 0,
778
+ ACTIVITY_TOOL_VALUE_LIMIT - omissionMarker.length - 1,
779
+ );
780
+ return `${formatted.slice(0, contentLimit).trimEnd()}…${omissionMarker}`;
781
+ }
782
+
783
+ function activityLabel(activity: AgentActivity, workingLabel: string): string {
784
+ const label = readableText(activity.label);
785
+ if (label.toLowerCase() === "processing") return workingLabel;
786
+ return (
787
+ humanizeAgentLabel(label) ||
788
+ humanizeAgentKind(activity.kind) ||
789
+ workingLabel
790
+ );
791
+ }
792
+
490
793
  function AgentIdentityChip({
491
794
  id,
492
795
  name,
796
+ fallbackName = "Agent",
493
797
  kind,
494
798
  status,
495
799
  }: {
496
800
  id: string;
497
801
  name: string;
802
+ fallbackName?: string;
498
803
  kind?: string;
499
804
  status?: AgentParticipant["status"];
500
805
  }) {
@@ -505,7 +810,9 @@ function AgentIdentityChip({
505
810
  data-agent-kind={kind}
506
811
  data-status={status}
507
812
  >
508
- <span className="agentkit-agent-name">{name}</span>
813
+ <span className="agentkit-agent-name">
814
+ {readableText(name) || fallbackName}
815
+ </span>
509
816
  </span>
510
817
  );
511
818
  }
@@ -533,7 +840,7 @@ function defaultInteractionLabel(
533
840
  case "closed":
534
841
  return labels.agentClosed;
535
842
  default:
536
- return interaction.kind;
843
+ return humanizeAgentKind(interaction.kind) || labels.working;
537
844
  }
538
845
  }
539
846
 
@@ -558,7 +865,29 @@ export function AgentInteractionItem({
558
865
  AgentParticipantView)
559
866
  : undefined;
560
867
  const ObjectRenderer = slots.object ?? AgentObjectReferenceView;
561
- const object = interaction.object ?? interaction.source;
868
+ const agentName = resolveAgentName(
869
+ thread,
870
+ interaction.agentId,
871
+ [interaction.source],
872
+ labels.assistant,
873
+ );
874
+ const targetName = resolveAgentName(
875
+ thread,
876
+ interaction.targetAgentId,
877
+ [interaction.object],
878
+ labels.assistant,
879
+ );
880
+ const object =
881
+ interaction.object ??
882
+ sourceObjectUnlessRepresented(interaction.source, [
883
+ interaction.agentId,
884
+ interaction.targetAgentId,
885
+ ]);
886
+ const label = readableText(interaction.label);
887
+ const visibleLabel =
888
+ humanizeAgentLabel(label) ||
889
+ defaultInteractionLabel({ ...interaction, label: undefined }, labels);
890
+ const detail = readableText(interaction.detail);
562
891
  return (
563
892
  <div
564
893
  className="agentkit-agent-interaction"
@@ -571,25 +900,25 @@ export function AgentInteractionItem({
571
900
  ) : (
572
901
  <AgentIdentityChip
573
902
  id={interaction.agentId}
574
- name={interaction.agentId}
903
+ name={agentName}
904
+ fallbackName={labels.assistant}
575
905
  />
576
906
  )}
577
- <span className="agentkit-agent-interaction-label">
578
- {defaultInteractionLabel(interaction, labels)}
579
- </span>
907
+ <span className="agentkit-agent-interaction-label">{visibleLabel}</span>
580
908
  {target && TargetRenderer ? (
581
909
  <TargetRenderer value={target} threadId={threadId} />
582
910
  ) : interaction.targetAgentId ? (
583
911
  <AgentIdentityChip
584
912
  id={interaction.targetAgentId}
585
- name={interaction.targetAgentId}
913
+ name={targetName}
914
+ fallbackName={labels.assistant}
586
915
  />
587
916
  ) : null}
588
917
  {object ? (
589
918
  <ObjectRenderer value={object} threadId={threadId} />
590
- ) : interaction.detail ? (
591
- <span className="agentkit-agent-interaction-detail">
592
- {interaction.detail}
919
+ ) : detail ? (
920
+ <span className="agentkit-agent-interaction-detail" title={detail}>
921
+ {detail}
593
922
  </span>
594
923
  ) : null}
595
924
  </div>
@@ -603,14 +932,36 @@ export function AgentActivityItem({
603
932
  const { slots, registry, labels } = useAgentKit();
604
933
  const thread = useAgentThread();
605
934
  const [open, setOpen] = useState(false);
606
- const expandable = Boolean(activity.summary?.length);
607
935
  const agent = activity.agentId ? thread.agents[activity.agentId] : undefined;
936
+ const agentName = resolveAgentName(
937
+ thread,
938
+ activity.agentId,
939
+ [activity.source, activity.object],
940
+ labels.assistant,
941
+ );
942
+ const tool = thread.tools[activity.id];
943
+ const toolInput = tool
944
+ ? formatActivityToolValue(tool.input, labels)
945
+ : undefined;
946
+ const toolResult = tool
947
+ ? formatActivityToolValue(tool.output, labels)
948
+ : undefined;
949
+ const toolInputLabel = labels.toolInput ?? defaultAgentKitLabels.toolInput!;
950
+ const toolResultLabel =
951
+ labels.toolResult ?? defaultAgentKitLabels.toolResult!;
952
+ const expandable = Boolean(
953
+ activity.summary?.length || toolInput || toolResult,
954
+ );
608
955
  const AgentRenderer = agent
609
956
  ? (registry.agents?.[agent.kind ?? ""] ??
610
957
  slots.agent ??
611
958
  AgentParticipantView)
612
959
  : undefined;
613
960
  const ObjectRenderer = slots.object ?? AgentObjectReferenceView;
961
+ const object =
962
+ activity.object ??
963
+ sourceObjectUnlessRepresented(activity.source, [activity.agentId]);
964
+ const detail = tool ? "" : readableText(activity.detail);
614
965
  return (
615
966
  <div
616
967
  className="agentkit-activity-item"
@@ -622,16 +973,20 @@ export function AgentActivityItem({
622
973
  {agent && AgentRenderer ? (
623
974
  <AgentRenderer value={agent} threadId={threadId} />
624
975
  ) : activity.agentId ? (
625
- <AgentIdentityChip id={activity.agentId} name={activity.agentId} />
626
- ) : null}
627
- <span className="agentkit-activity-label">{activity.label}</span>
628
- {activity.object ? (
629
- <ObjectRenderer value={activity.object} threadId={threadId} />
976
+ <AgentIdentityChip
977
+ id={activity.agentId}
978
+ name={agentName}
979
+ fallbackName={labels.assistant}
980
+ />
630
981
  ) : null}
631
- {!activity.object && activity.source ? (
632
- <ObjectRenderer value={activity.source} threadId={threadId} />
633
- ) : !activity.object && activity.detail ? (
634
- <span className="agentkit-activity-detail">{activity.detail}</span>
982
+ <span className="agentkit-activity-label">
983
+ {activityLabel(activity, labels.working)}
984
+ </span>
985
+ {object ? <ObjectRenderer value={object} threadId={threadId} /> : null}
986
+ {detail ? (
987
+ <span className="agentkit-activity-detail" title={detail}>
988
+ {detail}
989
+ </span>
635
990
  ) : null}
636
991
  {expandable ? (
637
992
  <button
@@ -651,13 +1006,54 @@ export function AgentActivityItem({
651
1006
  </div>
652
1007
  {open ? (
653
1008
  <div className="agentkit-activity-summary">
654
- {activity.summary?.map((part, index) => (
655
- <AgentMessagePartView
656
- key={`${activity.id}-summary-${index}`}
657
- value={part}
658
- threadId={threadId}
659
- />
660
- ))}
1009
+ {activity.summary?.map((part, index) => {
1010
+ const safePart =
1011
+ part.type === "text"
1012
+ ? {
1013
+ ...part,
1014
+ text: part.text.trim()
1015
+ ? formatActivityText(part.text, labels)
1016
+ : "",
1017
+ }
1018
+ : part;
1019
+ return safePart.type === "text" && !safePart.text ? null : (
1020
+ <AgentMessagePartView
1021
+ key={`${activity.id}-summary-${index}`}
1022
+ value={safePart}
1023
+ threadId={threadId}
1024
+ />
1025
+ );
1026
+ })}
1027
+ {toolInput ? (
1028
+ <div className="agentkit-activity-summary-section">
1029
+ <div className="agentkit-activity-summary-label">
1030
+ {toolInputLabel}
1031
+ </div>
1032
+ <pre
1033
+ role="region"
1034
+ aria-label={toolInputLabel}
1035
+ tabIndex={0}
1036
+ className="agentkit-activity-summary-value"
1037
+ >
1038
+ {toolInput}
1039
+ </pre>
1040
+ </div>
1041
+ ) : null}
1042
+ {toolResult ? (
1043
+ <div className="agentkit-activity-summary-section">
1044
+ <div className="agentkit-activity-summary-label">
1045
+ {toolResultLabel}
1046
+ </div>
1047
+ <pre
1048
+ role="region"
1049
+ aria-label={toolResultLabel}
1050
+ tabIndex={0}
1051
+ className="agentkit-activity-summary-value"
1052
+ >
1053
+ {toolResult}
1054
+ </pre>
1055
+ </div>
1056
+ ) : null}
661
1057
  </div>
662
1058
  ) : null}
663
1059
  </div>
@@ -710,18 +1106,27 @@ function RepeatedActivityCluster({
710
1106
  activities: AgentActivity[];
711
1107
  threadId: string;
712
1108
  }) {
713
- const { slots, registry } = useAgentKit();
1109
+ const { slots, registry, labels } = useAgentKit();
714
1110
  const thread = useAgentThread();
715
1111
  const [open, setOpen] = useState(false);
716
1112
  const activity = activities[0];
717
1113
  if (!activity) return null;
718
1114
  const agent = activity.agentId ? thread.agents[activity.agentId] : undefined;
1115
+ const agentName = resolveAgentName(
1116
+ thread,
1117
+ activity.agentId,
1118
+ [activity.source, activity.object],
1119
+ labels.assistant,
1120
+ );
719
1121
  const AgentRenderer = agent
720
1122
  ? (registry.agents?.[agent.kind ?? ""] ??
721
1123
  slots.agent ??
722
1124
  AgentParticipantView)
723
1125
  : undefined;
724
1126
  const ObjectRenderer = slots.object ?? AgentObjectReferenceView;
1127
+ const object =
1128
+ activity.object ??
1129
+ sourceObjectUnlessRepresented(activity.source, [activity.agentId]);
725
1130
  return (
726
1131
  <details
727
1132
  className="agentkit-activity-cluster"
@@ -739,15 +1144,16 @@ function RepeatedActivityCluster({
739
1144
  {agent && AgentRenderer ? (
740
1145
  <AgentRenderer value={agent} threadId={threadId} />
741
1146
  ) : activity.agentId ? (
742
- <AgentIdentityChip id={activity.agentId} name={activity.agentId} />
743
- ) : null}
744
- <span className="agentkit-activity-label">{activity.label}</span>
745
- {activity.object ? (
746
- <ObjectRenderer value={activity.object} threadId={threadId} />
747
- ) : null}
748
- {!activity.object && activity.source ? (
749
- <ObjectRenderer value={activity.source} threadId={threadId} />
1147
+ <AgentIdentityChip
1148
+ id={activity.agentId}
1149
+ name={agentName}
1150
+ fallbackName={labels.assistant}
1151
+ />
750
1152
  ) : null}
1153
+ <span className="agentkit-activity-label">
1154
+ {activityLabel(activity, labels.working)}
1155
+ </span>
1156
+ {object ? <ObjectRenderer value={object} threadId={threadId} /> : null}
751
1157
  <span className="agentkit-activity-cluster-count">
752
1158
  ×{activities.length}
753
1159
  </span>
@@ -776,12 +1182,17 @@ function formatToolDiagnostic(value: unknown): string | undefined {
776
1182
  }
777
1183
  }
778
1184
 
779
- function toolToActivity(tool: AgentToolCall): AgentActivity {
1185
+ function toolToActivity(
1186
+ tool: AgentToolCall,
1187
+ labels: Partial<AgentKitLabels> = {},
1188
+ ): AgentActivity {
780
1189
  const failed = tool.status === "failed";
781
1190
  const errorMessage = failed
782
- ? ((tool.error?.message?.trim() ? tool.error.message : undefined) ??
783
- formatToolDiagnostic(tool.output) ??
784
- formatToolDiagnostic(tool.error?.details))
1191
+ ? ((tool.error?.message?.trim()
1192
+ ? formatActivityToolValue(tool.error.message, labels)
1193
+ : undefined) ??
1194
+ formatActivityToolValue(tool.output, labels) ??
1195
+ formatActivityToolValue(tool.error?.details, labels))
785
1196
  : undefined;
786
1197
  return {
787
1198
  id: tool.id,
@@ -1152,7 +1563,11 @@ export function AgentActivityGroup({
1152
1563
  toolMap.set(event.toolCall.id, tool);
1153
1564
  remember(event.toolCall.id, event.sequence);
1154
1565
  latestEventOrder.set(event.toolCall.id, eventOrder);
1155
- rememberUsefulActivity(toolToActivity(tool), event.sequence, eventOrder);
1566
+ rememberUsefulActivity(
1567
+ toolToActivity(tool, labels),
1568
+ event.sequence,
1569
+ eventOrder,
1570
+ );
1156
1571
  }
1157
1572
  if (event.type === "tool.delta") {
1158
1573
  if (excludeAgentActivities && delegatedToolIds.has(event.toolCallId)) {
@@ -1162,7 +1577,7 @@ export function AgentActivityGroup({
1162
1577
  if (tool) {
1163
1578
  toolMap.set(tool.id, tool);
1164
1579
  rememberUsefulActivity(
1165
- toolToActivity(tool),
1580
+ toolToActivity(tool, labels),
1166
1581
  event.sequence,
1167
1582
  eventOrder,
1168
1583
  );
@@ -1183,7 +1598,7 @@ export function AgentActivityGroup({
1183
1598
  const activity = activityMap.get(id);
1184
1599
  if (activity) return [activity];
1185
1600
  const tool = toolMap.get(id);
1186
- return tool ? [toolToActivity(tool)] : [];
1601
+ return tool ? [toolToActivity(tool, labels)] : [];
1187
1602
  });
1188
1603
  const durableToolResults = items.flatMap((activity) => {
1189
1604
  const tool = toolMap.get(activity.id);
@@ -1276,7 +1691,9 @@ export function AgentActivityGroup({
1276
1691
  status: "running",
1277
1692
  })
1278
1693
  : undefined;
1279
- const currentActivityLabel = currentActivity?.label;
1694
+ const currentActivityLabel = currentActivity
1695
+ ? activityLabel(currentActivity, labels.working)
1696
+ : undefined;
1280
1697
  const displayGroups: AgentActivity[][] = [];
1281
1698
  const clusterIdentity = (activity: AgentActivity) => {
1282
1699
  const tool = toolMap.get(activity.id);
@@ -1640,12 +2057,18 @@ export function AgentTaskItem({
1640
2057
  value: task,
1641
2058
  threadId,
1642
2059
  }: AgentKitRenderProps<AgentTask>) {
1643
- const { slots, registry } = useAgentKit();
2060
+ const { slots, registry, labels } = useAgentKit();
1644
2061
  const thread = useAgentThread();
1645
2062
  const ObjectRenderer = slots.object ?? AgentObjectReferenceView;
1646
2063
  const agent = task.assignedAgentId
1647
2064
  ? thread.agents[task.assignedAgentId]
1648
2065
  : undefined;
2066
+ const agentName = resolveAgentName(
2067
+ thread,
2068
+ task.assignedAgentId,
2069
+ [task.source, task.object],
2070
+ labels.assistant,
2071
+ );
1649
2072
  const AgentRenderer = agent
1650
2073
  ? (registry.agents?.[agent.kind ?? ""] ??
1651
2074
  slots.agent ??
@@ -1654,25 +2077,34 @@ export function AgentTaskItem({
1654
2077
  const progress = task.progress
1655
2078
  ? `${task.progress.completed}/${task.progress.total}`
1656
2079
  : undefined;
2080
+ const title =
2081
+ humanizeAgentLabel(task.title) ||
2082
+ (task.assignedAgentId ? agentName : labels.tasks);
2083
+ const detail = readableText(task.detail);
2084
+ const object =
2085
+ task.object ??
2086
+ sourceObjectUnlessRepresented(task.source, [task.assignedAgentId]);
2087
+ const showAgent =
2088
+ task.assignedAgentId &&
2089
+ title.toLocaleLowerCase() !== agentName.toLocaleLowerCase();
1657
2090
  return (
1658
2091
  <div className="agentkit-task-row" data-status={task.status}>
1659
2092
  <IconChecklist aria-hidden="true" className="agentkit-icon" />
1660
- {agent && AgentRenderer ? (
2093
+ {showAgent && agent && AgentRenderer ? (
1661
2094
  <AgentRenderer value={agent} threadId={threadId} />
1662
- ) : task.assignedAgentId ? (
2095
+ ) : showAgent && task.assignedAgentId ? (
1663
2096
  <AgentIdentityChip
1664
2097
  id={task.assignedAgentId}
1665
- name={task.assignedAgentId}
2098
+ name={agentName}
2099
+ fallbackName={labels.assistant}
1666
2100
  />
1667
2101
  ) : null}
1668
- <span className="agentkit-task-title">{task.title}</span>
1669
- {task.object ? (
1670
- <ObjectRenderer value={task.object} threadId={threadId} />
1671
- ) : null}
1672
- {!task.object && task.source ? (
1673
- <ObjectRenderer value={task.source} threadId={threadId} />
1674
- ) : !task.object && task.detail ? (
1675
- <span className="agentkit-task-detail">{task.detail}</span>
2102
+ <span className="agentkit-task-title">{title}</span>
2103
+ {object ? <ObjectRenderer value={object} threadId={threadId} /> : null}
2104
+ {detail ? (
2105
+ <span className="agentkit-task-detail" title={detail}>
2106
+ {detail}
2107
+ </span>
1676
2108
  ) : null}
1677
2109
  {progress ? (
1678
2110
  <span className="agentkit-task-progress">{progress}</span>