@kuntur/a2a-carbon-chat-adapter 0.1.6 → 0.1.8

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/dist/index.d.cts CHANGED
@@ -1203,6 +1203,7 @@ interface TranslatorState {
1203
1203
  responseId: string;
1204
1204
  itemId: string;
1205
1205
  accumulatedText: string;
1206
+ accumulatedThinking: string;
1206
1207
  reasoningSteps: ReasoningStep[];
1207
1208
  chainOfThought: ChainOfThoughtStep[];
1208
1209
  pendingToolCalls: Map<string, number>;
@@ -1260,6 +1261,10 @@ declare class A2AToCarbonTranslator {
1260
1261
  * Get accumulated text
1261
1262
  */
1262
1263
  getAccumulatedText(): string;
1264
+ /**
1265
+ * Get accumulated thinking content (for reasoning.content mode)
1266
+ */
1267
+ getAccumulatedThinking(): string;
1263
1268
  /**
1264
1269
  * Get current reasoning steps
1265
1270
  */
@@ -1300,7 +1305,11 @@ declare class A2AToCarbonTranslator {
1300
1305
  */
1301
1306
  translatePart(part: A2APartWithMetadata, artifactMetadata?: Record<string, unknown>): CarbonStreamChunk | null;
1302
1307
  /**
1303
- * Translate thinking/reasoning content to Carbon reasoning step
1308
+ * Translate thinking/reasoning content to Carbon format
1309
+ *
1310
+ * ROUTING LOGIC:
1311
+ * - content_type='thinking' (no title) → reasoning.content (streaming)
1312
+ * - content_type='reasoning_step' WITH title → reasoning.steps[] (discrete)
1304
1313
  */
1305
1314
  private translateThinkingPart;
1306
1315
  /**
package/dist/index.d.ts CHANGED
@@ -1203,6 +1203,7 @@ interface TranslatorState {
1203
1203
  responseId: string;
1204
1204
  itemId: string;
1205
1205
  accumulatedText: string;
1206
+ accumulatedThinking: string;
1206
1207
  reasoningSteps: ReasoningStep[];
1207
1208
  chainOfThought: ChainOfThoughtStep[];
1208
1209
  pendingToolCalls: Map<string, number>;
@@ -1260,6 +1261,10 @@ declare class A2AToCarbonTranslator {
1260
1261
  * Get accumulated text
1261
1262
  */
1262
1263
  getAccumulatedText(): string;
1264
+ /**
1265
+ * Get accumulated thinking content (for reasoning.content mode)
1266
+ */
1267
+ getAccumulatedThinking(): string;
1263
1268
  /**
1264
1269
  * Get current reasoning steps
1265
1270
  */
@@ -1300,7 +1305,11 @@ declare class A2AToCarbonTranslator {
1300
1305
  */
1301
1306
  translatePart(part: A2APartWithMetadata, artifactMetadata?: Record<string, unknown>): CarbonStreamChunk | null;
1302
1307
  /**
1303
- * Translate thinking/reasoning content to Carbon reasoning step
1308
+ * Translate thinking/reasoning content to Carbon format
1309
+ *
1310
+ * ROUTING LOGIC:
1311
+ * - content_type='thinking' (no title) → reasoning.content (streaming)
1312
+ * - content_type='reasoning_step' WITH title → reasoning.steps[] (discrete)
1304
1313
  */
1305
1314
  private translateThinkingPart;
1306
1315
  /**
package/dist/index.js CHANGED
@@ -625,6 +625,8 @@ var A2AToCarbonTranslator = class {
625
625
  responseId: this.generateResponseId(),
626
626
  itemId: "1",
627
627
  accumulatedText: "",
628
+ accumulatedThinking: "",
629
+ // Initialize empty for streaming thinking tokens
628
630
  reasoningSteps: [],
629
631
  chainOfThought: [],
630
632
  pendingToolCalls: /* @__PURE__ */ new Map(),
@@ -686,6 +688,12 @@ var A2AToCarbonTranslator = class {
686
688
  getAccumulatedText() {
687
689
  return this.state.accumulatedText;
688
690
  }
691
+ /**
692
+ * Get accumulated thinking content (for reasoning.content mode)
693
+ */
694
+ getAccumulatedThinking() {
695
+ return this.state.accumulatedThinking;
696
+ }
689
697
  /**
690
698
  * Get current reasoning steps
691
699
  */
@@ -740,7 +748,7 @@ var A2AToCarbonTranslator = class {
740
748
  }
741
749
  };
742
750
  if (includeReasoning) {
743
- chunk.partial_response.message_options.reasoning = { steps: [] };
751
+ chunk.partial_response.message_options.reasoning = { content: "" };
744
752
  }
745
753
  return chunk;
746
754
  }
@@ -858,17 +866,58 @@ var A2AToCarbonTranslator = class {
858
866
  return null;
859
867
  }
860
868
  /**
861
- * Translate thinking/reasoning content to Carbon reasoning step
869
+ * Translate thinking/reasoning content to Carbon format
870
+ *
871
+ * ROUTING LOGIC:
872
+ * - content_type='thinking' (no title) → reasoning.content (streaming)
873
+ * - content_type='reasoning_step' WITH title → reasoning.steps[] (discrete)
862
874
  */
863
875
  translateThinkingPart(text, metadata) {
864
- const stepNumber = metadata?.step;
876
+ const contentType = metadata?.content_type;
865
877
  const stepTitle = metadata?.title;
878
+ if (contentType === "thinking" || !stepTitle) {
879
+ this.state.accumulatedThinking += text;
880
+ console.log("[Translator] Streaming thinking token:", {
881
+ tokenLength: text.length,
882
+ totalLength: this.state.accumulatedThinking.length
883
+ });
884
+ return {
885
+ partial_item: {
886
+ response_type: MessageResponseTypes.TEXT,
887
+ text: "",
888
+ streaming_metadata: {
889
+ id: this.state.itemId,
890
+ cancellable: true
891
+ }
892
+ },
893
+ partial_response: {
894
+ message_options: {
895
+ response_user_profile: this.agentProfile,
896
+ reasoning: {
897
+ content: this.state.accumulatedThinking,
898
+ // Stream to content
899
+ // Preserve any existing discrete steps
900
+ steps: this.state.reasoningSteps.length > 0 ? this.state.reasoningSteps : void 0
901
+ }
902
+ }
903
+ },
904
+ streaming_metadata: {
905
+ response_id: this.state.responseId
906
+ }
907
+ };
908
+ }
866
909
  const newStep = {
867
- title: stepTitle || `Thinking Step ${(stepNumber ?? this.state.reasoningSteps.length) + 1}`,
910
+ title: stepTitle,
911
+ // No fallback - only real titles become discrete steps
868
912
  content: text,
869
913
  open_state: "default" /* DEFAULT */
870
914
  };
871
915
  this.state.reasoningSteps.push(newStep);
916
+ console.log("[Translator] Added discrete reasoning step:", {
917
+ title: stepTitle,
918
+ textLength: text.length,
919
+ totalSteps: this.state.reasoningSteps.length
920
+ });
872
921
  return {
873
922
  partial_item: {
874
923
  response_type: MessageResponseTypes.TEXT,
@@ -882,9 +931,10 @@ var A2AToCarbonTranslator = class {
882
931
  message_options: {
883
932
  response_user_profile: this.agentProfile,
884
933
  reasoning: {
934
+ // Include accumulated streaming content if any
935
+ content: this.state.accumulatedThinking || void 0,
885
936
  steps: this.state.reasoningSteps,
886
937
  open_state: "default" /* DEFAULT */
887
- // Auto-expand during streaming
888
938
  }
889
939
  }
890
940
  },
@@ -1063,6 +1113,14 @@ var A2AToCarbonTranslator = class {
1063
1113
  * Optional but useful for accessibility and corrections.
1064
1114
  */
1065
1115
  createCompleteItem(wasStopped = false) {
1116
+ const hasThinking = this.state.accumulatedThinking.length > 0;
1117
+ const hasSteps = this.state.reasoningSteps.length > 0;
1118
+ const reasoning = hasThinking || hasSteps ? {
1119
+ content: hasThinking ? this.state.accumulatedThinking : void 0,
1120
+ steps: hasSteps ? this.state.reasoningSteps : void 0,
1121
+ open_state: "close" /* CLOSE */
1122
+ // Collapse after completion
1123
+ } : void 0;
1066
1124
  return {
1067
1125
  complete_item: {
1068
1126
  response_type: MessageResponseTypes.TEXT,
@@ -1075,11 +1133,7 @@ var A2AToCarbonTranslator = class {
1075
1133
  partial_response: {
1076
1134
  message_options: {
1077
1135
  response_user_profile: this.agentProfile,
1078
- reasoning: this.state.reasoningSteps.length > 0 ? {
1079
- steps: this.state.reasoningSteps,
1080
- open_state: "close" /* CLOSE */
1081
- // Collapse after completion
1082
- } : void 0,
1136
+ reasoning,
1083
1137
  chain_of_thought: this.state.chainOfThought.length > 0 ? this.state.chainOfThought : void 0
1084
1138
  }
1085
1139
  },
@@ -1095,6 +1149,14 @@ var A2AToCarbonTranslator = class {
1095
1149
  * Without this, the UI will remain in a loading state.
1096
1150
  */
1097
1151
  createFinalResponse() {
1152
+ const hasThinking = this.state.accumulatedThinking.length > 0;
1153
+ const hasSteps = this.state.reasoningSteps.length > 0;
1154
+ const reasoning = hasThinking || hasSteps ? {
1155
+ content: hasThinking ? this.state.accumulatedThinking : void 0,
1156
+ steps: hasSteps ? this.state.reasoningSteps : void 0,
1157
+ open_state: "close" /* CLOSE */
1158
+ // Collapse after completion
1159
+ } : void 0;
1098
1160
  return {
1099
1161
  final_response: {
1100
1162
  id: this.state.responseId,
@@ -1111,11 +1173,7 @@ var A2AToCarbonTranslator = class {
1111
1173
  },
1112
1174
  message_options: {
1113
1175
  response_user_profile: this.agentProfile,
1114
- reasoning: this.state.reasoningSteps.length > 0 ? {
1115
- steps: this.state.reasoningSteps,
1116
- open_state: "close" /* CLOSE */
1117
- // Collapse after completion
1118
- } : void 0,
1176
+ reasoning,
1119
1177
  chain_of_thought: this.state.chainOfThought.length > 0 ? this.state.chainOfThought : void 0
1120
1178
  }
1121
1179
  }
@@ -1724,6 +1782,13 @@ function A2AChat({
1724
1782
  const instanceRef = useRef(null);
1725
1783
  const translatorRef = useRef(null);
1726
1784
  const abortControllerRef = useRef(null);
1785
+ const [isViewOpen, setIsViewOpen] = useState(true);
1786
+ const [showExternalLauncher, setShowExternalLauncher] = useState(false);
1787
+ const [sidebarClosing, setSidebarClosing] = useState(false);
1788
+ const layoutRef = useRef(layout);
1789
+ useEffect(() => {
1790
+ layoutRef.current = layout;
1791
+ }, [layout]);
1727
1792
  useEffect(() => {
1728
1793
  if (typeof window !== "undefined") {
1729
1794
  import('@carbon/ai-chat').then((mod) => {
@@ -1740,6 +1805,40 @@ function A2AChat({
1740
1805
  useEffect(() => {
1741
1806
  onConnectionChange?.(connectionState);
1742
1807
  }, [connectionState, onConnectionChange]);
1808
+ const SIDEBAR_ANIMATION_MS = 250;
1809
+ const onViewChange = useCallback(
1810
+ (event) => {
1811
+ const currentLayout = layoutRef.current;
1812
+ setIsViewOpen(event.newViewState.mainWindow);
1813
+ if (currentLayout === "sidebar") {
1814
+ if (event.newViewState.mainWindow) {
1815
+ setShowExternalLauncher(false);
1816
+ setSidebarClosing(false);
1817
+ onOpen?.();
1818
+ } else {
1819
+ setSidebarClosing(false);
1820
+ setShowExternalLauncher(true);
1821
+ onClose?.();
1822
+ }
1823
+ }
1824
+ },
1825
+ [onOpen, onClose]
1826
+ );
1827
+ const onViewPreChange = useCallback(
1828
+ async (event) => {
1829
+ if (layoutRef.current === "sidebar" && !event.newViewState.mainWindow) {
1830
+ setSidebarClosing(true);
1831
+ await new Promise((resolve) => setTimeout(resolve, SIDEBAR_ANIMATION_MS));
1832
+ }
1833
+ },
1834
+ []
1835
+ );
1836
+ const handleOpenSidebar = useCallback(() => {
1837
+ const instance = instanceRef.current;
1838
+ if (instance?.actions?.changeView) {
1839
+ instance.actions.changeView("MAIN_WINDOW");
1840
+ }
1841
+ }, []);
1743
1842
  const handleSendMessage = useCallback(
1744
1843
  async (message) => {
1745
1844
  if (!agent) {
@@ -1892,6 +1991,21 @@ function A2AChat({
1892
1991
  instanceRef.current = instance;
1893
1992
  console.log("[A2AChat] Chat instance ready");
1894
1993
  }, []);
1994
+ const elementClassName = useMemo(() => {
1995
+ const classes = ["a2a-chat__element"];
1996
+ if (layout === "sidebar") {
1997
+ classes.push("a2a-chat__element--sidebar");
1998
+ if (sidebarClosing) {
1999
+ classes.push("a2a-chat__element--sidebar-closing");
2000
+ }
2001
+ } else if (layout === "fullscreen") {
2002
+ classes.push("a2a-chat__element--fullscreen");
2003
+ }
2004
+ if (!isViewOpen) {
2005
+ classes.push("cds-aichat--hidden");
2006
+ }
2007
+ return classes.join(" ");
2008
+ }, [layout, isViewOpen, sidebarClosing]);
1895
2009
  if (!agent) {
1896
2010
  return /* @__PURE__ */ jsx("div", { className: `a2a-chat a2a-chat--error ${className}`, children: /* @__PURE__ */ jsx("p", { children: "No agent configured. Provide `agent`, `agentId`, or `agentUrl` prop." }) });
1897
2011
  }
@@ -1945,7 +2059,7 @@ function A2AChat({
1945
2059
  ChatCustomElement,
1946
2060
  {
1947
2061
  ...{
1948
- className: "a2a-chat__element",
2062
+ className: elementClassName,
1949
2063
  debug: false,
1950
2064
  aiEnabled: true,
1951
2065
  openChatByDefault: true,
@@ -1962,6 +2076,8 @@ function A2AChat({
1962
2076
  showFrame: layout === "float",
1963
2077
  showCloseAndRestartButton: layout !== "fullscreen"
1964
2078
  },
2079
+ onViewChange,
2080
+ onViewPreChange,
1965
2081
  onAfterRender: handleAfterRender,
1966
2082
  renderUserDefinedResponse: renderCustomResponse,
1967
2083
  messaging: {
@@ -1976,6 +2092,29 @@ function A2AChat({
1976
2092
  }
1977
2093
  }
1978
2094
  ),
2095
+ layout === "sidebar" && showExternalLauncher && /* @__PURE__ */ jsx(
2096
+ "button",
2097
+ {
2098
+ className: "a2a-chat__external-launcher",
2099
+ onClick: handleOpenSidebar,
2100
+ "aria-label": "Open chat",
2101
+ title: "Open chat",
2102
+ children: /* @__PURE__ */ jsxs(
2103
+ "svg",
2104
+ {
2105
+ width: "24",
2106
+ height: "24",
2107
+ viewBox: "0 0 32 32",
2108
+ fill: "currentColor",
2109
+ "aria-hidden": "true",
2110
+ children: [
2111
+ /* @__PURE__ */ jsx("path", { d: "M17.74 30L16 29l4-7h6a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2H6a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h9v2H6a4 4 0 0 1-4-4V8a4 4 0 0 1 4-4h20a4 4 0 0 1 4 4v12a4 4 0 0 1-4 4h-4.84Z" }),
2112
+ /* @__PURE__ */ jsx("path", { d: "M8 10h16v2H8zM8 16h10v2H8z" })
2113
+ ]
2114
+ }
2115
+ )
2116
+ }
2117
+ ),
1979
2118
  formOverlay
1980
2119
  ] });
1981
2120
  }